diff --git a/app/Notifications/SendPasswordReset.php b/app/Notifications/SendPasswordReset.php index 2f1519ce..83d88216 100644 --- a/app/Notifications/SendPasswordReset.php +++ b/app/Notifications/SendPasswordReset.php @@ -57,7 +57,7 @@ class SendPasswordReset extends Notification implements ShouldQueue return (new MailMessage) ->subject('Reset Password') ->line('You are receiving this email because we received a password reset request for your account.') - ->action('Reset Password', url('/auth/password/reset/' . $this->token . '?email=' . $notifiable->email)) + ->action('Reset Password', url('/auth/password/reset/' . $this->token . '?email=' . urlencode($notifiable->email))) ->line('If you did not request a password reset, no further action is required.'); } } diff --git a/database/seeds/eggs/minecraft/egg-bungeecord.json b/database/seeds/eggs/minecraft/egg-bungeecord.json index 3d8974a3..e768c78d 100644 --- a/database/seeds/eggs/minecraft/egg-bungeecord.json +++ b/database/seeds/eggs/minecraft/egg-bungeecord.json @@ -8,7 +8,7 @@ "author": "support@pterodactyl.io", "description": "For a long time, Minecraft server owners have had a dream that encompasses a free, easy, and reliable way to connect multiple Minecraft servers together. BungeeCord is the answer to said dream. Whether you are a small server wishing to string multiple game-modes together, or the owner of the ShotBow Network, BungeeCord is the ideal solution for you. With the help of BungeeCord, you will be able to unlock your community's full potential.", "features": ["eula"], - "image": "quay.io\/pterodactyl\/core:java", + "images": ["quay.io\/pterodactyl\/core:java", "quay.io\/pterodactyl\/core:java-11"], "startup": "java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}", "config": { "files": "{\r\n \"config.yml\": {\r\n \"parser\": \"yaml\",\r\n \"find\": {\r\n \"listeners[0].query_enabled\": true,\r\n \"listeners[0].query_port\": \"{{server.build.default.port}}\",\r\n \"listeners[0].host\": \"0.0.0.0:{{server.build.default.port}}\",\r\n \"servers.*.address\": {\r\n \"regex:^(127\\\\.0\\\\.0\\\\.1|localhost)(:\\\\d{1,5})?$\": \"{{config.docker.interface}}$2\"\r\n }\r\n }\r\n }\r\n}", diff --git a/database/seeds/eggs/minecraft/egg-forge-minecraft.json b/database/seeds/eggs/minecraft/egg-forge-minecraft.json index 75a23d14..ef84a8d1 100644 --- a/database/seeds/eggs/minecraft/egg-forge-minecraft.json +++ b/database/seeds/eggs/minecraft/egg-forge-minecraft.json @@ -8,7 +8,7 @@ "author": "support@pterodactyl.io", "description": "Minecraft Forge Server. Minecraft Forge is a modding API (Application Programming Interface), which makes it easier to create mods, and also make sure mods are compatible with each other.", "features": ["eula"], - "image": "quay.io\/pterodactyl\/core:java", + "images": ["quay.io\/pterodactyl\/core:java", "quay.io\/pterodactyl\/core:java-11"], "startup": "java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}", "config": { "files": "{\r\n \"server.properties\": {\r\n \"parser\": \"properties\",\r\n \"find\": {\r\n \"server-ip\": \"0.0.0.0\",\r\n \"enable-query\": \"true\",\r\n \"server-port\": \"{{server.build.default.port}}\",\r\n \"query.port\": \"{{server.build.default.port}}\"\r\n }\r\n }\r\n}", @@ -61,4 +61,4 @@ "rules": "nullable|string|max:20" } ] -} \ No newline at end of file +} diff --git a/database/seeds/eggs/minecraft/egg-paper.json b/database/seeds/eggs/minecraft/egg-paper.json index 19e1a969..daa357c2 100644 --- a/database/seeds/eggs/minecraft/egg-paper.json +++ b/database/seeds/eggs/minecraft/egg-paper.json @@ -8,7 +8,7 @@ "author": "parker@pterodactyl.io", "description": "High performance Spigot fork that aims to fix gameplay and mechanics inconsistencies.", "features": ["eula"], - "image": "quay.io\/pterodactyl\/core:java-11", + "images": ["quay.io\/pterodactyl\/core:java-11", "quay.io\/pterodactyl\/core:java"], "startup": "java -Xms128M -Xmx{{SERVER_MEMORY}}M -Dterminal.jline=false -Dterminal.ansi=true -jar {{SERVER_JARFILE}}", "config": { "files": "{\r\n \"server.properties\": {\r\n \"parser\": \"properties\",\r\n \"find\": {\r\n \"server-ip\": \"0.0.0.0\",\r\n \"server-port\": \"{{server.build.default.port}}\"\r\n }\r\n }\r\n}", diff --git a/database/seeds/eggs/minecraft/egg-sponge--sponge-vanilla.json b/database/seeds/eggs/minecraft/egg-sponge--sponge-vanilla.json index db3f7fc9..7fb8d4c5 100644 --- a/database/seeds/eggs/minecraft/egg-sponge--sponge-vanilla.json +++ b/database/seeds/eggs/minecraft/egg-sponge--sponge-vanilla.json @@ -8,7 +8,7 @@ "author": "support@pterodactyl.io", "description": "SpongeVanilla is the SpongeAPI implementation for Vanilla Minecraft.", "features": ["eula"], - "image": "quay.io\/pterodactyl\/core:java-glibc", + "images": ["quay.io\/pterodactyl\/core:java-glibc"], "startup": "java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}", "config": { "files": "{\r\n \"server.properties\": {\r\n \"parser\": \"properties\",\r\n \"find\": {\r\n \"server-ip\": \"0.0.0.0\",\r\n \"enable-query\": \"true\",\r\n \"server-port\": \"{{server.build.default.port}}\",\r\n \"query.port\": \"{{server.build.default.port}}\"\r\n }\r\n }\r\n}", diff --git a/database/seeds/eggs/minecraft/egg-vanilla-minecraft.json b/database/seeds/eggs/minecraft/egg-vanilla-minecraft.json index a5343447..6f46e527 100644 --- a/database/seeds/eggs/minecraft/egg-vanilla-minecraft.json +++ b/database/seeds/eggs/minecraft/egg-vanilla-minecraft.json @@ -8,7 +8,7 @@ "author": "support@pterodactyl.io", "description": "Minecraft is a game about placing blocks and going on adventures. Explore randomly generated worlds and build amazing things from the simplest of homes to the grandest of castles. Play in Creative Mode with unlimited resources or mine deep in Survival Mode, crafting weapons and armor to fend off dangerous mobs. Do all this alone or with friends.", "features": ["eula"], - "image": "quay.io\/pterodactyl\/core:java", + "images": ["quay.io\/pterodactyl\/core:java", "quay.io\/pterodactyl\/core:java-11"], "startup": "java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}", "config": { "files": "{\r\n \"server.properties\": {\r\n \"parser\": \"properties\",\r\n \"find\": {\r\n \"server-ip\": \"0.0.0.0\",\r\n \"enable-query\": \"true\",\r\n \"server-port\": \"{{server.build.default.port}}\"\r\n }\r\n }\r\n}", diff --git a/resources/scripts/TransitionRouter.tsx b/resources/scripts/TransitionRouter.tsx index 342e31a7..5e5777fe 100644 --- a/resources/scripts/TransitionRouter.tsx +++ b/resources/scripts/TransitionRouter.tsx @@ -1,10 +1,9 @@ -import React, { useRef } from 'react'; +import React from 'react'; import { Route } from 'react-router'; import { SwitchTransition } from 'react-transition-group'; import Fade from '@/components/elements/Fade'; import styled from 'styled-components/macro'; import tw from 'twin.macro'; -import v4 from 'uuid/v4'; const StyledSwitchTransition = styled(SwitchTransition)` ${tw`relative`}; @@ -15,13 +14,11 @@ const StyledSwitchTransition = styled(SwitchTransition)` `; const TransitionRouter: React.FC = ({ children }) => { - const uuid = useRef(v4()).current; - return ( ( - +
{children}
diff --git a/resources/scripts/components/server/schedules/ScheduleContainer.tsx b/resources/scripts/components/server/schedules/ScheduleContainer.tsx index 04c30291..ddcd0a86 100644 --- a/resources/scripts/components/server/schedules/ScheduleContainer.tsx +++ b/resources/scripts/components/server/schedules/ScheduleContainer.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import getServerSchedules from '@/api/server/schedules/getServerSchedules'; import { ServerContext } from '@/state/server'; import Spinner from '@/components/elements/Spinner'; -import { RouteComponentProps } from 'react-router-dom'; +import { useHistory, useRouteMatch } from 'react-router-dom'; import FlashMessageRender from '@/components/FlashMessageRender'; import ScheduleRow from '@/components/server/schedules/ScheduleRow'; import { httpErrorToHuman } from '@/api/http'; @@ -14,7 +14,10 @@ import GreyRowBox from '@/components/elements/GreyRowBox'; import Button from '@/components/elements/Button'; import ServerContentBlock from '@/components/elements/ServerContentBlock'; -export default ({ match, history }: RouteComponentProps) => { +export default () => { + const match = useRouteMatch(); + const history = useHistory(); + const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); const { clearFlashes, addError } = useFlash(); const [ loading, setLoading ] = useState(true); diff --git a/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx b/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx index 4e204e1c..17d58ac4 100644 --- a/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx +++ b/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { RouteComponentProps } from 'react-router-dom'; +import { useHistory, useLocation, useParams } from 'react-router-dom'; import { Schedule } from '@/api/server/schedules/getServerSchedules'; import getServerSchedule from '@/api/server/schedules/getServerSchedule'; import Spinner from '@/components/elements/Spinner'; @@ -45,7 +45,11 @@ const ActivePill = ({ active }: { active: boolean }) => ( ); -export default ({ match, history, location: { state } }: RouteComponentProps, State>) => { +export default () => { + const params = useParams() as Params; + const history = useHistory(); + const state: State = useLocation().state; + const id = ServerContext.useStoreState(state => state.server.data!.id); const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); @@ -57,20 +61,20 @@ export default ({ match, history, location: { state } }: RouteComponentProps actions.schedules.appendSchedule); useEffect(() => { - if (schedule?.id === Number(match.params.id)) { + if (schedule?.id === Number(params.id)) { setIsLoading(false); return; } clearFlashes('schedules'); - getServerSchedule(uuid, Number(match.params.id)) + getServerSchedule(uuid, Number(params.id)) .then(schedule => appendSchedule(schedule)) .catch(error => { console.error(error); clearAndAddHttpError({ error, key: 'schedules' }); }) .then(() => setIsLoading(false)); - }, [ match ]); + }, [ params ]); const toggleEditModal = useCallback(() => { setShowEditModal(s => !s); diff --git a/resources/scripts/components/server/users/UsersContainer.tsx b/resources/scripts/components/server/users/UsersContainer.tsx index f5589f4a..ab72b1f5 100644 --- a/resources/scripts/components/server/users/UsersContainer.tsx +++ b/resources/scripts/components/server/users/UsersContainer.tsx @@ -48,7 +48,7 @@ export default () => { } return ( - + {!subusers.length ?

diff --git a/resources/scripts/hoc/RequireServerPermission.tsx b/resources/scripts/hoc/RequireServerPermission.tsx new file mode 100644 index 00000000..ba825a59 --- /dev/null +++ b/resources/scripts/hoc/RequireServerPermission.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import Can from '@/components/elements/Can'; +import ScreenBlock from '@/components/screens/ScreenBlock'; +export interface RequireServerPermissionProps { + permissions: string | string[] +} + +const RequireServerPermission: React.FC = ({ children, permissions }) => { + return ( + + } + > + {children} + + ); +}; + +export default RequireServerPermission; diff --git a/resources/scripts/hoc/requireServerPermission.tsx b/resources/scripts/hoc/requireServerPermission.tsx deleted file mode 100644 index 2cafa8fc..00000000 --- a/resources/scripts/hoc/requireServerPermission.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -import Can from '@/components/elements/Can'; -import ScreenBlock from '@/components/screens/ScreenBlock'; -import isEqual from 'react-fast-compare'; - -const requireServerPermission = (Component: React.ComponentType, permissions: string | string[]) => { - return class extends React.Component { - shouldComponentUpdate (nextProps: Readonly) { - return !isEqual(nextProps, this.props); - } - - render () { - return ( - - } - > - - - ); - } - }; -}; - -export default requireServerPermission; diff --git a/resources/scripts/routers/ServerRouter.tsx b/resources/scripts/routers/ServerRouter.tsx index 533491db..c917bf59 100644 --- a/resources/scripts/routers/ServerRouter.tsx +++ b/resources/scripts/routers/ServerRouter.tsx @@ -27,10 +27,10 @@ import SubNavigation from '@/components/elements/SubNavigation'; import NetworkContainer from '@/components/server/network/NetworkContainer'; import InstallListener from '@/components/server/InstallListener'; import StartupContainer from '@/components/server/startup/StartupContainer'; -import requireServerPermission from '@/hoc/requireServerPermission'; import ErrorBoundary from '@/components/elements/ErrorBoundary'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons'; +import RequireServerPermission from '@/hoc/RequireServerPermission'; const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>) => { const rootAdmin = useStoreState(state => state.user.data!.rootAdmin); @@ -142,50 +142,44 @@ const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>) - - ( - - - - )} - exact - /> - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/yarn.lock b/yarn.lock index f798f0b3..e59b38f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2166,19 +2166,9 @@ camelize@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" -caniuse-lite@^1.0.30001088: - version "1.0.30001093" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001093.tgz#833e80f64b1a0455cbceed2a4a3baf19e4abd312" - integrity sha512-0+ODNoOjtWD5eS9aaIpf4K0gQqZfILNY4WSNuYzeT1sXni+lMrrVjc0odEobJt6wrODofDZUX8XYi/5y7+xl8g== - -caniuse-lite@^1.0.30001135: - version "1.0.30001148" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001148.tgz#dc97c7ed918ab33bf8706ddd5e387287e015d637" - integrity sha512-E66qcd0KMKZHNJQt9hiLZGE3J4zuTqE1OnU53miEVtylFbwOEmeA5OsRu90noZful+XGSQOni1aT2tiqu/9yYw== - -caniuse-lite@^1.0.30001165: +caniuse-lite@^1.0.30001088, caniuse-lite@^1.0.30001135, caniuse-lite@^1.0.30001165: version "1.0.30001170" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz" integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA== chalk@^2.0, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: