This commit is contained in:
Théo LAGACHE
2026-02-23 12:04:48 +01:00
parent 5df6dd169a
commit 496be692e7
17 changed files with 4196 additions and 1346 deletions
+654 -512
View File
File diff suppressed because it is too large Load Diff
+70 -57
View File
@@ -1,63 +1,76 @@
import { env } from "@/env.mjs";
import { getOidcProviders } from "./oidc";
export interface AuthProviderConfig {
id: string;
isActive: boolean;
name?: string;
icon: string;
isManual?: boolean;
title?: string;
description?: string;
type: "social" | "sso" | "credential" | "passkey";
id: string;
isActive: boolean;
name?: string;
icon: string;
isManual?: boolean;
title?: string;
description?: string;
type: "social" | "sso" | "credential" | "passkey";
allowLinking?: boolean;
allowUnlinking?: boolean;
}
const oidcProviders = getOidcProviders();
export const SUPPORTED_PROVIDERS: AuthProviderConfig[] = [
{
id: "credential",
isActive: env.AUTH_EMAIL_PASSWORD_ENABLED === "true",
name: "Password",
icon: "lucide:lock",
title: "Password",
description: "Standard email and password login.",
isManual: true,
type: "credential"
},
{
id: "google",
isActive: !!env.AUTH_GOOGLE_ID,
name: "Google",
icon: "logos:google-icon",
title: "Google",
description: "Sign in with your Google account.",
type: "social"
},
{
id: "github",
isActive: !!env.AUTH_GITHUB_ID,
name: "GitHub",
icon: "logos:github-icon",
title: "GitHub",
description: "Sign in with your GitHub account.",
type: "social"
},
{
id: env.AUTH_OIDC_ID || "oidc",
isActive: !!env.AUTH_OIDC_CLIENT,
name: env.AUTH_OIDC_TITLE || "SSO",
icon: env.AUTH_OIDC_ICON || "lucide:building",
title: env.AUTH_OIDC_TITLE || "SSO",
description: env.AUTH_OIDC_DESC || "Sign in with your SSO account.",
isManual: true,
type: "sso"
},
{
id: "passkey",
isActive: env.AUTH_PASSKEY_ENABLED === "true",
name: "Passkey",
icon: "lucide:fingerprint",
title: "Passkey",
description: "Sign in with your passkey.",
isManual: false,
type: "passkey"
}
];
{
id: "credential",
isActive: env.AUTH_EMAIL_PASSWORD_ENABLED === "true",
name: "Password",
icon: "lucide:lock",
title: "Password",
description: "Standard email and password login.",
isManual: true,
type: "credential",
allowLinking: true,
allowUnlinking: true,
},
{
id: "google",
isActive: !!env.AUTH_GOOGLE_ID,
name: "Google",
icon: "logos:google-icon",
title: "Google",
description: "Sign in with your Google account.",
type: "social",
allowLinking: true,
allowUnlinking: true,
},
{
id: "github",
isActive: !!env.AUTH_GITHUB_ID,
name: "GitHub",
icon: "logos:github-icon",
title: "GitHub",
description: "Sign in with your GitHub account.",
type: "social",
allowLinking: true,
allowUnlinking: true,
},
...oidcProviders.map((p) => ({
id: p.id,
isActive: true,
name: p.title,
icon: p.icon,
title: p.title,
description: p.description,
isManual: true,
type: "sso" as const,
allowLinking: p.allowLinking,
allowUnlinking: p.allowUnlinking,
})),
{
id: "passkey",
isActive: env.AUTH_PASSKEY_ENABLED === "true",
name: "Passkey",
icon: "lucide:fingerprint",
title: "Passkey",
description: "Sign in with your passkey.",
isManual: false,
type: "passkey",
},
];
+93
View File
@@ -0,0 +1,93 @@
import { env } from "@/env.mjs";
export interface OIDCProvider {
id: string;
title: string;
description: string;
icon: string;
client: string;
secret: string;
issuerUrl: string;
host: string;
scopes?: string;
discoveryEndpoint?: string;
jwksEndpoint?: string;
pkce: boolean;
allowedGroup?: string;
roleMap?: string;
defaultRole?: string;
allowLinking: boolean;
allowUnlinking: boolean;
}
export function getOidcProviders(): OIDCProvider[] {
const providers: OIDCProvider[] = [];
if (
env.AUTH_OIDC_CLIENT &&
(env.AUTH_OIDC_ISSUER_URL || env.AUTH_OIDC_DISCOVERY_ENDPOINT)
) {
providers.push({
id: env.AUTH_OIDC_ID || "oidc",
title: env.AUTH_OIDC_TITLE || "SSO",
description: env.AUTH_OIDC_DESC || "Sign in with your SSO account.",
icon: env.AUTH_OIDC_ICON || "lucide:building",
client: env.AUTH_OIDC_CLIENT,
secret: env.AUTH_OIDC_SECRET || "",
issuerUrl: env.AUTH_OIDC_ISSUER_URL || "",
host: env.AUTH_OIDC_HOST || "",
scopes: env.AUTH_OIDC_SCOPES,
discoveryEndpoint: env.AUTH_OIDC_DISCOVERY_ENDPOINT,
jwksEndpoint: env.AUTH_OIDC_JWKS_ENDPOINT,
pkce: env.AUTH_OIDC_PKCE === "true",
allowedGroup: env.ALLOWED_GROUP,
roleMap: process.env.AUTH_OIDC_ROLE_MAP,
defaultRole: process.env.AUTH_OIDC_DEFAULT_ROLE,
allowLinking: process.env.AUTH_OIDC_ALLOW_LINKING !== "false",
allowUnlinking: process.env.AUTH_OIDC_ALLOW_UNLINKING !== "false",
});
}
const prefixes = new Set<string>();
Object.keys(process.env).forEach((key) => {
const match = key.match(/^AUTH_OIDC_(.+)_CLIENT$/);
if (match) {
prefixes.add(match[1]);
}
});
prefixes.forEach((prefix) => {
const client = process.env[`AUTH_OIDC_${prefix}_CLIENT`];
const issuer = process.env[`AUTH_OIDC_${prefix}_ISSUER_URL`];
const discovery = process.env[`AUTH_OIDC_${prefix}_DISCOVERY_ENDPOINT`];
if (!client || (!issuer && !discovery)) return;
providers.push({
id: process.env[`AUTH_OIDC_${prefix}_ID`] || prefix.toLowerCase(),
title: process.env[`AUTH_OIDC_${prefix}_TITLE`] || prefix,
description:
process.env[`AUTH_OIDC_${prefix}_DESC`] || `Sign in with ${prefix}`,
icon: process.env[`AUTH_OIDC_${prefix}_ICON`] || "lucide:building",
client: client,
secret: process.env[`AUTH_OIDC_${prefix}_SECRET`] || "",
issuerUrl: issuer || "",
host: process.env[`AUTH_OIDC_${prefix}_HOST`] || "",
scopes: process.env[`AUTH_OIDC_${prefix}_SCOPES`],
discoveryEndpoint: discovery,
jwksEndpoint: process.env[`AUTH_OIDC_${prefix}_JWKS_ENDPOINT`],
pkce: process.env[`AUTH_OIDC_${prefix}_PKCE`] === "true",
allowedGroup:
process.env[`AUTH_OIDC_${prefix}_ALLOWED_GROUP`] ||
process.env.ALLOWED_GROUP,
roleMap: process.env[`AUTH_OIDC_${prefix}_ROLE_MAP`],
defaultRole: process.env[`AUTH_OIDC_${prefix}_DEFAULT_ROLE`],
allowLinking:
process.env[`AUTH_OIDC_${prefix}_ALLOW_LINKING`] !== "false",
allowUnlinking:
process.env[`AUTH_OIDC_${prefix}_ALLOW_UNLINKING`] !== "false",
});
});
return providers;
}