diff --git a/backend/src/auth/auth.controller.ts b/backend/src/auth/auth.controller.ts index 1a9dcf57..5dd8e3c6 100644 --- a/backend/src/auth/auth.controller.ts +++ b/backend/src/auth/auth.controller.ts @@ -120,7 +120,7 @@ export class AuthController { const accessToken = await this.authService.refreshAccessToken( request.cookies.refresh_token ); - response.cookie("access_token", accessToken); + response = this.addTokensToResponse(response, undefined, accessToken); return new TokenDTO().from({ accessToken }); } @@ -162,11 +162,13 @@ export class AuthController { refreshToken?: string, accessToken?: string ) { - if (accessToken) response.cookie("access_token", accessToken); + if (accessToken) + response.cookie("access_token", accessToken, { sameSite: "lax" }); if (refreshToken) response.cookie("refresh_token", refreshToken, { path: "/api/auth/token", httpOnly: true, + sameSite: "strict", maxAge: 1000 * 60 * 60 * 24 * 30 * 3, }); diff --git a/backend/src/auth/auth.service.ts b/backend/src/auth/auth.service.ts index 4ff00a66..45137038 100644 --- a/backend/src/auth/auth.service.ts +++ b/backend/src/auth/auth.service.ts @@ -110,26 +110,30 @@ export class AuthService { { sub: user.id, email: user.email, + isAdmin: user.isAdmin, refreshTokenId, }, { - expiresIn: "15min", + expiresIn: "10s", secret: this.config.get("JWT_SECRET"), } ); } async signOut(accessToken: string) { - const { refreshTokenId } = this.jwtService.decode(accessToken) as { - refreshTokenId: string; - }; + const { refreshTokenId } = + (this.jwtService.decode(accessToken) as { + refreshTokenId: string; + }) || {}; - await this.prisma.refreshToken - .delete({ where: { id: refreshTokenId } }) - .catch((e) => { - // Ignore error if refresh token doesn't exist - if (e.code != "P2025") throw e; - }); + if (refreshTokenId) { + await this.prisma.refreshToken + .delete({ where: { id: refreshTokenId } }) + .catch((e) => { + // Ignore error if refresh token doesn't exist + if (e.code != "P2025") throw e; + }); + } } async refreshAccessToken(refreshToken: string) { diff --git a/backend/src/config/config.controller.ts b/backend/src/config/config.controller.ts index 5c721357..e7488731 100644 --- a/backend/src/config/config.controller.ts +++ b/backend/src/config/config.controller.ts @@ -1,4 +1,5 @@ import { Body, Controller, Get, Patch, Post, UseGuards } from "@nestjs/common"; +import { SkipThrottle } from "@nestjs/throttler"; import { AdministratorGuard } from "src/auth/guard/isAdmin.guard"; import { JwtGuard } from "src/auth/guard/jwt.guard"; import { EmailService } from "src/email/email.service"; @@ -16,6 +17,7 @@ export class ConfigController { ) {} @Get() + @SkipThrottle() async list() { return new ConfigDTO().fromList(await this.configService.list()); } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index eeb17e42..8cbe4a65 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -21,6 +21,7 @@ "cookies-next": "^2.1.1", "file-saver": "^2.0.5", "jose": "^4.11.2", + "jwt-decode": "^3.1.2", "mime-types": "^2.1.35", "moment": "^2.29.4", "next": "^13.1.2", @@ -5610,6 +5611,11 @@ "node": ">=4.0" } }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, "node_modules/klona": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", @@ -12122,6 +12128,11 @@ "object.assign": "^4.1.2" } }, + "jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, "klona": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", diff --git a/frontend/package.json b/frontend/package.json index d320fd19..677d343f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,6 +22,7 @@ "cookies-next": "^2.1.1", "file-saver": "^2.0.5", "jose": "^4.11.2", + "jwt-decode": "^3.1.2", "mime-types": "^2.1.35", "moment": "^2.29.4", "next": "^13.1.2", diff --git a/frontend/src/components/account/showEnableTotpModal.tsx b/frontend/src/components/account/showEnableTotpModal.tsx index 9d1828e8..4bacaa59 100644 --- a/frontend/src/components/account/showEnableTotpModal.tsx +++ b/frontend/src/components/account/showEnableTotpModal.tsx @@ -14,7 +14,6 @@ import { useForm, yupResolver } from "@mantine/form"; import { useModals } from "@mantine/modals"; import { ModalsContextProps } from "@mantine/modals/lib/context"; import * as yup from "yup"; -import useUser from "../../hooks/user.hook"; import authService from "../../services/auth.service"; import toast from "../../utils/toast.util"; diff --git a/frontend/src/components/admin/configuration/AdminConfigTable.tsx b/frontend/src/components/admin/configuration/AdminConfigTable.tsx index 74259869..ae20e325 100644 --- a/frontend/src/components/admin/configuration/AdminConfigTable.tsx +++ b/frontend/src/components/admin/configuration/AdminConfigTable.tsx @@ -9,6 +9,7 @@ import { Title, } from "@mantine/core"; import { useMediaQuery } from "@mantine/hooks"; +import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import useConfig from "../../../hooks/config.hook"; import configService from "../../../services/config.service"; @@ -27,6 +28,7 @@ import TestEmailButton from "./TestEmailButton"; const AdminConfigTable = () => { const config = useConfig(); + const router = useRouter(); const isMobile = useMediaQuery("(max-width: 560px)"); const [updatedConfigVariables, setUpdatedConfigVariables] = useState< @@ -68,7 +70,7 @@ const AdminConfigTable = () => { .updateMany(updatedConfigVariables) .then(async () => { await configService.finishSetup(); - window.location.reload(); + router.replace("/upload"); }) .catch(toast.axiosError); } else { diff --git a/frontend/src/middleware.ts b/frontend/src/middleware.ts new file mode 100644 index 00000000..c58fb61c --- /dev/null +++ b/frontend/src/middleware.ts @@ -0,0 +1,111 @@ +import jwtDecode from "jwt-decode"; +import { NextRequest, NextResponse } from "next/server"; +import configService from "./services/config.service"; + +// This middleware redirects based on different conditions: +// - Authentication state +// - Setup status +// - Admin privileges + +export const config = { + matcher: "/((?!api|static|.*\\..*|_next).*)", +}; + +export async function middleware(request: NextRequest) { + // Get config from backend + const config = await ( + await fetch("http://localhost:8080/api/configs") + ).json(); + + const getConfig = (key: string) => { + return configService.get(key, config); + }; + + const containsRoute = (routes: string[], url: string) => { + for (const route of routes) { + if (new RegExp("^" + route.replace(/\*/g, ".*") + "$").test(url)) + return true; + } + return false; + }; + + const route = request.nextUrl.pathname; + let user: { isAdmin: boolean } | null = null; + const accessToken = request.cookies.get("access_token")?.value; + + try { + const claims = jwtDecode<{ exp: number; isAdmin: boolean }>( + accessToken as string + ); + if (claims.exp * 1000 > Date.now()) { + user = claims; + } + } catch { + user = null; + } + + const unauthenticatedRoutes = ["/auth/signIn", "/"]; + let publicRoutes = ["/share/*", "/upload/*"]; + const setupStatusRegisteredRoutes = ["/auth/*", "/admin/setup"]; + const adminRoutes = ["/admin/*"]; + const accountRoutes = ["/account/*"]; + + if (getConfig("ALLOW_REGISTRATION")) { + unauthenticatedRoutes.push("/auth/signUp"); + } + + if (getConfig("ALLOW_UNAUTHENTICATED_SHARES")) { + publicRoutes = ["*"]; + } + + const isPublicRoute = containsRoute(publicRoutes, route); + const isUnauthenticatedRoute = containsRoute(unauthenticatedRoutes, route); + const isAdminRoute = containsRoute(adminRoutes, route); + const isAccountRoute = containsRoute(accountRoutes, route); + const isSetupStatusRegisteredRoute = containsRoute( + setupStatusRegisteredRoutes, + route + ); + + // prettier-ignore + const rules = [ + // Setup status + { + condition: getConfig("SETUP_STATUS") == "STARTED" && route != "/auth/signUp", + path: "/auth/signUp", + }, + { + condition: getConfig("SETUP_STATUS") == "REGISTERED" && !isSetupStatusRegisteredRoute, + path: user ? "/admin/setup" : "/auth/signIn", + }, + // Authenticated state + { + condition: user && isUnauthenticatedRoute, + path: "/upload", + }, + // Unauthenticated state + { + condition: !user && !isPublicRoute && !isUnauthenticatedRoute, + path: "/auth/signIn", + }, + { + condition: !user && isAccountRoute, + path: "/upload", + }, + // Admin privileges + { + condition: isAdminRoute && !user?.isAdmin, + path: "/upload", + }, + // Home page + { + condition: (!getConfig("SHOW_HOME_PAGE") || user) && route == "/", + path: "/upload", + }, + ]; + + for (const rule of rules) { + if (rule.condition) + return NextResponse.redirect(new URL(rule.path, request.url)); + } +} diff --git a/frontend/src/pages/_app.tsx b/frontend/src/pages/_app.tsx index f327f7eb..17d0df9f 100644 --- a/frontend/src/pages/_app.tsx +++ b/frontend/src/pages/_app.tsx @@ -9,7 +9,6 @@ import { useColorScheme } from "@mantine/hooks"; import { ModalsProvider } from "@mantine/modals"; import { NotificationsProvider } from "@mantine/notifications"; import type { AppProps } from "next/app"; -import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import Header from "../components/navBar/NavBar"; import { ConfigContext } from "../hooks/config.hook"; @@ -26,7 +25,7 @@ import { GlobalLoadingContext } from "../utils/loading.util"; function App({ Component, pageProps }: AppProps) { const systemTheme = useColorScheme(); - const router = useRouter(); + const preferences = usePreferences(); const [colorScheme, setColorScheme] = useState("light"); const [isLoading, setIsLoading] = useState(true); @@ -46,25 +45,6 @@ function App({ Component, pageProps }: AppProps) { getInitalData(); }, []); - // Redirect to setup page if setup is not completed - useEffect(() => { - if ( - configVariables && - !["/auth/signUp", "/admin/setup"].includes(router.asPath) - ) { - const setupStatus = configVariables.filter( - (variable) => variable.key == "SETUP_STATUS" - )[0].value; - if (setupStatus == "STARTED") { - router.replace("/auth/signUp"); - } else if (user && setupStatus == "REGISTERED") { - router.replace("/admin/setup"); - } else if (setupStatus == "REGISTERED") { - router.replace("/auth/signIn"); - } - } - }, [configVariables, router.asPath]); - useEffect(() => { setColorScheme( preferences.get("colorScheme") == "system" diff --git a/frontend/src/pages/account/index.tsx b/frontend/src/pages/account/index.tsx index 0180b23e..796871a4 100644 --- a/frontend/src/pages/account/index.tsx +++ b/frontend/src/pages/account/index.tsx @@ -13,7 +13,6 @@ import { } from "@mantine/core"; import { useForm, yupResolver } from "@mantine/form"; import { useModals } from "@mantine/modals"; -import { useRouter } from "next/router"; import { Tb2Fa } from "react-icons/tb"; import * as yup from "yup"; import showEnableTotpModal from "../../components/account/showEnableTotpModal"; @@ -27,7 +26,6 @@ import toast from "../../utils/toast.util"; const Account = () => { const { user, setUser } = useUser(); const modals = useModals(); - const router = useRouter(); const accountForm = useForm({ initialValues: { @@ -85,11 +83,6 @@ const Account = () => { const refreshUser = async () => setUser(await userService.getCurrentUser()); - if (!user) { - router.push("/"); - return; - } - return ( <> @@ -171,7 +164,7 @@ const Account = () => { - {user.totpVerified ? ( + {user!.totpVerified ? ( <>
{ diff --git a/frontend/src/pages/account/reverseShares.tsx b/frontend/src/pages/account/reverseShares.tsx index 7be03197..5d81dccd 100644 --- a/frontend/src/pages/account/reverseShares.tsx +++ b/frontend/src/pages/account/reverseShares.tsx @@ -13,7 +13,6 @@ import { import { useClipboard } from "@mantine/hooks"; import { useModals } from "@mantine/modals"; import moment from "moment"; -import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import { TbInfoCircle, TbLink, TbPlus, TbTrash } from "react-icons/tb"; import showShareLinkModal from "../../components/account/showShareLinkModal"; @@ -21,7 +20,6 @@ import CenterLoader from "../../components/core/CenterLoader"; import Meta from "../../components/Meta"; import showCreateReverseShareModal from "../../components/share/modals/showCreateReverseShareModal"; import useConfig from "../../hooks/config.hook"; -import useUser from "../../hooks/user.hook"; import shareService from "../../services/share.service"; import { MyReverseShare } from "../../types/share.type"; import { byteToHumanSizeString } from "../../utils/fileSize.util"; @@ -30,10 +28,8 @@ import toast from "../../utils/toast.util"; const MyShares = () => { const modals = useModals(); const clipboard = useClipboard(); - const router = useRouter(); - const config = useConfig(); - const { user } = useUser(); + const config = useConfig(); const [reverseShares, setReverseShares] = useState(); @@ -47,154 +43,145 @@ const MyShares = () => { getReverseShares(); }, []); - if (!user) { - router.replace("/"); - } else { - if (!reverseShares) return ; - return ( - <> - - - - My reverse shares - - - - - - - + + + + - {reverseShares.length == 0 ? ( -
- - It's empty here 👀 - You don't have any reverse shares. - -
- ) : ( - - - - - - - - - - - - - {reverseShares.map((reverseShare) => ( - - - - - - + + ))} + +
NameVisitorsMax share sizeExpires at
- {reverseShare.share ? ( - reverseShare.share?.id - ) : ( - No share created yet - )} - {reverseShare.share?.views ?? "0"} - {byteToHumanSizeString( - parseInt(reverseShare.maxShareSize) - )} - - {moment(reverseShare.shareExpiration).unix() === 0 - ? "Never" - : moment(reverseShare.shareExpiration).format("LLL")} - - - {reverseShare.share && ( - { - if (window.isSecureContext) { - clipboard.copy( - `${config.get("APP_URL")}/share/${ - reverseShare.share!.id - }` - ); - toast.success( - "The share link was copied to the keyboard." - ); - } else { - showShareLinkModal( - modals, - reverseShare.share!.id, - config.get("APP_URL") - ); - } - }} - > - - - )} + + + {reverseShares.length == 0 ? ( +
+ + It's empty here 👀 + You don't have any reverse shares. + +
+ ) : ( + + + + + + + + + + + + + {reverseShares.map((reverseShare) => ( + + + + + + - - ))} - -
NameVisitorsMax share sizeExpires at
+ {reverseShare.share ? ( + reverseShare.share?.id + ) : ( + No share created yet + )} + {reverseShare.share?.views ?? "0"} + {byteToHumanSizeString(parseInt(reverseShare.maxShareSize))} + + {moment(reverseShare.shareExpiration).unix() === 0 + ? "Never" + : moment(reverseShare.shareExpiration).format("LLL")} + + + {reverseShare.share && ( { - modals.openConfirmModal({ - title: `Delete reverse share`, - children: ( - - Do you really want to delete this reverse - share? If you do, the share will be deleted as - well. - - ), - confirmProps: { - color: "red", - }, - labels: { confirm: "Confirm", cancel: "Cancel" }, - onConfirm: () => { - shareService.removeReverseShare( - reverseShare.id - ); - setReverseShares( - reverseShares.filter( - (item) => item.id !== reverseShare.id - ) - ); - }, - }); + if (window.isSecureContext) { + clipboard.copy( + `${config.get("APP_URL")}/share/${ + reverseShare.share!.id + }` + ); + toast.success( + "The share link was copied to the keyboard." + ); + } else { + showShareLinkModal( + modals, + reverseShare.share!.id, + config.get("APP_URL") + ); + } }} > - + - -
-
- )} - - ); - } + )} + { + modals.openConfirmModal({ + title: `Delete reverse share`, + children: ( + + Do you really want to delete this reverse share? + If you do, the share will be deleted as well. + + ), + confirmProps: { + color: "red", + }, + labels: { confirm: "Confirm", cancel: "Cancel" }, + onConfirm: () => { + shareService.removeReverseShare(reverseShare.id); + setReverseShares( + reverseShares.filter( + (item) => item.id !== reverseShare.id + ) + ); + }, + }); + }} + > + + + +
+
+ )} + + ); }; export default MyShares; diff --git a/frontend/src/pages/account/shares.tsx b/frontend/src/pages/account/shares.tsx index b761fba3..834f4b5a 100644 --- a/frontend/src/pages/account/shares.tsx +++ b/frontend/src/pages/account/shares.tsx @@ -15,13 +15,11 @@ import { useClipboard } from "@mantine/hooks"; import { useModals } from "@mantine/modals"; import moment from "moment"; import Link from "next/link"; -import { useRouter } from "next/router"; import { useEffect, useState } from "react"; import { TbLink, TbTrash } from "react-icons/tb"; import showShareLinkModal from "../../components/account/showShareLinkModal"; import Meta from "../../components/Meta"; import useConfig from "../../hooks/config.hook"; -import useUser from "../../hooks/user.hook"; import shareService from "../../services/share.service"; import { MyShare } from "../../types/share.type"; import toast from "../../utils/toast.util"; @@ -29,122 +27,115 @@ import toast from "../../utils/toast.util"; const MyShares = () => { const modals = useModals(); const clipboard = useClipboard(); - const router = useRouter(); const config = useConfig(); - const { user } = useUser(); - const [shares, setShares] = useState(); useEffect(() => { shareService.getMyShares().then((shares) => setShares(shares)); }, []); - if (!user) { - router.replace("/"); - } else { - if (!shares) return ; - return ( - <> - - - My shares - - {shares.length == 0 ? ( -
- - It's empty here 👀 - You don't have any shares. - - - -
- ) : ( - - - - - - - - + if (!shares) return ; + return ( + <> + + + My shares + + {shares.length == 0 ? ( +
+ + It's empty here 👀 + You don't have any shares. + + + +
+ ) : ( + +
NameVisitorsExpires at
+ + + + + + + + + + {shares.map((share) => ( + + + + + - - - {shares.map((share) => ( - - - - - - - ))} - -
NameVisitorsExpires at
{share.id}{share.views} + {moment(share.expiration).unix() === 0 + ? "Never" + : moment(share.expiration).format("LLL")} + + + { + if (window.isSecureContext) { + clipboard.copy( + `${config.get("APP_URL")}/share/${share.id}` + ); + toast.success( + "Your link was copied to the keyboard." + ); + } else { + showShareLinkModal( + modals, + share.id, + config.get("APP_URL") + ); + } + }} + > + + + { + modals.openConfirmModal({ + title: `Delete share ${share.id}`, + children: ( + + Do you really want to delete this share? + + ), + confirmProps: { + color: "red", + }, + labels: { confirm: "Confirm", cancel: "Cancel" }, + onConfirm: () => { + shareService.remove(share.id); + setShares( + shares.filter((item) => item.id !== share.id) + ); + }, + }); + }} + > + + + +
{share.id}{share.views} - {moment(share.expiration).unix() === 0 - ? "Never" - : moment(share.expiration).format("LLL")} - - - { - if (window.isSecureContext) { - clipboard.copy( - `${config.get("APP_URL")}/share/${share.id}` - ); - toast.success( - "Your link was copied to the keyboard." - ); - } else { - showShareLinkModal( - modals, - share.id, - config.get("APP_URL") - ); - } - }} - > - - - { - modals.openConfirmModal({ - title: `Delete share ${share.id}`, - children: ( - - Do you really want to delete this share? - - ), - confirmProps: { - color: "red", - }, - labels: { confirm: "Confirm", cancel: "Cancel" }, - onConfirm: () => { - shareService.remove(share.id); - setShares( - shares.filter((item) => item.id !== share.id) - ); - }, - }); - }} - > - - - -
-
- )} - - ); - } + ))} + + + + )} + + ); }; export default MyShares; diff --git a/frontend/src/pages/admin/setup.tsx b/frontend/src/pages/admin/setup.tsx index 87785803..e61eeb6e 100644 --- a/frontend/src/pages/admin/setup.tsx +++ b/frontend/src/pages/admin/setup.tsx @@ -1,25 +1,10 @@ import { Box, Stack, Text, Title } from "@mantine/core"; -import { useRouter } from "next/router"; import AdminConfigTable from "../../components/admin/configuration/AdminConfigTable"; import Logo from "../../components/Logo"; import Meta from "../../components/Meta"; -import useConfig from "../../hooks/config.hook"; -import useUser from "../../hooks/user.hook"; const Setup = () => { - const router = useRouter(); - const config = useConfig(); - const { user } = useUser(); - - if (!user) { - router.push("/auth/signUp"); - return; - } else if (config.get("SETUP_STATUS") == "FINISHED") { - router.push("/"); - return; - } - return ( <> diff --git a/frontend/src/pages/auth/signIn.tsx b/frontend/src/pages/auth/signIn.tsx index 279bf0ff..0665fa8f 100644 --- a/frontend/src/pages/auth/signIn.tsx +++ b/frontend/src/pages/auth/signIn.tsx @@ -1,20 +1,25 @@ +import { LoadingOverlay } from "@mantine/core"; import { useRouter } from "next/router"; import SignInForm from "../../components/auth/SignInForm"; import Meta from "../../components/Meta"; import useUser from "../../hooks/user.hook"; const SignIn = () => { - const { user } = useUser(); const router = useRouter(); + const { user } = useUser(); + + // If the access token is expired, the middleware redirects to this page. + // If the refresh token is still valid, the user will be redirected to the home page. if (user) { router.replace("/"); - } else { - return ( - <> - - - - ); + return ; } + + return ( + <> + + + + ); }; export default SignIn; diff --git a/frontend/src/pages/auth/signUp.tsx b/frontend/src/pages/auth/signUp.tsx index dfd9683a..b3185be3 100644 --- a/frontend/src/pages/auth/signUp.tsx +++ b/frontend/src/pages/auth/signUp.tsx @@ -1,24 +1,12 @@ -import { useRouter } from "next/router"; import SignUpForm from "../../components/auth/SignUpForm"; import Meta from "../../components/Meta"; -import useConfig from "../../hooks/config.hook"; -import useUser from "../../hooks/user.hook"; const SignUp = () => { - const config = useConfig(); - const { user } = useUser(); - const router = useRouter(); - if (user) { - router.replace("/"); - } else if (!config.get("ALLOW_REGISTRATION")) { - router.replace("/auth/signIn"); - } else { - return ( - <> - - - - ); - } + return ( + <> + + + + ); }; export default SignUp; diff --git a/frontend/src/pages/index.tsx b/frontend/src/pages/index.tsx index 039d873b..07e75edf 100644 --- a/frontend/src/pages/index.tsx +++ b/frontend/src/pages/index.tsx @@ -10,11 +10,8 @@ import { } from "@mantine/core"; import Image from "next/image"; import Link from "next/link"; -import { useRouter } from "next/router"; import { TbCheck } from "react-icons/tb"; import Meta from "../components/Meta"; -import useConfig from "../hooks/config.hook"; -import useUser from "../hooks/user.hook"; const useStyles = createStyles((theme) => ({ inner: { @@ -69,94 +66,85 @@ const useStyles = createStyles((theme) => ({ })); export default function Home() { - const config = useConfig(); - const { user } = useUser(); - const { classes } = useStyles(); - const router = useRouter(); - if (user || config.get("ALLOW_UNAUTHENTICATED_SHARES")) { - router.replace("/upload"); - } else if (!config.get("SHOW_HOME_PAGE")) { - router.replace("/auth/signIn"); - } else { - return ( - <> - - -
-
- - A <span className={classes.highlight}>self-hosted</span> <br />{" "} - file sharing platform. - - - Do you really want to give your personal files in the hand of - third parties like WeTransfer? - - - - - } + return ( + <> + + +
+
+ + A <span className={classes.highlight}>self-hosted</span> <br />{" "} + file sharing platform. + + + Do you really want to give your personal files in the hand of + third parties like WeTransfer? + + + + + + } + > + +
+ Self-Hosted - Host Pingvin Share on your own machine. +
+
+ +
+ Privacy - Your files are your files and should never + get into the hands of third parties. +
+
+ +
+ No annoying file size limit - Upload as big files as + you want. Only your hard drive will be your limit. +
+
+
+ + + - - -
- - Pingvin Share Logo + Get started + +
-
- - ); - } + + Pingvin Share Logo + +
+ + + ); } diff --git a/frontend/src/pages/upload/index.tsx b/frontend/src/pages/upload/index.tsx index af6a7bfa..9db7a05b 100644 --- a/frontend/src/pages/upload/index.tsx +++ b/frontend/src/pages/upload/index.tsx @@ -2,8 +2,6 @@ import { Button, Group } from "@mantine/core"; import { useModals } from "@mantine/modals"; import { cleanNotifications } from "@mantine/notifications"; import { AxiosError } from "axios"; -import { getCookie } from "cookies-next"; -import { useRouter } from "next/router"; import pLimit from "p-limit"; import { useEffect, useState } from "react"; import Meta from "../../components/Meta"; @@ -30,7 +28,6 @@ const Upload = ({ maxShareSize?: number; isReverseShare: boolean; }) => { - const router = useRouter(); const modals = useModals(); const { user } = useUser(); @@ -158,51 +155,42 @@ const Upload = ({ } }, [files]); - if ( - !user && - !config.get("ALLOW_UNAUTHENTICATED_SHARES") && - !getCookie("reverse_share_token") - ) { - router.replace("/"); - return null; - } else { - return ( - <> - - - - - - {files.length > 0 && } - - ); - } + return ( + <> + + + + + + {files.length > 0 && } + + ); }; export default Upload;