Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66d1fa427f | ||
|
|
bee396a433 | ||
|
|
8727a52931 | ||
|
|
ed5c076a5a | ||
|
|
db5c575ae0 | ||
|
|
2a0f482578 | ||
|
|
c041cf371a | ||
|
|
c6daf09cd2 | ||
|
|
7296e2e012 | ||
|
|
43bf176ef7 |
@@ -67,6 +67,10 @@ OTEL_SERVICE_NAME="langfuse"
|
||||
# AUTH_GITHUB_CLIENT_ID=
|
||||
# AUTH_GITHUB_CLIENT_SECRET=
|
||||
# AUTH_GITHUB_ALLOW_ACCOUNT_LINKING=false
|
||||
# AUTH_GITHUB_ENTERPRISE_CLIENT_ID=
|
||||
# AUTH_GITHUB_ENTERPRISE_CLIENT_SECRET=
|
||||
# AUTH_GITHUB_ENTERPRISE_BASE_URL=
|
||||
# AUTH_GITHUB_ENTERPRISE_ALLOW_ACCOUNT_LINKING=false
|
||||
# AUTH_GITLAB_CLIENT_ID=
|
||||
# AUTH_GITLAB_CLIENT_SECRET=
|
||||
# AUTH_GITLAB_ALLOW_ACCOUNT_LINKING=false
|
||||
@@ -87,6 +91,10 @@ OTEL_SERVICE_NAME="langfuse"
|
||||
# AUTH_COGNITO_CLIENT_SECRET=
|
||||
# AUTH_COGNITO_ISSUER=
|
||||
# AUTH_COGNITO_ALLOW_ACCOUNT_LINKING=false
|
||||
# AUTH_KEYCLOAK_CLIENT_ID=
|
||||
# AUTH_KEYCLOAK_CLIENT_SECRET=
|
||||
# AUTH_KEYCLOAK_ISSUER=
|
||||
# AUTH_KEYCLOAK_ALLOW_ACCOUNT_LINKING=false
|
||||
# AUTH_CUSTOM_CLIENT_ID=
|
||||
# AUTH_CUSTOM_CLIENT_SECRET=
|
||||
# AUTH_CUSTOM_ISSUER=
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "langfuse",
|
||||
"version": "2.92.0",
|
||||
"version": "2.93.3",
|
||||
"author": "engineering@langfuse.com",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import type { OAuthConfig, OAuthUserConfig } from "next-auth/providers/oauth";
|
||||
import type { GithubProfile, GithubEmail } from "next-auth/providers/github";
|
||||
|
||||
export function GitHubEnterpriseProvider<P extends GithubProfile>(
|
||||
options: OAuthUserConfig<P> & {
|
||||
enterprise?: {
|
||||
baseUrl?: string;
|
||||
};
|
||||
}
|
||||
): OAuthConfig<P> {
|
||||
const baseUrl = options?.enterprise?.baseUrl ?? "https://github.com"
|
||||
const apiBaseUrl = options?.enterprise?.baseUrl
|
||||
? `${options?.enterprise?.baseUrl}/api/v3`
|
||||
: "https://api.github.com"
|
||||
|
||||
return {
|
||||
id: "github-enterprise",
|
||||
name: "GitHub Enterprise",
|
||||
type: "oauth",
|
||||
authorization: {
|
||||
url: `${baseUrl}/login/oauth/authorize`,
|
||||
params: { scope: "read:user user:email" },
|
||||
},
|
||||
token: `${baseUrl}/login/oauth/access_token`,
|
||||
userinfo: {
|
||||
url: `${apiBaseUrl}/user`,
|
||||
async request({ client, tokens }) {
|
||||
const profile = await client.userinfo(tokens.access_token!)
|
||||
|
||||
if (!profile.email) {
|
||||
// If the user does not have a public email, get another via the GitHub API
|
||||
// See https://docs.github.com/en/rest/users/emails#list-email-addresses-for-the-authenticated-user
|
||||
const res = await fetch(`${apiBaseUrl}/user/emails`, {
|
||||
headers: { Authorization: `token ${tokens.access_token}` },
|
||||
})
|
||||
|
||||
if (res.ok) {
|
||||
const emails: GithubEmail[] = await res.json()
|
||||
profile.email = (emails.find((e) => e.primary) ?? emails[0]).email
|
||||
}
|
||||
}
|
||||
|
||||
return profile
|
||||
},
|
||||
},
|
||||
profile(profile) {
|
||||
return {
|
||||
id: profile.id.toString(),
|
||||
name: profile.name ?? profile.login,
|
||||
email: profile.email,
|
||||
image: profile.avatar_url,
|
||||
}
|
||||
},
|
||||
style: {
|
||||
logo: "https://raw.githubusercontent.com/nextauthjs/next-auth/main/packages/next-auth/provider-logos/github.svg",
|
||||
logoDark:
|
||||
"https://raw.githubusercontent.com/nextauthjs/next-auth/main/packages/next-auth/provider-logos/github-dark.svg",
|
||||
bg: "#fff",
|
||||
bgDark: "#000",
|
||||
text: "#000",
|
||||
textDark: "#fff",
|
||||
},
|
||||
options,
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ export * from "./services/PromptService";
|
||||
export * from "./services/traces-ui-table-service";
|
||||
export * from "./auth/apiKeys";
|
||||
export * from "./auth/customSsoProvider";
|
||||
export * from "./auth/gitHubEnterpriseProvider";
|
||||
export * from "./llm/fetchLLMCompletion";
|
||||
export * from "./llm/types";
|
||||
export * from "./utils/DatabaseReadStream";
|
||||
|
||||
+28
-16
@@ -97,6 +97,7 @@ const nextConfig = {
|
||||
...(env.SENTRY_CSP_REPORT_URI ? [reportToHeader] : []),
|
||||
],
|
||||
},
|
||||
// CSP header
|
||||
{
|
||||
source: "/:path((?!api).*)*",
|
||||
headers: [
|
||||
@@ -105,26 +106,37 @@ const nextConfig = {
|
||||
value: cspHeader.replace(/\n/g, ""),
|
||||
},
|
||||
],
|
||||
// Disable CSP on Hugging Face to allow for embedded use of Langfuse
|
||||
missing: [
|
||||
{
|
||||
type: "host",
|
||||
value: "huggingface.co",
|
||||
},
|
||||
{
|
||||
type: "host",
|
||||
value: ".*\\.hf\\.space$", // *.hf.space
|
||||
},
|
||||
],
|
||||
},
|
||||
// Required to check authentication status from langfuse.com
|
||||
...(env.NEXT_PUBLIC_LANGFUSE_CLOUD_REGION !== undefined
|
||||
? [
|
||||
{
|
||||
source: "/api/auth/session",
|
||||
headers: [
|
||||
{
|
||||
key: "Access-Control-Allow-Origin",
|
||||
value: "https://langfuse.com",
|
||||
},
|
||||
{ key: "Access-Control-Allow-Credentials", value: "true" },
|
||||
{ key: "Access-Control-Allow-Methods", value: "GET,POST" },
|
||||
{
|
||||
key: "Access-Control-Allow-Headers",
|
||||
value: "Content-Type, Authorization",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
{
|
||||
source: "/api/auth/session",
|
||||
headers: [
|
||||
{
|
||||
key: "Access-Control-Allow-Origin",
|
||||
value: "https://langfuse.com",
|
||||
},
|
||||
{ key: "Access-Control-Allow-Credentials", value: "true" },
|
||||
{ key: "Access-Control-Allow-Methods", value: "GET,POST" },
|
||||
{
|
||||
key: "Access-Control-Allow-Headers",
|
||||
value: "Content-Type, Authorization",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
// all files in /public/generated are public and can be accessed from any origin, e.g. to render an API reference based on our openapi schema
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "web",
|
||||
"version": "2.92.0",
|
||||
"version": "2.93.3",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const VERSION = "v2.92.0";
|
||||
export const VERSION = "v2.93.3";
|
||||
|
||||
@@ -28,6 +28,20 @@ export const GithubProviderSchema = base.extend({
|
||||
.nullish(),
|
||||
});
|
||||
|
||||
export const GithubEnterpriseProviderSchema = base.extend({
|
||||
authProvider: z.literal("github-enterprise"),
|
||||
authConfig: z
|
||||
.object({
|
||||
clientId: z.string(),
|
||||
clientSecret: z.string(),
|
||||
enterprise: z.object({
|
||||
baseUrl: z.string().url(),
|
||||
}),
|
||||
allowDangerousEmailAccountLinking: z.boolean().optional().default(false),
|
||||
})
|
||||
.nullish(),
|
||||
});
|
||||
|
||||
export const GitlabProviderSchema = base.extend({
|
||||
authProvider: z.literal("gitlab"),
|
||||
authConfig: z
|
||||
@@ -88,6 +102,18 @@ export const CognitoProviderSchema = base.extend({
|
||||
.nullish(),
|
||||
});
|
||||
|
||||
export const KeycloakProviderSchema = base.extend({
|
||||
authProvider: z.literal("keycloak"),
|
||||
authConfig: z
|
||||
.object({
|
||||
clientId: z.string(),
|
||||
clientSecret: z.string(),
|
||||
issuer: z.string(),
|
||||
allowDangerousEmailAccountLinking: z.boolean().optional().default(false),
|
||||
})
|
||||
.nullish(),
|
||||
});
|
||||
|
||||
export const CustomProviderSchema = base.extend({
|
||||
authProvider: z.literal("custom"),
|
||||
authConfig: z
|
||||
@@ -104,21 +130,25 @@ export const CustomProviderSchema = base.extend({
|
||||
|
||||
export type GoogleProviderSchema = z.infer<typeof GoogleProviderSchema>;
|
||||
export type GithubProviderSchema = z.infer<typeof GithubProviderSchema>;
|
||||
export type GithubEnterpriseProviderSchema = z.infer<typeof GithubEnterpriseProviderSchema>;
|
||||
export type GitlabProviderSchema = z.infer<typeof GitlabProviderSchema>;
|
||||
export type Auth0ProviderSchema = z.infer<typeof Auth0ProviderSchema>;
|
||||
export type OktaProviderSchema = z.infer<typeof OktaProviderSchema>;
|
||||
export type AzureAdProviderSchema = z.infer<typeof AzureAdProviderSchema>;
|
||||
export type CognitoProviderSchema = z.infer<typeof CognitoProviderSchema>;
|
||||
export type KeycloakProviderSchema = z.infer<typeof KeycloakProviderSchema>;
|
||||
export type CustomProviderSchema = z.infer<typeof CustomProviderSchema>;
|
||||
|
||||
export const SsoProviderSchema = z.discriminatedUnion("authProvider", [
|
||||
GoogleProviderSchema,
|
||||
GithubProviderSchema,
|
||||
GithubEnterpriseProviderSchema,
|
||||
GitlabProviderSchema,
|
||||
Auth0ProviderSchema,
|
||||
OktaProviderSchema,
|
||||
AzureAdProviderSchema,
|
||||
CognitoProviderSchema,
|
||||
KeycloakProviderSchema,
|
||||
CustomProviderSchema,
|
||||
]);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import GitHubProvider from "next-auth/providers/github";
|
||||
import GitLabProvider from "next-auth/providers/gitlab";
|
||||
import OktaProvider from "next-auth/providers/okta";
|
||||
import CognitoProvider from "next-auth/providers/cognito";
|
||||
import KeycloakProvider from "next-auth/providers/keycloak";
|
||||
import Auth0Provider from "next-auth/providers/auth0";
|
||||
import AzureADProvider from "next-auth/providers/azure-ad";
|
||||
import { isEeEnabled } from "@/src/ee/utils/isEeEnabled";
|
||||
@@ -12,6 +13,7 @@ import { decrypt } from "@langfuse/shared/encryption";
|
||||
import { SsoProviderSchema } from "./types";
|
||||
import {
|
||||
CustomSSOProvider,
|
||||
GitHubEnterpriseProvider,
|
||||
logger,
|
||||
traceException,
|
||||
} from "@langfuse/shared/src/server";
|
||||
@@ -188,6 +190,12 @@ const dbToNextAuthProvider = (provider: SsoProviderSchema): Provider | null => {
|
||||
...provider.authConfig,
|
||||
clientSecret: decrypt(provider.authConfig.clientSecret),
|
||||
});
|
||||
else if (provider.authProvider === "keycloak")
|
||||
return KeycloakProvider({
|
||||
id: getAuthProviderIdForSsoConfig(provider), // use the domain as the provider id as we use domain-specific credentials
|
||||
...provider.authConfig,
|
||||
clientSecret: decrypt(provider.authConfig.clientSecret),
|
||||
});
|
||||
else if (provider.authProvider === "custom")
|
||||
return CustomSSOProvider({
|
||||
id: getAuthProviderIdForSsoConfig(provider), // use the domain as the provider id as we use domain-specific credentials
|
||||
@@ -197,6 +205,15 @@ const dbToNextAuthProvider = (provider: SsoProviderSchema): Provider | null => {
|
||||
params: { scope: provider.authConfig.scope ?? "openid email profile" },
|
||||
},
|
||||
});
|
||||
else if (provider.authProvider === "github-enterprise")
|
||||
return GitHubEnterpriseProvider({
|
||||
id: getAuthProviderIdForSsoConfig(provider), // use the domain as the provider id as we use domain-specific credentials
|
||||
...provider.authConfig,
|
||||
clientSecret: decrypt(provider.authConfig.clientSecret),
|
||||
enterprise: {
|
||||
baseUrl: provider.authConfig.enterprise.baseUrl,
|
||||
},
|
||||
});
|
||||
else {
|
||||
// Type check to ensure we handle all providers
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
||||
+19
-1
@@ -46,7 +46,7 @@ export const env = createEnv({
|
||||
LANGFUSE_DEFAULT_PROJECT_ROLE: z
|
||||
.enum(["OWNER", "ADMIN", "MEMBER", "VIEWER"])
|
||||
.optional(),
|
||||
LANGFUSE_CSP_ENFORCE_HTTPS: z.enum(["true", "false"]).optional(),
|
||||
LANGFUSE_CSP_ENFORCE_HTTPS: z.enum(["true", "false"]).optional().default("false"),
|
||||
// Telemetry
|
||||
TELEMETRY_ENABLED: z.enum(["true", "false"]).optional(),
|
||||
// AUTH
|
||||
@@ -57,6 +57,10 @@ export const env = createEnv({
|
||||
AUTH_GITHUB_CLIENT_ID: z.string().optional(),
|
||||
AUTH_GITHUB_CLIENT_SECRET: z.string().optional(),
|
||||
AUTH_GITHUB_ALLOW_ACCOUNT_LINKING: z.enum(["true", "false"]).optional(),
|
||||
AUTH_GITHUB_ENTERPRISE_CLIENT_ID: z.string().optional(),
|
||||
AUTH_GITHUB_ENTERPRISE_CLIENT_SECRET: z.string().optional(),
|
||||
AUTH_GITHUB_ENTERPRISE_BASE_URL: z.string().optional(),
|
||||
AUTH_GITHUB_ENTERPRISE_ALLOW_ACCOUNT_LINKING: z.enum(["true", "false"]).optional(),
|
||||
AUTH_GITLAB_CLIENT_ID: z.string().optional(),
|
||||
AUTH_GITLAB_CLIENT_SECRET: z.string().optional(),
|
||||
AUTH_GITLAB_ALLOW_ACCOUNT_LINKING: z.enum(["true", "false"]).optional(),
|
||||
@@ -77,6 +81,10 @@ export const env = createEnv({
|
||||
AUTH_COGNITO_CLIENT_SECRET: z.string().optional(),
|
||||
AUTH_COGNITO_ISSUER: z.string().url().optional(),
|
||||
AUTH_COGNITO_ALLOW_ACCOUNT_LINKING: z.enum(["true", "false"]).optional(),
|
||||
AUTH_KEYCLOAK_CLIENT_ID: z.string().optional(),
|
||||
AUTH_KEYCLOAK_CLIENT_SECRET: z.string().optional(),
|
||||
AUTH_KEYCLOAK_ISSUER: z.string().optional(),
|
||||
AUTH_KEYCLOAK_ALLOW_ACCOUNT_LINKING: z.enum(["true", "false"]).optional(),
|
||||
AUTH_CUSTOM_CLIENT_ID: z.string().optional(),
|
||||
AUTH_CUSTOM_CLIENT_SECRET: z.string().optional(),
|
||||
AUTH_CUSTOM_ISSUER: z.string().url().optional(),
|
||||
@@ -291,6 +299,11 @@ export const env = createEnv({
|
||||
AUTH_GITHUB_CLIENT_SECRET: process.env.AUTH_GITHUB_CLIENT_SECRET,
|
||||
AUTH_GITHUB_ALLOW_ACCOUNT_LINKING:
|
||||
process.env.AUTH_GITHUB_ALLOW_ACCOUNT_LINKING,
|
||||
AUTH_GITHUB_ENTERPRISE_CLIENT_ID: process.env.AUTH_GITHUB_ENTERPRISE_CLIENT_ID,
|
||||
AUTH_GITHUB_ENTERPRISE_CLIENT_SECRET: process.env.AUTH_GITHUB_ENTERPRISE_CLIENT_SECRET,
|
||||
AUTH_GITHUB_ENTERPRISE_BASE_URL: process.env.AUTH_GITHUB_ENTERPRISE_BASE_URL,
|
||||
AUTH_GITHUB_ENTERPRISE_ALLOW_ACCOUNT_LINKING:
|
||||
process.env.AUTH_GITHUB_ENTERPRISE_ALLOW_ACCOUNT_LINKING,
|
||||
AUTH_GITLAB_ISSUER: process.env.AUTH_GITLAB_ISSUER,
|
||||
AUTH_GITLAB_CLIENT_ID: process.env.AUTH_GITLAB_CLIENT_ID,
|
||||
AUTH_GITLAB_CLIENT_SECRET: process.env.AUTH_GITLAB_CLIENT_SECRET,
|
||||
@@ -316,6 +329,11 @@ export const env = createEnv({
|
||||
AUTH_COGNITO_ISSUER: process.env.AUTH_COGNITO_ISSUER,
|
||||
AUTH_COGNITO_ALLOW_ACCOUNT_LINKING:
|
||||
process.env.AUTH_COGNITO_ALLOW_ACCOUNT_LINKING,
|
||||
AUTH_KEYCLOAK_CLIENT_ID: process.env.AUTH_KEYCLOAK_CLIENT_ID,
|
||||
AUTH_KEYCLOAK_CLIENT_SECRET: process.env.AUTH_KEYCLOAK_CLIENT_SECRET,
|
||||
AUTH_KEYCLOAK_ISSUER: process.env.AUTH_KEYCLOAK_ISSUER,
|
||||
AUTH_KEYCLOAK_ALLOW_ACCOUNT_LINKING:
|
||||
process.env.AUTH_KEYCLOAK_ALLOW_ACCOUNT_LINKING,
|
||||
AUTH_CUSTOM_CLIENT_ID: process.env.AUTH_CUSTOM_CLIENT_ID,
|
||||
AUTH_CUSTOM_CLIENT_SECRET: process.env.AUTH_CUSTOM_CLIENT_SECRET,
|
||||
AUTH_CUSTOM_ISSUER: process.env.AUTH_CUSTOM_ISSUER,
|
||||
|
||||
@@ -14,7 +14,7 @@ import { env } from "@/src/env.mjs";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { FcGoogle } from "react-icons/fc";
|
||||
import { FaGithub, FaGitlab } from "react-icons/fa";
|
||||
import { SiOkta, SiAuth0, SiAmazoncognito } from "react-icons/si";
|
||||
import { SiOkta, SiAuth0, SiAmazoncognito, SiKeycloak } from "react-icons/si";
|
||||
import { TbBrandAzure, TbBrandOauth } from "react-icons/tb";
|
||||
import { signIn } from "next-auth/react";
|
||||
import Head from "next/head";
|
||||
@@ -46,11 +46,13 @@ export type PageProps = {
|
||||
credentials: boolean;
|
||||
google: boolean;
|
||||
github: boolean;
|
||||
githubEnterprise: boolean;
|
||||
gitlab: boolean;
|
||||
okta: boolean;
|
||||
azureAd: boolean;
|
||||
auth0: boolean;
|
||||
cognito: boolean;
|
||||
keycloak: boolean;
|
||||
custom:
|
||||
| {
|
||||
name: string;
|
||||
@@ -74,6 +76,10 @@ export const getServerSideProps: GetServerSideProps<PageProps> = async () => {
|
||||
github:
|
||||
env.AUTH_GITHUB_CLIENT_ID !== undefined &&
|
||||
env.AUTH_GITHUB_CLIENT_SECRET !== undefined,
|
||||
githubEnterprise:
|
||||
env.AUTH_GITHUB_ENTERPRISE_CLIENT_ID !== undefined &&
|
||||
env.AUTH_GITHUB_ENTERPRISE_CLIENT_SECRET !== undefined &&
|
||||
env.AUTH_GITHUB_ENTERPRISE_BASE_URL !== undefined,
|
||||
gitlab:
|
||||
env.AUTH_GITLAB_CLIENT_ID !== undefined &&
|
||||
env.AUTH_GITLAB_CLIENT_SECRET !== undefined,
|
||||
@@ -94,6 +100,10 @@ export const getServerSideProps: GetServerSideProps<PageProps> = async () => {
|
||||
env.AUTH_COGNITO_CLIENT_ID !== undefined &&
|
||||
env.AUTH_COGNITO_CLIENT_SECRET !== undefined &&
|
||||
env.AUTH_COGNITO_ISSUER !== undefined,
|
||||
keycloak:
|
||||
env.AUTH_KEYCLOAK_CLIENT_ID !== undefined &&
|
||||
env.AUTH_KEYCLOAK_CLIENT_SECRET !== undefined &&
|
||||
env.AUTH_KEYCLOAK_ISSUER !== undefined,
|
||||
custom:
|
||||
env.AUTH_CUSTOM_CLIENT_ID !== undefined &&
|
||||
env.AUTH_CUSTOM_CLIENT_SECRET !== undefined &&
|
||||
@@ -165,6 +175,16 @@ export function SSOButtons({
|
||||
Github
|
||||
</Button>
|
||||
)}
|
||||
{authProviders.githubEnterprise && (
|
||||
<Button
|
||||
onClick={() => handleSignIn("github-enterprise")}
|
||||
variant="secondary"
|
||||
loading={providerSigningIn === "github-enterprise"}
|
||||
>
|
||||
<FaGithub className="mr-3" size={18} />
|
||||
Github Enterprise
|
||||
</Button>
|
||||
)}
|
||||
{authProviders.gitlab && (
|
||||
<Button
|
||||
onClick={() => handleSignIn("gitlab")}
|
||||
@@ -215,6 +235,18 @@ export function SSOButtons({
|
||||
Cognito
|
||||
</Button>
|
||||
)}
|
||||
{authProviders.keycloak && (
|
||||
<Button
|
||||
onClick={() => {
|
||||
capture("sign_in:button_click", { provider: "keycloak" });
|
||||
void signIn("keycloak");
|
||||
}}
|
||||
variant="secondary"
|
||||
>
|
||||
<SiKeycloak className="mr-3" size={18} />
|
||||
Keycloak
|
||||
</Button>
|
||||
)}
|
||||
{authProviders.custom && (
|
||||
<Button
|
||||
onClick={() => handleSignIn("custom")}
|
||||
|
||||
@@ -23,6 +23,7 @@ import EmailProvider from "next-auth/providers/email";
|
||||
import Auth0Provider from "next-auth/providers/auth0";
|
||||
import CognitoProvider from "next-auth/providers/cognito";
|
||||
import AzureADProvider from "next-auth/providers/azure-ad";
|
||||
import KeycloakProvider from "next-auth/providers/keycloak";
|
||||
import { type Provider } from "next-auth/providers/index";
|
||||
import { getCookieName, getCookieOptions } from "./utils/cookies";
|
||||
import {
|
||||
@@ -33,6 +34,7 @@ import { z } from "zod";
|
||||
import { CloudConfigSchema } from "@langfuse/shared";
|
||||
import {
|
||||
CustomSSOProvider,
|
||||
GitHubEnterpriseProvider,
|
||||
traceException,
|
||||
sendResetPasswordVerificationRequest,
|
||||
instrumentAsync,
|
||||
@@ -227,6 +229,22 @@ if (env.AUTH_GITHUB_CLIENT_ID && env.AUTH_GITHUB_CLIENT_SECRET)
|
||||
}),
|
||||
);
|
||||
|
||||
if (
|
||||
env.AUTH_GITHUB_ENTERPRISE_CLIENT_ID &&
|
||||
env.AUTH_GITHUB_ENTERPRISE_CLIENT_SECRET &&
|
||||
env.AUTH_GITHUB_ENTERPRISE_BASE_URL
|
||||
) {
|
||||
staticProviders.push(
|
||||
GitHubEnterpriseProvider({
|
||||
clientId: env.AUTH_GITHUB_ENTERPRISE_CLIENT_ID,
|
||||
clientSecret: env.AUTH_GITHUB_ENTERPRISE_CLIENT_SECRET,
|
||||
enterprise: { baseUrl: env.AUTH_GITHUB_ENTERPRISE_BASE_URL },
|
||||
allowDangerousEmailAccountLinking:
|
||||
env.AUTH_GITHUB_ENTERPRISE_ALLOW_ACCOUNT_LINKING === "true",
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (env.AUTH_GITLAB_CLIENT_ID && env.AUTH_GITLAB_CLIENT_SECRET)
|
||||
staticProviders.push(
|
||||
GitLabProvider({
|
||||
@@ -263,11 +281,27 @@ if (
|
||||
clientId: env.AUTH_COGNITO_CLIENT_ID,
|
||||
clientSecret: env.AUTH_COGNITO_CLIENT_SECRET,
|
||||
issuer: env.AUTH_COGNITO_ISSUER,
|
||||
checks: "nonce",
|
||||
allowDangerousEmailAccountLinking:
|
||||
env.AUTH_COGNITO_ALLOW_ACCOUNT_LINKING === "true",
|
||||
}),
|
||||
);
|
||||
|
||||
if (
|
||||
env.AUTH_KEYCLOAK_CLIENT_ID &&
|
||||
env.AUTH_KEYCLOAK_CLIENT_SECRET &&
|
||||
env.AUTH_KEYCLOAK_ISSUER
|
||||
)
|
||||
staticProviders.push(
|
||||
KeycloakProvider({
|
||||
clientId: env.AUTH_KEYCLOAK_CLIENT_ID,
|
||||
clientSecret: env.AUTH_KEYCLOAK_CLIENT_SECRET,
|
||||
issuer: env.AUTH_KEYCLOAK_ISSUER,
|
||||
allowDangerousEmailAccountLinking:
|
||||
env.AUTH_KEYCLOAK_ALLOW_ACCOUNT_LINKING === "true",
|
||||
}),
|
||||
);
|
||||
|
||||
// Extend Prisma Adapter
|
||||
const prismaAdapter = PrismaAdapter(prisma);
|
||||
const extendedPrismaAdapter: Adapter = {
|
||||
@@ -294,6 +328,22 @@ const extendedPrismaAdapter: Adapter = {
|
||||
|
||||
return user;
|
||||
},
|
||||
|
||||
async linkAccount(data) {
|
||||
if (!prismaAdapter.linkAccount)
|
||||
throw new Error("NextAuth: prismaAdapter.linkAccount not implemented");
|
||||
|
||||
// Keycloak returns incompatible data with the nextjs-auth schema
|
||||
// (refresh_expires_in and not-before-policy in).
|
||||
// So, we need to remove this data from the payload before linking an account.
|
||||
// https://github.com/nextauthjs/next-auth/issues/7655
|
||||
if (data.provider === "keycloak") {
|
||||
delete data["refresh_expires_in"];
|
||||
delete data["not-before-policy"];
|
||||
}
|
||||
|
||||
await prismaAdapter.linkAccount(data);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "worker",
|
||||
"version": "2.92.0",
|
||||
"version": "2.93.3",
|
||||
"description": "",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const VERSION = "v2.92.0";
|
||||
export const VERSION = "v2.93.3";
|
||||
|
||||
Reference in New Issue
Block a user