"feat: Added debug server and related components for improved development experience"
This commit is contained in:
72
frontend/src/server/auth/index.ts
Normal file
72
frontend/src/server/auth/index.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import type { UserRole } from "@/server/auth/permissions";
|
||||
import { db } from "@/server/db";
|
||||
import { sessions, users } from "@/server/db/schema";
|
||||
import { DrizzleSQLiteAdapter } from "@lucia-auth/adapter-drizzle";
|
||||
import { Lucia, type RegisteredDatabaseUserAttributes, type Session } from "lucia";
|
||||
import { cookies } from "next/headers";
|
||||
import { cache } from "react";
|
||||
|
||||
//@ts-ignore
|
||||
const adapter = new DrizzleSQLiteAdapter(db, sessions, users);
|
||||
|
||||
export const lucia = new Lucia(adapter, {
|
||||
sessionCookie: {
|
||||
expires: false,
|
||||
attributes: {
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
},
|
||||
},
|
||||
getUserAttributes: (attributes) => {
|
||||
return {
|
||||
id: attributes.id,
|
||||
username: attributes.username,
|
||||
displayName: attributes.displayName,
|
||||
email: attributes.email,
|
||||
role: attributes.role,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const validateRequest = cache(
|
||||
async (): Promise<{ user: RegisteredDatabaseUserAttributes; session: Session } | { user: null; session: null }> => {
|
||||
const sessionId = cookies().get(lucia.sessionCookieName)?.value ?? null;
|
||||
if (!sessionId) {
|
||||
return {
|
||||
user: null,
|
||||
session: null,
|
||||
};
|
||||
}
|
||||
|
||||
const result = await lucia.validateSession(sessionId);
|
||||
// next.js throws when you attempt to set cookie when rendering page
|
||||
try {
|
||||
if (result.session?.fresh) {
|
||||
const sessionCookie = lucia.createSessionCookie(result.session.id);
|
||||
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||
}
|
||||
if (!result.session) {
|
||||
const sessionCookie = lucia.createBlankSessionCookie();
|
||||
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||
}
|
||||
} catch {}
|
||||
|
||||
return result as {
|
||||
user: RegisteredDatabaseUserAttributes;
|
||||
session: Session;
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
declare module "lucia" {
|
||||
interface Register {
|
||||
Lucia: typeof Lucia;
|
||||
DatabaseUserAttributes: {
|
||||
id: string;
|
||||
github_id: number;
|
||||
username: string;
|
||||
displayName: string;
|
||||
email: string;
|
||||
role: UserRole;
|
||||
};
|
||||
}
|
||||
}
|
||||
54
frontend/src/server/auth/oauth.ts
Normal file
54
frontend/src/server/auth/oauth.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { GitHub } from "arctic";
|
||||
import { ALLOWED_CALLBACK_HOSTS, FRONTEND_URL, OAUTH_CALLBACK_URL } from "@/utils/api-config";
|
||||
|
||||
// Helper-Funktion, um die passende Callback-URL zu bestimmen
|
||||
const getCallbackUrl = () => {
|
||||
// Wenn eine spezifische OAuth-Callback-URL definiert ist, verwende diese
|
||||
if (process.env.NEXT_PUBLIC_OAUTH_CALLBACK_URL) {
|
||||
console.log("Verwende konfigurierte OAuth Callback URL:", process.env.NEXT_PUBLIC_OAUTH_CALLBACK_URL);
|
||||
return process.env.NEXT_PUBLIC_OAUTH_CALLBACK_URL;
|
||||
}
|
||||
|
||||
// Für spezifischen Unternehmens-Hostname
|
||||
if (FRONTEND_URL.includes('corpintra.net') || FRONTEND_URL.includes('m040tbaraspi001')) {
|
||||
const url = `http://m040tbaraspi001.de040.corpintra.net/auth/login/callback`;
|
||||
console.log("Verwende Unternehmens-Hostname für OAuth Callback:", url);
|
||||
return url;
|
||||
}
|
||||
|
||||
// Fallback für lokale Entwicklung
|
||||
console.log("Verwende Standard OAuth Callback URL:", OAUTH_CALLBACK_URL);
|
||||
return OAUTH_CALLBACK_URL;
|
||||
};
|
||||
|
||||
// Berechne die Callback-URL
|
||||
export const USED_CALLBACK_URL = getCallbackUrl();
|
||||
|
||||
// Erstelle GitHub OAuth-Client mit expliziter Redirect-URI
|
||||
export const github = new GitHub(
|
||||
process.env.OAUTH_CLIENT_ID as string,
|
||||
process.env.OAUTH_CLIENT_SECRET as string,
|
||||
{
|
||||
enterpriseDomain: "https://git.i.mercedes-benz.com",
|
||||
redirectURI: USED_CALLBACK_URL,
|
||||
}
|
||||
);
|
||||
|
||||
// Hilfsfunktion zur Validierung von OAuth-Callbacks
|
||||
export function isValidCallbackHost(url: string): boolean {
|
||||
try {
|
||||
const parsedUrl = new URL(url);
|
||||
return ALLOWED_CALLBACK_HOSTS.some(host => parsedUrl.hostname === host ||
|
||||
parsedUrl.hostname.includes(host));
|
||||
} catch (e) {
|
||||
console.error("Ungültige URL beim Validieren des Callback-Hosts:", url, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export interface GitHubUserResult {
|
||||
id: number;
|
||||
login: string;
|
||||
name: string;
|
||||
email: string;
|
||||
}
|
||||
28
frontend/src/server/auth/permissions.ts
Normal file
28
frontend/src/server/auth/permissions.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { RegisteredDatabaseUserAttributes } from "lucia";
|
||||
|
||||
export enum UserRole {
|
||||
ADMIN = "admin",
|
||||
USER = "user",
|
||||
GUEST = "guest",
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export function hasRole(user: RegisteredDatabaseUserAttributes | null | undefined, role: UserRole) {
|
||||
return user?.role === role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export function translateUserRole(role: UserRole) {
|
||||
switch (role) {
|
||||
case UserRole.ADMIN:
|
||||
return "Administrator";
|
||||
case UserRole.USER:
|
||||
return "Benutzer";
|
||||
case UserRole.GUEST:
|
||||
return "Gast";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user