✨ Add 401 page (#1508)
This commit is contained in:
1 parent
4072ebc5a5
commit
5b3a236194
11 files changed
+107
-46
No files matched your search
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "Access denied",
|
||||
"text": "You do not have sufficient permissions to access this page. If you believe, that this is not intentional, please contact your administrator.",
|
||||
"switchAccount": "Switch to a different account"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="793" height="551.73152" viewBox="0 0 793 551.73152" xmlns:xlink="http://www.w3.org/1999/xlink"><ellipse cx="158" cy="539.73152" rx="158" ry="12" fill="#e6e6e6"/><path d="M324.27227,296.55377c27.49676-11.6953,61.74442-4.28528,95.19092.85757.31124-6.228,4.08385-13.80782.132-18.15284-4.80115-5.2788-4.35917-10.82529-1.47008-16.40375,7.38788-14.265-3.1969-29.44375-13.88428-42.0647a23.66937,23.66937,0,0,0-19.75537-8.29179l-19.7975,1.41411A23.70939,23.70939,0,0,0,343.635,230.85851v0c-4.72724,6.42917-7.25736,12.84055-5.66438,19.21854-7.08065,4.83882-8.27029,10.67977-5.08851,17.2644,2.698,4.14592,2.66928,8.18161-.12275,12.1056a55.89079,55.89079,0,0,0-8.31011,16.5061Z" transform="translate(-203.5 -174.13424)" fill="#2f2e41"/><path d="M977.70889,651.09727H417.29111A18.79111,18.79111,0,0,1,398.5,632.30616h0q304.727-35.41512,598,0h0A18.79111,18.79111,0,0,1,977.70889,651.09727Z" transform="translate(-203.5 -174.13424)" fill="#2f2e41"/><path d="M996.5,633.41151l-598-1.10536,69.30611-116.61553.3316-.55268V258.13057a23.7522,23.7522,0,0,1,23.75418-23.75418H899.792a23.7522,23.7522,0,0,1,23.75418,23.75418V516.90649Z" transform="translate(-203.5 -174.13424)" fill="#3f3d56"/><path d="M491.35028,250.95679a7.74623,7.74623,0,0,0-7.73753,7.73753V493.03073a7.74657,7.74657,0,0,0,7.73753,7.73752H903.64972a7.74691,7.74691,0,0,0,7.73753-7.73752V258.69432a7.74657,7.74657,0,0,0-7.73753-7.73753Z" transform="translate(-203.5 -174.13424)" fill="#fff"/><path d="M493.07794,531.71835a3.32522,3.32522,0,0,0-3.01275,1.93006l-21.35537,46.42514a3.31594,3.31594,0,0,0,3.01221,4.7021H920.81411a3.3157,3.3157,0,0,0,2.96526-4.79925L900.5668,533.55126a3.29926,3.29926,0,0,0-2.96526-1.83291Z" transform="translate(-203.5 -174.13424)" fill="#2f2e41"/><circle cx="492.34196" cy="67.97967" r="4.97412" fill="#fff"/><path d="M651.69986,593.61853a3.32114,3.32114,0,0,0-3.20165,2.4536l-5.35679,19.89649a3.31576,3.31576,0,0,0,3.20166,4.17856h101.874a3.31531,3.31531,0,0,0,3.13257-4.40093l-6.88691-19.89649a3.31784,3.31784,0,0,0-3.13366-2.23123Z" transform="translate(-203.5 -174.13424)" fill="#2f2e41"/><polygon points="720.046 337.135 720.046 341.556 264.306 341.556 264.649 341.004 264.649 337.135 720.046 337.135" fill="#2f2e41"/><circle cx="707.33457" cy="77.37523" r="77.37523" fill="#fa5252"/><path d="M942.89,285.223H878.77911a4.42582,4.42582,0,0,1-4.42144-4.42145V242.11391a4.42616,4.42616,0,0,1,4.42144-4.42144H942.89a4.42616,4.42616,0,0,1,4.42144,4.42144v38.68761A4.42582,4.42582,0,0,1,942.89,285.223Zm-64.11091-43.10906v38.68761h64.11415L942.89,242.11391Z" transform="translate(-203.5 -174.13424)" fill="#fff"/><path d="M930.73105,242.11391h-39.793V224.42814c0-12.80987,8.36792-22.10721,19.89649-22.10721s19.89648,9.29734,19.89648,22.10721Zm-35.37153-4.42144h30.95009V224.42814c0-10.413-6.36338-17.68576-15.475-17.68576s-15.47505,7.27281-15.47505,17.68576Z" transform="translate(-203.5 -174.13424)" fill="#fff"/><circle cx="707.33457" cy="86.21811" r="4.42144" fill="#fff"/><path d="M856.81994,421.28372H538.18006a5.90767,5.90767,0,0,1-5.90073-5.90073V336.342a5.90767,5.90767,0,0,1,5.90073-5.90072H856.81994a5.90767,5.90767,0,0,1,5.90073,5.90072V415.383A5.90767,5.90767,0,0,1,856.81994,421.28372Zm-318.63988-88.4821a3.5443,3.5443,0,0,0-3.54043,3.54043V415.383a3.54431,3.54431,0,0,0,3.54043,3.54044H856.81994a3.54431,3.54431,0,0,0,3.54043-3.54044V336.342a3.5443,3.5443,0,0,0-3.54043-3.54043Z" transform="translate(-203.5 -174.13424)" fill="#e6e6e6"/><circle cx="384.19021" cy="198.69546" r="24.03645" fill="#e6e6e6"/><path d="M643.203,356.80541a4.00608,4.00608,0,1,0,0,8.01215H832.06074a4.00607,4.00607,0,0,0,0-8.01215Z" transform="translate(-203.5 -174.13424)" fill="#e6e6e6"/><path d="M643.203,380.84186a4.00607,4.00607,0,1,0,0,8.01214H724.469a4.00607,4.00607,0,1,0,0-8.01214Z" transform="translate(-203.5 -174.13424)" fill="#e6e6e6"/><path d="M467.022,382.46241,408.1189,413.778l-.74561-26.09629c19.22553-3.20948,37.51669-8.7974,54.42941-17.8946l6.1605-15.22008a10.31753,10.31753,0,0,1,17.53643-2.67788l0,0a10.31753,10.31753,0,0,1-.90847,14.06885Z" transform="translate(-203.5 -174.13424)" fill="#ffb8b8"/><path d="M323.09819,563.26707v0a11.57378,11.57378,0,0,1,1.46928-9.36311l12.93931-19.85777a22.61221,22.61221,0,0,1,29.335-7.73927h0c-5.438,9.25647-4.67994,17.37679,1.87806,24.43365a117.63085,117.63085,0,0,0-27.93606,19.04492A11.57386,11.57386,0,0,1,323.09819,563.26707Z" transform="translate(-203.5 -174.13424)" fill="#2f2e41"/><path d="M469.70475,537.30274l0,0a22.20314,22.20314,0,0,1-18.87085,10.77909l-85.96027.65122-3.728-21.62264,38.026-11.18413-32.06116-24.60507L402.154,450.31277l63.65,59.32431A22.20317,22.20317,0,0,1,469.70475,537.30274Z" transform="translate(-203.5 -174.13424)" fill="#2f2e41"/><path d="M351.45266,685.17939H331.32124c-18.07509-123.89772-36.47383-248.14186,17.8946-294.51529l64.12231,10.43852L405.13646,455.532l-35.7892,41.00845Z" transform="translate(-203.5 -174.13424)" fill="#2f2e41"/><path d="M369.14917,713.24594hLine truncated
|
||||
|
After Width: | Height: | Size: 6.4 KiB |
@@ -0,0 +1,55 @@
|
||||
import { Button, Center, Stack, Title, Text, createStyles } from "@mantine/core";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import Image from "next/image";
|
||||
import Head from "next/head";
|
||||
import { MainLayout } from "~/components/layout/Templates/MainLayout";
|
||||
import Link from "next/link";
|
||||
|
||||
import imageAccessDenied from '~/images/undraw_secure_login_pdn4.svg';
|
||||
import { pageAccessDeniedNamespaces } from "~/tools/server/translation-namespaces";
|
||||
import { getServerSideTranslations } from "~/tools/server/getServerSideTranslations";
|
||||
import { GetServerSidePropsContext } from "next";
|
||||
|
||||
export default function Custom401() {
|
||||
const { classes } = useStyles();
|
||||
const { t } = useTranslation('layout/errors/access-denied');
|
||||
return (
|
||||
<MainLayout>
|
||||
<Center h="100dvh" w="100dvw">
|
||||
<Head>
|
||||
<title>Access denied • Homarr</title>
|
||||
</Head>
|
||||
<Stack maw={500} p="xl">
|
||||
<Image className={classes.image} src={imageAccessDenied} width={200} height={200} alt="" />
|
||||
<Title>{t('title')}</Title>
|
||||
<Text>{t('text')}</Text>
|
||||
|
||||
<Button component={Link} variant="light" href="/auth/login">
|
||||
{t('switchAccount')}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Center>
|
||||
</MainLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps({ req, res, locale }: GetServerSidePropsContext) {
|
||||
const translations = await getServerSideTranslations(
|
||||
[...pageAccessDeniedNamespaces, 'common'],
|
||||
locale,
|
||||
req,
|
||||
res
|
||||
);
|
||||
return {
|
||||
props: {
|
||||
...translations,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const useStyles = createStyles(() => ({
|
||||
image: {
|
||||
margin: '0 auto',
|
||||
display: 'block',
|
||||
},
|
||||
}));
|
||||
@@ -44,6 +44,7 @@ import { MainLayout } from '~/components/layout/Templates/MainLayout';
|
||||
import { createTrpcServersideHelpers } from '~/server/api/helper';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
import { firstUpperCase } from '~/tools/shared/strings';
|
||||
import { api } from '~/utils/api';
|
||||
import { useI18nZodResolver } from '~/utils/i18n-zod-resolver';
|
||||
@@ -275,22 +276,22 @@ const routeParamsSchema = z.object({
|
||||
slug: z.string(),
|
||||
});
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, res, locale, params }) => {
|
||||
const routeParams = routeParamsSchema.safeParse(params);
|
||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||
const routeParams = routeParamsSchema.safeParse(context.params);
|
||||
if (!routeParams.success) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
}
|
||||
|
||||
const session = await getServerAuthSession({ req, res });
|
||||
if (!session?.user.isAdmin) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
const session = await getServerAuthSession({ req: context.req, res: context.res });
|
||||
|
||||
const result = checkForSessionOrAskForLogin(context, session, () => session?.user.isAdmin == true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const helpers = await createTrpcServersideHelpers({ req, res });
|
||||
const helpers = await createTrpcServersideHelpers({ req: context.req, res: context.res });
|
||||
|
||||
const config = await helpers.config.byName.fetch({ name: routeParams.data.slug });
|
||||
|
||||
@@ -305,9 +306,9 @@ export const getServerSideProps: GetServerSideProps = async ({ req, res, locale,
|
||||
'settings/customization/gridstack',
|
||||
'settings/customization/access',
|
||||
],
|
||||
locale,
|
||||
req,
|
||||
res
|
||||
context.locale,
|
||||
context.req,
|
||||
context.res
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -11,6 +11,7 @@ import { getDefaultBoardAsync } from '~/server/db/queries/userSettings';
|
||||
import { userSettings } from '~/server/db/schema';
|
||||
import { getFrontendConfig } from '~/tools/config/getFrontendConfig';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
import { boardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { ConfigType } from '~/types/config';
|
||||
|
||||
@@ -45,15 +46,9 @@ export const getServerSideProps: GetServerSideProps<BoardGetServerSideProps> = a
|
||||
);
|
||||
const config = await getFrontendConfig(boardName);
|
||||
|
||||
if (!config?.settings?.access?.allowGuests && !session?.user) {
|
||||
return {
|
||||
notFound: true,
|
||||
props: {
|
||||
primaryColor: config.settings.customization.colors.primary,
|
||||
secondaryColor: config.settings.customization.colors.secondary,
|
||||
primaryShade: config.settings.customization.colors.shade,
|
||||
},
|
||||
};
|
||||
const result = checkForSessionOrAskForLogin(ctx, session, () => true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -23,6 +23,7 @@ import { getServerSideTranslations } from '~/tools/server/getServerSideTranslati
|
||||
import { OnlyKeysWithStructure } from '~/types/helpers';
|
||||
|
||||
import { type quickActions } from '../../../public/locales/en/manage/index.json';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
|
||||
const ManagementPage = () => {
|
||||
const { t } = useTranslation('manage/index');
|
||||
@@ -118,10 +119,9 @@ const QuickActionCard = ({ type, href }: QuickActionCardProps) => {
|
||||
export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
||||
const session = await getServerAuthSession(ctx);
|
||||
|
||||
if (!session?.user) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
const result = checkForSessionOrAskForLogin(ctx, session, () => true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const translations = await getServerSideTranslations(
|
||||
|
||||
@@ -11,6 +11,7 @@ import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
|
||||
import { dockerRouter } from '~/server/api/routers/docker/router';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
import { boardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { api } from '~/utils/api';
|
||||
|
||||
@@ -54,24 +55,23 @@ export default function DockerPage({
|
||||
);
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ locale, req, res }) => {
|
||||
const session = await getServerAuthSession({ req, res });
|
||||
if (!session?.user.isAdmin) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||
const session = await getServerAuthSession({ req: context.req, res: context.res });
|
||||
const result = checkForSessionOrAskForLogin(context, session, () => session?.user.isAdmin == true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const caller = dockerRouter.createCaller({
|
||||
session: session,
|
||||
cookies: req.cookies,
|
||||
cookies: context.req.cookies,
|
||||
});
|
||||
|
||||
const translations = await getServerSideTranslations(
|
||||
[...boardNamespaces, 'layout/manage', 'tools/docker'],
|
||||
locale,
|
||||
req,
|
||||
res
|
||||
context.locale,
|
||||
context.req,
|
||||
context.res
|
||||
);
|
||||
|
||||
let containers = [];
|
||||
|
||||
@@ -26,6 +26,7 @@ import { openDeleteUserModal } from '~/components/Manage/User/delete-user.modal'
|
||||
import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
import { manageNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { api } from '~/utils/api';
|
||||
|
||||
@@ -180,11 +181,9 @@ const ManageUsersPage = () => {
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
||||
const session = await getServerAuthSession(ctx);
|
||||
|
||||
if (!session?.user.isAdmin) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
const result = checkForSessionOrAskForLogin(ctx, session, () => session?.user.isAdmin == true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const translations = await getServerSideTranslations(
|
||||
|
||||
@@ -20,6 +20,7 @@ import { openCreateInviteModal } from '~/components/Manage/User/Invite/create-in
|
||||
import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder';
|
||||
import { manageNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { api } from '~/utils/api';
|
||||
|
||||
@@ -152,11 +153,9 @@ const useStyles = createStyles(() => ({
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
||||
const session = await getServerAuthSession(ctx);
|
||||
|
||||
if (!session?.user.isAdmin) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
const result = checkForSessionOrAskForLogin(ctx, session, () => session?.user.isAdmin == true);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const translations = await getServerSideTranslations(
|
||||
|
||||
@@ -4,7 +4,9 @@ import {
|
||||
GetServerSidePropsResult,
|
||||
PreviewData,
|
||||
} from 'next';
|
||||
|
||||
import { Session } from 'next-auth';
|
||||
|
||||
import { ParsedUrlQuery } from 'querystring';
|
||||
|
||||
export const checkForSessionOrAskForLogin = (
|
||||
@@ -13,7 +15,6 @@ export const checkForSessionOrAskForLogin = (
|
||||
accessCallback: () => boolean
|
||||
): GetServerSidePropsResult<any> | undefined => {
|
||||
if (!session?.user) {
|
||||
console.log('detected logged out user!');
|
||||
return {
|
||||
props: {},
|
||||
redirect: {
|
||||
@@ -26,7 +27,10 @@ export const checkForSessionOrAskForLogin = (
|
||||
if (!accessCallback()) {
|
||||
return {
|
||||
props: {},
|
||||
notFound: true,
|
||||
redirect: {
|
||||
destination: '/401',
|
||||
permanent: false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -51,3 +51,5 @@ export const manageNamespaces = [
|
||||
export const loginNamespaces = ['authentication/login'];
|
||||
|
||||
export const pageNotFoundNamespaces = ['layout/errors/not-found'];
|
||||
|
||||
export const pageAccessDeniedNamespaces = ['layout/errors/access-denied'];
|
||||
Reference in new issue
Block a user