mirror of
https://github.com/fosrl/pangolin.git
synced 2025-07-28 14:44:55 +02:00
fix rendering issues on resource unauthorized
This commit is contained in:
parent
5bbf32f6a6
commit
500a81aa42
8 changed files with 58 additions and 20 deletions
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
)
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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}`;
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue