diff --git a/app/Notifications/SendPasswordReset.php b/app/Notifications/SendPasswordReset.php index 2f1519cec..83d88216c 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 3d8974a3e..e768c78d2 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 75a23d147..ef84a8d19 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 19e1a9698..daa357c25 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 db3f7fc94..7fb8d4c5f 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 a5343447f..6f46e527e 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 342e31a7a..5e5777fee 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 04c302917..ddcd0a865 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 4e204e1c0..17d58ac4e 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 f5589f4a5..ab72b1f5d 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 000000000..ba825a59e --- /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 2cafa8fcb..000000000 --- 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 533491db6..c917bf590 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 f798f0b35..e59b38f21 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: