fix rendering issues on resource unauthorized

This commit is contained in:
Milo Schwartz 2024-11-29 21:48:48 -05:00
parent 5bbf32f6a6
commit 500a81aa42
No known key found for this signature in database
8 changed files with 58 additions and 20 deletions

View file

@ -4,7 +4,7 @@
"private": true,
"type": "module",
"scripts": {
"dev": "ENVIRONMENT=dev tsx watch server/index.ts",
"dev": "NODE_ENV=development ENVIRONMENT=dev tsx watch server/index.ts",
"db:generate": "drizzle-kit generate",
"db:push": "npx tsx server/db/migrate.ts",
"db:hydrate": "npx tsx scripts/hydrate.ts",

View file

@ -51,7 +51,7 @@ app.prepare().then(() => {
externalServer.use(logIncomingMiddleware);
externalServer.use(prefix, unauthenticated);
externalServer.use(prefix, authenticated);
externalServer.use(`${prefix}/ws`, wsRouter);
// externalServer.use(`${prefix}/ws`, wsRouter);
externalServer.use(notFoundMiddleware);
@ -68,7 +68,7 @@ app.prepare().then(() => {
);
});
handleWSUpgrade(httpServer);
// handleWSUpgrade(httpServer);
externalServer.use(errorHandlerMiddleware);

View file

@ -10,6 +10,7 @@ import {
resourcePassword,
resourcePincode,
resources,
User,
userOrgs,
} from "@server/db/schema";
import { and, eq } from "drizzle-orm";
@ -106,7 +107,7 @@ export async function verifyResourceSession(
const { session, user } = await validateSessionToken(sessionToken);
if (session && user) {
const isAllowed = await isUserAllowedToAccessResource(
user.userId,
user,
resource,
);
@ -191,15 +192,19 @@ function allowed(res: Response) {
}
async function isUserAllowedToAccessResource(
userId: string,
user: User,
resource: Resource,
) {
): Promise<boolean> {
if (config.flags?.require_email_verification && !user.emailVerified) {
return false;
}
const userOrgRole = await db
.select()
.from(userOrgs)
.where(
and(
eq(userOrgs.userId, userId),
eq(userOrgs.userId, user.userId),
eq(userOrgs.orgId, resource.orgId),
),
)
@ -229,7 +234,7 @@ async function isUserAllowedToAccessResource(
.from(userResources)
.where(
and(
eq(userResources.userId, userId),
eq(userResources.userId, user.userId),
eq(userResources.resourceId, resource.resourceId),
),
)

View file

@ -1,3 +1,6 @@
"use client";
import { Button } from "@app/components/ui/button";
import {
Card,
CardContent,
@ -5,8 +8,9 @@ import {
CardHeader,
CardTitle,
} from "@app/components/ui/card";
import Link from "next/link";
export default async function ResourceAccessDenied() {
export default function ResourceAccessDenied() {
return (
<Card className="w-full max-w-md">
<CardHeader>
@ -17,6 +21,11 @@ export default async function ResourceAccessDenied() {
<CardContent>
You're not alowed to access this resource. If this is a mistake,
please contact the administrator.
<div className="text-center mt-4">
<Button>
<Link href="/">Go Home</Link>
</Button>
</div>
</CardContent>
</Card>
);

View file

@ -1,6 +1,6 @@
"use client";
import { useState } from "react";
import { useEffect, useState } from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import * as z from "zod";
@ -23,7 +23,7 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { LockIcon, UserIcon, Binary, Key, User } from "lucide-react";
import { LockIcon, Binary, Key, User } from "lucide-react";
import {
InputOTP,
InputOTPGroup,
@ -34,11 +34,10 @@ import { useRouter } from "next/navigation";
import { Alert, AlertDescription } from "@app/components/ui/alert";
import { formatAxiosError } from "@app/lib/utils";
import { AxiosResponse } from "axios";
import { LoginResponse } from "@server/routers/auth";
import ResourceAccessDenied from "./ResourceAccessDenied";
import LoginForm from "@app/components/LoginForm";
import { AuthWithPasswordResponse } from "@server/routers/resource";
import { redirect } from "next/dist/server/api-utils";
import ResourceAccessDenied from "./ResourceAccessDenied";
const pinSchema = z.object({
pin: z
@ -159,13 +158,15 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
};
async function handleSSOAuth() {
let isAllowed = false;
try {
await api.get(`/resource/${props.resource.id}`);
isAllowed = true;
} catch (e) {
setAccessDenied(true);
}
if (!accessDenied) {
if (isAllowed) {
window.location.href = props.redirect;
}
}
@ -174,6 +175,11 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
<div>
{!accessDenied ? (
<div>
<div className="text-center mb-2">
<span className="text-sm text-muted-foreground">
Powered by Fossorial
</span>
</div>
<Card>
<CardHeader>
<CardTitle>Authentication Required</CardTitle>
@ -365,7 +371,11 @@ export default function ResourceAuthPortal(props: ResourceAuthPortalProps) {
className={`${numMethods <= 1 ? "mt-0" : ""}`}
>
<LoginForm
redirect={window.location.href}
redirect={
typeof window !== "undefined"
? window.location.href
: ""
}
onLogin={async () =>
await handleSSOAuth()
}

View file

@ -1,3 +1,4 @@
import { Button } from "@app/components/ui/button";
import {
Card,
CardContent,
@ -5,6 +6,7 @@ import {
CardHeader,
CardTitle,
} from "@app/components/ui/card";
import Link from "next/link";
export default async function ResourceNotFound() {
return (
@ -15,7 +17,12 @@ export default async function ResourceNotFound() {
</CardTitle>
</CardHeader>
<CardContent>
The resource you're trying to access does not exist
The resource you're trying to access does not exist.
<div className="text-center mt-4">
<Button>
<Link href="/">Go Home</Link>
</Button>
</div>
</CardContent>
</Card>
);

View file

@ -33,7 +33,7 @@ export default async function ResourceAuthPage(props: {
} catch (e) {}
const getUser = cache(verifySession);
const user = await getUser();
const user = await getUser({ skipCheckVerifyEmail: true });
if (!authInfo) {
return (
@ -48,6 +48,16 @@ export default async function ResourceAuthPage(props: {
const redirectUrl = searchParams.redirect || authInfo.url;
if (
user &&
!user.emailVerified &&
process.env.FLAGS_EMAIL_VERIFICATION_REQUIRED === "true"
) {
redirect(
`/auth/verify-email?redirect=/auth/resource/${authInfo.resourceId}`,
);
}
const allCookies = await cookies();
const cookieName =
process.env.RESOURCE_SESSION_COOKIE_NAME + `_${params.resourceId}`;

View file

@ -72,14 +72,11 @@ export default function LoginForm({ redirect, onLogin }: LoginFormProps) {
);
});
console.log(res);
if (res && res.status === 200) {
setError(null);
if (res.data?.data?.emailVerificationRequired) {
if (redirect) {
console.log("here", redirect)
router.push(`/auth/verify-email?redirect=${redirect}`);
} else {
router.push("/auth/verify-email");