Compare commits

...

426 commits

Author SHA1 Message Date
esy
61faabcbfd feat: add license
Some checks failed
Docker / Push (push) Has been cancelled
Laravel / Static Analysis (push) Has been cancelled
Laravel / Lint (push) Has been cancelled
Laravel / Tests (mariadb:10.2, 8.1) (push) Has been cancelled
Laravel / Tests (mariadb:10.2, 8.2) (push) Has been cancelled
Laravel / Tests (mariadb:10.9, 8.1) (push) Has been cancelled
Laravel / Tests (mariadb:10.9, 8.2) (push) Has been cancelled
Laravel / Tests (mysql:8, 8.1) (push) Has been cancelled
Laravel / Tests (mysql:8, 8.2) (push) Has been cancelled
Laravel / Tests (postgres:13, 8.1) (push) Has been cancelled
Laravel / Tests (postgres:13, 8.2) (push) Has been cancelled
Laravel / Tests (postgres:14, 8.1) (push) Has been cancelled
Laravel / Tests (postgres:14, 8.2) (push) Has been cancelled
Laravel / Tests (postgres:15, 8.1) (push) Has been cancelled
Laravel / Tests (postgres:15, 8.2) (push) Has been cancelled
UI / Lint (push) Has been cancelled
UI / Tests (16) (push) Has been cancelled
UI / Tests (18) (push) Has been cancelled
2024-09-23 20:07:52 +00:00
Matthew Penner
a9bdf7a1ef
Merge branch '1.0-develop' into develop 2023-10-02 17:06:39 -06:00
Matthew Penner
7fa0c26d80
Update README.md 2023-10-02 17:06:05 -06:00
Matthew Penner
804a08bd2e
nix: update flake.lock 2023-10-02 16:59:23 -06:00
Matthew Penner
8ffe0f1ff0
chore: fix eslint 2023-10-02 16:56:48 -06:00
Matthew Penner
9b35a55eea
ui: make the Input component slightly shorter 2023-09-29 16:34:56 -06:00
Matthew Penner
35ded9def8
ui(admin): fix server egg select improperly switching 2023-09-29 16:33:15 -06:00
Matthew Penner
3721b2007b
ui(admin): fix egg creation 2023-09-28 13:48:21 -06:00
Matthew Penner
6f5fb09c13
Merge branch '1.0-develop' into develop 2023-08-22 19:22:50 -06:00
Boy132
5a417e9adb
app(setup): replace mail with sendmail driver (#4750) 2023-08-22 19:18:05 -06:00
Boy132
51cee7688a
app: update prune-backup command description (#4754) 2023-08-22 19:17:18 -06:00
Boy132
67b2d944a6
ui(client): allow MassActionBar to be clicked through (#4753) 2023-08-22 19:12:57 -06:00
Matthew Penner
57d27293d2
github(template): update paste domain (#4757)
Switch from `bin.ptdl.co` to `pteropaste.com`
2023-08-22 15:08:14 -10:00
Boy132
1af200c464 Replace bin.ptdl.co with pteropaste.com
ptdl.co always has cert issues. pteropaste is used anywhere else (e.g. in Discord bot commands)
Also increased the line number to 150.
2023-08-22 15:05:55 -10:00
Matthew Penner
97049f48c3
ui(server): hide sensitive information in copy-on-click notifications (#4761) 2023-08-22 15:04:35 -10:00
Vadym
2d4071ca25 do not show strings with password in notification text 2023-08-22 15:03:47 -10:00
Matthew Penner
5cd2697be3
api(client): allow setting empty server description
Closes https://github.com/pterodactyl/panel/issues/4752
2023-08-22 15:02:56 -10:00
Robert Nisipeanu
85f1259709 fix(4752): check if description field present on request 2023-08-22 15:01:49 -10:00
Matthew Penner
bf1768406b
ui(server): fix permissions check on file manager (#4793) 2023-08-22 15:01:14 -10:00
Boy132
a83058668f only files check for "read-content", check folders for "read"
fixes #4792
2023-08-22 15:00:25 -10:00
Matthew Penner
987440c8ca
app: fix formatting 2023-08-22 18:59:34 -06:00
Matthew Penner
341fa0a52d
docker: fix log directory (#4839) 2023-08-22 14:59:12 -10:00
Michael Parker
aa2f797f6f fix panel log folder
resolves #4838

Fixes an issue with the log symlink as well
2023-08-22 14:57:45 -10:00
Matthew Penner
04d83edd36
app: fix getMySQLTimezoneOffset() truncating seconds
Previously the `getMySQLTimezoneOffset()` function would truncate the
seconds part of a time offset (returning `+9:00` instead of `+9:30`) for
example. This only affects timezones with offsets that contain minutes.

Closes https://github.com/pterodactyl/panel/issues/4821
Superseeds https://github.com/pterodactyl/panel/pull/4827

Co-authored-by: danny6167 <daniel@barteck.com.au>
2023-08-22 18:54:59 -06:00
Matthew Penner
15860613b6
Update README.md 2023-08-22 18:50:11 -06:00
Matthew Penner
3cd15d6f21
ci(docker): skip login on pull requests 2023-07-11 20:52:09 -06:00
Matthew Penner
d3c6568522
Merge branch '1.0-develop' into develop 2023-07-11 20:40:41 -06:00
Matthew Penner
29783ed240
egg(rust): add support for Carbon
Rebased version of #4734 to 1.0-develop
2023-07-11 20:37:14 -06:00
Matthew Penner
b7b128efc5
Merge branch '1.0-develop' into develop 2023-06-28 20:24:29 -06:00
Matthew Penner
7c8bdfc4d8
Update README.md 2023-06-28 20:23:53 -06:00
Matthew Penner
eaf46429f2
Merge branch '1.0-develop' into develop 2023-05-12 23:12:06 -06:00
Matthew Penner
bad765039b
Update README.md 2023-05-12 23:10:17 -06:00
Matthew Penner
b23f3114e4
Update README.md 2023-05-12 23:08:43 -06:00
Matthew Penner
dc6fadd1c5
Merge branch '1.0-develop' into develop 2023-03-11 14:12:23 -07:00
Matthew Penner
8bfcffc477
Update README.md 2023-03-11 14:11:34 -07:00
Matthew Penner
f5ce1a240c
ci: install pnpm 2023-02-23 14:39:45 -07:00
Matthew Penner
8320c64918
switch from yarn to pnpm 2023-02-23 14:37:12 -07:00
Matthew Penner
0d225b0e8f
ci(docker): revert workflow changes 2023-02-23 14:35:07 -07:00
Matthew Penner
8ae40a7c71
containerfile: remove platform arg 2023-02-23 14:22:31 -07:00
Matthew Penner
7241829da6
containerfile: reinstall tzdata
ref; https://bugzilla.redhat.com/show_bug.cgi?id=1870814
2023-02-23 14:09:24 -07:00
Matthew Penner
05d8de0671
ci(container): tweak options 2023-02-23 13:47:39 -07:00
Matthew Penner
f98aa11a3a
ci(container): update to ubuntu-22.04 2023-02-23 13:43:40 -07:00
Matthew Penner
ab4b4e6ada
ci(container): replace old docker workflow 2023-02-23 13:40:04 -07:00
Matthew Penner
673f7282e0
ui: fix prettier 2023-02-23 13:15:06 -07:00
Matthew Penner
2195aa6447
ci(docker): upgrade to php 8.2 2023-02-23 13:08:49 -07:00
Matthew Penner
187c7f74cd
yarn: upgrade dependencies 2023-02-23 13:08:40 -07:00
Matthew Penner
0af39492e3
app(services): fix DeployServerDatabaseService phpstan 2023-02-23 12:49:07 -07:00
Matthew Penner
733771ae75
nix: update flake lock 2023-02-23 12:48:53 -07:00
Matthew Penner
85df1a4ec7
ci(laravel): add PHP 8.2 to test matrix 2023-02-23 12:48:28 -07:00
Matthew Penner
a1e5afccb4
composer: update lock 2023-02-23 12:37:27 -07:00
Matthew Penner
18f6611a2d
Merge branch '1.0-develop' into develop 2023-02-23 12:36:22 -07:00
Matthew Penner
1d38b4f0e2
Laravel 10 (#4706) 2023-02-23 12:30:16 -07:00
Matthew Penner
ad4ddc6300
nix: update flake 2023-02-23 12:24:47 -07:00
Devonte W
b746c3ead1
fix(api/client): add validation for backup request body (#4704) 2023-02-23 12:23:12 -07:00
Devonte W
aea5c474db
fix(resources/api): allow svg xml format (#4705) 2023-02-23 12:19:58 -07:00
Matthew Penner
582c50c6d4
Merge branch '1.0-develop' into develop 2023-02-06 10:22:50 -07:00
Matthew Penner
2a7833ca17
Update README.md 2023-02-06 10:22:21 -07:00
Alex
9b47403e00
egg(rust): add server.queryport option (#4681) 2023-02-04 14:42:04 -07:00
Matthew Penner
3bd8164415
Merge branch '1.0-develop' into develop 2023-01-27 13:09:22 -07:00
Matthew Penner
43f7c10617
Update CHANGELOG.md 2023-01-27 12:24:55 -07:00
Matthew Penner
c5be3ad04b
nix: update flake lock 2023-01-25 13:34:47 -07:00
Matthew Penner
d8b7747828
ui(server): lazy load server console to reduce main bundle size 2023-01-25 11:39:07 -07:00
Matthew Penner
7c67ff3711
yarn: upgrade dependencies 2023-01-25 11:36:42 -07:00
Matthew Penner
d09e61b4f4
Update Containerfile to node 18, install composer through rpms 2023-01-25 11:36:28 -07:00
Matthew Penner
4b82ca1042
ui(admin): fix users list 2023-01-25 11:14:39 -07:00
Matthew Penner
5063db7d95
Merge branch '1.0-develop' into develop 2023-01-25 10:47:17 -07:00
Matthew Penner
866b6df4b0
api(task): ensure sequence_id always starts at 1 2023-01-24 16:19:34 -07:00
Matthew Penner
2b14e46eec
api: fix sequence_id being ignored in server task API
Closes #4434
2023-01-24 15:57:24 -07:00
Matthew Penner
20f23a0b27
db: add uuid column to failed_jobs table
Refer to
<https://laravel.com/docs/8.x/upgrade#failed-jobs-table-batch-support>
for more information regarding this change.

Closes #4652
2023-01-24 14:02:41 -07:00
Matthew Penner
a27ea3d1bc
config(queue): default to redis driver
Updates the default `QUEUE_CONNECTION` value to be `redis`
instead of `sync`.  This can cause problems if users skip
the initial setup or select the prefilled options rather
than the recommended ones.

Closes #4660
2023-01-24 13:48:34 -07:00
Matthew Penner
0b237071f2
Update README.md, fix CI status badge 2023-01-17 15:26:08 -07:00
Matthew Penner
62238ad418
Merge branch '1.0-develop' into develop 2023-01-17 15:25:28 -07:00
Matthew Penner
fbdac5b63f
ui(server): fix reinstall_failed conflict state 2023-01-17 15:21:31 -07:00
Jelco
c74314d2ab
Fix file repository not catching 404 responses (#4637) 2023-01-17 15:12:22 -07:00
Matthew Penner
dd595437e6
Update README.md, fix CI status badge 2023-01-17 15:06:56 -07:00
Boy132
2ed7f1c912
Fix MAIL_FROM_ADDRESS in EmailSettingsCommand (#4648) 2023-01-17 15:01:53 -07:00
Matthew Penner
7665eea14d
app(server): rename oom_disabled to oom_killer and invert existing values 2023-01-17 12:11:31 -07:00
Matthew Penner
450fba00bc
ui(admin): fix oom killer setting toggle 2023-01-17 11:43:26 -07:00
Matthew Penner
f6cf4a1236
ui: add read-only styling to Input element 2023-01-13 11:59:11 -07:00
Matthew Penner
e88197c4b1
ui: fix DashboardRouter trailing slashes 2023-01-13 11:58:40 -07:00
Matthew Penner
b59e1da860
tests: fix remaining failures 2023-01-12 13:19:01 -07:00
Matthew Penner
f45eac623c
chore: run php-cs-fixer 2023-01-12 12:46:40 -07:00
Matthew Penner
3d7112b702
ui: fix eslint 2023-01-12 12:45:07 -07:00
Matthew Penner
7e1aa8d7e2
ui: fix tests 2023-01-12 12:44:49 -07:00
Matthew Penner
155d7bb876
chore: run prettier 2023-01-12 12:31:47 -07:00
Matthew Penner
9cdbbc3a00
ui(admin): fix server editing 2023-01-12 12:25:58 -07:00
Matthew Penner
216c464ac8
ui(admin): update New Nest button 2023-01-12 12:12:06 -07:00
Matthew Penner
bc7737840a
ui(editor): fix editor child styling 2023-01-12 12:08:11 -07:00
Matthew Penner
76b67cb889
ui: fix IPv6 formatting logic 2023-01-12 11:28:11 -07:00
Matthew Penner
42d8f2cb82
ui(server): fix file editor and file manager 2023-01-12 11:22:24 -07:00
Matthew Penner
27e3eec5fc
yarn: upgrade @codemirror/* 2023-01-12 11:21:32 -07:00
Matthew Penner
f68864db00
Merge branch '1.0-develop' into develop 2023-01-01 15:26:55 -07:00
Matthew Penner
a2fb319ff5
Update README.md sponsors 2023-01-01 15:26:38 -07:00
Matthew Penner
089860b721
ui(admin): update button components, fix Editor for eggs 2022-12-21 14:27:55 -07:00
Matthew Penner
4e56f6dbea
yarn: upgrade dependencies 2022-12-21 14:27:07 -07:00
Matthew Penner
5402584508
ui(admin): add "working" React admin ui 2022-12-15 19:06:14 -07:00
Matthew Penner
d1c7494933
app: fix DeployServerDatabaseService 2022-12-15 12:39:37 -07:00
Matthew Penner
926c8563d0
user: cleanup 2022-12-15 12:26:34 -07:00
Matthew Penner
7f669828c6
tests: more fixes, but stuff is still broken 2022-12-14 19:53:07 -07:00
Matthew Penner
10b2380e9e
Make sure to actually update other references as well 2022-12-14 19:15:19 -07:00
Matthew Penner
8fff0846a0
Attempt to fix Fractal object type being null 2022-12-14 19:13:00 -07:00
Matthew Penner
507a802dec
database-host: reverse node relationship 2022-12-14 18:53:31 -07:00
Matthew Penner
0c5416ee27
cli: fix up command override 2022-12-14 18:43:20 -07:00
Matthew Penner
160c3ddeff
composer: update dependencies 2022-12-14 18:41:39 -07:00
Matthew Penner
a24c594cbd
user: remove name_first and name_last from tests 2022-12-14 18:23:46 -07:00
Matthew Penner
6b11836a41
user: remove name_first and name_last 2022-12-14 18:17:27 -07:00
Matthew Penner
2f15d94957
database: fix migrations with postgres 2022-12-14 18:17:16 -07:00
Matthew Penner
f68c46b0a0
eggs: remove config_logs field 2022-12-14 18:10:12 -07:00
Matthew Penner
3670dc6d4b
phpstan 2022-12-14 18:08:50 -07:00
Matthew Penner
7ed2be50fd
php-cs-fixer and phpstan 2022-12-14 18:04:16 -07:00
Matthew Penner
363c4fd49f
php-cs-fixer 2022-12-14 17:06:28 -07:00
Matthew Penner
67bf3e342e
api(application): v2 backport 2022-12-14 17:05:46 -07:00
Matthew Penner
4cd0bee231
yeet 2022-12-14 14:36:07 -07:00
Matthew Penner
7fde336036
Merge branch '1.0-develop' into develop 2022-12-14 14:21:01 -07:00
Omar Kamel
e43da311fe
api(client): keep existing server description when empty (#4619) 2022-12-14 14:19:45 -07:00
Matthew Penner
5fbc7a89e4
nix&docker: simplify Caddyfile 2022-12-12 19:23:03 -07:00
Matthew Penner
4138fb7497
Merge branch '1.0-develop' into develop 2022-12-12 16:23:11 -07:00
Matthew Penner
ac53e7b061
Update CHANGELOG.md 2022-12-12 16:09:09 -07:00
Matthew Penner
8978da335e
app(telemetry): disable server_usage for eggs and nests 2022-12-12 16:07:33 -07:00
VibeGAMESNL
680bce6d94
api(client): fix decompress timeout (#4568) 2022-12-12 16:07:13 -07:00
Matthew Penner
428311e854
database: fix mail settings migration 2022-12-12 15:47:48 -07:00
Matthew Penner
6df31e1923
database: fix migration transaction failure? 2022-12-12 15:26:47 -07:00
Matthew Penner
c8c648f0e5
php-cs-fixer 2022-12-12 15:14:37 -07:00
Matthew Penner
0751eeec97
database: add migration for new mail config keys 2022-12-12 15:12:03 -07:00
Matthew Penner
24e1c56378
Update SECURITY.md 2022-12-12 14:35:24 -07:00
Matthew Penner
4626118d77
app: fix remaining email config keys 2022-12-12 14:31:49 -07:00
Matthew Penner
6377e3309a
config(queue): fix queue names 2022-12-12 14:29:19 -07:00
Matthew Penner
c14fc1ccb0
config(mail): fix SERVER_NAME; closes #4600 2022-12-12 14:26:07 -07:00
Matthew Penner
63a179d7f3
app: fix email config keys 2022-12-12 14:21:47 -07:00
Matthew Penner
c44842e517
chore: run prettier 2022-12-12 14:09:22 -07:00
Matthew Penner
e64e28839b
Merge branch '1.0-develop' into develop 2022-12-12 14:06:52 -07:00
Matthew Penner
3b062ed2d9
yarn: upgrade dependencies 2022-12-12 14:01:31 -07:00
Matthew Penner
3432cadd4a
ci(docker): fix version starting with v prefix 2022-12-05 15:43:10 -07:00
Matthew Penner
411017198e
Update CHANGELOG.md 2022-12-05 13:16:03 -07:00
Matthew Penner
e763c72d63
ci(docker): fix version in app.php 2022-12-05 12:39:07 -07:00
Matthew Penner
a2970cd784
ci: tweak docker and release workflows 2022-12-05 09:58:13 -07:00
Matthew Penner
ca4aa795be
ci(docker): fix latest tag 2022-12-04 18:37:45 -07:00
Matthew Penner
c802b49b7a
ci(docker): fix app version 2022-12-04 18:36:26 -07:00
Matthew Penner
7d93f1566c
ci: overhaul workflows 2022-12-04 17:40:17 -07:00
Matthew Penner
598c956e4e
ui(server): fix file uploads being canceled instead of completed 2022-12-04 16:36:53 -07:00
Matthew Penner
158facd534
eslint: fix prettier config 2022-12-04 16:32:15 -07:00
Matthew Penner
dd69652942
Fix No application encryption key has been specified error while trying to generate said key 2022-12-04 16:09:42 -07:00
Matthew Penner
8425076f8b
Merge branch '1.0-develop' into develop 2022-12-04 15:27:52 -07:00
Matthew Penner
73b27aea8e
Update CHANGELOG.md 2022-12-04 15:27:21 -07:00
Matthew Penner
ae27a8a65c
Merge branch '1.0-develop' into develop 2022-12-04 15:10:06 -07:00
Matthew Penner
fa7503816a
Add telemetry prompt in p:environment:setup command 2022-12-04 14:59:45 -07:00
Matthew Penner
250c557e23
telemetry: include more detailed server egg and nest usage 2022-12-01 12:09:27 -07:00
Matthew Penner
6272bb6710
api(remote): cleanup 2022-12-01 11:52:22 -07:00
Matthew Penner
3c278a8c51
api(remote): check if transfer is present before trying to update status 2022-12-01 11:51:26 -07:00
Matthew Penner
794248d4d7
routes: fix imports 2022-12-01 11:51:26 -07:00
Matthew Penner
209711c826
ui(server): disable file manager upload, due to library issues 2022-11-29 14:39:48 -07:00
Matthew Penner
ee863fa262
phpstan 2022-11-29 10:56:16 -07:00
Matthew Penner
3ea6d45cda
php-cs-fixer 2022-11-29 10:53:59 -07:00
Matthew Penner
16e34af773
nix: add panel and container packages 2022-11-29 10:48:14 -07:00
Matthew Penner
56839a14c5
Update Containerfile 2022-11-29 10:45:30 -07:00
Matthew Penner
fd356c7219
composer: update dependencies 2022-11-29 10:44:52 -07:00
Wunderharke
c8f7bdf9cb
egg(teamspeak): fix database support (#4513) 2022-11-28 12:04:56 -07:00
TaktischerSpeck
75f36839df
egg(teamspeak): port and argument updates (#4546) 2022-11-28 11:59:48 -07:00
Lance Pioch
a1a52754ad
chore: add phpstan static analysis minimum (#4511) 2022-11-28 09:56:03 -07:00
Matthew Penner
3f7e2a565f
Merge branch '1.0-develop' into develop 2022-11-28 09:33:33 -07:00
Charles Morgan
a4e547dc67
ui(server): fix console searchbar z-index (#4587) 2022-11-27 19:38:28 -07:00
Matthew Penner
f76155aa13
ci(docker): update build-push-action from v2 to v3 2022-11-27 17:02:10 -07:00
Matthew Penner
dae40ee02d
ci(docker): temporarily disable arm64 dev build 2022-11-27 15:57:54 -07:00
Matthew Penner
db4aa86fbc
docker: cleanup, install shadow-utils 2022-11-27 12:41:35 -07:00
Matthew Penner
490690f1d0
docker: overhaul container image 2022-11-27 12:34:31 -07:00
Matthew Penner
c475d601f3
ui: remove unused codemirror 5 editor 2022-11-27 11:53:46 -07:00
Lance Pioch
3bf5a71802
PostgreSQL Support (#4486)
Co-authored-by: Matthew Penner <matthew@pterodactyl.io>
2022-11-25 13:29:04 -07:00
Matthew Penner
21613fa602
React 18 and Vite (#4510) 2022-11-25 13:25:03 -07:00
Matthew Penner
1bb1b13f6d
Update CHANGELOG.md 2022-11-22 13:40:58 -07:00
Matthew Penner
5b36313c57
Update README.md 2022-11-22 13:39:57 -07:00
Matthew Penner
ee033d6d08
Telemetry (#4564) 2022-11-22 13:39:43 -07:00
Dane Everitt
df9a7f71f9
Support canceling file uploads (#4441)
Closes #4440
2022-11-21 13:58:55 -07:00
Lance Pioch
a4f6870518
server: track reinstall failures differently from initial install failures (#4531) 2022-11-21 13:53:54 -07:00
Matthew Penner
039ad4abf0
api(server): log activity when server description is changed 2022-11-21 13:43:19 -07:00
Devonte W
634c9353e3
fix(transformers): force object type for properties (#4544) 2022-11-21 13:28:46 -07:00
Matthew Penner
c3521e0221
api(server): fix undefined header 2022-11-21 13:20:50 -07:00
Matthew Penner
2f4a60c961
ui(admin): change MB suffixes to MiB
Closes #4542
2022-11-21 13:10:00 -07:00
Matthew Penner
c1584d9a5b
Update CHANGELOG.md 2022-11-14 20:31:03 -07:00
Matthew Penner
897ca48ded
github: re-enable blank issues 2022-11-14 18:28:02 -07:00
Matthew Penner
df2402b54f
Streaming Transfers (#4548) 2022-11-14 18:25:07 -07:00
Boy132
032e4f2e31
Apply node maintenance mode to servers (#4421) 2022-11-06 16:02:30 -07:00
Lance Pioch
4032481a4f
Update validation rules for remote activity logs (#4526) 2022-11-06 15:42:48 -07:00
Lance Pioch
9b218f2190
URL encode password in JDBC connection string (#4527) 2022-11-06 15:24:33 -07:00
Alex
c068f57e4e
fix(forge): validate only input and not length (#4528)
Only allows digits, dots and dashes in the input, which is what Forge versions consists of. Removes arbitrary char limit.
2022-11-06 15:15:12 -07:00
Matthew Penner
f8ec8b4d5a
Merge branch 'develop' into 1.0-develop 2022-10-31 12:10:04 -06:00
Matthew Penner
d466934103
Laravel Sail (#4508) 2022-10-31 11:38:56 -06:00
Matthew Penner
846ff7644f
Fix missing email sender 2022-10-31 11:02:34 -06:00
Matthew Penner
b7a65436fa
Merge branch '1.0-develop' into develop 2022-10-31 10:59:35 -06:00
Matthew Penner
1b78030291
Fix compatibility with old queue names 2022-10-31 10:58:32 -06:00
Quinten
e21aab2537
Update mumble egg (#4437) 2022-10-31 10:29:29 -06:00
Lance Pioch
16c2b606b4
Add ManifestDoesNotExistException and Solution (#4455)
Co-authored-by: Matthew Penner <matthew@pterodactyl.io>
2022-10-31 10:29:10 -06:00
Boy132
f2095e815e
Allow users to change the server description (#4420) 2022-10-31 10:20:53 -06:00
Matthew Penner
b1abae8106
Update README.md 2022-10-30 13:58:29 -06:00
Lance Pioch
548affba84
Fix linting (#4504) 2022-10-29 17:58:55 -06:00
Matthew Penner
5f57e63fe4
ci(lint): install composer dependencies 2022-10-26 10:45:43 -06:00
Matthew Penner
6f0bb43314
ci: cleanup, add dedicated lint workflow 2022-10-26 10:43:05 -06:00
Jelco
5c78b380c5
Fix InMemoryFilesystemAdapter (#4489) 2022-10-26 10:26:56 -06:00
Matthew Penner
d31ece1c75
nix: add flake with dev shell 2022-10-24 09:48:30 -06:00
Lance Pioch
e49ba65709
Fix config key names (#4464) 2022-10-23 18:51:20 -06:00
Matthew Penner
7266c66ebf
un-type getRulesForUpdate; fixes #4463 2022-10-23 18:14:50 -06:00
Lance Pioch
860b2d890b
Fix php artisan up (#4457) 2022-10-21 11:31:59 -06:00
Matthew Penner
5331fd2cdb
ci(docker): build local code checkout, add caching to dev build 2022-10-20 14:32:23 -06:00
Matthew Penner
4dd30fe2f0
composer: update lock 2022-10-19 22:47:53 -06:00
Dane Everitt
d1beb2e1ad
Fix file verification on upload; just block folders (#4442) 2022-10-16 17:24:49 -06:00
Matthew Penner
9c6822f62d
Update CHANGELOG.md 2022-10-16 12:34:36 -06:00
Matthew Penner
2828a4b1e0
fix AssetManifestService error when loading the panel 2022-10-14 11:00:10 -06:00
Matthew Penner
cbcf62086f
Upgrade to Laravel 9 (#4413)
Co-authored-by: DaneEveritt <dane@daneeveritt.com>
2022-10-14 10:59:20 -06:00
Matthew Penner
95e15d2c8a
Cleanup FQDN validation logic, fallback to old hostname check (#4409)
Co-authored-by: DaneEveritt <dane@daneeveritt.com>
2022-10-09 16:19:16 -06:00
Dane Everitt
c748fa9842
fix: exclude any permissions not defined internally when updating or creating subusers (#4416) 2022-10-09 16:14:16 -06:00
Cubxity
597821b3bb
fix: byte units (#4419) 2022-10-09 16:09:24 -06:00
Dane Everitt
e0e0689846
feat: bump account key limit to 25 (#4417)
Closes #4394
2022-10-08 15:14:03 -06:00
DaneEveritt
2e61a4db13
fix: eslint errors 2022-10-08 11:30:14 -07:00
Matthew Penner
ba10646e8a
Update CONTRIBUTING.md and SECURITY.md 2022-10-05 10:31:06 -06:00
Matthew Penner
ac8629d449
Update CHANGELOG.md 2022-10-04 20:49:03 -06:00
Devonte
9b531d5fd9
Include oom_disabled in application API request (#4262) 2022-10-04 20:12:46 -06:00
Aspect
d7b387be3e
Show UptimeDuration for starting servers (#4284) 2022-10-04 20:12:07 -06:00
Matthew Penner
7b91c38396
Lookup both A and AAAA records for node FQDNs (#4398)
Allows IPv6 addresses to be used, instead of IPv4 being required.

Closes <https://github.com/pterodactyl/panel/issues/4011>
2022-10-04 20:03:52 -06:00
Matthew Penner
815e1e4c4d
Ensure server is not in a conflicting state before initiating a transfer (#4403) 2022-10-04 19:57:24 -06:00
Matthew Penner
ff37c51eef
Use different clone logic for arrays (#4402)
Closes <https://github.com/pterodactyl/panel/issues/3985>
2022-10-04 19:48:08 -06:00
Matthew Penner
44598bf724
Support configuring storage class for S3 backup uploads (#4399)
Closes <https://github.com/pterodactyl/panel/issues/4072>
2022-10-04 19:39:25 -06:00
diamkil
6aede6b63d
Allow uploading multiple files via web UI (#4392) 2022-09-29 17:43:20 -06:00
Matthew Penner
16c110a489
Update FUNDING.yml 2022-09-26 11:23:48 -06:00
Matthew Penner
2dcc46ecd6
backups: support Cloudflare R2 by listing uploaded parts from Wings 2022-09-26 11:15:52 -06:00
Matthew Penner
0dc77aec25
Update README.md 2022-09-25 19:12:08 -06:00
Matthew Penner
9bcafd983f
admin: fix rendering of egg descriptions 2022-09-25 19:00:49 -06:00
Pascal Zarrad
1ca4b08b48
backups: add S3 part size configuration (#4382) 2022-09-25 14:38:49 -06:00
Matthew Penner
68e9100e57
admin(eggs): add force_outgoing_ip option (#4323)
Closes #3841
2022-09-25 13:24:54 -06:00
Boy132
b04a47a4a4
Handle "in:true,false" variable rules as checkbox (#4334) 2022-09-25 13:18:13 -06:00
Matthew Penner
8e1a21563e
server: add configuration for install notifications (#4331)
* server: track `installed_at`, only send install notification on first install
* server: add configuration for install notifications
2022-09-25 13:16:58 -06:00
SS
23124c9b08
docker: update README.md (#4388) 2022-09-25 13:11:45 -06:00
Harry W
a6b250913b
fix: page title for SSH keys (#4391) 2022-09-25 13:05:53 -06:00
DaneEveritt
e040fd1ebd
Fix display of database rows when password is not available
closes #4381
2022-09-17 11:50:40 -07:00
DaneEveritt
bf2456d0fc
Ensure eggs endpoint always returns an object, even when empty
closes #4296
2022-09-17 11:36:41 -07:00
Cam White (Jex)
b050174f90
Bump fork-ts-checker-webpack-plugin to 6.5.2 (#4357) 2022-09-05 14:01:03 -04:00
hz-ad
ab08afb2da
Updating sponsors (#4345) 2022-09-01 15:47:17 -04:00
DaneEveritt
be29fe1db2
Break activity log values ignoring word boundaries
Not my favorite approach, but it'll work. closes #4305
2022-08-07 15:00:43 -04:00
DaneEveritt
2da8042b0f
Fix clock() usage causing errors in prod environments 2022-07-24 20:43:14 -04:00
DaneEveritt
07f1ef4262
Update security versions 2022-07-24 19:45:49 -04:00
DaneEveritt
f614b443dd
Update CHANGELOG.md 2022-07-24 19:37:15 -04:00
DaneEveritt
03a6e26c4d
Improve create directory dialog 2022-07-24 19:23:45 -04:00
DaneEveritt
8d82aa2124
Improve design of drag & drop overlay 2022-07-24 18:59:20 -04:00
DaneEveritt
4458822c60
Cleanup file upload behavior 2022-07-24 18:50:47 -04:00
DaneEveritt
1cfa4100ad
Show an error if a user attempts to upload a folder 2022-07-24 18:22:50 -04:00
DaneEveritt
1d5d92f678
Use a different styling for file uploads 2022-07-24 18:03:45 -04:00
Boy132
12242848b0
File upload status (v2 backport) (#4219) 2022-07-24 17:18:32 -04:00
DaneEveritt
2eda1995b9
Send server name and description to wings to make available to replacers 2022-07-24 17:15:24 -04:00
DaneEveritt
abac317802
Make recaptcha domain configurable 2022-07-24 17:13:17 -04:00
DaneEveritt
f8c48214a5
Track file uploads on Wings, not the panel 2022-07-24 17:13:17 -04:00
Alex
6a11c32bb2
fix: do not style 2fa QR code (#4278)
Dark rounded background shadow around the QR code makes it more difficult or impossible to scan on some devices. Replaces it with a white shadow to make easier scanning.
2022-07-24 17:10:59 -04:00
Michael (Parker) Parker
eb503c5523
fix docker builds (#4249)
Updates php to 8.1
Resolves the issue when running docker-compose unconfigured redirects to https.
2022-07-16 08:48:40 -04:00
simonmicro
1250713299
Changed scroll down indicator icon (#4231)
Co-authored-by: Dane Everitt <dane@daneeveritt.com>
2022-07-16 08:48:10 -04:00
Simon Stjernholm
5700dd6a8e
fixes loading overlay to console only (#4246)
Co-authored-by: DaneEveritt <dane@daneeveritt.com>
2022-07-16 08:30:00 -04:00
DaneEveritt
d4708e9e63
Always show IP address to admins 2022-07-10 14:56:19 -04:00
DaneEveritt
d6c30092ec
Utilize a unique ID for activity logs to improve rendering perf 2022-07-10 14:53:29 -04:00
DaneEveritt
e878015109
Correctly wrap content in pre tag so it doesn't overflow 2022-07-10 14:53:15 -04:00
DaneEveritt
edbbe520a7
Fix missing padding on overflowing dialogs 2022-07-10 14:52:57 -04:00
DaneEveritt
7558c0380e
Don't log SFTP logins, it just is noisy 2022-07-10 14:30:11 -04:00
DaneEveritt
8b59c1c1a8
Support new sftp event types 2022-07-10 13:47:19 -04:00
DaneEveritt
33ab762f5a
Add support for tracking more SFTP specific events 2022-07-09 19:30:38 -04:00
DaneEveritt
2e01891074
Account for natural event naming 2022-07-09 17:53:07 -04:00
DaneEveritt
1eee55b27c
Add endpoint needed for recieving and processing activity 2022-07-09 17:45:38 -04:00
DaneEveritt
9b8479e85d
Update README.md 2022-07-09 12:01:24 -04:00
DaneEveritt
26d7d7e0e0
Fix SWR key logic 2022-07-04 18:22:58 -04:00
DaneEveritt
d6b6ac6dab
Key activity log cache to the server instance, not the user instance. 2022-07-04 18:13:15 -04:00
DaneEveritt
4a8c3c4a34
Add activity tracking for console/power actions 2022-07-04 18:11:53 -04:00
DaneEveritt
dc90d8b505
Include the "user_uuid" claim on JWTs for easier Wings user tracking 2022-07-04 17:34:56 -04:00
DaneEveritt
74c3b00828
Update CHANGELOG.md 2022-07-03 19:51:12 -04:00
DaneEveritt
15aaa2b3c3
Fix display issues due to removal of quirks mode 2022-07-03 14:44:00 -04:00
DaneEveritt
0216e3fd5b
Don't log activity if the email wasn't actually changed 2022-07-03 14:29:01 -04:00
DaneEveritt
2d836156d2
Update totp disable modal; require password for enable operation 2022-07-03 14:27:37 -04:00
DaneEveritt
92926ca193
Cleanup logic powering totp enabling modal 2022-07-03 13:43:54 -04:00
DaneEveritt
a4feed24a8
Improve dialog logic, add "asDialog" helper 2022-07-03 13:29:23 -04:00
DaneEveritt
822949408f
Use new two-step configuration modal 2022-07-02 18:53:03 -04:00
DaneEveritt
870a964050
Fix checkboxes 2022-07-02 18:27:29 -04:00
DaneEveritt
e49e6ee802
Better dialog setting logic 2022-07-02 18:27:22 -04:00
DaneEveritt
7a6440988b
Support tooltip on disabled buttons, support click action 2022-07-02 17:24:49 -04:00
DaneEveritt
25d61525b3
Update new input styling 2022-07-02 17:24:24 -04:00
DaneEveritt
7c4028f8f1
Update dialog logic to support defining buttons/icon from anywhere 2022-07-02 17:24:12 -04:00
DaneEveritt
48af9bced1
Fix activity log rendering; closes #4208 2022-06-30 21:06:50 -04:00
DaneEveritt
0d0c595909
Show starting/stopping correctly in stats; closes #4209 2022-06-30 20:33:09 -04:00
DaneEveritt
3120e1d4a0
Fix console rendering on Safari; closes #4189 2022-06-30 20:30:01 -04:00
Boy132
003afb271b
fix: java version modal default value (#4216) 2022-06-30 20:23:40 -04:00
VinGal
cc06d1faa9
Fixes rounding when 0.001% or less on CPU usage. (#4207) 2022-06-30 20:23:27 -04:00
Arnaud Lier
ccea09c9d9
Enable standards mode (#4194) 2022-06-30 20:23:15 -04:00
DaneEveritt
4fa735da3f
Update CHANGELOG.md 2022-06-27 21:01:24 -04:00
DaneEveritt
20a7794a18
Fix incorrect type definitions 2022-06-27 20:54:58 -04:00
DaneEveritt
4aa163b76f
Hide IP addresses from activity logs not generated by the user themselves 2022-06-27 20:52:27 -04:00
DaneEveritt
b570769a34
Fix permission matching on routes; closes #4181 2022-06-27 20:41:49 -04:00
DaneEveritt
bd278b2688
Fix install warning display and make it reactive 2022-06-27 20:36:24 -04:00
Boy132
2dda151a49
fix: correct route for console (#4178)
fixes #4177
2022-06-27 20:21:12 -04:00
DaneEveritt
7886251cd8
Fix infinity display 2022-06-27 20:16:43 -04:00
DaneEveritt
050d4e7a36
Show the resource limits next to numbers 2022-06-27 20:14:55 -04:00
DaneEveritt
5f156e193a
Improve the graph display; hide the bottom bar when no data exists. 2022-06-27 19:59:36 -04:00
DaneEveritt
bf287c45d6
Logic improvements, move stat blocks to right side 2022-06-27 19:56:26 -04:00
DaneEveritt
ad6e9f076b
Fix copy to clipboard when clicking server address
closes #4187
2022-06-27 19:18:58 -04:00
DaneEveritt
72f545259f
Roll back changes to conversion unit (1000->1024)
closes #4183
2022-06-27 18:46:36 -04:00
Ziga Zajc
1b5d77dc17
Changed Mb to MB (#4171) 2022-06-27 18:30:46 -04:00
Boy132
ac997cd7a6
fix: use correct network stat (#4175) 2022-06-27 18:30:21 -04:00
Boy132
63cf6ee96e
fix: round cpu usage in chart (#4182)
fixes #4168
2022-06-27 18:30:00 -04:00
DaneEveritt
16725e656b
Bundle the new eslintrc config file 2022-06-26 21:18:53 -04:00
Argonaut Network
9bcf90db93
Fix grammatical error (#4138) 2022-06-26 21:17:02 -04:00
Torsten Widmann
8f2defc6f8
add new map to description (#4142) 2022-06-26 21:16:39 -04:00
Alex
3339a316ca
feat: use max percentage instead of xmx (#4146)
Replaces Xmx with a percentage-based argument, in this case leaving 5% overhead.

Resolves issue of container OOM/freezing when all memory is allocated to the java application or when users attempt to use unlimited memory of 0. That's because all the allocated memory is set to Xmx by default. Causes Wings resource overhead allocation to be unnecessary.

Expands Forge installer exit code to provide instructions regarding increasing Wings installer resource limits when using unlimited memory (0) as the default 1024MB is not enough to run the installer.

The percentage is set as a floating point, because of a JDK 8 bug with integers
2022-06-26 21:16:26 -04:00
DaneEveritt
c9ab0abba9
Use node 16 for all build actions 2022-06-26 21:09:40 -04:00
DaneEveritt
446562fcff
Update NodeFactory.php 2022-06-26 21:00:19 -04:00
DaneEveritt
80ae600fe1
Correctly update dependencies for release 2022-06-26 17:31:47 -04:00
DaneEveritt
13bdb66ff0
Revert "Package updates prior to release"
This reverts commit af2a84d379.
2022-06-26 17:19:12 -04:00
DaneEveritt
af2a84d379
Package updates prior to release 2022-06-26 17:11:55 -04:00
DaneEveritt
3f2bd78563
Generate a more unique username 2022-06-26 16:37:43 -04:00
DaneEveritt
43156e8d53
Improve error messaging for validation exceptions 2022-06-26 16:31:48 -04:00
DaneEveritt
271197e823
Fix cs-fix run 2022-06-26 16:21:07 -04:00
DaneEveritt
c166f1305b
Remove unused deps 2022-06-26 16:14:32 -04:00
DaneEveritt
d172d2829f
Update CHANGELOG.md 2022-06-26 15:42:11 -04:00
DaneEveritt
fc6c8f1d82
remove old eslint config 2022-06-26 15:30:30 -04:00
DaneEveritt
922d75f471
fix remaining eslint error 2022-06-26 15:30:05 -04:00
DaneEveritt
dc84af9937
Apply new eslint rules; default to prettier for styling 2022-06-26 15:13:52 -04:00
DaneEveritt
f22cce8881
Update eslint parsers for new typescript version 2022-06-26 14:38:58 -04:00
DaneEveritt
1eb3ea2ee4
Some code cleanup, add jest coverage and begin using it for utility functions 2022-06-26 14:34:09 -04:00
DaneEveritt
ca39830333
allow filtering servers by description; closes #4150 2022-06-26 13:26:12 -04:00
DaneEveritt
b3a57bd0ad
fix includes for client API keys on admin accounts; closes #4164 2022-06-26 13:23:22 -04:00
DaneEveritt
82d8713b5d
Fix allocation display when a description is present 2022-06-25 21:41:52 -04:00
DaneEveritt
47d6235ea0
Keep server address at the top 2022-06-25 21:31:10 -04:00
DaneEveritt
00338e431b
Automatically hide the kill modal when server stops 2022-06-25 21:29:41 -04:00
DaneEveritt
76f3b996fe
Auto resize values when they'd overflow the container 2022-06-25 21:27:18 -04:00
DaneEveritt
182507ff0e
Upgrade charts to ChartJS 3 and improve UI for them 2022-06-25 20:51:49 -04:00
Dane Everitt
980f828edd
Update README.md 2022-06-24 10:51:39 -04:00
DaneEveritt
54c619e6ba
Some mobile improvements for the UI; make console fill space better 2022-06-21 18:43:59 -04:00
DaneEveritt
faff263f17
First pass at new server console design 2022-06-20 17:26:47 -04:00
DaneEveritt
61018b5e67
Update more of the UI to use new design elements 2022-06-20 15:28:27 -04:00
DaneEveritt
2824db7352
Update file manager design a bit 2022-06-20 14:16:42 -04:00
DaneEveritt
8bd518048e
Fix excessive re-rendering due to route changesd 2022-06-20 13:19:40 -04:00
DaneEveritt
7b0e2ce99d
Button styling cleanup, prop consistency 2022-06-20 12:38:23 -04:00
DaneEveritt
7dd74ecc9d
Modal cleanup, begin transitioning towards the new dialog 2022-06-20 11:17:33 -04:00
DaneEveritt
3834aca3fe
Use nicer avatars when showing activity log 2022-06-19 13:46:15 -04:00
DaneEveritt
76472411e3
Some better activity translations 2022-06-18 16:36:19 -04:00
DaneEveritt
cf01490883
Support hiding activity from admin accounts not associated with the server 2022-06-18 15:48:22 -04:00
DaneEveritt
95de4c30fc
Abuse the translation engine to handle more of the formatting for us 2022-06-18 15:28:42 -04:00
DaneEveritt
b052d29a5f
Fix failing integration test 2022-06-18 14:25:24 -04:00
DaneEveritt
7224ca81de
Fix bug preventing the creation of API keys with CIDR ranges 2022-06-18 14:21:20 -04:00
DaneEveritt
d47a05881b
Show when an event was triggered via the API directly 2022-06-18 12:52:26 -04:00
DaneEveritt
4f3651b578
Fix typo with identifier 2022-06-18 12:16:54 -04:00
DaneEveritt
0520014c0f
Add support for tracking when an activity event is triggered from an API key 2022-06-18 12:07:44 -04:00
DaneEveritt
92c1c162af
Code cleanup for facades 2022-06-18 12:07:32 -04:00
DaneEveritt
6ffe5730da
Log when an API key is blocked due to IP restrictions 2022-06-18 12:04:51 -04:00
DaneEveritt
0be96cfd26
Update README.md 2022-06-16 20:36:15 -04:00
DaneEveritt
cd97936179
Improve mobile support 2022-06-12 15:40:14 -04:00
DaneEveritt
68a654f9e8
Selectively show the additional metadata if it isn't in the display string at all 2022-06-12 15:30:49 -04:00
DaneEveritt
88987fb6c7
Correctly pull button styles 2022-06-12 15:17:14 -04:00
DaneEveritt
2f1c8ae91d
Add basic server activity log view 2022-06-12 15:16:48 -04:00
DaneEveritt
0b4936ff1c
Break out rows for activity; show metadata icon 2022-06-12 15:08:26 -04:00
DaneEveritt
33823b65de
Fix dialog and tooltip design 2022-06-12 15:07:52 -04:00
DaneEveritt
064a942574
Little bit of language cleanup 2022-06-12 13:36:42 -04:00
DaneEveritt
b50e722948
Add account related routes to router file 2022-06-12 13:33:25 -04:00
DaneEveritt
7197d28815
Chunk out the different routers and clean up feature logic 2022-06-12 11:56:00 -04:00
DaneEveritt
04e97cc67e
Make it easier for plugins to extend the navigation and add routes 2022-06-12 11:36:55 -04:00
DaneEveritt
88a7bd7578
Make the delay less goofy when mousing over elements 2022-06-12 09:39:20 -04:00
DaneEveritt
f860fd2cfe
Improve usability of icon buttons in header with tooltip 2022-06-12 09:35:02 -04:00
DaneEveritt
9c957952fb
Improve mobile display of activity log 2022-06-12 09:09:01 -04:00
DaneEveritt
4d30cc9e7e
Add translation values to activity log output 2022-06-11 14:52:41 -04:00
DaneEveritt
06427f8d13
Don't make two API calls for activity log data 2022-06-11 14:52:33 -04:00
DaneEveritt
986c375052
Improve support for use of i18next; rely on browser caching to keep things simple 2022-06-11 14:04:09 -04:00
DaneEveritt
8e02966935
Use a normal HTML tag for this 2022-06-11 11:05:03 -04:00
DaneEveritt
e17c2ec262
Add base activity log strings 2022-06-11 11:03:40 -04:00
DaneEveritt
278d8b7bf6
Update CHANGELOG.md 2022-06-11 10:04:44 -04:00
DaneEveritt
0bfba306bf
Add filtering support for activity logs 2022-06-05 19:23:25 -04:00
DaneEveritt
c6e8b893c8
Add basic activity log view 2022-06-05 18:35:53 -04:00
DaneEveritt
d1da46c5aa
Fix incorrect API definitions 2022-06-05 18:28:08 -04:00
DaneEveritt
2a2fc42e37
Add support for tooltips 2022-06-05 18:27:54 -04:00
DaneEveritt
1a5465dc34
Update react, add some V2 components for V1 usage 2022-06-05 14:56:42 -04:00
DaneEveritt
921da09a63
Update to Tailwind 3; support normal tailwind usage without twin.macro 2022-06-05 14:34:29 -04:00
DaneEveritt
21ca91abd0
Allow SES region configuration; closes #4124 2022-06-05 13:32:36 -04:00
DaneEveritt
8771597560
Fix database deletion; closes #4114
Co-Authored-By: Dawid <minerpl03@gmail.com>
2022-06-05 13:28:46 -04:00
Harry W
c0a3dea6d8
Disable autocapitalization on console input (#4120) 2022-06-05 13:22:41 -04:00
Kevin Brekelmans
7743d00aee
Update README.md (#4104) 2022-05-30 18:18:10 -04:00
DaneEveritt
03a497fb8a
Use a post request to delete SSH keys, some hashes use slashes which cause 404 errors; closes #4100 2022-05-30 17:28:42 -04:00
DaneEveritt
5143faa4b1
Update changelog 2022-05-30 11:40:21 -04:00
DaneEveritt
4213775b5c
Fix mounting behavior to work correctly when adding to a server 2022-05-30 11:33:42 -04:00
DaneEveritt
dbc9846320
Fix cache busting when creating a new server 2022-05-30 11:09:51 -04:00
Boy132
025e1a21ae
fix validator import (#4094) 2022-05-30 10:24:59 -04:00
DaneEveritt
8cf1311b84
Update dependencies prior to release tag 2022-05-29 20:43:52 -04:00
DaneEveritt
e5fec9934d
Update CHANGELOG.md 2022-05-29 20:42:55 -04:00
DaneEveritt
9300e1116d
Fix failing tests 2022-05-29 20:39:51 -04:00
DaneEveritt
a5521ecb79
Add support for returning transforming activity logs on the front-end 2022-05-29 20:34:48 -04:00
DaneEveritt
e15985ea39
Add support for automatically pruning activity logs 2022-05-29 19:45:00 -04:00
DaneEveritt
9b7af02690
Add activity logging to most of the endpoints 2022-05-29 19:26:28 -04:00
DaneEveritt
287fd60891
Log activity when modifying account details 2022-05-29 18:48:35 -04:00
DaneEveritt
0b2c0db170
Remove last references to audit logs 2022-05-29 18:20:54 -04:00
DaneEveritt
0621d8475d
Return tests to passing now that we don't ignore a critical event... 2022-05-29 17:52:14 -04:00
DaneEveritt
09832cc558
Ensure we can properly create an activity log entry; always return soft-deleted models 2022-05-29 17:07:54 -04:00
DaneEveritt
f1c1699994
Fix tests with model events 2022-05-29 17:07:34 -04:00
DaneEveritt
2fc5a734f9
Update backup logic to use activity logs, not audit logs 2022-05-29 16:19:04 -04:00
DaneEveritt
cbecfff6da
Add activity logging for files 2022-05-29 13:56:39 -04:00
DaneEveritt
0999ad7ff0
Add activity logging for authentication events 2022-05-28 17:03:58 -04:00
DaneEveritt
5bb66a00d8
Add new activity logging code to replace audit log 2022-05-28 15:36:26 -04:00
DaneEveritt
c14c7b436e
Pass along new fields to Wings instance when endpoint is used; closes #4048 2022-05-28 13:45:23 -04:00
DaneEveritt
3fceb588fb
Fix router logic to account for logged out users; closes #4085
Middleware was removed from the `/` route to redirect users without authentication, so now we need to handle this on the front-end properly.
2022-05-28 13:32:35 -04:00
DaneEveritt
b051718afe
Fix up API handling logic for keys and set a prefix on all keys 2022-05-22 19:03:51 -04:00
DaneEveritt
8605d175d6
Ensure admin endpoints continue to work 2022-05-22 18:56:22 -04:00
DaneEveritt
3f99b00cf7
Fix display exception handling 2022-05-22 18:21:38 -04:00
DaneEveritt
dca53611ff
Ensure we don't cause a mess with the auth providers 2022-05-22 18:16:47 -04:00
DaneEveritt
3ae70efc14
Use existing method to handle the login 2022-05-22 17:26:32 -04:00
DaneEveritt
4d3362b24f
Perform a bit of code cleanup 2022-05-22 17:23:48 -04:00
DaneEveritt
be88e4e893
Ignore migrations, pass credentials 2022-05-22 17:01:39 -04:00
DaneEveritt
56f15c15a1
We can make this middleware significantly simpler 2022-05-22 16:54:07 -04:00
DaneEveritt
0fa33e0438
Mark a request as being stateful if a cookie for the session is provided at all
This accounts for poorly configured API clients that try to use cookies for authentication purposes. Treat everything with a session cookie as being a stateful request from the front-end.
2022-05-22 16:50:36 -04:00
DaneEveritt
33bafe9277
Simplify transformer logic 2022-05-22 16:23:22 -04:00
DaneEveritt
f7fc67344e
Ensure tokens are found in the database using the expected logic 2022-05-22 16:05:58 -04:00
DaneEveritt
e9c633fd03
Update transformers and controllers to no longer pull an API key attribute 2022-05-22 15:37:39 -04:00
DaneEveritt
bd37978a98
Initial pass at implementing Laravel Sanctum for authorization on the API 2022-05-22 14:57:06 -04:00
DaneEveritt
e313dff674
Massively simplify API binding logic
Changes the API internals to use normal Laravel binding which automatically supports nested-models and can determine their relationships. This removes a lot of confusingly complex internal logic and replaces it with standard Laravel code.

This also removes a deprecated "getModel" method and fully replaces it with a "parameter" method that does stricter type-checking.
2022-05-22 14:10:01 -04:00
DaneEveritt
f1235c7f88
Update CHANGELOG.md 2022-05-21 17:02:40 -04:00
DaneEveritt
05f41a2ca8
Don't trim strings on file manager endpoints; ref #4081 2022-05-21 16:58:06 -04:00
Alex
d0b6ae00dc
fix: update Paper API (#4080)
Paper api endpoints have been updated to api.papermc.io/v2 from the old papermc.io/api/v2
2022-05-21 15:50:07 -04:00
DaneEveritt
d4bf6bd46a
Add test coverage and fix permissions mistake 2022-05-15 17:30:57 -04:00
DaneEveritt
8483db755d
Fix SSH key factory 2022-05-15 16:47:58 -04:00
DaneEveritt
a9364061c1
Store keys in standard format; query with fingerprint not public key 2022-05-15 16:41:15 -04:00
DaneEveritt
b563f13d09
Trim the key provided to query correctly; don't increment throttles when keys aren't found 2022-05-15 16:23:17 -04:00
DaneEveritt
3d6a30c9fd
Oops, don't make this abstract 2022-05-15 16:06:00 -04:00
DaneEveritt
412ac5ef39
Have the panel handle all of the authorization for both public key and password based attempts 2022-05-15 16:00:08 -04:00
DaneEveritt
e856daee19
Reject requests for public key auth when the user has no keys 2022-05-15 15:47:06 -04:00
DaneEveritt
12927a3202
Update SFTP authentication endpoint to support returning user public keys 2022-05-15 15:37:58 -04:00
DaneEveritt
cca0010a00
Update egg import/update logic to all use the same pathwaus 2022-05-15 14:40:19 -04:00
DaneEveritt
6554164252
Add test coverage for the SSH key endpoints 2022-05-14 18:08:48 -04:00
DaneEveritt
97280a62a2
Add support for storing SSH keys on user accounts 2022-05-14 17:31:53 -04:00
DaneEveritt
5705d7dbdd
Run php-cs-fixer 2022-05-14 16:03:50 -04:00
DaneEveritt
65f27d41a2
Switch to more recent Laravel route definition methods 2022-05-14 15:51:05 -04:00
1499 changed files with 43091 additions and 51753 deletions

View file

@ -1,11 +0,0 @@
module.exports = {
twin: {
preset: 'styled-components',
autoCssProp: true,
},
styledComponents: {
pure: true,
displayName: true,
fileName: true,
},
};

View file

@ -1,15 +1,17 @@
root = true root = true
[*] [*]
end_of_line = lf
insert_final_newline = true
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
tab_width = 4
end_of_line = lf
charset = utf-8 charset = utf-8
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true
[.*yml]
indent_size = 2
[*.md] [*.md]
trim_trailing_whitespace = false trim_trailing_whitespace = false
[*.{md,nix,yml,yaml}]
indent_size = 2
tab_width = 2

19
.env.ci
View file

@ -1,19 +0,0 @@
APP_ENV=testing
APP_DEBUG=true
APP_KEY=SomeRandomString3232RandomString
APP_THEME=pterodactyl
APP_TIMEZONE=America/Los_Angeles
APP_URL=http://localhost/
DB_HOST=127.0.0.1
DB_DATABASE=panel_test
DB_USERNAME=root
DB_PASSWORD=
CACHE_DRIVER=array
SESSION_DRIVER=array
MAIL_DRIVER=array
QUEUE_DRIVER=sync
HASHIDS_SALT=test123
APP_ENVIRONMENT_ONLY=true

View file

@ -1,41 +1,43 @@
APP_ENV=production APP_ENV=production
APP_DEBUG=false APP_DEBUG=false
APP_KEY= APP_KEY=
APP_THEME=pterodactyl APP_TIMEZONE=UTC
APP_TIMEZONE=America/New_York
APP_CLEAR_TASKLOG=720
APP_DELETE_MINUTES=10
APP_ENVIRONMENT_ONLY=true
LOG_CHANNEL=daily
APP_LOCALE=en
APP_URL=http://panel.example.com APP_URL=http://panel.example.com
APP_LOCALE=en
APP_ENVIRONMENT_ONLY=true
LOG_CHANNEL=daily
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1 DB_HOST=127.0.0.1
DB_PORT=3306 DB_PORT=3306
DB_DATABASE=panel DB_DATABASE=panel
DB_USERNAME=pterodactyl DB_USERNAME=pterodactyl
DB_PASSWORD= DB_PASSWORD=
SESSION_DRIVER=file REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
CACHE_DRIVER=file CACHE_DRIVER=file
QUEUE_CONNECTION=redis
SESSION_DRIVER=file
HASHIDS_SALT= HASHIDS_SALT=
HASHIDS_LENGTH=8 HASHIDS_LENGTH=8
MAIL_DRIVER=smtp MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com MAIL_HOST=smtp.example.com
MAIL_PORT=25 MAIL_PORT=25
MAIL_USERNAME= MAIL_USERNAME=
MAIL_PASSWORD= MAIL_PASSWORD=
MAIL_ENCRYPTION=tls MAIL_ENCRYPTION=tls
MAIL_FROM=no-reply@example.com MAIL_FROM_ADDRESS=no-reply@example.com
MAILGUN_ENDPOINT=api.mailgun.net MAIL_FROM_NAME="Pterodactyl Panel"
# You should set this to your domain to prevent it defaulting to 'localhost', causing # You should set this to your domain to prevent it defaulting to 'localhost', causing
# mail servers such as Gmail to reject your mail. # mail servers such as Gmail to reject your mail.
# #
# @see: https://github.com/pterodactyl/panel/pull/3110 # @see: https://github.com/pterodactyl/panel/pull/3110
# SERVER_NAME=panel.example.com # MAIL_EHLO_DOMAIN=panel.example.com
QUEUE_HIGH=high
QUEUE_STANDARD=standard
QUEUE_LOW=low

View file

@ -1,4 +1,6 @@
public public
node_modules node_modules
resources/views resources/views
babel.config.js
tailwind.config.js
webpack.config.js webpack.config.js

52
.eslintrc.js Normal file
View file

@ -0,0 +1,52 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 6,
ecmaFeatures: {
jsx: true,
},
project: './tsconfig.json',
tsconfigRootDir: './',
},
settings: {
react: {
pragma: 'React',
version: 'detect',
},
linkComponents: [
{ name: 'Link', linkAttribute: 'to' },
{ name: 'NavLink', linkAttribute: 'to' },
],
},
env: {
browser: true,
es6: true,
},
plugins: ['react', 'react-hooks', 'prettier', '@typescript-eslint'],
extends: [
// 'standard',
'eslint:recommended',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:@typescript-eslint/recommended',
],
rules: {
eqeqeq: 'error',
'prettier/prettier': ['error', {}, { usePrettierrc: true }],
// TypeScript can infer this significantly better than eslint ever can.
'react/prop-types': 0,
'react/display-name': 0,
'react/no-unknown-property': ['error', {ignore: ['css']}],
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-non-null-assertion': 0,
// This setup is required to avoid a spam of errors when running eslint about React being
// used before it is defined.
//
// @see https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md#how-to-use
'no-use-before-define': 0,
'@typescript-eslint/no-use-before-define': 'warn',
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'@typescript-eslint/ban-ts-comment': ['error', { 'ts-expect-error': 'allow-with-description' }],
},
};

View file

@ -1,98 +0,0 @@
parser: "@typescript-eslint/parser"
parserOptions:
ecmaVersion: 6
ecmaFeatures:
jsx: true
project: "./tsconfig.json"
tsconfigRootDir: "./"
settings:
react:
pragma: "React"
version: "detect"
linkComponents:
- name: Link
linkAttribute: to
- name: NavLink
linkAttribute: to
env:
browser: true
es6: true
plugins:
- "react"
- "react-hooks"
- "@typescript-eslint"
extends:
- "standard"
- "plugin:react/recommended"
- "plugin:@typescript-eslint/recommended"
rules:
quotes:
- warn
- single
indent:
- warn
- 4
- SwitchCase: 1
semi:
- warn
- always
comma-dangle:
- warn
- always-multiline
spaced-comment:
- warn
array-bracket-spacing:
- warn
- always
# Remove errors for not having newlines between operands of ternary expressions https://eslint.org/docs/rules/multiline-ternary
multiline-ternary: 0
"react-hooks/rules-of-hooks":
- error
"react-hooks/exhaustive-deps": 0
"@typescript-eslint/explicit-function-return-type": 0
"@typescript-eslint/explicit-member-accessibility": 0
"@typescript-eslint/ban-ts-ignore": 0
"@typescript-eslint/no-explicit-any": 0
"@typescript-eslint/no-non-null-assertion": 0
"@typescript-eslint/ban-ts-comment": 0
# This would be nice to have, but don't want to deal with the warning spam at the moment.
"@typescript-eslint/explicit-module-boundary-types": 0
no-restricted-imports:
- error
- paths:
- name: styled-components
message: Please import from styled-components/macro.
patterns:
- "!styled-components/macro"
# Not sure, this rule just doesn't work right and is protected by our use of Typescript anyways
# so I'm just not going to worry about it.
"react/prop-types": 0
"react/display-name": 0
"react/jsx-indent-props":
- warn
- 4
"react/jsx-boolean-value":
- warn
- never
"react/jsx-closing-bracket-location":
- 1
- "line-aligned"
"react/jsx-closing-tag-location": 1
# This setup is required to avoid a spam of errors when running eslint about React being
# used before it is defined.
#
# see https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md#how-to-use
no-use-before-define: 0
"@typescript-eslint/no-use-before-define":
- warn
overrides:
- files:
- "**/*.tsx"
rules:
operator-linebreak:
- error
- before
- overrides:
"&&": "after"
"?": "ignore"
":": "ignore"

3
.github/FUNDING.yml vendored
View file

@ -1,2 +1 @@
github: [DaneEveritt] github: [matthewpi]
custom: ["https://paypal.me/PterodactylSoftware"]

View file

@ -68,8 +68,8 @@ body:
Run the following command to collect logs on your system. Run the following command to collect logs on your system.
Wings: `sudo wings diagnostics` Wings: `sudo wings diagnostics`
Panel: `tail -n 100 /var/www/pterodactyl/storage/logs/laravel-$(date +%F).log | nc bin.ptdl.co 99` Panel: `tail -n 150 /var/www/pterodactyl/storage/logs/laravel-$(date +%F).log | nc pteropaste.com 99`
placeholder: "https://bin.ptdl.co/a1h6z" placeholder: "https://pteropaste.com/a1h6z"
render: bash render: bash
validations: validations:
required: false required: false

View file

@ -1,4 +1,4 @@
blank_issues_enabled: false blank_issues_enabled: true
contact_links: contact_links:
- name: Installation Help - name: Installation Help
url: https://discord.gg/pterodactyl url: https://discord.gg/pterodactyl

21
.github/docker/Caddyfile vendored Normal file
View file

@ -0,0 +1,21 @@
:8080 {
root * /var/www/pterodactyl/public/
file_server
header {
-Server
-X-Powered-By
Referrer-Policy "same-origin"
X-Frame-Options "deny"
X-XSS-Protection "1; mode=block"
X-Content-Type-Options "nosniff"
}
encode gzip zstd
php_fastcgi 127.0.0.1:9000 {
trusted_proxies 172.20.0.0/16
}
try_files {path} {path}/ /index.php?{query}
}

View file

@ -1,76 +0,0 @@
# Pterodactyl Panel - Docker Image
This is a ready to use docker image for the panel.
## Requirements
This docker image requires some additional software to function. The software can either be provided in other containers (see the [docker-compose.yml](https://github.com/pterodactyl/panel/blob/develop/docker-compose.example.yml) as an example) or as existing instances.
A mysql database is required. We recommend the stock [MariaDB Image](https://hub.docker.com/_/mariadb/) image if you prefer to run it in a docker container. As a non-containerized option we recommend mariadb.
A caching software is required as well. We recommend the stock [Redis Image](https://hub.docker.com/_/redis/) image. You can choose any of the [supported options](#cache-drivers).
You can provide additional settings using a custom `.env` file or by setting the appropriate environment variables in the docker-compose file.
## Setup
Start the docker container and the required dependencies (either provide existing ones or start containers as well, see the [docker-compose.yml](https://github.com/pterodactyl/panel/blob/develop/docker-compose.example.yml) file as an example.
After the startup is complete you'll need to create a user.
If you are running the docker container without docker-compose, use:
```
docker exec -it <container id> php artisan p:user:make
```
If you are using docker compose use
```
docker-compose exec panel php artisan p:user:make
```
## Environment Variables
There are multiple environment variables to configure the panel when not providing your own `.env` file, see the following table for details on each available option.
Note: If your `APP_URL` starts with `https://` you need to provide an `LETSENCRYPT_EMAIL` as well so Certificates can be generated.
| Variable | Description | Required |
| ------------------- | ------------------------------------------------------------------------------ | -------- |
| `APP_URL` | The URL the panel will be reachable with (including protocol) | yes |
| `APP_TIMEZONE` | The timezone to use for the panel | yes |
| `LE_EMAIL` | The email used for letsencrypt certificate generation | yes |
| `DB_HOST` | The host of the mysql instance | yes |
| `DB_PORT` | The port of the mysql instance | yes |
| `DB_DATABASE` | The name of the mysql database | yes |
| `DB_USERNAME` | The mysql user | yes |
| `DB_PASSWORD` | The mysql password for the specified user | yes |
| `CACHE_DRIVER` | The cache driver (see [Cache drivers](#cache-drivers) for detais) | yes |
| `SESSION_DRIVER` | | yes |
| `QUEUE_DRIVER` | | yes |
| `REDIS_HOST` | The hostname or IP address of the redis database | yes |
| `REDIS_PASSWORD` | The password used to secure the redis database | maybe |
| `REDIS_PORT` | The port the redis database is using on the host | maybe |
| `MAIL_DRIVER` | The email driver (see [Mail drivers](#mail-drivers) for details) | yes |
| `MAIL_FROM` | The email that should be used as the sender email | yes |
| `MAIL_HOST` | The host of your mail driver instance | maybe |
| `MAIL_PORT` | The port of your mail driver instance | maybe |
| `MAIL_USERNAME` | The username for your mail driver | maybe |
| `MAIL_PASSWORD` | The password for your mail driver | maybe |
### Cache drivers
You can choose between different cache drivers depending on what you prefer.
We recommend redis when using docker as it can be started in a container easily.
| Driver | Description | Required variables |
| -------- | ------------------------------------ | ------------------------------------------------------ |
| redis | host where redis is running | `REDIS_HOST` |
| redis | port redis is running on | `REDIS_PORT` |
| redis | redis database password | `REDIS_PASSWORD` |
### Mail drivers
You can choose between different mail drivers according to your needs.
Every driver requires `MAIL_FROM` to be set.
| Driver | Description | Required variables |
| -------- | ------------------------------------ | ------------------------------------------------------------- |
| mail | uses the installed php mail | |
| mandrill | [Mandrill](http://www.mandrill.com/) | `MAIL_USERNAME` |
| postmark | [Postmark](https://postmarkapp.com/) | `MAIL_USERNAME` |
| mailgun | [Mailgun](https://www.mailgun.com/) | `MAIL_USERNAME`, `MAIL_HOST` |
| smtp | Any SMTP server can be configured | `MAIL_USERNAME`, `MAIL_HOST`, `MAIL_PASSWORD`, `MAIL_PORT` |

View file

@ -1,51 +0,0 @@
# If using Ubuntu this file should be placed in:
# /etc/nginx/sites-available/
#
# If using CentOS this file should be placed in:
# /etc/nginx/conf.d/
#
server {
listen 80;
server_name _;
root /app/public;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/pterodactyl.app-error.log error;
# allow larger file uploads and longer script runtimes
client_max_body_size 100m;
client_body_timeout 120s;
sendfile off;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# the fastcgi_pass path needs to be changed accordingly when using CentOS
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_PROXY "";
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
}
location ~ /\.ht {
deny all;
}
}

View file

@ -1,70 +0,0 @@
# If using Ubuntu this file should be placed in:
# /etc/nginx/sites-available/
#
server {
listen 80;
server_name <domain>;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name <domain>;
root /app/public;
index index.php;
access_log /var/log/nginx/pterodactyl.app-access.log;
error_log /var/log/nginx/pterodactyl.app-error.log error;
# allow larger file uploads and longer script runtimes
client_max_body_size 100m;
client_body_timeout 120s;
sendfile off;
# strengthen ssl security
ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
# See the link below for more SSL information:
# https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
#
# ssl_dhparam /etc/ssl/certs/dhparam.pem;
# Add headers to serve security related headers
add_header Strict-Transport-Security "max-age=15768000; preload;";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header Content-Security-Policy "frame-ancestors 'self'";
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_PROXY "";
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
include /etc/nginx/fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}

View file

@ -1,81 +0,0 @@
#!/bin/ash -e
cd /app
mkdir -p /var/log/panel/logs/ /var/log/supervisord/ /var/log/nginx/ /var/log/php7/ \
&& chmod 777 /var/log/panel/logs/ \
&& ln -s /var/log/panel/logs/ /app/storage/logs/
## check for .env file and generate app keys if missing
if [ -f /app/var/.env ]; then
echo "external vars exist."
rm -rf /app/.env
ln -s /app/var/.env /app/
else
echo "external vars don't exist."
rm -rf /app/.env
touch /app/var/.env
## manually generate a key because key generate --force fails
if [ -z $APP_KEY ]; then
echo -e "Generating key."
APP_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
echo -e "Generated app key: $APP_KEY"
echo -e "APP_KEY=$APP_KEY" > /app/var/.env
else
echo -e "APP_KEY exists in environment, using that."
echo -e "APP_KEY=$APP_KEY" > /app/var/.env
fi
ln -s /app/var/.env /app/
fi
echo "Checking if https is required."
if [ -f /etc/nginx/http.d/panel.conf ]; then
echo "Using nginx config already in place."
if [ $LE_EMAIL ]; then
echo "Checking for cert update"
certbot certonly -d $(echo $APP_URL | sed 's~http[s]*://~~g') --standalone -m $LE_EMAIL --agree-tos -n
else
echo "No letsencrypt email is set"
fi
else
echo "Checking if letsencrypt email is set."
if [ -z $LE_EMAIL ]; then
echo "No letsencrypt email is set using http config."
cp .github/docker/default.conf /etc/nginx/http.d/panel.conf
else
echo "writing ssl config"
cp .github/docker/default_ssl.conf /etc/nginx/http.d/panel.conf
echo "updating ssl config for domain"
sed -i "s|<domain>|$(echo $APP_URL | sed 's~http[s]*://~~g')|g" /etc/nginx/http.d/panel.conf
echo "generating certs"
certbot certonly -d $(echo $APP_URL | sed 's~http[s]*://~~g') --standalone -m $LE_EMAIL --agree-tos -n
fi
echo "Removing the default nginx config"
rm -rf /etc/nginx/http.d/default.conf
fi
if [[ -z $DB_PORT ]]; then
echo -e "DB_PORT not specified, defaulting to 3306"
DB_PORT=3306
fi
## check for DB up before starting the panel
echo "Checking database status."
until nc -z -v -w30 $DB_HOST $DB_PORT
do
echo "Waiting for database connection..."
# wait for 1 seconds before check again
sleep 1
done
## make sure the db is set up
echo -e "Migrating and Seeding D.B"
php artisan migrate --seed --force
## start cronjobs for the queue
echo -e "Starting cron jobs."
crond -L /var/log/crond -l 5
echo -e "Starting supervisord."
exec "$@"

21
.github/docker/php-fpm.conf vendored Normal file
View file

@ -0,0 +1,21 @@
[global]
error_log = /dev/stderr
daemonize = no
[www]
user = nobody
group = nobody
listen = 127.0.0.1:9000
pm = dynamic
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 16
pm.max_children = 64
pm.max_requests = 256
clear_env = no
catch_workers_output = yes
decorate_workers_output = no

View file

@ -1,39 +1,57 @@
[unix_http_server]
file=/tmp/supervisor.sock ; path to your socket file
[supervisord] [supervisord]
logfile=/var/log/supervisord/supervisord.log ; supervisord log file logfile=/dev/stdout
logfile_maxbytes=50MB ; maximum size of logfile before rotation logfile_maxbytes=0
logfile_backups=2 ; number of backed up logfiles loglevel=info
loglevel=error ; info, debug, warn, trace minfds=1024
pidfile=/var/run/supervisord.pid ; pidfile location minprocs=200
nodaemon=false ; run supervisord as a daemon nodaemon=true
minfds=1024 ; number of startup file descriptors pidfile=/dev/null
minprocs=200 ; number of process descriptors
user=root ; default user
childlogdir=/var/log/supervisord/ ; where child log files will live
[rpcinterface:supervisor] [unix_http_server]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface file=/tmp/supervisor.sock
[supervisorctl] [supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket serverurl=unix:///tmp/supervisor.sock
[program:php-fpm] [rpcinterface:supervisor]
command=/usr/local/sbin/php-fpm -F supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface
autostart=true
autorestart=true
[program:queue-worker] [program:caddy]
command=/usr/local/bin/php /app/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3 command=/usr/local/bin/caddy run --config /etc/caddy/Caddyfile
user=nginx
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx -g 'daemon off;'
autostart=true autostart=true
autorestart=true autorestart=true
priority=10 priority=10
stdout_events_enabled=true stdout_logfile=/dev/stdout
stderr_events_enabled=true stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:php-fpm]
command=/usr/sbin/php-fpm --nodaemonize
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
environment=LOG_CHANNEL="stderr"
[program:queue-worker]
command=/usr/bin/php /var/www/pterodactyl/artisan queue:work --queue=standard --sleep=3 --tries=3
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
environment=LOG_CHANNEL="stderr"
[program:yacron]
command=/usr/local/bin/yacron -c /etc/yacron.yaml
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
environment=LOG_CHANNEL="stderr"

View file

@ -1,16 +0,0 @@
[www]
user = nginx
group = nginx
listen = 127.0.0.1:9000
listen.owner = nginx
listen.group = nginx
listen.mode = 0750
pm = ondemand
pm.max_children = 9
pm.process_idle_timeout = 10s
pm.max_requests = 200
clear_env = no

8
.github/docker/yacron.yaml vendored Normal file
View file

@ -0,0 +1,8 @@
jobs:
- name: scheduler
command:
- /usr/bin/php
- /var/www/pterodactyl/artisan
- schedule:run
schedule: "* * * * *"
utc: true

View file

@ -1,24 +0,0 @@
name: Build Panel
on:
push:
branches:
- 'develop'
- 'v2'
pull_request:
jobs:
build:
runs-on: ubuntu-20.04
if: "!contains(github.event.head_commit.message, 'skip ci') && !contains(github.event.head_commit.message, 'ci skip')"
strategy:
matrix:
node-version: [16.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm install -g yarn
- run: yarn install
- run: yarn build:production

67
.github/workflows/docker.yaml vendored Normal file
View file

@ -0,0 +1,67 @@
name: Docker
on:
push:
branches:
- develop
- 1.0-develop
pull_request:
branches:
- develop
- 1.0-develop
release:
types:
- published
jobs:
push:
name: Push
runs-on: ubuntu-22.04
steps:
- name: Code checkout
uses: actions/checkout@v3
- name: Fetch metadata
id: metadata
uses: docker/metadata-action@v4
with:
images: ghcr.io/pterodactyl/panel
flavor: |
latest=false
tags: |
type=raw,value=latest,enable=${{ github.event_name == 'release' && github.event.action == 'published' && github.event.release.prerelease == false }}
type=ref,event=tag
type=ref,event=branch
- name: Setup QEMU
uses: docker/setup-qemu-action@v2
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v2
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
if: "github.event_name != 'pull_request'"
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Update version
if: "github.event_name == 'release' && github.event.action == 'published'"
env:
REF: ${{ github.event.release.tag_name }}
run: |
sed -i "s/ 'version' => 'canary',/ 'version' => '${REF:1}',/" config/app.php
- name: Build and Push
uses: docker/build-push-action@v4
with:
context: .
file: ./Containerfile
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64,linux/arm64
labels: ${{ steps.metadata.outputs.labels }}
tags: ${{ steps.metadata.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max

View file

@ -1,49 +0,0 @@
name: Publish Docker Image
on:
push:
branches:
- 'develop'
tags:
- 'v*'
jobs:
push_to_registry:
name: Push Image to GitHub Packages
runs-on: ubuntu-latest
# Always run against a tag, even if the commit into the tag has [docker skip]
# within the commit message.
if: "!contains(github.ref, 'develop') || (!contains(github.event.head_commit.message, 'skip docker') && !contains(github.event.head_commit.message, 'docker skip'))"
steps:
- uses: actions/checkout@v2
- uses: crazy-max/ghaction-docker-meta@v1
id: docker_meta
with:
images: ghcr.io/pterodactyl/panel
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Bump Version
if: "!contains(github.ref, 'develop')"
env:
REF: ${{ github.ref }}
run: |
sed -i "s/ 'version' => 'canary',/ 'version' => '${REF:11}',/" config/app.php
- name: Release Production Build
uses: docker/build-push-action@v2
if: "!contains(github.ref, 'develop')"
with:
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
- name: Release Development Build
uses: docker/build-push-action@v2
if: "contains(github.ref, 'develop')"
with:
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64,linux/arm64
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}

210
.github/workflows/laravel.yaml vendored Normal file
View file

@ -0,0 +1,210 @@
name: Laravel
on:
push:
branches:
- "develop"
- "1.0-develop"
pull_request:
branches:
- "develop"
- "1.0-develop"
jobs:
analysis:
name: Static Analysis
runs-on: ubuntu-22.04
env:
APP_ENV: testing
APP_DEBUG: "true"
APP_KEY: SomeRandomString3232RandomString
CACHE_DRIVER: array
MAIL_MAILER: array
SESSION_DRIVER: array
QUEUE_CONNECTION: sync
steps:
- name: Code checkout
uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
extensions: bcmath, cli, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
tools: composer:v2
coverage: none
- name: Install dependencies
run: composer install --no-interaction --no-progress --no-suggest --prefer-dist
- name: Analyze
run: vendor/bin/phpstan analyse
lint:
name: Lint
runs-on: ubuntu-22.04
steps:
- name: Code checkout
uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
# TODO: Update to 8.2 once php-cs-fixer supports it
php-version: 8.1
extensions: bcmath, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
tools: composer:v2
coverage: none
- name: Install dependencies
run: composer install --no-interaction --no-progress --no-suggest --prefer-dist
- name: PHP CS Fixer
run: vendor/bin/php-cs-fixer fix --dry-run --diff
mysql:
name: Tests
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
php: [8.1, 8.2]
database: ["mariadb:10.2", "mariadb:10.9", "mysql:8"]
services:
database:
image: docker.io/library/${{ matrix.database }}
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: testing
ports:
- 3306/tcp
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
env:
APP_ENV: testing
APP_DEBUG: "true"
APP_KEY: SomeRandomString3232RandomString
APP_THEME: pterodactyl
APP_TIMEZONE: UTC
APP_URL: http://localhost/
APP_ENVIRONMENT_ONLY: "true"
CACHE_DRIVER: array
MAIL_MAILER: array
SESSION_DRIVER: array
QUEUE_CONNECTION: sync
HASHIDS_SALT: test123
DB_CONNECTION: mysql
DB_HOST: 127.0.0.1
DB_DATABASE: testing
DB_USERNAME: root
steps:
- name: Code checkout
uses: actions/checkout@v3
- name: Get cache directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-${{ matrix.php }}-
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: bcmath, cli, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
tools: composer:v2
coverage: none
- name: Install dependencies
run: composer install --no-interaction --no-progress --no-suggest --prefer-dist
- name: Unit tests
run: vendor/bin/phpunit --bootstrap vendor/autoload.php tests/Unit
env:
DB_HOST: UNIT_NO_DB
- name: Integration tests
run: vendor/bin/phpunit tests/Integration
env:
DB_PORT: ${{ job.services.database.ports[3306] }}
postgres:
name: Tests
runs-on: ubuntu-22.04
if: "!contains(github.event.head_commit.message, 'skip ci') && !contains(github.event.head_commit.message, 'ci skip')"
strategy:
fail-fast: false
matrix:
php: [8.1, 8.2]
database: ["postgres:13", "postgres:14", "postgres:15"]
services:
database:
image: docker.io/library/${{ matrix.database }}
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: testing
ports:
- 5432/tcp
options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3
env:
APP_ENV: testing
APP_DEBUG: "true"
APP_KEY: SomeRandomString3232RandomString
APP_THEME: pterodactyl
APP_TIMEZONE: UTC
APP_URL: http://localhost/
APP_ENVIRONMENT_ONLY: "true"
CACHE_DRIVER: array
MAIL_MAILER: array
SESSION_DRIVER: array
QUEUE_CONNECTION: sync
HASHIDS_SALT: test123
DB_CONNECTION: pgsql
DB_HOST: 127.0.0.1
DB_DATABASE: testing
DB_USERNAME: postgres
DB_PASSWORD: postgres
steps:
- name: Code checkout
uses: actions/checkout@v3
- name: Get cache directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-${{ matrix.php }}-
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: bcmath, cli, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
tools: composer:v2
coverage: none
- name: Install dependencies
run: composer install --no-interaction --no-progress --no-suggest --prefer-dist
- name: Unit tests
run: vendor/bin/phpunit --bootstrap vendor/autoload.php tests/Unit
env:
DB_HOST: UNIT_NO_DB
- name: Integration tests
run: vendor/bin/phpunit tests/Integration
env:
DB_PORT: ${{ job.services.database.ports[5432] }}

View file

@ -1,16 +1,32 @@
name: Create Release name: Release
on: on:
push: push:
tags: tags:
- 'v*' - "v*"
jobs: jobs:
release: release:
runs-on: ubuntu-20.04 name: Release
runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - name: Code checkout
- uses: actions/setup-node@v1 uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Setup Node
uses: actions/setup-node@v3
with: with:
node-version: '12' node-version: 18
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
- name: Create release branch and bump version - name: Create release branch and bump version
env: env:
@ -23,26 +39,19 @@ jobs:
git push -u origin $BRANCH git push -u origin $BRANCH
sed -i "s/ 'version' => 'canary',/ 'version' => '${REF:11}',/" config/app.php sed -i "s/ 'version' => 'canary',/ 'version' => '${REF:11}',/" config/app.php
git add config/app.php git add config/app.php
git commit -m "bump version for release" git commit -m "ci(release): bump version"
git push git push
- name: Build assets
run: |
yarn install
yarn run build:production
- name: Create release archive - name: Create release archive
run: | run: |
rm -rf node_modules/ test/ codecov.yml CODE_OF_CONDUCT.md CONTRIBUTING.md phpunit.xml Vagrantfile rm -rf node_modules tests CODE_OF_CONDUCT.md CONTRIBUTING.md flake.lock flake.nix phpstan.neon phpunit.xml shell.nix
tar -czf panel.tar.gz * .env.example .eslintignore .eslintrc.yml .babel-plugin-macrosrc.js tar -czf panel.tar.gz * .editorconfig .env.example .eslintignore .eslintrc.js .gitignore .prettierrc.json
- name: Extract changelog - name: Extract changelog
id: extract_changelog
env: env:
REF: ${{ github.ref }} REF: ${{ github.ref }}
run: | run: |
sed -n "/^## ${REF:10}/,/^## /{/^## /b;p}" CHANGELOG.md > ./RELEASE_CHANGELOG sed -n "/^## ${REF:10}/,/^## /{/^## /b;p}" CHANGELOG.md > ./RELEASE_CHANGELOG
echo ::set-output name=version_name::`sed -nr "s/^## (${REF:10} .*)$/\1/p" CHANGELOG.md`
- name: Create checksum and add to changelog - name: Create checksum and add to changelog
run: | run: |
@ -50,19 +59,17 @@ jobs:
echo -e "\n#### SHA256 Checksum\n\n\`\`\`\n$SUM\n\`\`\`\n" >> ./RELEASE_CHANGELOG echo -e "\n#### SHA256 Checksum\n\n\`\`\`\n$SUM\n\`\`\`\n" >> ./RELEASE_CHANGELOG
echo $SUM > checksum.txt echo $SUM > checksum.txt
- name: Create Release - name: Create release
id: create_release id: create_release
uses: actions/create-release@v1 uses: softprops/action-gh-release@v1
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
tag_name: ${{ github.ref }}
release_name: ${{ steps.extract_changelog.outputs.version_name }}
body_path: ./RELEASE_CHANGELOG
draft: true draft: true
prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'alpha') }} prerelease: ${{ contains(github.ref, 'rc') || contains(github.ref, 'beta') || contains(github.ref, 'alpha') }}
body_path: ./RELEASE_CHANGELOG
- name: Upload binary - name: Upload release archive
id: upload-release-archive id: upload-release-archive
uses: actions/upload-release-asset@v1 uses: actions/upload-release-asset@v1
env: env:
@ -73,7 +80,7 @@ jobs:
asset_name: panel.tar.gz asset_name: panel.tar.gz
asset_content_type: application/gzip asset_content_type: application/gzip
- name: Upload checksum - name: Upload release checksum
id: upload-release-checksum id: upload-release-checksum
uses: actions/upload-release-asset@v1 uses: actions/upload-release-asset@v1
env: env:

View file

@ -1,58 +0,0 @@
name: Run Tests
on:
push:
branches:
- 'develop'
- 'v2'
pull_request:
jobs:
tests:
runs-on: ubuntu-20.04
if: "!contains(github.event.head_commit.message, 'skip ci') && !contains(github.event.head_commit.message, 'ci skip')"
strategy:
fail-fast: false
matrix:
php: [ 7.4, 8.0, 8.1 ]
database: [ 'mariadb:10.2', 'mysql:8' ]
services:
database:
image: ${{ matrix.database }}
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: panel_test
ports:
- 3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
name: "php-${{ matrix.php }} (${{ matrix.database }})"
steps:
- uses: actions/checkout@v2
- name: get cache directory
id: composer-cache
run: |
echo "::set-output name=dir::$(composer config cache-files-dir)"
- uses: actions/cache@v2
with:
path: |
~/.php_cs.cache
${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-cache-${{ matrix.php }}-${{ hashFiles('**.composer.lock') }}
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: bcmath, cli, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
tools: composer:v2
coverage: none
- run: cp .env.ci .env
- run: composer install --prefer-dist --no-interaction --no-progress
- run: vendor/bin/php-cs-fixer fix --dry-run --diff --diff-format=udiff --config .php-cs-fixer.dist.php
continue-on-error: true
- name: execute unit tests
run: vendor/bin/phpunit --bootstrap vendor/autoload.php tests/Unit
if: ${{ always() }}
env:
DB_HOST: UNIT_NO_DB
- name: execute integration tests
run: vendor/bin/phpunit tests/Integration
env:
DB_PORT: ${{ job.services.database.ports[3306] }}
DB_USERNAME: root

63
.github/workflows/ui.yaml vendored Normal file
View file

@ -0,0 +1,63 @@
name: UI
on:
push:
branches:
- "develop"
- "1.0-develop"
pull_request:
branches:
- "develop"
- "1.0-develop"
jobs:
lint:
name: Lint
runs-on: ubuntu-22.04
steps:
- name: Code checkout
uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Lint
run: pnpm run lint
tests:
name: Tests
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
node: [16, 18]
steps:
- name: Code checkout
uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
- name: Tests
run: pnpm run test

6
.gitignore vendored
View file

@ -8,6 +8,7 @@
storage/framework/* storage/framework/*
/.idea /.idea
/nbproject /nbproject
/.direnv
node_modules node_modules
*.log *.log
@ -28,3 +29,8 @@ misc
coverage.xml coverage.xml
resources/lang/locales.js resources/lang/locales.js
.phpunit.result.cache .phpunit.result.cache
/public/build
/public/hot
result
docker-compose.yaml

1
.npmrc Normal file
View file

@ -0,0 +1 @@
shamefully-hoist=true

4
.prettierignore Normal file
View file

@ -0,0 +1,4 @@
.github
public
node_modules
resources/views

22
.prettierrc.json Normal file
View file

@ -0,0 +1,22 @@
{
"printWidth": 120,
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": true,
"jsxSingleQuote": false,
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "avoid",
"endOfLine": "lf",
"overrides": [
{
"files": ["**/*.md"],
"options": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": false
}
}
]
}

View file

@ -1 +0,0 @@
@types/react-native

View file

@ -1,63 +0,0 @@
# Local Development
Pterodactyl is now powered by React, Typescript, and Tailwindcss using webpack at its core to generate compiled assets.
Release versions of Pterodactyl will include pre-compiled, minified, and hashed assets ready-to-go.
However, if you are interested in running custom themes or making modifications to the React files you'll need a build
system in place to generate these compiled assets. To get your environment setup you'll need at minimum:
* [Node.js](https://nodejs.org/en/) v14.x.x
* [Yarn](https://classic.yarnpkg.com/lang/en/) v1.x.x
* [Go](https://golang.org/) 1.17.x
### Install Dependencies
```bash
yarn install
```
The command above will download all of the dependencies necessary to get Pterodactyl assets building. After that, its as
simple as running the command below to generate assets while you're developing. Until you've run this command at least
once you'll likely see a 500 error on your Panel about a missing `manifest.json` file. This is generated by the commands
below.
```bash
# Build the compiled set of assets for development.
yarn run build
# Build the assets automatically as they are changed. This allows you to refresh
# the page and see the changes immediately.
yarn run watch
```
### Hot Module Reloading
For more advanced users, we also support 'Hot Module Reloading', allowing you to quickly see changes you're making
to the Vue template files without having to reload the page you're on. To Get started with this, you just need
to run the command below.
```bash
PUBLIC_PATH=http://192.168.1.1:8080 yarn run serve --host 192.168.1.1
```
There are two _very important_ parts of this command to take note of and change for your specific environment. The first
is the `--host` flag, which is required and should point to the machine where the `webpack-serve` server will be running.
The second is the `PUBLIC_PATH` environment variable which is the URL pointing to the HMR server and is appended to all of
the asset URLs used in Pterodactyl.
#### Development Environment
If you're using the [`pterodactyl/development`](https://github.com/pterodactyl/development) environments, which are
highly recommended, you can just run `yarn run serve` to run the HMR server, no additional configuration is necessary.
### Building for Production
Once you have your files squared away and ready for the live server, you'll be needing to generate compiled, minified,
and hashed assets to push live. To do so, run the command below:
```bash
yarn run build:production
```
This will generate a production JS bundle and associated assets, all located in `public/assets/` which will need to
be uploaded to your server or CDN for clients to use.
### Running Wings
To run `wings` in development all you need to do is set up the configuration file as normal when adding a new node, and
then you can build and run a local version of Wings by executing `make debug` in the Wings code directory. This must
be run on a Linux VM of some sort, you cannot run this locally on macOS or Windows.

View file

@ -3,17 +3,232 @@ This file is a running track of new features and fixes to each version of the pa
This project follows [Semantic Versioning](http://semver.org) guidelines. This project follows [Semantic Versioning](http://semver.org) guidelines.
## v1.11.3
### Changed
* When updating a server's description through the client API, if no value is specified, the description will now remain unchanged.
* When installing the Panel for the first time, the queue driver will now all default to `redis` instead of `sync`.
### Fixed
* `php artisan p:environment:mail` not correctly setting the right variable for `MAIL_FROM_ADDRESS`.
* Fixed the conflict state rendering on the UI for a server showing `reinstall_failed` as `restoring_backup`.
* Fixed the unknown column `uuid` error when jobs fail, causing them not to get stored correctly.
* Fixed the server task endpoints in the client API not allowing `sequence_id` and `continue_on_failure` to be set.
## v1.11.2
### Changed
* Telemetry no longer sends a map of Egg and Nest UUIDs to the number of servers using them.
* Increased the timeout for the decompress files endpoint in the client API from 15 seconds to 15 minutes.
### Fixed
* Fixed Panel Docker image having a `v` prefix in the version displayed in the admin area.
* Fixed emails using the wrong queue name, causing them to not be sent.
* Fixed the settings keys used for configuring SMTP settings, causing settings to not save properly.
* Fixed the `MAIL_EHLO_DOMAIN` environment variable not being properly backwards compatible with the old `SERVER_NAME` variable.
## v1.11.1
### Fixed
* Fixed Panel Docker image showing `canary` as it's version.
## v1.11.0
### Changed (since 1.10.4)
* Changed minimum PHP version requirement from `7.4` to `8.0`.
* Upgraded from Laravel 8 to Laravel 9.
* This release requires Wings v1.11.x in order for Server Transfers to work.
* `MB` byte suffixes are now displayed as `MiB` to more accurately reflect the actual value.
* Server re-installation failures are tracked independently of the initial installation process.
### Fixed (since 1.10.4)
* Node maintenance mode now properly blocks access to servers.
* Fixed the length validation on the Minecraft Forge egg.
* Fixed the password in the JDBC string not being properly URL encoded.
* Fixed an issue where Wings would throw a validation error while attempting to upload activity logs.
* Properly handle a missing `Content-Length` header in the response from the daemon.
* Ensure activity log properties are always returned as an object instead of an empty array.
### Added (since 1.10.4)
* Added the `server:settings.description` activity log event for when a server description is changed.
* Added the ability to cancel file uploads in the file manager for a server.
* Added a telemetry service to collect anonymous metrics from the panel, this feature is *enabled* by default and can be toggled using the `PTERODACTYL_TELEMETRY_ENABLED` environment variable.
## v1.11.0-rc.2
### Changed
* `MB` byte suffixes are now displayed as `MiB` to more accurately reflect the actual value.
* Server re-installation failures are tracked independently of the initial installation process.
### Fixed
* Properly handle a missing `Content-Length` header in the response from the daemon.
* Ensure activity log properties are always returned as an object instead of an empty array.
### Added
* Added the `server:settings.description` activity log event for when a server description is changed.
* Added the ability to cancel file uploads in the file manager for a server.
* Added a telemetry service to collect anonymous metrics from the panel, this feature is disabled by default and can be toggled using the `PTERODACTYL_TELEMETRY_ENABLED` environment variable.
## v1.11.0-rc.1
### Changed
* Changed minimum PHP version requirement from `7.4` to `8.0`.
* Upgraded from Laravel 8 to Laravel 9.
* This release requires Wings v1.11.x in order for Server Transfers to work.
### Fixed
* Node maintenance mode now properly blocks access to servers.
* Fixed the length validation on the Minecraft Forge egg.
* Fixed the password in the JDBC string not being properly URL encoded.
* Fixed an issue where Wings would throw a validation error while attempting to upload activity logs.
## v1.10.4
### Fixed
* Fixed an issue where subusers could be given permissions that are not actually registered or used.
* Fixed an issue where node FQDNs could not just be IP addresses.
### Changed
* Change maximum number of API keys per user from `10` to `25`.
* Change byte unit prefix from `B` to `iB` to better reflect our usage of base 2 (multiples of 1024).
## v1.10.3
### Fixed
* S3 Backup driver now supports Cloudflare R2.
* Node FQDNs can now be used with AAAA records with no A records present.
* Server transfers can no longer be initiated if the server is being installed, transferred, or restoring a backup.
* Fixed an issue relating to the use of arrays in the `config_files` field with eggs.
* Fixed `oom_disabled` not being mapped in the Application API when creating a new server.
### Added
* File manager now supports selecting multiple files for upload (when using the upload button).
* Added a configuration option for specifying the S3 storage class for backups.
### Changed
* Servers will now show the current uptime when the server is starting rather than only showing when the server is marked as online.
## v1.10.2
### Fixed
* Fixes a rendering issue with egg descriptions in the admin area
* Fixes the page title on the SSH Keys page
### Changed
* Additional validation rules will now show a toggle switch rather than an input when editing server variables
* The eggs endpoint will now always return an empty JSON object for the `config_files` field, even if the field is completely empty
### Added
* Adds a `Force Outgoing IP` option for eggs that can be used to ensure servers making outgoing connections use their allocation IP rather than the node's primary ip
* Adds options to configure sending of email (re)install notifications
* Add an option to configure the part size for backups uploaded to S3
## v1.10.1
### Fixed
* Fixes a surprise `clock()` function that was used for debugging and should not have made it into the release. This was causing activity events to not properly sync between the Panel and Wings.
## v1.10.0
### Fixed
* Fixes improper cache key naming on the frontend causing server activity logs to be duplicated across server page views.
* Fixes overflow issues on dialogs when the internal content is too long.
* Fixes spinner overlay on console improperly taking up the entire page making it impossible to use navigation controls.
* Fixes 2FA QR code background being too dark for some phones to properly scan.
* File manager now properly displays an error message if a user attempts to upload a folder rather than files.
* Fixes the "Create Directory" dialog persisting the previously entered value when it is re-opened.
### Changed
* IP addresses in activity logs are now always displayed to administrators, regardless of if they own the server or not.
* Scroll down indicator on the console has been changed to a down arrow to be clearer.
* Docker builds have been updated to use `PHP 8.1`.
* Recaptcha validation domain is now configurable using the `RECAPTCHA_DOMAIN` environment variable.
* Drag and drop overlay on the file manager has been tweaked to be slightly more consistent with the frontend style and be a little easier to read.
### Added
* Adds support for the `user_uuid` claim on all generated JWTs which allows Wings to properly identify the user performing each action.
* Adds support for recieving external activity log events from Wings instances (power state, commands, SFTP, and uploads).
* Adds support for tracking failed password-based SFTP logins.
* Server name and description are now passed along to Wings making them available in egg variables for parsing and including.
* Adds support for displaying all active file uploads in the file manager.
## v1.9.2
### Fixed
* Fixes rouding in sidebar of CPU usage graph that was causing an excessive number of zeros to be rendered.
* Fixes the Java Version selector modal having the wrong default value selected initially.
* Fixes console rendering in Safari that was causing the console to resize excessively and graphs to overlay content.
* Fixes missing "Starting"/"Stopping" status display in the server uptime block.
* Fixes incorrect formatting of activity log when viewing certain file actions.
### Changed
* Updated the UI for the two-step authorization setup on accounts to use new Dialog UI and provide better clarity to new users.
### Added
* Added missing `<DOCTYPE html>` tag to template output to avoid entering quirks mode in browsers.
* Added password requirement when enabling TOTP on an account.
## v1.9.1
### Fixed
* Fixes missing "Click to Copy" for server address on the console data blocks.
* Fixes data points on the graphs not being properly rounded to two decimal places.
* Returns byte formatting logic to use `1024` as the base value, rather than `1000`.
* Fixes permission error occurring when a server is marked as installing and an admin navigates to the console screen.
* Fixes improper display of install/transfer warning on the server console page.
* Fixes permission matching for the server settings page to correctly allow access when a user has _any_ of the needed permissions.
### Changed
* Moves the server data blocks to the right-hand side of the console, rather than the left.
* Rather than defaulting graph values at `0` when resetting or refreshing the page, their values are now hidden entirely.
* **[security]** Hides IP addresses from all activity log entries that are not directly associated with the currently signed in user.
### Added
* Adds the current resource limits for a server next to each data block on the console screen.
## v1.9.0
### Added
* Added support for using Tailwind classes inside components using `className={}` rather than having to use `twin.macro` with the `css={}` prop.
* Added HeadlessUI and Heroicons packages.
* Added new `Tooltip.tsx` component to support displaying tooltips within the Panel.
* Adds a new activity log view for both user accounts and individual servers. This builds upon data collected in previous releases.
* Added a new column `api_key_id` to the `activity_logs` table to indicate if the user performed the action while using an API key.
* Adds initial support for language translations on the front-end. The underlying implementation details are working, however work has not yet begun on actually translating all of the strings yet. Expect this to continue in future releases.
* Improved accessibility for navigation icons by adding a tooltip on hover to indicate what each one does.
* Adds logging for API keys that are blocked from performing an API action due to IP address limiting.
* Adds support for `?filter[description]=foo` when querying servers on both the client and application API.
### Changed
* Updated how release assets are generated to perform more logical bundle splitting. This should help reduce the amount of data users have to download at once in order to render the UI.
* Upgraded From TailwindCSS 2 to 3 — for most people this should have minimal if any impact.
* Chart.js updated from v2 to v3.
* Reduced the number of custom colors in use — by default we now use Tailwind's default color pallet, with the exception of a custom gray scheme.
* **[deprecated]** The use of `neutral` and `primary` have been deprecated in class names, prefer `gray` and `blue` respectively.
* Begins the process of dropping the use of Gravatars for user avatars and replaces them with dynamically generated SVG images.
* Improved front-end route definitions to make it easier for external modifications to inject their routes and components into the codebase without having to modify as many core files.
* Redesigned the server console screen to better display data users might be looking for, and increase the height of the console itself.
* Merged the two network data graphs into a single dual-line graph to better display incoming and outgoing data volumes.
* Updated all byte formatting logic to use `1000` as the divisor rather than `1024` to be more consistent with what users most likely expect.
* Changed the underlying `eslint` rules applied to the front-end codebase to simplify them dramatically. We now utilize `prettier` in combination with some basic default rulesets to make it easier to understand the expected formatting.
### Fixed
* Fixes a bug causing a 404 error when attempting to delete a database from a server in the admin control panel.
* Fixes console input auto-capitalizing and auto-correcting when entering text on some mobile devices.
* Fixes SES service configuration using a hard-coded `us-east-1` region.
* Fixes a bug causing a 404 error when attempting to delete an SSH key from your account when the SHA256 hash includes a slash.
* Fixes mobile keyboards automatically attempting to capitalize and spellcheck typing on the server console.
* Fixes improper support for IP address CIDR ranges when creating API keys for the client area.
* Fixes a bug preventing additional included details from being returned from the application API when utilizing a client API key as an administrator.
## v1.8.1
### Fixed
* Fixes a bug causing mounts to return a 404 error when adding them to a server.
* Fixes a bug causing the Egg Image dropdown to not display properly when creating a new server.
* Fixes a bug causing an error when attemping to create a new server via the API.
## v1.8.0 ## v1.8.0
**Important:** this version updates the `version` field on generated Eggs to be `PTDL_v2` due to formatting changes. This **Important:** this version updates the `version` field on generated Eggs to be `PTDL_v2` due to formatting changes. This
should be completely seamless for most installations as the Panel is able to convert between the two. Custom solutions should be completely seamless for most installations as the Panel is able to convert between the two. Custom solutions
using these eggs should be updated to account for the new format. using these eggs should be updated to account for the new format.
This release also changes API key behavior — "client" keys belonging to admin users can now be used to access
the `/api/application` endpoints in their entirety. Existing "application" keys generated in the admin area should
be considered deprecated, but will continue to work. Application keys _will not_ work with the client API.
### Fixed ### Fixed
* Schedules are no longer run when a server is suspended or marked as installing. * Schedules are no longer run when a server is suspended or marked as installing.
* The remote field when creating a database is no longer limited to an IP address and `%` wildcard — all expected MySQL remote host values are allowed. * The remote field when creating a database is no longer limited to an IP address and `%` wildcard — all expected MySQL remote host values are allowed.
* Allocations cannot be deleted from a server by a user if the server is configured with an `allocation_limit` set to `0`. * Allocations cannot be deleted from a server by a user if the server is configured with an `allocation_limit` set to `0`.
* The Java Version modal no longer shows a dropdown and update option to users that do not have permission to make those changes. * The Java Version modal no longer shows a dropdown and update option to users that do not have permission to make those changes.
* The Java Version modal now correctly returns only the images available to the server's selected Egg. * The Java Version modal now correctly returns only the images available to the server's selected Egg.
* Fixes leading and trailing spaces being removed from variable values on file manager endpoints, causing errors when trying to perform actions against certain files and folders.
### Changed ### Changed
* Forces HTTPS on URLs when the `APP_URL` value is set and includes `https://` within the URL. This addresses proxy misconfiguration issues that would cause URLs to be generated incorrectly. * Forces HTTPS on URLs when the `APP_URL` value is set and includes `https://` within the URL. This addresses proxy misconfiguration issues that would cause URLs to be generated incorrectly.
@ -21,6 +236,8 @@ using these eggs should be updated to account for the new format.
* Additional permissions (`CREATE TEMPORARY TABLES`, `CREATE VIEW`, `SHOW VIEW`, `EVENT`, and `TRIGGER`) are granted to users when creating new databases for servers. * Additional permissions (`CREATE TEMPORARY TABLES`, `CREATE VIEW`, `SHOW VIEW`, `EVENT`, and `TRIGGER`) are granted to users when creating new databases for servers.
* development: removed Laravel Debugbar in favor of Clockwork for debugging. * development: removed Laravel Debugbar in favor of Clockwork for debugging.
* The 2FA input field when logging in is now correctly identified as `one-time-password` to help browser autofill capabilities. * The 2FA input field when logging in is now correctly identified as `one-time-password` to help browser autofill capabilities.
* Changed API authentication mechanisms to make use of Laravel Sanctum to significantly clean up our internal handling of sessions.
* API keys generated by the system now set a prefix to identify them as Pterodactyl API keys, and if they are client or application keys. This prefix looks like `ptlc_` for client keys, and `ptla_` for application keys. Existing API keys are unaffected by this change.
### Added ### Added
* Added support for PHP 8.1 in addition to PHP 8.0 and 7.4. * Added support for PHP 8.1 in addition to PHP 8.0 and 7.4.
@ -32,9 +249,13 @@ using these eggs should be updated to account for the new format.
* Adds command to return the configuration for a specific node in both YAML and JSON format (`php artisan p:node:configuration`). * Adds command to return the configuration for a specific node in both YAML and JSON format (`php artisan p:node:configuration`).
* Adds command to return a list of all nodes available on the Panel in both table and JSON format (`php artisan p:node:list`). * Adds command to return a list of all nodes available on the Panel in both table and JSON format (`php artisan p:node:list`).
* Adds server network (inbound/outbound) usage graphs to the console screen. * Adds server network (inbound/outbound) usage graphs to the console screen.
* Adds support for configuring CORS on the API by setting the `APP_CORS_ALLOWED_ORIGINS=example.com,dashboard.example.com` environment variable. By default all instances are configured with this set to `*` which allows any origin.
* Adds proper activity logging for the following areas of the Panel: authentication, user account modifications, server modification. This is an initial test implementation before further roll-out in the software. Events are logged into the database but are not currently exposed in the UI — they will be displayed in a future update.
### Removed ### Removed
* Removes Google Analytics from the front end code. * Removes Google Analytics from the front end code.
* Removes multiple middleware that were previously used for configuring API access and controlling model fetching. This has all been replaced with Laravel Sanctum and standard Laravel API tooling. This should make codebase discovery significantly more simple.
* **DEPRECATED**: The use of `Pterodactyl\Models\AuditLog` is deprecated and all references to this model have been removed from the codebase. In the next major release this model and table will be fully dropped.
## v1.7.0 ## v1.7.0
### Fixed ### Fixed

View file

@ -1,27 +1,31 @@
# Contributing # Contributing
Pterodactyl does not accept Pull Requests (PRs) _for new functionality_ from users that are not currently part of the Pterodactyl does not accept Pull Requests (PRs) _for new functionality_ from users that are not currently part of the
core project team. It has become overwhelming to try and give the proper time and attention that such complicated PRs core project team. It has become overwhelming to try and give the proper time and attention that such complicated PRs
tend to require — and deserve. As a result, it is in the project's best interest to limit the scope of work on tend to require — and deserve. As a result, it is in the project's best interest to limit the scope of work on
new functionality to work done within the core project team. new functionality to work done within the core project team.
PRs that address existing _bugs_ with a corresponding issue opened in our issue tracker will continue to be accepted PRs that address existing _bugs_ with a corresponding issue opened in our issue tracker will continue to be accepted
and reviewed. Their scope is often signficantly more targeted, and simply improving upon existing and well defined and reviewed. Their scope is often significantly more targeted, and simply improving upon existing and well defined
logic. logic.
### Responsible Disclosure ### Responsible Disclosure
This is a fairly in-depth project and makes use of a lot of parts. We strive to keep everything as secure as possible This is a fairly in-depth project and makes use of a lot of parts. We strive to keep everything as secure as possible
and welcome you to take a look at the code provided in this project yourself. We do ask that you be considerate of and welcome you to take a look at the code provided in this project yourself. We do ask that you be considerate of
others who are using the software and not publicly disclose security issues without contacting us first by email. others who are using the software and not publicly disclose security issues without contacting us first by email.
We'll make a deal with you: if you contact us by email and we fail to respond to you within a week you are welcome to We'll make a deal with you: if you contact us by email, and we fail to respond to you within a week you are welcome to
publicly disclose whatever issue you have found. We understand how frustrating it is when you find something big and publicly disclose whatever issue you have found. We understand how frustrating it is when you find something big and
no one will respond to you. This holds us to a standard of providing prompt attention to any issues that arise and no one will respond to you. This holds us to a standard of providing prompt attention to any issues that arise and
keeping this community safe. keeping this community safe.
If you've found what you believe is a security issue please email `dane åt pterodactyl døt io`. If you've found what you believe is a security issue please email `matthew@pterodactyl.io`. Please check
[SECURITY.md](/SECURITY.md) for additional details.
### Contact Us ### Contact Us
You can find us in a couple places online. First and foremost, we're active right here on Github. If you encounter a
You can find us in a couple places online. First and foremost, we're active right here on GitHub. If you encounter a
bug or other problems, open an issue on here for us to take a look at it. We also accept feature requests here as well. bug or other problems, open an issue on here for us to take a look at it. We also accept feature requests here as well.
You can also find us on [Discord](https://discord.gg/pterodactyl). You can also find us on [Discord](https://discord.gg/pterodactyl).

77
Containerfile Normal file
View file

@ -0,0 +1,77 @@
# Stage 1 - Builder
FROM --platform=$TARGETOS/$TARGETARCH registry.access.redhat.com/ubi9/nodejs-18-minimal AS builder
USER 0
RUN npm install -g pnpm
WORKDIR /var/www/pterodactyl
COPY --chown=1001:0 public ./public
COPY --chown=1001:0 resources/scripts ./resources/scripts
COPY --chown=1001:0 .eslintignore .eslintrc.js .npmrc .prettierrc.json package.json pnpm-lock.yaml tailwind.config.js tsconfig.json vite.config.ts .
RUN /opt/app-root/src/.npm-global/bin/pnpm install \
&& /opt/app-root/src/.npm-global/bin/pnpm build \
&& rm -rf resources/scripts .eslintignore .eslintrc.yml .npmrc package.json pnpm-lock.yaml tailwind.config.js tsconfig.json vite.config.ts node_modules
USER 1001
COPY --chown=1001:0 app ./app
COPY --chown=1001:0 bootstrap ./bootstrap
COPY --chown=1001:0 config ./config
COPY --chown=1001:0 database ./database
COPY --chown=1001:0 resources/lang ./resources/lang
COPY --chown=1001:0 resources/views ./resources/views
COPY --chown=1001:0 routes ./routes
COPY --chown=1001:0 .env.example ./.env
COPY --chown=1001:0 artisan CHANGELOG.md composer.json composer.lock LICENSE.md README.md SECURITY.md .
# Stage 2 - Final
FROM --platform=$TARGETOS/$TARGETARCH registry.access.redhat.com/ubi9/ubi-minimal
RUN microdnf update -y \
&& rpm --install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \
&& rpm --install https://rpms.remirepo.net/enterprise/remi-release-9.rpm \
&& microdnf update -y \
&& microdnf install -y ca-certificates shadow-utils tar tzdata unzip wget \
# ref; https://bugzilla.redhat.com/show_bug.cgi?id=1870814
&& microdnf reinstall -y tzdata \
&& microdnf module -y reset php \
&& microdnf module -y enable php:remi-8.2 \
&& microdnf install -y composer cronie php-{bcmath,cli,common,fpm,gd,gmp,intl,json,mbstring,mysqlnd,opcache,pdo,pecl-redis5,pecl-zip,phpiredis,pgsql,process,sodium,xml,zstd} supervisor \
&& rm /etc/php-fpm.d/www.conf \
&& useradd --home-dir /var/lib/caddy --create-home caddy \
&& mkdir /etc/caddy \
&& wget -O /usr/local/bin/yacron https://github.com/gjcarneiro/yacron/releases/download/0.17.0/yacron-0.17.0-x86_64-unknown-linux-gnu \
&& chmod 755 /usr/local/bin/yacron \
&& microdnf remove -y tar wget \
&& microdnf clean all
COPY --chown=caddy:caddy --from=builder /var/www/pterodactyl /var/www/pterodactyl
WORKDIR /var/www/pterodactyl
RUN mkdir -p /tmp/pterodactyl/cache /tmp/pterodactyl/framework/{cache,sessions,views} storage/framework \
&& rm -rf bootstrap/cache storage/framework/sessions storage/framework/views storage/framework/cache \
&& ln -s /tmp/pterodactyl/cache /var/www/pterodactyl/bootstrap/cache \
&& ln -s /tmp/pterodactyl/framework/cache /var/www/pterodactyl/storage/framework/cache \
&& ln -s /tmp/pterodactyl/framework/sessions /var/www/pterodactyl/storage/framework/sessions \
&& ln -s /tmp/pterodactyl/framework/views /var/www/pterodactyl/storage/framework/views \
&& chmod -R 755 /var/www/pterodactyl/storage/* /tmp/pterodactyl/cache \
&& chown -R caddy:caddy /var/www/pterodactyl /tmp/pterodactyl/{cache,framework}
USER caddy
ENV USER=caddy
RUN composer install --no-dev --optimize-autoloader \
&& rm -rf bootstrap/cache/*.php \
&& rm -rf .env storage/logs/*.log
COPY --from=docker.io/library/caddy:latest /usr/bin/caddy /usr/local/bin/caddy
COPY .github/docker/Caddyfile /etc/caddy/Caddyfile
COPY .github/docker/php-fpm.conf /etc/php-fpm.conf
COPY .github/docker/supervisord.conf /etc/supervisord.conf
COPY .github/docker/yacron.yaml /etc/yacron.yaml
EXPOSE 8080
CMD ["/usr/bin/supervisord", "--configuration=/etc/supervisord.conf"]

View file

@ -1,40 +0,0 @@
# Stage 0:
# Build the assets that are needed for the frontend. This build stage is then discarded
# since we won't need NodeJS anymore in the future. This Docker image ships a final production
# level distribution of Pterodactyl.
FROM --platform=$TARGETOS/$TARGETARCH mhart/alpine-node:14
WORKDIR /app
COPY . ./
RUN yarn install --frozen-lockfile \
&& yarn run build:production
# Stage 1:
# Build the actual container with all of the needed PHP dependencies that will run the application.
FROM --platform=$TARGETOS/$TARGETARCH php:7.4-fpm-alpine
WORKDIR /app
COPY . ./
COPY --from=0 /app/public/assets ./public/assets
RUN apk add --no-cache --update ca-certificates dcron curl git supervisor tar unzip nginx libpng-dev libxml2-dev libzip-dev certbot certbot-nginx \
&& docker-php-ext-configure zip \
&& docker-php-ext-install bcmath gd pdo_mysql zip \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
&& cp .env.example .env \
&& mkdir -p bootstrap/cache/ storage/logs storage/framework/sessions storage/framework/views storage/framework/cache \
&& chmod 777 -R bootstrap storage \
&& composer install --no-dev --optimize-autoloader \
&& rm -rf .env bootstrap/cache/*.php \
&& chown -R nginx:nginx .
RUN rm /usr/local/etc/php-fpm.conf \
&& echo "* * * * * /usr/local/bin/php /app/artisan schedule:run >> /dev/null 2>&1" >> /var/spool/cron/crontabs/root \
&& echo "0 23 * * * certbot renew --nginx --quiet" >> /var/spool/cron/crontabs/root \
&& sed -i s/ssl_session_cache/#ssl_session_cache/g /etc/nginx/nginx.conf \
&& mkdir -p /var/run/php /var/run/nginx
COPY .github/docker/default.conf /etc/nginx/http.d/default.conf
COPY .github/docker/www.conf /usr/local/etc/php-fpm.conf
COPY .github/docker/supervisord.conf /etc/supervisord.conf
EXPOSE 80 443
ENTRYPOINT [ "/bin/ash", ".github/docker/entrypoint.sh" ]
CMD [ "supervisord", "-n", "-c", "/etc/supervisord.conf" ]

9
LICENSE Normal file
View file

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2024 Skynet
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -1,11 +1,12 @@
[![Logo Image](https://cdn.pterodactyl.io/logos/new/pterodactyl_logo.png)](https://pterodactyl.io) [![Logo Image](https://cdn.pterodactyl.io/logos/new/pterodactyl_logo.png)](https://pterodactyl.io)
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/pterodactyl/panel/tests?label=Tests&style=for-the-badge) ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/pterodactyl/panel/laravel.yaml?label=Tests&style=for-the-badge&branch=develop)
![Discord](https://img.shields.io/discord/122900397965705216?label=Discord&logo=Discord&logoColor=white&style=for-the-badge) ![Discord](https://img.shields.io/discord/122900397965705216?label=Discord&logo=Discord&logoColor=white&style=for-the-badge)
![GitHub Releases](https://img.shields.io/github/downloads/pterodactyl/panel/latest/total?style=for-the-badge) ![GitHub Releases](https://img.shields.io/github/downloads/pterodactyl/panel/latest/total?style=for-the-badge)
![GitHub contributors](https://img.shields.io/github/contributors/pterodactyl/panel?style=for-the-badge) ![GitHub contributors](https://img.shields.io/github/contributors/pterodactyl/panel?style=for-the-badge)
# Pterodactyl Panel # Pterodactyl Panel
Pterodactyl® is a free, open-source game server management panel built with PHP, React, and Go. Designed with security Pterodactyl® is a free, open-source game server management panel built with PHP, React, and Go. Designed with security
in mind, Pterodactyl runs all game servers in isolated Docker containers while exposing a beautiful and intuitive in mind, Pterodactyl runs all game servers in isolated Docker containers while exposing a beautiful and intuitive
UI to end users. UI to end users.
@ -15,38 +16,31 @@ Stop settling for less. Make game servers a first class citizen on your platform
![Image](https://cdn.pterodactyl.io/site-assets/pterodactyl_v1_demo.gif) ![Image](https://cdn.pterodactyl.io/site-assets/pterodactyl_v1_demo.gif)
## Documentation ## Documentation
* [Panel Documentation](https://pterodactyl.io/panel/1.0/getting_started.html) * [Panel Documentation](https://pterodactyl.io/panel/1.0/getting_started.html)
* [Wings Documentation](https://pterodactyl.io/wings/1.0/installing.html) * [Wings Documentation](https://pterodactyl.io/wings/1.0/installing.html)
* [Community Guides](https://pterodactyl.io/community/about.html) * [Community Guides](https://pterodactyl.io/community/about.html)
* Or, get additional help [via Discord](https://discord.gg/pterodactyl) * Or, get additional help [via Discord](https://discord.gg/pterodactyl)
## Sponsors ## Sponsors
I would like to extend my sincere thanks to the following sponsors for helping fund Pterodactyl's developement.
[Interested in becoming a sponsor?](https://github.com/sponsors/DaneEveritt)
| Company | About | I would like to extend my sincere thanks to the following sponsors for helping fund Pterodactyl's development.
| ------- | ----- | [Interested in becoming a sponsor?](https://github.com/sponsors/matthewpi)
| [**WISP**](https://wisp.gg) | Extra features. |
| [**MixmlHosting**](https://mixmlhosting.com) | MixmlHosting provides high quality Virtual Private Servers along with game servers, all at a affordable price. | | Company | About |
| [**BisectHosting**](https://www.bisecthosting.com/) | BisectHosting provides Minecraft, Valheim and other server hosting services with the highest reliability and lightning fast support since 2012. | |-----------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [**Tempest**](https://tempest.net/) | Tempest Hosting is a subsidiary of Path Network, Inc. offering **unmetered DDoS protected 10Gbps dedicated servers**, starting at just $80/month. Full anycast, tons of filters. | | [**WISP**](https://wisp.gg) | Extra features. |
| [**Bloom.host**](https://bloom.host) | Bloom.host offers dedicated core VPS and Minecraft hosting with Ryzen 9 processors. With owned-hardware, we offer truly unbeatable prices on high-performance hosting. | | [**Aussie Server Hosts**](https://aussieserverhosts.com/) | No frills Australian Owned and operated High Performance Server hosting for some of the most demanding games serving Australia and New Zealand. |
| [**MineStrator**](https://minestrator.com/) | Looking for a French highend hosting company for you minecraft server? More than 14,000 members on our discord, trust us. | | [**WemX**](https://wemx.net/) | WemX helps automate your hosting company or SaaS business by automating billing, user management, authentication, and much more. |
| [**DedicatedMC**](https://dedicatedmc.io/) | DedicatedMC provides Raw Power hosting at affordable pricing, making sure to never compromise on your performance and giving you the best performance money can buy. | | [**BisectHosting**](https://www.bisecthosting.com/) | BisectHosting provides Minecraft, Valheim and other server hosting services with the highest reliability and lightning fast support since 2012. |
| [**Skynode**](https://www.skynode.pro/) | Skynode provides blazing fast game servers along with a top-notch user experience. Whatever our clients are looking for, we're able to provide it! | | [**MineStrator**](https://minestrator.com/) | Looking for the most highend French hosting company for your minecraft server? More than 24,000 members on our discord trust us. Give us a try! |
| [**XCORE**](https://xcore-server.de/) | XCORE offers High-End Servers for hosting and gaming since 2012. Fast, excellent and well-known for eSports Gaming. | | [**VibeGAMES**](https://vibegames.net/) | VibeGAMES is a game server provider that specializes in DDOS protection for the games we offer. We have multiple locations in the US, Brazil, France, Germany, Singapore, Australia and South Africa. |
| [**RoyaleHosting**](https://royalehosting.net/) | Build your dreams and deploy them with RoyaleHostings reliable servers and network. Easy to use, provisioned in a couple of minutes. | | [**DutchIS**](https://dutchis.net?ref=pterodactyl) | DutchIS provides instant infrastructure such as pay per use VPS hosting. Start your game hosting journey on DutchIS. |
| [**Spill Hosting**](https://spillhosting.no/) | Spill Hosting is a Norwegian hosting service, which aims for inexpensive services on quality servers. Premium i9-9900K processors will run your game like a dream. | | [**Skoali**](https://skoali.com/) | Skoali is a French company that hosts game servers and other types of services (VPS, WEB, Dedicated servers, ...). We also have a free plan for Minecraft and Garry's Mod. |
| [**DeinServerHost**](https://deinserverhost.de/) | DeinServerHost offers Dedicated, vps and Gameservers for many popular Games like Minecraft and Rust in Germany since 2013. | | [**Rabbit Computing**](https://www.rabbitcomputing.com/link.php?id=5) | Rabbit Computing offers powerful VPS servers, highly available game hosting, and fully unlimited web hosting. Use code README for 20% off your first three months! |
| [**HostBend**](https://hostbend.com/) | HostBend offers a variety of solutions for developers, students, and others who have a tight budget but don't want to compromise quality and support. |
| [**Capitol Hosting Solutions**](https://chs.gg/) | CHS is *the* budget friendly hosting company for Australian and American gamers, offering a variety of plans from Web Hosting to Game Servers; Custom Solutions too! |
| [**ByteAnia**](https://byteania.com/?utm_source=pterodactyl) | ByteAnia offers the best performing and most affordable **Ryzen 5000 Series hosting** on the market for *unbeatable prices*! |
| [**Aussie Server Hosts**](https://aussieserverhosts.com/) | No frills Australian Owned and operated High Performance Server hosting for some of the most demanding games serving Australia and New Zealand. |
| [**VibeGAMES**](https://vibegames.net/) | VibeGAMES is a game server provider that specializes in DDOS protection for the games we offer. We have multiple locations in the US, Brazil, France, Germany, Singapore, Australia and South Africa.|
| [**RocketNode**](https://rocketnode.net) | RocketNode is a VPS and Game Server provider that offers the best performing VPS and Game hosting Solutions at affordable prices! |
| [**HostEZ**](https://hostez.io) | Providing North America Valheim, Minecraft and other popular games with low latency, high uptime and maximum availability. EZ! |
### Supported Games ### Supported Games
Pterodactyl supports a wide variety of games by utilizing Docker containers to isolate each instance. This gives Pterodactyl supports a wide variety of games by utilizing Docker containers to isolate each instance. This gives
you the power to run game servers without bloating machines with a host of additional dependencies. you the power to run game servers without bloating machines with a host of additional dependencies.
@ -75,6 +69,7 @@ and there are plenty more games available provided by the community. Some of the
* [and many more...](https://github.com/parkervcp/eggs) * [and many more...](https://github.com/parkervcp/eggs)
## License ## License
Pterodactyl® Copyright © 2015 - 2022 Dane Everitt and contributors. Pterodactyl® Copyright © 2015 - 2022 Dane Everitt and contributors.
Code released under the [MIT License](./LICENSE.md). Code released under the [MIT License](./LICENSE.md).

View file

@ -1,17 +1,19 @@
# Security Policy # Security Policy
## Supported Versions ## Supported Versions
The following versions of Pterodactyl are receiving active support and maintenance. Any security vulnerabilities discovered must be reproducible in supported versions. The following versions of Pterodactyl are receiving active support and maintenance. Any security vulnerabilities discovered must be reproducible in supported versions.
| Panel | Daemon | Supported | | Panel | Daemon | Supported |
| ----- | ------------ | ------------------ | |--------|--------------|--------------------|
| 1.7.x | wings@1.5.x | :white_check_mark: | | 1.10.x | wings@1.7.x | :white_check_mark: |
| 0.7.x | daemon@0.6.x | :x: | | 1.11.x | wings@1.11.x | :white_check_mark: |
| 0.7.x | daemon@0.6.x | :x: |
## Reporting a Vulnerability ## Reporting a Vulnerability
Please reach out directly to any project team member on Discord when reporting a security vulnerability, or you can send an email to `dane@pterodactyl.io`. Please reach out directly to any project team member on Discord when reporting a security vulnerability, or you can email `matthew@pterodactyl.io`.
We make every effort to respond as soon as possible, although it may take a day or two for us to sync internally and determine the severity of the report and its impact. Please, _do not_ use a public facing channel or GitHub issues to report sensitive security issues. We make every effort to respond as soon as possible, although it may take a day or two for us to sync internally and determine the severity of the report and its impact. Please, _do not_ use a public facing channel or GitHub issues to report sensitive security issues.

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Console\Commands\Environment; namespace Pterodactyl\Console\Commands\Environment;
use DateTimeZone;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Contracts\Console\Kernel; use Illuminate\Contracts\Console\Kernel;
use Pterodactyl\Traits\Commands\EnvironmentWriterTrait; use Pterodactyl\Traits\Commands\EnvironmentWriterTrait;
@ -31,19 +30,8 @@ class AppSettingsCommand extends Command
'sync' => 'Sync', 'sync' => 'Sync',
]; ];
/**
* @var \Illuminate\Contracts\Console\Kernel
*/
protected $command;
/**
* @var string
*/
protected $description = 'Configure basic environment settings for the Panel.'; protected $description = 'Configure basic environment settings for the Panel.';
/**
* @var string
*/
protected $signature = 'p:environment:setup protected $signature = 'p:environment:setup
{--new-salt : Whether or not to generate a new salt for Hashids.} {--new-salt : Whether or not to generate a new salt for Hashids.}
{--author= : The email that services created on this instance should be linked to.} {--author= : The email that services created on this instance should be linked to.}
@ -55,21 +43,17 @@ class AppSettingsCommand extends Command
{--redis-host= : Redis host to use for connections.} {--redis-host= : Redis host to use for connections.}
{--redis-pass= : Password used to connect to redis.} {--redis-pass= : Password used to connect to redis.}
{--redis-port= : Port to connect to redis over.} {--redis-port= : Port to connect to redis over.}
{--settings-ui= : Enable or disable the settings UI.}'; {--settings-ui= : Enable or disable the settings UI.}
{--telemetry= : Enable or disable anonymous telemetry.}';
/** protected array $variables = [];
* @var array
*/
protected $variables = [];
/** /**
* AppSettingsCommand constructor. * AppSettingsCommand constructor.
*/ */
public function __construct(Kernel $command) public function __construct(private Kernel $console)
{ {
parent::__construct(); parent::__construct();
$this->command = $command;
} }
/** /**
@ -77,7 +61,7 @@ class AppSettingsCommand extends Command
* *
* @throws \Pterodactyl\Exceptions\PterodactylException * @throws \Pterodactyl\Exceptions\PterodactylException
*/ */
public function handle() public function handle(): int
{ {
if (empty(config('hashids.salt')) || $this->option('new-salt')) { if (empty(config('hashids.salt')) || $this->option('new-salt')) {
$this->variables['HASHIDS_SALT'] = str_random(20); $this->variables['HASHIDS_SALT'] = str_random(20);
@ -98,13 +82,13 @@ class AppSettingsCommand extends Command
$this->output->comment('The application URL MUST begin with https:// or http:// depending on if you are using SSL or not. If you do not include the scheme your emails and other content will link to the wrong location.'); $this->output->comment('The application URL MUST begin with https:// or http:// depending on if you are using SSL or not. If you do not include the scheme your emails and other content will link to the wrong location.');
$this->variables['APP_URL'] = $this->option('url') ?? $this->ask( $this->variables['APP_URL'] = $this->option('url') ?? $this->ask(
'Application URL', 'Application URL',
config('app.url', 'http://example.org') config('app.url', 'https://example.com')
); );
$this->output->comment('The timezone should match one of PHP\'s supported timezones. If you are unsure, please reference http://php.net/manual/en/timezones.php.'); $this->output->comment('The timezone should match one of PHP\'s supported timezones. If you are unsure, please reference https://php.net/manual/en/timezones.php.');
$this->variables['APP_TIMEZONE'] = $this->option('timezone') ?? $this->anticipate( $this->variables['APP_TIMEZONE'] = $this->option('timezone') ?? $this->anticipate(
'Application Timezone', 'Application Timezone',
DateTimeZone::listIdentifiers(DateTimeZone::ALL), \DateTimeZone::listIdentifiers(),
config('app.timezone') config('app.timezone')
); );
@ -135,15 +119,23 @@ class AppSettingsCommand extends Command
$this->variables['APP_ENVIRONMENT_ONLY'] = $this->confirm('Enable UI based settings editor?', true) ? 'false' : 'true'; $this->variables['APP_ENVIRONMENT_ONLY'] = $this->confirm('Enable UI based settings editor?', true) ? 'false' : 'true';
} }
$this->output->comment('Please reference https://pterodactyl.io/panel/1.0/additional_configuration.html#telemetry for more detailed information regarding telemetry data and collection.');
$this->variables['PTERODACTYL_TELEMETRY_ENABLED'] = $this->option('telemetry') ?? $this->confirm(
'Enable sending anonymous telemetry data?',
config('pterodactyl.telemetry.enabled', true)
) ? 'true' : 'false';
// Make sure session cookies are set as "secure" when using HTTPS // Make sure session cookies are set as "secure" when using HTTPS
if (strpos($this->variables['APP_URL'], 'https://') === 0) { if (str_starts_with($this->variables['APP_URL'], 'https://')) {
$this->variables['SESSION_SECURE_COOKIE'] = 'true'; $this->variables['SESSION_SECURE_COOKIE'] = 'true';
} }
$this->checkForRedis(); $this->checkForRedis();
$this->writeToEnvironment($this->variables); $this->writeToEnvironment($this->variables);
$this->info($this->command->output()); $this->info($this->console->output());
return 0;
} }
/** /**

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Console\Commands\Environment; namespace Pterodactyl\Console\Commands\Environment;
use PDOException;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Contracts\Console\Kernel; use Illuminate\Contracts\Console\Kernel;
use Illuminate\Database\DatabaseManager; use Illuminate\Database\DatabaseManager;
@ -12,24 +11,8 @@ class DatabaseSettingsCommand extends Command
{ {
use EnvironmentWriterTrait; use EnvironmentWriterTrait;
/**
* @var \Illuminate\Contracts\Console\Kernel
*/
protected $console;
/**
* @var \Illuminate\Database\DatabaseManager
*/
protected $database;
/**
* @var string
*/
protected $description = 'Configure database settings for the Panel.'; protected $description = 'Configure database settings for the Panel.';
/**
* @var string
*/
protected $signature = 'p:environment:database protected $signature = 'p:environment:database
{--host= : The connection address for the MySQL server.} {--host= : The connection address for the MySQL server.}
{--port= : The connection port for the MySQL server.} {--port= : The connection port for the MySQL server.}
@ -37,30 +20,22 @@ class DatabaseSettingsCommand extends Command
{--username= : Username to use when connecting.} {--username= : Username to use when connecting.}
{--password= : Password to use for this database.}'; {--password= : Password to use for this database.}';
/** protected array $variables = [];
* @var array
*/
protected $variables = [];
/** /**
* DatabaseSettingsCommand constructor. * DatabaseSettingsCommand constructor.
*/ */
public function __construct(DatabaseManager $database, Kernel $console) public function __construct(private DatabaseManager $database, private Kernel $console)
{ {
parent::__construct(); parent::__construct();
$this->console = $console;
$this->database = $database;
} }
/** /**
* Handle command execution. * Handle command execution.
* *
* @return int
*
* @throws \Pterodactyl\Exceptions\PterodactylException * @throws \Pterodactyl\Exceptions\PterodactylException
*/ */
public function handle() public function handle(): int
{ {
$this->output->note('It is highly recommended to not use "localhost" as your database host as we have seen frequent socket connection issues. If you want to use a local connection you should be using "127.0.0.1".'); $this->output->note('It is highly recommended to not use "localhost" as your database host as we have seen frequent socket connection issues. If you want to use a local connection you should be using "127.0.0.1".');
$this->variables['DB_HOST'] = $this->option('host') ?? $this->ask( $this->variables['DB_HOST'] = $this->option('host') ?? $this->ask(
@ -96,7 +71,7 @@ class DatabaseSettingsCommand extends Command
try { try {
$this->testMySQLConnection(); $this->testMySQLConnection();
} catch (PDOException $exception) { } catch (\PDOException $exception) {
$this->output->error(sprintf('Unable to connect to the MySQL server using the provided credentials. The error returned was "%s".', $exception->getMessage())); $this->output->error(sprintf('Unable to connect to the MySQL server using the provided credentials. The error returned was "%s".', $exception->getMessage()));
$this->output->error('Your connection credentials have NOT been saved. You will need to provide valid connection information before proceeding.'); $this->output->error('Your connection credentials have NOT been saved. You will need to provide valid connection information before proceeding.');

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Console\Commands\Environment; namespace Pterodactyl\Console\Commands\Environment;
@ -17,19 +10,8 @@ class EmailSettingsCommand extends Command
{ {
use EnvironmentWriterTrait; use EnvironmentWriterTrait;
/**
* @var \Illuminate\Contracts\Config\Repository
*/
protected $config;
/**
* @var string
*/
protected $description = 'Set or update the email sending configuration for the Panel.'; protected $description = 'Set or update the email sending configuration for the Panel.';
/**
* @var string
*/
protected $signature = 'p:environment:mail protected $signature = 'p:environment:mail
{--driver= : The mail driver to use.} {--driver= : The mail driver to use.}
{--email= : Email address that messages from the Panel will originate from.} {--email= : Email address that messages from the Panel will originate from.}
@ -41,19 +23,14 @@ class EmailSettingsCommand extends Command
{--username=} {--username=}
{--password=}'; {--password=}';
/** protected array $variables = [];
* @var array
*/
protected $variables = [];
/** /**
* EmailSettingsCommand constructor. * EmailSettingsCommand constructor.
*/ */
public function __construct(ConfigRepository $config) public function __construct(private ConfigRepository $config)
{ {
parent::__construct(); parent::__construct();
$this->config = $config;
} }
/** /**
@ -67,12 +44,12 @@ class EmailSettingsCommand extends Command
trans('command/messages.environment.mail.ask_driver'), trans('command/messages.environment.mail.ask_driver'),
[ [
'smtp' => 'SMTP Server', 'smtp' => 'SMTP Server',
'mail' => 'PHP\'s Internal Mail Function', 'sendmail' => 'sendmail Binary',
'mailgun' => 'Mailgun Transactional Email', 'mailgun' => 'Mailgun Transactional Email',
'mandrill' => 'Mandrill Transactional Email', 'mandrill' => 'Mandrill Transactional Email',
'postmark' => 'Postmarkapp Transactional Email', 'postmark' => 'Postmark Transactional Email',
], ],
$this->config->get('mail.driver', 'smtp') $this->config->get('mail.default', 'smtp')
); );
$method = 'setup' . studly_case($this->variables['MAIL_DRIVER']) . 'DriverVariables'; $method = 'setup' . studly_case($this->variables['MAIL_DRIVER']) . 'DriverVariables';
@ -80,7 +57,7 @@ class EmailSettingsCommand extends Command
$this->{$method}(); $this->{$method}();
} }
$this->variables['MAIL_FROM'] = $this->option('email') ?? $this->ask( $this->variables['MAIL_FROM_ADDRESS'] = $this->option('email') ?? $this->ask(
trans('command/messages.environment.mail.ask_mail_from'), trans('command/messages.environment.mail.ask_mail_from'),
$this->config->get('mail.from.address') $this->config->get('mail.from.address')
); );
@ -90,12 +67,6 @@ class EmailSettingsCommand extends Command
$this->config->get('mail.from.name') $this->config->get('mail.from.name')
); );
$this->variables['MAIL_ENCRYPTION'] = $this->option('encryption') ?? $this->choice(
trans('command/messages.environment.mail.ask_encryption'),
['tls' => 'TLS', 'ssl' => 'SSL', '' => 'None'],
$this->config->get('mail.encryption', 'tls')
);
$this->writeToEnvironment($this->variables); $this->writeToEnvironment($this->variables);
$this->line('Updating stored environment configuration file.'); $this->line('Updating stored environment configuration file.');
@ -109,22 +80,28 @@ class EmailSettingsCommand extends Command
{ {
$this->variables['MAIL_HOST'] = $this->option('host') ?? $this->ask( $this->variables['MAIL_HOST'] = $this->option('host') ?? $this->ask(
trans('command/messages.environment.mail.ask_smtp_host'), trans('command/messages.environment.mail.ask_smtp_host'),
$this->config->get('mail.host') $this->config->get('mail.mailers.smtp.host')
); );
$this->variables['MAIL_PORT'] = $this->option('port') ?? $this->ask( $this->variables['MAIL_PORT'] = $this->option('port') ?? $this->ask(
trans('command/messages.environment.mail.ask_smtp_port'), trans('command/messages.environment.mail.ask_smtp_port'),
$this->config->get('mail.port') $this->config->get('mail.mailers.smtp.port')
); );
$this->variables['MAIL_USERNAME'] = $this->option('username') ?? $this->ask( $this->variables['MAIL_USERNAME'] = $this->option('username') ?? $this->ask(
trans('command/messages.environment.mail.ask_smtp_username'), trans('command/messages.environment.mail.ask_smtp_username'),
$this->config->get('mail.username') $this->config->get('mail.mailers.smtp.username')
); );
$this->variables['MAIL_PASSWORD'] = $this->option('password') ?? $this->secret( $this->variables['MAIL_PASSWORD'] = $this->option('password') ?? $this->secret(
trans('command/messages.environment.mail.ask_smtp_password') trans('command/messages.environment.mail.ask_smtp_password')
); );
$this->variables['MAIL_ENCRYPTION'] = $this->option('encryption') ?? $this->choice(
trans('command/messages.environment.mail.ask_encryption'),
['tls' => 'TLS', 'ssl' => 'SSL', '' => 'None'],
$this->config->get('mail.mailers.smtp.encryption', 'tls')
);
} }
/** /**

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Console\Commands; namespace Pterodactyl\Console\Commands;
@ -15,35 +8,16 @@ use Illuminate\Contracts\Config\Repository as ConfigRepository;
class InfoCommand extends Command class InfoCommand extends Command
{ {
/**
* @var string
*/
protected $description = 'Displays the application, database, and email configurations along with the panel version.'; protected $description = 'Displays the application, database, and email configurations along with the panel version.';
/**
* @var \Illuminate\Contracts\Config\Repository
*/
protected $config;
/**
* @var string
*/
protected $signature = 'p:info'; protected $signature = 'p:info';
/**
* @var \Pterodactyl\Services\Helpers\SoftwareVersionService
*/
protected $versionService;
/** /**
* VersionCommand constructor. * VersionCommand constructor.
*/ */
public function __construct(ConfigRepository $config, SoftwareVersionService $versionService) public function __construct(private ConfigRepository $config, private SoftwareVersionService $softwareVersionService)
{ {
parent::__construct(); parent::__construct();
$this->config = $config;
$this->versionService = $versionService;
} }
/** /**
@ -53,9 +27,9 @@ class InfoCommand extends Command
{ {
$this->output->title('Version Information'); $this->output->title('Version Information');
$this->table([], [ $this->table([], [
['Panel Version', $this->config->get('app.version')], ['Panel Version', $this->softwareVersionService->getCurrentVersion()],
['Latest Version', $this->versionService->getPanel()], ['Latest Version', $this->softwareVersionService->getLatestPanel()],
['Up-to-Date', $this->versionService->isLatestPanel() ? 'Yes' : $this->formatText('No', 'bg=red')], ['Up-to-Date', $this->softwareVersionService->isLatestPanel() ? 'Yes' : $this->formatText('No', 'bg=red')],
['Unique Identifier', $this->config->get('pterodactyl.service.author')], ['Unique Identifier', $this->config->get('pterodactyl.service.author')],
], 'compact'); ], 'compact');
@ -78,33 +52,29 @@ class InfoCommand extends Command
$driver = $this->config->get('database.default'); $driver = $this->config->get('database.default');
$this->table([], [ $this->table([], [
['Driver', $driver], ['Driver', $driver],
['Host', $this->config->get("database.connections.{$driver}.host")], ['Host', $this->config->get("database.connections.$driver.host")],
['Port', $this->config->get("database.connections.{$driver}.port")], ['Port', $this->config->get("database.connections.$driver.port")],
['Database', $this->config->get("database.connections.{$driver}.database")], ['Database', $this->config->get("database.connections.$driver.database")],
['Username', $this->config->get("database.connections.{$driver}.username")], ['Username', $this->config->get("database.connections.$driver.username")],
], 'compact'); ], 'compact');
// TODO: Update this to handle other mail drivers
$this->output->title('Email Configuration'); $this->output->title('Email Configuration');
$this->table([], [ $this->table([], [
['Driver', $this->config->get('mail.driver')], ['Driver', $this->config->get('mail.default')],
['Host', $this->config->get('mail.host')], ['Host', $this->config->get('mail.mailers.smtp.host')],
['Port', $this->config->get('mail.port')], ['Port', $this->config->get('mail.mailers.smtp.port')],
['Username', $this->config->get('mail.username')], ['Username', $this->config->get('mail.mailers.smtp.username')],
['From Address', $this->config->get('mail.from.address')], ['From Address', $this->config->get('mail.from.address')],
['From Name', $this->config->get('mail.from.name')], ['From Name', $this->config->get('mail.from.name')],
['Encryption', $this->config->get('mail.encryption')], ['Encryption', $this->config->get('mail.mailers.smtp.encryption')],
], 'compact'); ], 'compact');
} }
/** /**
* Format output in a Name: Value manner. * Format output in a Name: Value manner.
*
* @param string $value
* @param string $opts
*
* @return string
*/ */
private function formatText($value, $opts = '') private function formatText(string $value, string $opts = ''): string
{ {
return sprintf('<%s>%s</>', $opts, $value); return sprintf('<%s>%s</>', $opts, $value);
} }

View file

@ -1,56 +1,28 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Console\Commands\Location; namespace Pterodactyl\Console\Commands\Location;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Pterodactyl\Services\Locations\LocationDeletionService; use Pterodactyl\Services\Locations\LocationDeletionService;
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface; use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
class DeleteLocationCommand extends Command class DeleteLocationCommand extends Command
{ {
/**
* @var \Pterodactyl\Services\Locations\LocationDeletionService
*/
protected $deletionService;
/**
* @var string
*/
protected $description = 'Deletes a location from the Panel.'; protected $description = 'Deletes a location from the Panel.';
/**
* @var \Illuminate\Support\Collection
*/
protected $locations;
/**
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
*/
protected $repository;
/**
* @var string
*/
protected $signature = 'p:location:delete {--short= : The short code of the location to delete.}'; protected $signature = 'p:location:delete {--short= : The short code of the location to delete.}';
protected Collection $locations;
/** /**
* DeleteLocationCommand constructor. * DeleteLocationCommand constructor.
*/ */
public function __construct( public function __construct(
LocationDeletionService $deletionService, private LocationDeletionService $deletionService,
LocationRepositoryInterface $repository private LocationRepositoryInterface $repository
) { ) {
parent::__construct(); parent::__construct();
$this->deletionService = $deletionService;
$this->repository = $repository;
} }
/** /**

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Console\Commands\Location; namespace Pterodactyl\Console\Commands\Location;
@ -14,31 +7,18 @@ use Pterodactyl\Services\Locations\LocationCreationService;
class MakeLocationCommand extends Command class MakeLocationCommand extends Command
{ {
/**
* @var \Pterodactyl\Services\Locations\LocationCreationService
*/
protected $creationService;
/**
* @var string
*/
protected $signature = 'p:location:make protected $signature = 'p:location:make
{--short= : The shortcode name of this location (ex. us1).} {--short= : The shortcode name of this location (ex. us1).}
{--long= : A longer description of this location.}'; {--long= : A longer description of this location.}';
/**
* @var string
*/
protected $description = 'Creates a new location on the system via the CLI.'; protected $description = 'Creates a new location on the system via the CLI.';
/** /**
* Create a new command instance. * Create a new command instance.
*/ */
public function __construct(LocationCreationService $creationService) public function __construct(private LocationCreationService $creationService)
{ {
parent::__construct(); parent::__construct();
$this->creationService = $creationService;
} }
/** /**

View file

@ -2,30 +2,21 @@
namespace Pterodactyl\Console\Commands\Maintenance; namespace Pterodactyl\Console\Commands\Maintenance;
use SplFileInfo;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory; use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory;
class CleanServiceBackupFilesCommand extends Command class CleanServiceBackupFilesCommand extends Command
{ {
public const BACKUP_THRESHOLD_MINUTES = 5; public const BACKUP_THRESHOLD_MINUTES = 5;
/**
* @var string
*/
protected $description = 'Clean orphaned .bak files created when modifying services.'; protected $description = 'Clean orphaned .bak files created when modifying services.';
/**
* @var \Illuminate\Contracts\Filesystem\Filesystem
*/
protected $disk;
/**
* @var string
*/
protected $signature = 'p:maintenance:clean-service-backups'; protected $signature = 'p:maintenance:clean-service-backups';
protected Filesystem $disk;
/** /**
* CleanServiceBackupFilesCommand constructor. * CleanServiceBackupFilesCommand constructor.
*/ */
@ -43,7 +34,7 @@ class CleanServiceBackupFilesCommand extends Command
{ {
$files = $this->disk->files('services/.bak'); $files = $this->disk->files('services/.bak');
collect($files)->each(function (SplFileInfo $file) { collect($files)->each(function (\SplFileInfo $file) {
$lastModified = Carbon::createFromTimestamp($this->disk->lastModified($file->getPath())); $lastModified = Carbon::createFromTimestamp($this->disk->lastModified($file->getPath()));
if ($lastModified->diffInMinutes(Carbon::now()) > self::BACKUP_THRESHOLD_MINUTES) { if ($lastModified->diffInMinutes(Carbon::now()) > self::BACKUP_THRESHOLD_MINUTES) {
$this->disk->delete($file->getPath()); $this->disk->delete($file->getPath());

View file

@ -3,30 +3,31 @@
namespace Pterodactyl\Console\Commands\Maintenance; namespace Pterodactyl\Console\Commands\Maintenance;
use Carbon\CarbonImmutable; use Carbon\CarbonImmutable;
use InvalidArgumentException;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Pterodactyl\Repositories\Eloquent\BackupRepository; use Pterodactyl\Repositories\Eloquent\BackupRepository;
class PruneOrphanedBackupsCommand extends Command class PruneOrphanedBackupsCommand extends Command
{ {
/**
* @var string
*/
protected $signature = 'p:maintenance:prune-backups {--prune-age=}'; protected $signature = 'p:maintenance:prune-backups {--prune-age=}';
/** protected $description = 'Marks all backups older than "n" minutes that have not yet completed as being failed.';
* @var string
*/
protected $description = 'Marks all backups that have not completed in the last "n" minutes as being failed.';
public function handle(BackupRepository $repository) /**
* PruneOrphanedBackupsCommand constructor.
*/
public function __construct(private BackupRepository $backupRepository)
{
parent::__construct();
}
public function handle()
{ {
$since = $this->option('prune-age') ?? config('backups.prune_age', 360); $since = $this->option('prune-age') ?? config('backups.prune_age', 360);
if (!$since || !is_digit($since)) { if (!$since || !is_digit($since)) {
throw new InvalidArgumentException('The "--prune-age" argument must be a value greater than 0.'); throw new \InvalidArgumentException('The "--prune-age" argument must be a value greater than 0.');
} }
$query = $repository->getBuilder() $query = $this->backupRepository->getBuilder()
->whereNull('completed_at') ->whereNull('completed_at')
->where('created_at', '<=', CarbonImmutable::now()->subMinutes($since)->toDateTimeString()); ->where('created_at', '<=', CarbonImmutable::now()->subMinutes($since)->toDateTimeString());
@ -37,7 +38,7 @@ class PruneOrphanedBackupsCommand extends Command
return; return;
} }
$this->warn("Marking {$count} backups that have not been marked as completed in the last {$since} minutes as failed."); $this->warn("Marking $count uncompleted backups that are older than $since minutes as failed.");
$query->update([ $query->update([
'is_successful' => false, 'is_successful' => false,

View file

@ -1,13 +1,5 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Console\Commands\Node; namespace Pterodactyl\Console\Commands\Node;
use Illuminate\Console\Command; use Illuminate\Console\Command;
@ -15,14 +7,6 @@ use Pterodactyl\Services\Nodes\NodeCreationService;
class MakeNodeCommand extends Command class MakeNodeCommand extends Command
{ {
/**
* @var \Pterodactyl\Services\Nodes\NodeCreationService
*/
protected $creationService;
/**
* @var string
*/
protected $signature = 'p:node:make protected $signature = 'p:node:make
{--name= : A name to identify the node.} {--name= : A name to identify the node.}
{--description= : A description to identify the node.} {--description= : A description to identify the node.}
@ -41,40 +25,33 @@ class MakeNodeCommand extends Command
{--daemonSFTPPort= : Enter the wings SFTP listening port.} {--daemonSFTPPort= : Enter the wings SFTP listening port.}
{--daemonBase= : Enter the base folder.}'; {--daemonBase= : Enter the base folder.}';
/**
* @var string
*/
protected $description = 'Creates a new node on the system via the CLI.'; protected $description = 'Creates a new node on the system via the CLI.';
/**
* MakeNodeCommand constructor.
*/
public function __construct(private NodeCreationService $creationService)
{
parent::__construct();
}
/** /**
* Handle the command execution process. * Handle the command execution process.
* *
* @throws \Pterodactyl\Exceptions\Model\DataValidationException * @throws \Pterodactyl\Exceptions\Model\DataValidationException
*/ */
public function handle(NodeCreationService $creationService) public function handle()
{ {
$this->creationService = $creationService;
$data['name'] = $this->option('name') ?? $this->ask('Enter a short identifier used to distinguish this node from others'); $data['name'] = $this->option('name') ?? $this->ask('Enter a short identifier used to distinguish this node from others');
$data['description'] = $this->option('description') ?? $this->ask('Enter a description to identify the node'); $data['description'] = $this->option('description') ?? $this->ask('Enter a description to identify the node');
$data['location_id'] = $this->option('locationId') ?? $this->ask('Enter a valid location id'); $data['location_id'] = $this->option('locationId') ?? $this->ask('Enter a valid location id');
$data['fqdn'] = $this->option('fqdn') ?? $this->ask('Enter a domain name (e.g node.example.com) to be used for connecting to the daemon. An IP address may only be used if you are not using SSL for this node');
if (!filter_var(gethostbyname($data['fqdn']), FILTER_VALIDATE_IP)) {
$this->error('The FQDN or IP address provided does not resolve to a valid IP address.');
return;
}
$data['public'] = $this->option('public') ?? $this->confirm('Should this node be public? As a note, setting a node to private you will be denying the ability to auto-deploy to this node.', true);
$data['scheme'] = $this->option('scheme') ?? $this->anticipate( $data['scheme'] = $this->option('scheme') ?? $this->anticipate(
'Please either enter https for SSL or http for a non-ssl connection', 'Please either enter https for SSL or http for a non-ssl connection',
['https', 'http'], ['https', 'http'],
'https' 'https'
); );
if (filter_var($data['fqdn'], FILTER_VALIDATE_IP) && $data['scheme'] === 'https') { $data['fqdn'] = $this->option('fqdn') ?? $this->ask('Enter a domain name (e.g node.example.com) to be used for connecting to the daemon. An IP address may only be used if you are not using SSL for this node');
$this->error('A fully qualified domain name that resolves to a public IP address is required in order to use SSL for this node.'); $data['public'] = $this->option('public') ?? $this->confirm('Should this node be public? As a note, setting a node to private you will be denying the ability to auto-deploy to this node.', true);
return;
}
$data['behind_proxy'] = $this->option('proxy') ?? $this->confirm('Is your FQDN behind a proxy?'); $data['behind_proxy'] = $this->option('proxy') ?? $this->confirm('Is your FQDN behind a proxy?');
$data['maintenance_mode'] = $this->option('maintenance') ?? $this->confirm('Should maintenance mode be enabled?'); $data['maintenance_mode'] = $this->option('maintenance') ?? $this->confirm('Should maintenance mode be enabled?');
$data['memory'] = $this->option('maxMemory') ?? $this->ask('Enter the maximum amount of memory'); $data['memory'] = $this->option('maxMemory') ?? $this->ask('Enter the maximum amount of memory');

View file

@ -13,7 +13,7 @@ class NodeConfigurationCommand extends Command
protected $description = 'Displays the configuration for the specified node.'; protected $description = 'Displays the configuration for the specified node.';
public function handle() public function handle(): int
{ {
$column = ctype_digit((string) $this->argument('node')) ? 'id' : 'uuid'; $column = ctype_digit((string) $this->argument('node')) ? 'id' : 'uuid';
@ -28,7 +28,7 @@ class NodeConfigurationCommand extends Command
if (!in_array($format, ['yaml', 'yml', 'json'])) { if (!in_array($format, ['yaml', 'yml', 'json'])) {
$this->error('Invalid format specified. Valid options are "yaml" and "json".'); $this->error('Invalid format specified. Valid options are "yaml" and "json".');
exit(1); return 1;
} }
if ($format === 'json') { if ($format === 'json') {

View file

@ -9,7 +9,7 @@ class NodeListCommand extends Command
{ {
protected $signature = 'p:node:list {--format=text : The output format: "text" or "json". }'; protected $signature = 'p:node:list {--format=text : The output format: "text" or "json". }';
public function handle() public function handle(): int
{ {
$nodes = Node::query()->with('location')->get()->map(function (Node $node) { $nodes = Node::query()->with('location')->get()->map(function (Node $node) {
return [ return [

View file

@ -13,14 +13,14 @@ class SeedCommand extends BaseSeedCommand
* Block someone from running this seed command if they have not completed * Block someone from running this seed command if they have not completed
* the migration process. * the migration process.
*/ */
public function handle() public function handle(): int
{ {
if (!$this->hasCompletedMigrations()) { if (!$this->hasCompletedMigrations()) {
$this->showMigrationWarning(); $this->showMigrationWarning();
return; return 1;
} }
parent::handle(); return parent::handle();
} }
} }

View file

@ -13,14 +13,14 @@ class UpCommand extends BaseUpCommand
* Block someone from running this up command if they have not completed * Block someone from running this up command if they have not completed
* the migration process. * the migration process.
*/ */
public function handle() public function handle(): int
{ {
if (!$this->hasCompletedMigrations()) { if (!$this->hasCompletedMigrations()) {
$this->showMigrationWarning(); $this->showMigrationWarning();
return; return 1;
} }
parent::handle(); return parent::handle();
} }
} }

View file

@ -3,7 +3,6 @@
namespace Pterodactyl\Console\Commands\Schedule; namespace Pterodactyl\Console\Commands\Schedule;
use Exception; use Exception;
use Throwable;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Pterodactyl\Models\Schedule; use Pterodactyl\Models\Schedule;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@ -12,20 +11,14 @@ use Pterodactyl\Services\Schedules\ProcessScheduleService;
class ProcessRunnableCommand extends Command class ProcessRunnableCommand extends Command
{ {
/**
* @var string
*/
protected $signature = 'p:schedule:process'; protected $signature = 'p:schedule:process';
/**
* @var string
*/
protected $description = 'Process schedules in the database and determine which are ready to run.'; protected $description = 'Process schedules in the database and determine which are ready to run.';
/** /**
* Handle command execution. * Handle command execution.
*/ */
public function handle() public function handle(): int
{ {
$schedules = Schedule::query() $schedules = Schedule::query()
->with('tasks') ->with('tasks')
@ -38,7 +31,7 @@ class ProcessRunnableCommand extends Command
if ($schedules->count() < 1) { if ($schedules->count() < 1) {
$this->line('There are no scheduled tasks for servers that need to be run.'); $this->line('There are no scheduled tasks for servers that need to be run.');
return; return 0;
} }
$bar = $this->output->createProgressBar(count($schedules)); $bar = $this->output->createProgressBar(count($schedules));
@ -50,6 +43,8 @@ class ProcessRunnableCommand extends Command
} }
$this->line(''); $this->line('');
return 0;
} }
/** /**
@ -72,10 +67,10 @@ class ProcessRunnableCommand extends Command
'schedule' => $schedule->name, 'schedule' => $schedule->name,
'hash' => $schedule->hashid, 'hash' => $schedule->hashid,
])); ]));
} catch (Throwable|Exception $exception) { } catch (\Throwable|\Exception $exception) {
Log::error($exception, ['schedule_id' => $schedule->id]); Log::error($exception, ['schedule_id' => $schedule->id]);
$this->error("An error was encountered while processing Schedule #{$schedule->id}: " . $exception->getMessage()); $this->error("An error was encountered while processing Schedule #$schedule->id: " . $exception->getMessage());
} }
} }
} }

View file

@ -4,6 +4,7 @@ namespace Pterodactyl\Console\Commands\Server;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Illuminate\Validation\Factory as ValidatorFactory; use Illuminate\Validation\Factory as ValidatorFactory;
use Pterodactyl\Repositories\Wings\DaemonPowerRepository; use Pterodactyl\Repositories\Wings\DaemonPowerRepository;
@ -11,31 +12,33 @@ use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
class BulkPowerActionCommand extends Command class BulkPowerActionCommand extends Command
{ {
/**
* @var string
*/
protected $signature = 'p:server:bulk-power protected $signature = 'p:server:bulk-power
{action : The action to perform (start, stop, restart, kill)} {action : The action to perform (start, stop, restart, kill)}
{--servers= : A comma separated list of servers.} {--servers= : A comma separated list of servers.}
{--nodes= : A comma separated list of nodes.}'; {--nodes= : A comma separated list of nodes.}';
/**
* @var string
*/
protected $description = 'Perform bulk power management on large groupings of servers or nodes at once.'; protected $description = 'Perform bulk power management on large groupings of servers or nodes at once.';
/**
* BulkPowerActionCommand constructor.
*/
public function __construct(private DaemonPowerRepository $powerRepository, private ValidatorFactory $validator)
{
parent::__construct();
}
/** /**
* Handle the bulk power request. * Handle the bulk power request.
* *
* @throws \Illuminate\Validation\ValidationException * @throws \Illuminate\Validation\ValidationException
*/ */
public function handle(DaemonPowerRepository $powerRepository, ValidatorFactory $validator) public function handle()
{ {
$action = $this->argument('action'); $action = $this->argument('action');
$nodes = empty($this->option('nodes')) ? [] : explode(',', $this->option('nodes')); $nodes = empty($this->option('nodes')) ? [] : explode(',', $this->option('nodes'));
$servers = empty($this->option('servers')) ? [] : explode(',', $this->option('servers')); $servers = empty($this->option('servers')) ? [] : explode(',', $this->option('servers'));
$validator = $validator->make([ $validator = $this->validator->make([
'action' => $action, 'action' => $action,
'nodes' => $nodes, 'nodes' => $nodes,
'servers' => $servers, 'servers' => $servers,
@ -61,6 +64,7 @@ class BulkPowerActionCommand extends Command
} }
$bar = $this->output->createProgressBar($count); $bar = $this->output->createProgressBar($count);
$powerRepository = $this->powerRepository;
$this->getQueryBuilder($servers, $nodes)->each(function (Server $server) use ($action, $powerRepository, &$bar) { $this->getQueryBuilder($servers, $nodes)->each(function (Server $server) use ($action, $powerRepository, &$bar) {
$bar->clear(); $bar->clear();
@ -84,10 +88,8 @@ class BulkPowerActionCommand extends Command
/** /**
* Returns the query builder instance that will return the servers that should be affected. * Returns the query builder instance that will return the servers that should be affected.
*
* @return \Illuminate\Database\Eloquent\Builder
*/ */
protected function getQueryBuilder(array $servers, array $nodes) protected function getQueryBuilder(array $servers, array $nodes): Builder
{ {
$instance = Server::query()->whereNull('status'); $instance = Server::query()->whereNull('status');

View file

@ -0,0 +1,34 @@
<?php
namespace Pterodactyl\Console\Commands;
use Illuminate\Console\Command;
use Symfony\Component\VarDumper\VarDumper;
use Pterodactyl\Services\Telemetry\TelemetryCollectionService;
class TelemetryCommand extends Command
{
protected $description = 'Displays all the data that would be sent to the Pterodactyl Telemetry Service if telemetry collection is enabled.';
protected $signature = 'p:telemetry';
/**
* TelemetryCommand constructor.
*/
public function __construct(private TelemetryCollectionService $telemetryCollectionService)
{
parent::__construct();
}
/**
* Handle execution of command.
*
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
*/
public function handle()
{
$this->output->info('Collecting telemetry data, this may take a while...');
VarDumper::dump($this->telemetryCollectionService->collect());
}
}

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Console\Commands; namespace Pterodactyl\Console\Commands;
use Closure;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Pterodactyl\Console\Kernel; use Pterodactyl\Console\Kernel;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
@ -12,7 +11,6 @@ class UpgradeCommand extends Command
{ {
protected const DEFAULT_URL = 'https://github.com/pterodactyl/panel/releases/%s/panel.tar.gz'; protected const DEFAULT_URL = 'https://github.com/pterodactyl/panel/releases/%s/panel.tar.gz';
/** @var string */
protected $signature = 'p:upgrade protected $signature = 'p:upgrade
{--user= : The user that PHP runs under. All files will be owned by this user.} {--user= : The user that PHP runs under. All files will be owned by this user.}
{--group= : The group that PHP runs under. All files will be owned by this group.} {--group= : The group that PHP runs under. All files will be owned by this group.}
@ -20,7 +18,6 @@ class UpgradeCommand extends Command
{--release= : A specific Pterodactyl version to download from GitHub. Leave blank to use latest.} {--release= : A specific Pterodactyl version to download from GitHub. Leave blank to use latest.}
{--skip-download : If set no archive will be downloaded.}'; {--skip-download : If set no archive will be downloaded.}';
/** @var string */
protected $description = 'Downloads a new archive for Pterodactyl from GitHub and then executes the normal upgrade commands.'; protected $description = 'Downloads a new archive for Pterodactyl from GitHub and then executes the normal upgrade commands.';
/** /**
@ -92,7 +89,7 @@ class UpgradeCommand extends Command
} }
} }
ini_set('output_buffering', 0); ini_set('output_buffering', '0');
$bar = $this->output->createProgressBar($skipDownload ? 9 : 10); $bar = $this->output->createProgressBar($skipDownload ? 9 : 10);
$bar->start(); $bar->start();
@ -179,7 +176,7 @@ class UpgradeCommand extends Command
$this->info('Panel has been successfully upgraded. Please ensure you also update any Wings instances: https://pterodactyl.io/wings/1.0/upgrading.html'); $this->info('Panel has been successfully upgraded. Please ensure you also update any Wings instances: https://pterodactyl.io/wings/1.0/upgrading.html');
} }
protected function withProgress(ProgressBar $bar, Closure $callback) protected function withProgress(ProgressBar $bar, \Closure $callback)
{ {
$bar->clear(); $bar->clear();
$callback(); $callback();

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Console\Commands\User; namespace Pterodactyl\Console\Commands\User;
@ -16,42 +9,19 @@ use Pterodactyl\Services\Users\UserDeletionService;
class DeleteUserCommand extends Command class DeleteUserCommand extends Command
{ {
/**
* @var \Pterodactyl\Services\Users\UserDeletionService
*/
protected $deletionService;
/**
* @var string
*/
protected $description = 'Deletes a user from the Panel if no servers are attached to their account.'; protected $description = 'Deletes a user from the Panel if no servers are attached to their account.';
/**
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
*/
protected $repository;
/**
* @var string
*/
protected $signature = 'p:user:delete {--user=}'; protected $signature = 'p:user:delete {--user=}';
/** /**
* DeleteUserCommand constructor. * DeleteUserCommand constructor.
*/ */
public function __construct(UserDeletionService $deletionService) public function __construct(private UserDeletionService $deletionService)
{ {
parent::__construct(); parent::__construct();
$this->deletionService = $deletionService;
} }
/** public function handle(): int
* @return bool
*
* @throws \Pterodactyl\Exceptions\DisplayException
*/
public function handle()
{ {
$search = $this->option('user') ?? $this->ask(trans('command/messages.user.search_users')); $search = $this->option('user') ?? $this->ask(trans('command/messages.user.search_users'));
Assert::notEmpty($search, 'Search term should be an email address, got: %s.'); Assert::notEmpty($search, 'Search term should be an email address, got: %s.');
@ -68,16 +38,16 @@ class DeleteUserCommand extends Command
return $this->handle(); return $this->handle();
} }
return false; return 1;
} }
if ($this->input->isInteractive()) { if ($this->input->isInteractive()) {
$tableValues = []; $tableValues = [];
foreach ($results as $user) { foreach ($results as $user) {
$tableValues[] = [$user->id, $user->email, $user->name]; $tableValues[] = [$user->id, $user->email, $user->username];
} }
$this->table(['User ID', 'Email', 'Name'], $tableValues); $this->table(['User ID', 'Email', 'Username'], $tableValues);
if (!$deleteUser = $this->ask(trans('command/messages.user.select_search_user'))) { if (!$deleteUser = $this->ask(trans('command/messages.user.select_search_user'))) {
return $this->handle(); return $this->handle();
} }
@ -85,7 +55,7 @@ class DeleteUserCommand extends Command
if (count($results) > 1) { if (count($results) > 1) {
$this->error(trans('command/messages.user.multiple_found')); $this->error(trans('command/messages.user.multiple_found'));
return false; return 1;
} }
$deleteUser = $results->first(); $deleteUser = $results->first();
@ -95,5 +65,7 @@ class DeleteUserCommand extends Command
$this->deletionService->handle($deleteUser); $this->deletionService->handle($deleteUser);
$this->info(trans('command/messages.user.deleted')); $this->info(trans('command/messages.user.deleted'));
} }
return 0;
} }
} }

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Console\Commands\User; namespace Pterodactyl\Console\Commands\User;
@ -14,29 +7,16 @@ use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
class DisableTwoFactorCommand extends Command class DisableTwoFactorCommand extends Command
{ {
/**
* @var string
*/
protected $description = 'Disable two-factor authentication for a specific user in the Panel.'; protected $description = 'Disable two-factor authentication for a specific user in the Panel.';
/**
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
*/
protected $repository;
/**
* @var string
*/
protected $signature = 'p:user:disable2fa {--email= : The email of the user to disable 2-Factor for.}'; protected $signature = 'p:user:disable2fa {--email= : The email of the user to disable 2-Factor for.}';
/** /**
* DisableTwoFactorCommand constructor. * DisableTwoFactorCommand constructor.
*/ */
public function __construct(UserRepositoryInterface $repository) public function __construct(private UserRepositoryInterface $repository)
{ {
parent::__construct(); parent::__construct();
$this->repository = $repository;
} }
/** /**

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Console\Commands\User; namespace Pterodactyl\Console\Commands\User;
@ -14,29 +7,16 @@ use Pterodactyl\Services\Users\UserCreationService;
class MakeUserCommand extends Command class MakeUserCommand extends Command
{ {
/**
* @var \Pterodactyl\Services\Users\UserCreationService
*/
protected $creationService;
/**
* @var string
*/
protected $description = 'Creates a user on the system via the CLI.'; protected $description = 'Creates a user on the system via the CLI.';
/**
* @var string
*/
protected $signature = 'p:user:make {--email=} {--username=} {--name-first=} {--name-last=} {--password=} {--admin=} {--no-password}'; protected $signature = 'p:user:make {--email=} {--username=} {--name-first=} {--name-last=} {--password=} {--admin=} {--no-password}';
/** /**
* MakeUserCommand constructor. * MakeUserCommand constructor.
*/ */
public function __construct(UserCreationService $creationService) public function __construct(private UserCreationService $creationService)
{ {
parent::__construct(); parent::__construct();
$this->creationService = $creationService;
} }
/** /**
@ -50,8 +30,6 @@ class MakeUserCommand extends Command
$root_admin = $this->option('admin') ?? $this->confirm(trans('command/messages.user.ask_admin')); $root_admin = $this->option('admin') ?? $this->confirm(trans('command/messages.user.ask_admin'));
$email = $this->option('email') ?? $this->ask(trans('command/messages.user.ask_email')); $email = $this->option('email') ?? $this->ask(trans('command/messages.user.ask_email'));
$username = $this->option('username') ?? $this->ask(trans('command/messages.user.ask_username')); $username = $this->option('username') ?? $this->ask(trans('command/messages.user.ask_username'));
$name_first = $this->option('name-first') ?? $this->ask(trans('command/messages.user.ask_name_first'));
$name_last = $this->option('name-last') ?? $this->ask(trans('command/messages.user.ask_name_last'));
if (is_null($password = $this->option('password')) && !$this->option('no-password')) { if (is_null($password = $this->option('password')) && !$this->option('no-password')) {
$this->warn(trans('command/messages.user.ask_password_help')); $this->warn(trans('command/messages.user.ask_password_help'));
@ -59,12 +37,11 @@ class MakeUserCommand extends Command
$password = $this->secret(trans('command/messages.user.ask_password')); $password = $this->secret(trans('command/messages.user.ask_password'));
} }
$user = $this->creationService->handle(compact('email', 'username', 'name_first', 'name_last', 'password', 'root_admin')); $user = $this->creationService->handle(compact('email', 'username', 'password', 'root_admin'));
$this->table(['Field', 'Value'], [ $this->table(['Field', 'Value'], [
['UUID', $user->uuid], ['UUID', $user->uuid],
['Email', $user->email], ['Email', $user->email],
['Username', $user->username], ['Username', $user->username],
['Name', $user->name],
['Admin', $user->root_admin ? 'Yes' : 'No'], ['Admin', $user->root_admin ? 'Yes' : 'No'],
]); ]);
} }

View file

@ -2,15 +2,23 @@
namespace Pterodactyl\Console; namespace Pterodactyl\Console;
use Ramsey\Uuid\Uuid;
use Pterodactyl\Models\ActivityLog;
use Illuminate\Console\Scheduling\Schedule; use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Database\Console\PruneCommand;
use Pterodactyl\Repositories\Eloquent\SettingsRepository;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel; use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Pterodactyl\Services\Telemetry\TelemetryCollectionService;
use Pterodactyl\Console\Commands\Schedule\ProcessRunnableCommand;
use Pterodactyl\Console\Commands\Maintenance\PruneOrphanedBackupsCommand;
use Pterodactyl\Console\Commands\Maintenance\CleanServiceBackupFilesCommand;
class Kernel extends ConsoleKernel class Kernel extends ConsoleKernel
{ {
/** /**
* Register the commands for the application. * Register the commands for the application.
*/ */
protected function commands() protected function commands(): void
{ {
$this->load(__DIR__ . '/Commands'); $this->load(__DIR__ . '/Commands');
} }
@ -18,17 +26,51 @@ class Kernel extends ConsoleKernel
/** /**
* Define the application's command schedule. * Define the application's command schedule.
*/ */
protected function schedule(Schedule $schedule) protected function schedule(Schedule $schedule): void
{ {
// https://laravel.com/docs/10.x/upgrade#redis-cache-tags
$schedule->command('cache:prune-stale-tags')->hourly();
// Execute scheduled commands for servers every minute, as if there was a normal cron running. // Execute scheduled commands for servers every minute, as if there was a normal cron running.
$schedule->command('p:schedule:process')->everyMinute()->withoutOverlapping(); $schedule->command(ProcessRunnableCommand::class)->everyMinute()->withoutOverlapping();
$schedule->command(CleanServiceBackupFilesCommand::class)->daily();
if (config('backups.prune_age')) { if (config('backups.prune_age')) {
// Every 30 minutes, run the backup pruning command so that any abandoned backups can be deleted. // Every 30 minutes, run the backup pruning command so that any abandoned backups can be deleted.
$schedule->command('p:maintenance:prune-backups')->everyThirtyMinutes(); $schedule->command(PruneOrphanedBackupsCommand::class)->everyThirtyMinutes();
} }
// Every day cleanup any internal backups of service files. if (config('activity.prune_days')) {
$schedule->command('p:maintenance:clean-service-backups')->daily(); $schedule->command(PruneCommand::class, ['--model' => [ActivityLog::class]])->daily();
}
if (config('pterodactyl.telemetry.enabled')) {
$this->registerTelemetry($schedule);
}
}
/**
* I wonder what this does.
*
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
private function registerTelemetry(Schedule $schedule): void
{
$settingsRepository = app()->make(SettingsRepository::class);
$uuid = $settingsRepository->get('app:telemetry:uuid');
if (is_null($uuid)) {
$uuid = Uuid::uuid4()->toString();
$settingsRepository->set('app:telemetry:uuid', $uuid);
}
// Calculate a fixed time to run the data push at, this will be the same time every day.
$time = hexdec(str_replace('-', '', substr($uuid, 27))) % 1440;
$hour = floor($time / 60);
$minute = $time % 60;
// Run the telemetry collector.
$schedule->call(app()->make(TelemetryCollectionService::class))->description('Collect Telemetry')->dailyAt("$hour:$minute");
} }
} }

View file

@ -33,7 +33,7 @@ trait RequiresDatabaseMigrations
* them to properly run the migrations rather than ignoring all of the other previous * them to properly run the migrations rather than ignoring all of the other previous
* errors... * errors...
*/ */
protected function showMigrationWarning() protected function showMigrationWarning(): void
{ {
$this->getOutput()->writeln('<options=bold> $this->getOutput()->writeln('<options=bold>
| @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |

View file

@ -1,24 +1,14 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Contracts\Criteria; namespace Pterodactyl\Contracts\Criteria;
use Illuminate\Database\Eloquent\Model;
use Pterodactyl\Repositories\Repository; use Pterodactyl\Repositories\Repository;
interface CriteriaInterface interface CriteriaInterface
{ {
/** /**
* Apply selected criteria to a repository call. * Apply selected criteria to a repository call.
*
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return mixed
*/ */
public function apply($model, Repository $repository); public function apply(Model $model, Repository $repository): mixed;
} }

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Contracts\Extensions; namespace Pterodactyl\Contracts\Extensions;
@ -16,12 +9,7 @@ interface HashidsInterface extends VendorHashidsInterface
/** /**
* Decode an encoded hashid and return the first result. * Decode an encoded hashid and return the first result.
* *
* @param string $encoded
* @param null $default
*
* @return mixed
*
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function decodeFirst($encoded, $default = null); public function decodeFirst(string $encoded, string $default = null): mixed;
} }

View file

@ -6,7 +6,7 @@ interface ClientPermissionsRequest
{ {
/** /**
* Returns the permissions string indicating which permission should be used to * Returns the permissions string indicating which permission should be used to
* validate that the authenticated user has permission to perform this action aganist * validate that the authenticated user has permission to perform this action against
* the given resource (server). * the given resource (server).
*/ */
public function permission(): string; public function permission(): string;

View file

@ -2,18 +2,18 @@
namespace Pterodactyl\Contracts\Repository; namespace Pterodactyl\Contracts\Repository;
use Pterodactyl\Models\Allocation;
interface AllocationRepositoryInterface extends RepositoryInterface interface AllocationRepositoryInterface extends RepositoryInterface
{ {
/** /**
* Return all of the allocations that exist for a node that are not currently * Return all the allocations that exist for a node that are not currently
* allocated. * allocated.
*/ */
public function getUnassignedAllocationIds(int $node): array; public function getUnassignedAllocationIds(int $node): array;
/** /**
* Return a single allocation from those meeting the requirements. * Return a single allocation from those meeting the requirements.
*
* @return \Pterodactyl\Models\Allocation|null
*/ */
public function getRandomAllocation(array $nodes, array $ports, bool $dedicated = false); public function getRandomAllocation(array $nodes, array $ports, bool $dedicated = false): ?Allocation;
} }

View file

@ -8,12 +8,12 @@ use Illuminate\Support\Collection;
interface ApiKeyRepositoryInterface extends RepositoryInterface interface ApiKeyRepositoryInterface extends RepositoryInterface
{ {
/** /**
* Get all of the account API keys that exist for a specific user. * Get all the account API keys that exist for a specific user.
*/ */
public function getAccountKeys(User $user): Collection; public function getAccountKeys(User $user): Collection;
/** /**
* Get all of the application API keys that exist for a specific user. * Get all the application API keys that exist for a specific user.
*/ */
public function getApplicationKeys(User $user): Collection; public function getApplicationKeys(User $user): Collection;

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Contracts\Repository; namespace Pterodactyl\Contracts\Repository;

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Contracts\Repository; namespace Pterodactyl\Contracts\Repository;
use Pterodactyl\Models\Database;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Contracts\Pagination\LengthAwarePaginator;
@ -12,10 +11,8 @@ interface DatabaseRepositoryInterface extends RepositoryInterface
/** /**
* Set the connection name to execute statements against. * Set the connection name to execute statements against.
*
* @return $this
*/ */
public function setConnection(string $connection); public function setConnection(string $connection): self;
/** /**
* Return the connection to execute statements against. * Return the connection to execute statements against.
@ -23,12 +20,12 @@ interface DatabaseRepositoryInterface extends RepositoryInterface
public function getConnection(): string; public function getConnection(): string;
/** /**
* Return all of the databases belonging to a server. * Return all the databases belonging to a server.
*/ */
public function getDatabasesForServer(int $server): Collection; public function getDatabasesForServer(int $server): Collection;
/** /**
* Return all of the databases for a given host with the server relationship loaded. * Return all the databases for a given host with the server relationship loaded.
*/ */
public function getDatabasesForHost(int $host, int $count = 25): LengthAwarePaginator; public function getDatabasesForHost(int $host, int $count = 25): LengthAwarePaginator;
@ -39,10 +36,8 @@ interface DatabaseRepositoryInterface extends RepositoryInterface
/** /**
* Create a new database user on a given connection. * Create a new database user on a given connection.
*
* @param $max_connections
*/ */
public function createUser(string $username, string $remote, string $password, string $max_connections): bool; public function createUser(string $username, string $remote, string $password, ?int $max_connections): bool;
/** /**
* Give a specific user access to a given database. * Give a specific user access to a given database.
@ -61,8 +56,6 @@ interface DatabaseRepositoryInterface extends RepositoryInterface
/** /**
* Drop a given user on a specific connection. * Drop a given user on a specific connection.
*
* @return mixed
*/ */
public function dropUser(string $username, string $remote): bool; public function dropUser(string $username, string $remote): bool;
} }

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Contracts\Repository; namespace Pterodactyl\Contracts\Repository;
@ -28,13 +21,11 @@ interface EggRepositoryInterface extends RepositoryInterface
/** /**
* Return an egg with the scriptFrom and configFrom relations loaded onto the model. * Return an egg with the scriptFrom and configFrom relations loaded onto the model.
*
* @param int|string $value
*/ */
public function getWithCopyAttributes($value, string $column = 'id'): Egg; public function getWithCopyAttributes(int|string $value, string $column = 'id'): Egg;
/** /**
* Return all of the data needed to export a service. * Return all the data needed to export a service.
* *
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Contracts\Repository; namespace Pterodactyl\Contracts\Repository;

View file

@ -13,14 +13,12 @@ interface LocationRepositoryInterface extends RepositoryInterface
public function getAllWithDetails(): Collection; public function getAllWithDetails(): Collection;
/** /**
* Return all of the available locations with the nodes as a relationship. * Return all the available locations with the nodes as a relationship.
*/ */
public function getAllWithNodes(): Collection; public function getAllWithNodes(): Collection;
/** /**
* Return all of the nodes and their respective count of servers for a location. * Return all the nodes and their respective count of servers for a location.
*
* @return mixed
* *
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
@ -29,8 +27,6 @@ interface LocationRepositoryInterface extends RepositoryInterface
/** /**
* Return a location and the count of nodes in that location. * Return a location and the count of nodes in that location.
* *
* @return mixed
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function getWithNodeCount(int $id): Location; public function getWithNodeCount(int $id): Location;

View file

@ -1,37 +1,25 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Contracts\Repository; namespace Pterodactyl\Contracts\Repository;
use Pterodactyl\Models\Nest; use Pterodactyl\Models\Nest;
use Illuminate\Database\Eloquent\Collection;
interface NestRepositoryInterface extends RepositoryInterface interface NestRepositoryInterface extends RepositoryInterface
{ {
/** /**
* Return a nest or all nests with their associated eggs and variables. * Return a nest or all nests with their associated eggs and variables.
* *
* @param int $id
*
* @return \Illuminate\Database\Eloquent\Collection|\Pterodactyl\Models\Nest
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function getWithEggs(int $id = null); public function getWithEggs(int $id = null): Collection|Nest;
/** /**
* Return a nest or all nests and the count of eggs and servers for that nest. * Return a nest or all nests and the count of eggs and servers for that nest.
* *
* @return \Pterodactyl\Models\Nest|\Illuminate\Database\Eloquent\Collection
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function getWithCounts(int $id = null); public function getWithCounts(int $id = null): Collection|Nest;
/** /**
* Return a nest along with its associated eggs and the servers relation on those eggs. * Return a nest along with its associated eggs and the servers relation on those eggs.

View file

@ -1,11 +1,4 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Contracts\Repository; namespace Pterodactyl\Contracts\Repository;

View file

@ -3,87 +3,67 @@
namespace Pterodactyl\Contracts\Repository; namespace Pterodactyl\Contracts\Repository;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Contracts\Pagination\LengthAwarePaginator;
interface RepositoryInterface interface RepositoryInterface
{ {
/** /**
* Return an identifier or Model object to be used by the repository. * Return an identifier or Model object to be used by the repository.
*
* @return string|\Closure|object
*/ */
public function model(); public function model(): string;
/** /**
* Return the model being used for this repository instance. * Return the model being used for this repository instance.
*
* @return mixed
*/ */
public function getModel(); public function getModel(): Model;
/** /**
* Returns an instance of a query builder. * Returns an instance of a query builder.
*
* @return mixed
*/ */
public function getBuilder(); public function getBuilder(): Builder;
/** /**
* Returns the columns to be selected or returned by the query. * Returns the columns to be selected or returned by the query.
*
* @return mixed
*/ */
public function getColumns(); public function getColumns(): array;
/** /**
* An array of columns to filter the response by. * An array of columns to filter the response by.
*
* @param array|string $columns
*
* @return $this
*/ */
public function setColumns($columns = ['*']); public function setColumns(array|string $columns = ['*']): self;
/** /**
* Stop repository update functions from returning a fresh * Stop repository update functions from returning a fresh
* model when changes are committed. * model when changes are committed.
*
* @return $this
*/ */
public function withoutFreshModel(); public function withoutFreshModel(): self;
/** /**
* Return a fresh model with a repository updates a model. * Return a fresh model with a repository updates a model.
*
* @return $this
*/ */
public function withFreshModel(); public function withFreshModel(): self;
/** /**
* Set whether or not the repository should return a fresh model * Set whether the repository should return a fresh model
* when changes are committed. * when changes are committed.
*
* @return $this
*/ */
public function setFreshModel(bool $fresh = true); public function setFreshModel(bool $fresh = true): self;
/** /**
* Create a new model instance and persist it to the database. * Create a new model instance and persist it to the database.
* *
* @return mixed
*
* @throws \Pterodactyl\Exceptions\Model\DataValidationException * @throws \Pterodactyl\Exceptions\Model\DataValidationException
*/ */
public function create(array $fields, bool $validate = true, bool $force = false); public function create(array $fields, bool $validate = true, bool $force = false): mixed;
/** /**
* Find a model that has the specific ID passed. * Find a model that has the specific ID passed.
* *
* @return mixed
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function find(int $id); public function find(int $id): mixed;
/** /**
* Find a model matching an array of where clauses. * Find a model matching an array of where clauses.
@ -93,11 +73,9 @@ interface RepositoryInterface
/** /**
* Find and return the first matching instance for the given fields. * Find and return the first matching instance for the given fields.
* *
* @return mixed
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function findFirstWhere(array $fields); public function findFirstWhere(array $fields): mixed;
/** /**
* Return a count of records matching the passed arguments. * Return a count of records matching the passed arguments.
@ -117,14 +95,10 @@ interface RepositoryInterface
/** /**
* Update a given ID with the passed array of fields. * Update a given ID with the passed array of fields.
* *
* @param int $id
*
* @return mixed
*
* @throws \Pterodactyl\Exceptions\Model\DataValidationException * @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */
public function update($id, array $fields, bool $validate = true, bool $force = false); public function update(int $id, array $fields, bool $validate = true, bool $force = false): mixed;
/** /**
* Perform a mass update where matching records are updated using whereIn. * Perform a mass update where matching records are updated using whereIn.
@ -135,11 +109,9 @@ interface RepositoryInterface
/** /**
* Update a record if it exists in the database, otherwise create it. * Update a record if it exists in the database, otherwise create it.
* *
* @return mixed
*
* @throws \Pterodactyl\Exceptions\Model\DataValidationException * @throws \Pterodactyl\Exceptions\Model\DataValidationException
*/ */
public function updateOrCreate(array $where, array $fields, bool $validate = true, bool $force = false); public function updateOrCreate(array $where, array $fields, bool $validate = true, bool $force = false): mixed;
/** /**
* Return all records associated with the given model. * Return all records associated with the given model.

View file

@ -8,12 +8,12 @@ use Illuminate\Support\Collection;
interface ScheduleRepositoryInterface extends RepositoryInterface interface ScheduleRepositoryInterface extends RepositoryInterface
{ {
/** /**
* Return all of the schedules for a given server. * Return all the schedules for a given server.
*/ */
public function findServerSchedules(int $server): Collection; public function findServerSchedules(int $server): Collection;
/** /**
* Return a schedule model with all of the associated tasks as a relationship. * Return a schedule model with all the associated tasks as a relationship.
* *
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/ */

View file

@ -67,7 +67,7 @@ interface ServerRepositoryInterface extends RepositoryInterface
public function isUniqueUuidCombo(string $uuid, string $short): bool; public function isUniqueUuidCombo(string $uuid, string $short): bool;
/** /**
* Returns all of the servers that exist for a given node in a paginated response. * Returns all the servers that exist for a given node in a paginated response.
*/ */
public function loadAllServersForNode(int $node, int $limit): LengthAwarePaginator; public function loadAllServersForNode(int $node, int $limit): LengthAwarePaginator;
} }

View file

@ -7,14 +7,12 @@ use Illuminate\Support\Collection;
interface SessionRepositoryInterface extends RepositoryInterface interface SessionRepositoryInterface extends RepositoryInterface
{ {
/** /**
* Return all of the active sessions for a user. * Return all the active sessions for a user.
*/ */
public function getUserSessions(int $user): Collection; public function getUserSessions(int $user): Collection;
/** /**
* Delete a session for a given user. * Delete a session for a given user.
*
* @return int|null
*/ */
public function deleteUserSession(int $user, string $session); public function deleteUserSession(int $user, string $session): ?int;
} }

View file

@ -14,12 +14,8 @@ interface SettingsRepositoryInterface extends RepositoryInterface
/** /**
* Retrieve a persistent setting from the database. * Retrieve a persistent setting from the database.
*
* @param mixed $default
*
* @return mixed
*/ */
public function get(string $key, $default); public function get(string $key, mixed $default): mixed;
/** /**
* Remove a key from the database cache. * Remove a key from the database cache.

View file

@ -15,8 +15,6 @@ interface TaskRepositoryInterface extends RepositoryInterface
/** /**
* Returns the next task in a schedule. * Returns the next task in a schedule.
*
* @return \Pterodactyl\Models\Task|null
*/ */
public function getNextTask(int $schedule, int $index); public function getNextTask(int $schedule, int $index): ?Task;
} }

View file

@ -0,0 +1,34 @@
<?php
namespace Pterodactyl\Events;
use Illuminate\Support\Str;
use Pterodactyl\Models\ActivityLog;
use Illuminate\Database\Eloquent\Model;
class ActivityLogged extends Event
{
public function __construct(public ActivityLog $model)
{
}
public function is(string $event): bool
{
return $this->model->event === $event;
}
public function actor(): ?Model
{
return $this->isSystem() ? null : $this->model->actor;
}
public function isServerEvent(): bool
{
return Str::startsWith($this->model->event, 'server:');
}
public function isSystem(): bool
{
return is_null($this->model->actor_id);
}
}

View file

@ -0,0 +1,13 @@
<?php
namespace Pterodactyl\Events\Auth;
use Pterodactyl\Models\User;
use Pterodactyl\Events\Event;
class DirectLogin extends Event
{
public function __construct(public User $user, public bool $remember)
{
}
}

View file

@ -1,43 +1,18 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Auth; namespace Pterodactyl\Events\Auth;
use Pterodactyl\Events\Event;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class FailedCaptcha class FailedCaptcha extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The IP that the request originated from.
*
* @var string
*/
public $ip;
/**
* The domain that was used to try to verify the request with recaptcha api.
*
* @var string
*/
public $domain;
/** /**
* Create a new event instance. * Create a new event instance.
*
* @param string $ip
* @param string $domain
*/ */
public function __construct($ip, $domain) public function __construct(public string $ip, public string $domain)
{ {
$this->ip = $ip;
$this->domain = $domain;
} }
} }

View file

@ -1,43 +1,18 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Auth; namespace Pterodactyl\Events\Auth;
use Pterodactyl\Events\Event;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class FailedPasswordReset class FailedPasswordReset extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The IP that the request originated from.
*
* @var string
*/
public $ip;
/**
* The email address that was used when the reset request failed.
*
* @var string
*/
public $email;
/** /**
* Create a new event instance. * Create a new event instance.
*
* @param string $ip
* @param string $email
*/ */
public function __construct($ip, $email) public function __construct(public string $ip, public string $email)
{ {
$this->ip = $ip;
$this->email = $email;
} }
} }

View file

@ -0,0 +1,13 @@
<?php
namespace Pterodactyl\Events\Auth;
use Pterodactyl\Models\User;
use Pterodactyl\Events\Event;
class ProvidedAuthenticationToken extends Event
{
public function __construct(public User $user, public bool $recovery = false)
{
}
}

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Server; namespace Pterodactyl\Events\Server;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Created class Created extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Server
*/
public $server;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Server $server) public function __construct(public Server $server)
{ {
$this->server = $server;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Server; namespace Pterodactyl\Events\Server;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Creating class Creating extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Server
*/
public $server;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Server $server) public function __construct(public Server $server)
{ {
$this->server = $server;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Server; namespace Pterodactyl\Events\Server;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Deleted class Deleted extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Server
*/
public $server;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Server $server) public function __construct(public Server $server)
{ {
$this->server = $server;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Server; namespace Pterodactyl\Events\Server;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Deleting class Deleting extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Server
*/
public $server;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Server $server) public function __construct(public Server $server)
{ {
$this->server = $server;
} }
} }

View file

@ -10,18 +10,10 @@ class Installed extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* @var \Pterodactyl\Models\Server
*/
public $server;
/** /**
* Create a new event instance. * Create a new event instance.
*
* @var \Pterodactyl\Models\Server
*/ */
public function __construct(Server $server) public function __construct(public Server $server)
{ {
$this->server = $server;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Server; namespace Pterodactyl\Events\Server;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Saved class Saved extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Server
*/
public $server;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Server $server) public function __construct(public Server $server)
{ {
$this->server = $server;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Server; namespace Pterodactyl\Events\Server;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Saving class Saving extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Server
*/
public $server;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Server $server) public function __construct(public Server $server)
{ {
$this->server = $server;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Server; namespace Pterodactyl\Events\Server;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Updated class Updated extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Server
*/
public $server;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Server $server) public function __construct(public Server $server)
{ {
$this->server = $server;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Server; namespace Pterodactyl\Events\Server;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Updating class Updating extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Server
*/
public $server;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Server $server) public function __construct(public Server $server)
{ {
$this->server = $server;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Subuser; namespace Pterodactyl\Events\Subuser;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Subuser; use Pterodactyl\Models\Subuser;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Created class Created extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Subuser
*/
public $subuser;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Subuser $subuser) public function __construct(public Subuser $subuser)
{ {
$this->subuser = $subuser;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Subuser; namespace Pterodactyl\Events\Subuser;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Subuser; use Pterodactyl\Models\Subuser;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Creating class Creating extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Subuser
*/
public $subuser;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Subuser $subuser) public function __construct(public Subuser $subuser)
{ {
$this->subuser = $subuser;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Subuser; namespace Pterodactyl\Events\Subuser;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Subuser; use Pterodactyl\Models\Subuser;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Deleted class Deleted extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Subuser
*/
public $subuser;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Subuser $subuser) public function __construct(public Subuser $subuser)
{ {
$this->subuser = $subuser;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\Subuser; namespace Pterodactyl\Events\Subuser;
use Pterodactyl\Events\Event;
use Pterodactyl\Models\Subuser; use Pterodactyl\Models\Subuser;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Deleting class Deleting extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\Subuser
*/
public $subuser;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(Subuser $subuser) public function __construct(public Subuser $subuser)
{ {
$this->subuser = $subuser;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\User; namespace Pterodactyl\Events\User;
use Pterodactyl\Models\User; use Pterodactyl\Models\User;
use Pterodactyl\Events\Event;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Created class Created extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\User
*/
public $user;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(User $user) public function __construct(public User $user)
{ {
$this->user = $user;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\User; namespace Pterodactyl\Events\User;
use Pterodactyl\Models\User; use Pterodactyl\Models\User;
use Pterodactyl\Events\Event;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Creating class Creating extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\User
*/
public $user;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(User $user) public function __construct(public User $user)
{ {
$this->user = $user;
} }
} }

View file

@ -1,33 +1,19 @@
<?php <?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Events\User; namespace Pterodactyl\Events\User;
use Pterodactyl\Models\User; use Pterodactyl\Models\User;
use Pterodactyl\Events\Event;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
class Deleted class Deleted extends Event
{ {
use SerializesModels; use SerializesModels;
/**
* The Eloquent model of the server.
*
* @var \Pterodactyl\Models\User
*/
public $user;
/** /**
* Create a new event instance. * Create a new event instance.
*/ */
public function __construct(User $user) public function __construct(public User $user)
{ {
$this->user = $user;
} }
} }

Some files were not shown because too many files have changed in this diff Show more