refactor: handle authentication state in middleware

This commit is contained in:
Elias Schneider
2023-02-04 18:12:49 +01:00
parent 064ef38d78
commit 4e840ecd29
17 changed files with 511 additions and 474 deletions

View File

@@ -120,7 +120,7 @@ export class AuthController {
const accessToken = await this.authService.refreshAccessToken( const accessToken = await this.authService.refreshAccessToken(
request.cookies.refresh_token request.cookies.refresh_token
); );
response.cookie("access_token", accessToken); response = this.addTokensToResponse(response, undefined, accessToken);
return new TokenDTO().from({ accessToken }); return new TokenDTO().from({ accessToken });
} }
@@ -162,11 +162,13 @@ export class AuthController {
refreshToken?: string, refreshToken?: string,
accessToken?: string accessToken?: string
) { ) {
if (accessToken) response.cookie("access_token", accessToken); if (accessToken)
response.cookie("access_token", accessToken, { sameSite: "lax" });
if (refreshToken) if (refreshToken)
response.cookie("refresh_token", refreshToken, { response.cookie("refresh_token", refreshToken, {
path: "/api/auth/token", path: "/api/auth/token",
httpOnly: true, httpOnly: true,
sameSite: "strict",
maxAge: 1000 * 60 * 60 * 24 * 30 * 3, maxAge: 1000 * 60 * 60 * 24 * 30 * 3,
}); });

View File

@@ -110,20 +110,23 @@ export class AuthService {
{ {
sub: user.id, sub: user.id,
email: user.email, email: user.email,
isAdmin: user.isAdmin,
refreshTokenId, refreshTokenId,
}, },
{ {
expiresIn: "15min", expiresIn: "10s",
secret: this.config.get("JWT_SECRET"), secret: this.config.get("JWT_SECRET"),
} }
); );
} }
async signOut(accessToken: string) { async signOut(accessToken: string) {
const { refreshTokenId } = this.jwtService.decode(accessToken) as { const { refreshTokenId } =
(this.jwtService.decode(accessToken) as {
refreshTokenId: string; refreshTokenId: string;
}; }) || {};
if (refreshTokenId) {
await this.prisma.refreshToken await this.prisma.refreshToken
.delete({ where: { id: refreshTokenId } }) .delete({ where: { id: refreshTokenId } })
.catch((e) => { .catch((e) => {
@@ -131,6 +134,7 @@ export class AuthService {
if (e.code != "P2025") throw e; if (e.code != "P2025") throw e;
}); });
} }
}
async refreshAccessToken(refreshToken: string) { async refreshAccessToken(refreshToken: string) {
const refreshTokenMetaData = await this.prisma.refreshToken.findUnique({ const refreshTokenMetaData = await this.prisma.refreshToken.findUnique({

View File

@@ -1,4 +1,5 @@
import { Body, Controller, Get, Patch, Post, UseGuards } from "@nestjs/common"; import { Body, Controller, Get, Patch, Post, UseGuards } from "@nestjs/common";
import { SkipThrottle } from "@nestjs/throttler";
import { AdministratorGuard } from "src/auth/guard/isAdmin.guard"; import { AdministratorGuard } from "src/auth/guard/isAdmin.guard";
import { JwtGuard } from "src/auth/guard/jwt.guard"; import { JwtGuard } from "src/auth/guard/jwt.guard";
import { EmailService } from "src/email/email.service"; import { EmailService } from "src/email/email.service";
@@ -16,6 +17,7 @@ export class ConfigController {
) {} ) {}
@Get() @Get()
@SkipThrottle()
async list() { async list() {
return new ConfigDTO().fromList(await this.configService.list()); return new ConfigDTO().fromList(await this.configService.list());
} }

View File

@@ -21,6 +21,7 @@
"cookies-next": "^2.1.1", "cookies-next": "^2.1.1",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"jose": "^4.11.2", "jose": "^4.11.2",
"jwt-decode": "^3.1.2",
"mime-types": "^2.1.35", "mime-types": "^2.1.35",
"moment": "^2.29.4", "moment": "^2.29.4",
"next": "^13.1.2", "next": "^13.1.2",
@@ -5610,6 +5611,11 @@
"node": ">=4.0" "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": { "node_modules/klona": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz",
@@ -12122,6 +12128,11 @@
"object.assign": "^4.1.2" "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": { "klona": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz",

View File

@@ -22,6 +22,7 @@
"cookies-next": "^2.1.1", "cookies-next": "^2.1.1",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"jose": "^4.11.2", "jose": "^4.11.2",
"jwt-decode": "^3.1.2",
"mime-types": "^2.1.35", "mime-types": "^2.1.35",
"moment": "^2.29.4", "moment": "^2.29.4",
"next": "^13.1.2", "next": "^13.1.2",

View File

@@ -14,7 +14,6 @@ import { useForm, yupResolver } from "@mantine/form";
import { useModals } from "@mantine/modals"; import { useModals } from "@mantine/modals";
import { ModalsContextProps } from "@mantine/modals/lib/context"; import { ModalsContextProps } from "@mantine/modals/lib/context";
import * as yup from "yup"; import * as yup from "yup";
import useUser from "../../hooks/user.hook";
import authService from "../../services/auth.service"; import authService from "../../services/auth.service";
import toast from "../../utils/toast.util"; import toast from "../../utils/toast.util";

View File

@@ -9,6 +9,7 @@ import {
Title, Title,
} from "@mantine/core"; } from "@mantine/core";
import { useMediaQuery } from "@mantine/hooks"; import { useMediaQuery } from "@mantine/hooks";
import { useRouter } from "next/router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import useConfig from "../../../hooks/config.hook"; import useConfig from "../../../hooks/config.hook";
import configService from "../../../services/config.service"; import configService from "../../../services/config.service";
@@ -27,6 +28,7 @@ import TestEmailButton from "./TestEmailButton";
const AdminConfigTable = () => { const AdminConfigTable = () => {
const config = useConfig(); const config = useConfig();
const router = useRouter();
const isMobile = useMediaQuery("(max-width: 560px)"); const isMobile = useMediaQuery("(max-width: 560px)");
const [updatedConfigVariables, setUpdatedConfigVariables] = useState< const [updatedConfigVariables, setUpdatedConfigVariables] = useState<
@@ -68,7 +70,7 @@ const AdminConfigTable = () => {
.updateMany(updatedConfigVariables) .updateMany(updatedConfigVariables)
.then(async () => { .then(async () => {
await configService.finishSetup(); await configService.finishSetup();
window.location.reload(); router.replace("/upload");
}) })
.catch(toast.axiosError); .catch(toast.axiosError);
} else { } else {

111
frontend/src/middleware.ts Normal file
View File

@@ -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));
}
}

View File

@@ -9,7 +9,6 @@ import { useColorScheme } from "@mantine/hooks";
import { ModalsProvider } from "@mantine/modals"; import { ModalsProvider } from "@mantine/modals";
import { NotificationsProvider } from "@mantine/notifications"; import { NotificationsProvider } from "@mantine/notifications";
import type { AppProps } from "next/app"; import type { AppProps } from "next/app";
import { useRouter } from "next/router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import Header from "../components/navBar/NavBar"; import Header from "../components/navBar/NavBar";
import { ConfigContext } from "../hooks/config.hook"; import { ConfigContext } from "../hooks/config.hook";
@@ -26,7 +25,7 @@ import { GlobalLoadingContext } from "../utils/loading.util";
function App({ Component, pageProps }: AppProps) { function App({ Component, pageProps }: AppProps) {
const systemTheme = useColorScheme(); const systemTheme = useColorScheme();
const router = useRouter();
const preferences = usePreferences(); const preferences = usePreferences();
const [colorScheme, setColorScheme] = useState<ColorScheme>("light"); const [colorScheme, setColorScheme] = useState<ColorScheme>("light");
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
@@ -46,25 +45,6 @@ function App({ Component, pageProps }: AppProps) {
getInitalData(); 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(() => { useEffect(() => {
setColorScheme( setColorScheme(
preferences.get("colorScheme") == "system" preferences.get("colorScheme") == "system"

View File

@@ -13,7 +13,6 @@ import {
} from "@mantine/core"; } from "@mantine/core";
import { useForm, yupResolver } from "@mantine/form"; import { useForm, yupResolver } from "@mantine/form";
import { useModals } from "@mantine/modals"; import { useModals } from "@mantine/modals";
import { useRouter } from "next/router";
import { Tb2Fa } from "react-icons/tb"; import { Tb2Fa } from "react-icons/tb";
import * as yup from "yup"; import * as yup from "yup";
import showEnableTotpModal from "../../components/account/showEnableTotpModal"; import showEnableTotpModal from "../../components/account/showEnableTotpModal";
@@ -27,7 +26,6 @@ import toast from "../../utils/toast.util";
const Account = () => { const Account = () => {
const { user, setUser } = useUser(); const { user, setUser } = useUser();
const modals = useModals(); const modals = useModals();
const router = useRouter();
const accountForm = useForm({ const accountForm = useForm({
initialValues: { initialValues: {
@@ -85,11 +83,6 @@ const Account = () => {
const refreshUser = async () => setUser(await userService.getCurrentUser()); const refreshUser = async () => setUser(await userService.getCurrentUser());
if (!user) {
router.push("/");
return;
}
return ( return (
<> <>
<Meta title="My account" /> <Meta title="My account" />
@@ -171,7 +164,7 @@ const Account = () => {
</Tabs.List> </Tabs.List>
<Tabs.Panel value="totp" pt="xs"> <Tabs.Panel value="totp" pt="xs">
{user.totpVerified ? ( {user!.totpVerified ? (
<> <>
<form <form
onSubmit={disableTotpForm.onSubmit((values) => { onSubmit={disableTotpForm.onSubmit((values) => {

View File

@@ -13,7 +13,6 @@ import {
import { useClipboard } from "@mantine/hooks"; import { useClipboard } from "@mantine/hooks";
import { useModals } from "@mantine/modals"; import { useModals } from "@mantine/modals";
import moment from "moment"; import moment from "moment";
import { useRouter } from "next/router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { TbInfoCircle, TbLink, TbPlus, TbTrash } from "react-icons/tb"; import { TbInfoCircle, TbLink, TbPlus, TbTrash } from "react-icons/tb";
import showShareLinkModal from "../../components/account/showShareLinkModal"; import showShareLinkModal from "../../components/account/showShareLinkModal";
@@ -21,7 +20,6 @@ import CenterLoader from "../../components/core/CenterLoader";
import Meta from "../../components/Meta"; import Meta from "../../components/Meta";
import showCreateReverseShareModal from "../../components/share/modals/showCreateReverseShareModal"; import showCreateReverseShareModal from "../../components/share/modals/showCreateReverseShareModal";
import useConfig from "../../hooks/config.hook"; import useConfig from "../../hooks/config.hook";
import useUser from "../../hooks/user.hook";
import shareService from "../../services/share.service"; import shareService from "../../services/share.service";
import { MyReverseShare } from "../../types/share.type"; import { MyReverseShare } from "../../types/share.type";
import { byteToHumanSizeString } from "../../utils/fileSize.util"; import { byteToHumanSizeString } from "../../utils/fileSize.util";
@@ -30,10 +28,8 @@ import toast from "../../utils/toast.util";
const MyShares = () => { const MyShares = () => {
const modals = useModals(); const modals = useModals();
const clipboard = useClipboard(); const clipboard = useClipboard();
const router = useRouter();
const config = useConfig();
const { user } = useUser(); const config = useConfig();
const [reverseShares, setReverseShares] = useState<MyReverseShare[]>(); const [reverseShares, setReverseShares] = useState<MyReverseShare[]>();
@@ -47,9 +43,6 @@ const MyShares = () => {
getReverseShares(); getReverseShares();
}, []); }, []);
if (!user) {
router.replace("/");
} else {
if (!reverseShares) return <CenterLoader />; if (!reverseShares) return <CenterLoader />;
return ( return (
<> <>
@@ -113,9 +106,7 @@ const MyShares = () => {
</td> </td>
<td>{reverseShare.share?.views ?? "0"}</td> <td>{reverseShare.share?.views ?? "0"}</td>
<td> <td>
{byteToHumanSizeString( {byteToHumanSizeString(parseInt(reverseShare.maxShareSize))}
parseInt(reverseShare.maxShareSize)
)}
</td> </td>
<td> <td>
{moment(reverseShare.shareExpiration).unix() === 0 {moment(reverseShare.shareExpiration).unix() === 0
@@ -160,9 +151,8 @@ const MyShares = () => {
title: `Delete reverse share`, title: `Delete reverse share`,
children: ( children: (
<Text size="sm"> <Text size="sm">
Do you really want to delete this reverse Do you really want to delete this reverse share?
share? If you do, the share will be deleted as If you do, the share will be deleted as well.
well.
</Text> </Text>
), ),
confirmProps: { confirmProps: {
@@ -170,9 +160,7 @@ const MyShares = () => {
}, },
labels: { confirm: "Confirm", cancel: "Cancel" }, labels: { confirm: "Confirm", cancel: "Cancel" },
onConfirm: () => { onConfirm: () => {
shareService.removeReverseShare( shareService.removeReverseShare(reverseShare.id);
reverseShare.id
);
setReverseShares( setReverseShares(
reverseShares.filter( reverseShares.filter(
(item) => item.id !== reverseShare.id (item) => item.id !== reverseShare.id
@@ -194,7 +182,6 @@ const MyShares = () => {
)} )}
</> </>
); );
}
}; };
export default MyShares; export default MyShares;

View File

@@ -15,13 +15,11 @@ import { useClipboard } from "@mantine/hooks";
import { useModals } from "@mantine/modals"; import { useModals } from "@mantine/modals";
import moment from "moment"; import moment from "moment";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { TbLink, TbTrash } from "react-icons/tb"; import { TbLink, TbTrash } from "react-icons/tb";
import showShareLinkModal from "../../components/account/showShareLinkModal"; import showShareLinkModal from "../../components/account/showShareLinkModal";
import Meta from "../../components/Meta"; import Meta from "../../components/Meta";
import useConfig from "../../hooks/config.hook"; import useConfig from "../../hooks/config.hook";
import useUser from "../../hooks/user.hook";
import shareService from "../../services/share.service"; import shareService from "../../services/share.service";
import { MyShare } from "../../types/share.type"; import { MyShare } from "../../types/share.type";
import toast from "../../utils/toast.util"; import toast from "../../utils/toast.util";
@@ -29,20 +27,14 @@ import toast from "../../utils/toast.util";
const MyShares = () => { const MyShares = () => {
const modals = useModals(); const modals = useModals();
const clipboard = useClipboard(); const clipboard = useClipboard();
const router = useRouter();
const config = useConfig(); const config = useConfig();
const { user } = useUser();
const [shares, setShares] = useState<MyShare[]>(); const [shares, setShares] = useState<MyShare[]>();
useEffect(() => { useEffect(() => {
shareService.getMyShares().then((shares) => setShares(shares)); shareService.getMyShares().then((shares) => setShares(shares));
}, []); }, []);
if (!user) {
router.replace("/");
} else {
if (!shares) return <LoadingOverlay visible />; if (!shares) return <LoadingOverlay visible />;
return ( return (
<> <>
@@ -144,7 +136,6 @@ const MyShares = () => {
)} )}
</> </>
); );
}
}; };
export default MyShares; export default MyShares;

View File

@@ -1,25 +1,10 @@
import { Box, Stack, Text, Title } from "@mantine/core"; import { Box, Stack, Text, Title } from "@mantine/core";
import { useRouter } from "next/router";
import AdminConfigTable from "../../components/admin/configuration/AdminConfigTable"; import AdminConfigTable from "../../components/admin/configuration/AdminConfigTable";
import Logo from "../../components/Logo"; import Logo from "../../components/Logo";
import Meta from "../../components/Meta"; import Meta from "../../components/Meta";
import useConfig from "../../hooks/config.hook";
import useUser from "../../hooks/user.hook";
const Setup = () => { 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 ( return (
<> <>
<Meta title="Setup" /> <Meta title="Setup" />

View File

@@ -1,20 +1,25 @@
import { LoadingOverlay } from "@mantine/core";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import SignInForm from "../../components/auth/SignInForm"; import SignInForm from "../../components/auth/SignInForm";
import Meta from "../../components/Meta"; import Meta from "../../components/Meta";
import useUser from "../../hooks/user.hook"; import useUser from "../../hooks/user.hook";
const SignIn = () => { const SignIn = () => {
const { user } = useUser();
const router = useRouter(); 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) { if (user) {
router.replace("/"); router.replace("/");
} else { return <LoadingOverlay overlayOpacity={1} visible />;
}
return ( return (
<> <>
<Meta title="Sign In" /> <Meta title="Sign In" />
<SignInForm /> <SignInForm />
</> </>
); );
}
}; };
export default SignIn; export default SignIn;

View File

@@ -1,24 +1,12 @@
import { useRouter } from "next/router";
import SignUpForm from "../../components/auth/SignUpForm"; import SignUpForm from "../../components/auth/SignUpForm";
import Meta from "../../components/Meta"; import Meta from "../../components/Meta";
import useConfig from "../../hooks/config.hook";
import useUser from "../../hooks/user.hook";
const SignUp = () => { 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 (
<> <>
<Meta title="Sign Up" /> <Meta title="Sign Up" />
<SignUpForm /> <SignUpForm />
</> </>
); );
}
}; };
export default SignUp; export default SignUp;

View File

@@ -10,11 +10,8 @@ import {
} from "@mantine/core"; } from "@mantine/core";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router";
import { TbCheck } from "react-icons/tb"; import { TbCheck } from "react-icons/tb";
import Meta from "../components/Meta"; import Meta from "../components/Meta";
import useConfig from "../hooks/config.hook";
import useUser from "../hooks/user.hook";
const useStyles = createStyles((theme) => ({ const useStyles = createStyles((theme) => ({
inner: { inner: {
@@ -69,16 +66,8 @@ const useStyles = createStyles((theme) => ({
})); }));
export default function Home() { export default function Home() {
const config = useConfig();
const { user } = useUser();
const { classes } = useStyles(); 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 ( return (
<> <>
<Meta title="Home" /> <Meta title="Home" />
@@ -159,4 +148,3 @@ export default function Home() {
</> </>
); );
} }
}

View File

@@ -2,8 +2,6 @@ import { Button, Group } from "@mantine/core";
import { useModals } from "@mantine/modals"; import { useModals } from "@mantine/modals";
import { cleanNotifications } from "@mantine/notifications"; import { cleanNotifications } from "@mantine/notifications";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import { getCookie } from "cookies-next";
import { useRouter } from "next/router";
import pLimit from "p-limit"; import pLimit from "p-limit";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import Meta from "../../components/Meta"; import Meta from "../../components/Meta";
@@ -30,7 +28,6 @@ const Upload = ({
maxShareSize?: number; maxShareSize?: number;
isReverseShare: boolean; isReverseShare: boolean;
}) => { }) => {
const router = useRouter();
const modals = useModals(); const modals = useModals();
const { user } = useUser(); const { user } = useUser();
@@ -158,14 +155,6 @@ const Upload = ({
} }
}, [files]); }, [files]);
if (
!user &&
!config.get("ALLOW_UNAUTHENTICATED_SHARES") &&
!getCookie("reverse_share_token")
) {
router.replace("/");
return null;
} else {
return ( return (
<> <>
<Meta title="Upload" /> <Meta title="Upload" />
@@ -203,6 +192,5 @@ const Upload = ({
{files.length > 0 && <FileList files={files} setFiles={setFiles} />} {files.length > 0 && <FileList files={files} setFiles={setFiles} />}
</> </>
); );
}
}; };
export default Upload; export default Upload;