From d0afdf5c91d2112d177ab7bb0315586cb64ad8d7 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Thu, 19 Sep 2024 23:33:22 +0800 Subject: [PATCH] feat: add custom oidc/oauth provider support --- src/client/api/authjs/useAuth.ts | 46 +++++++++++++++++--------------- src/client/routes/login.tsx | 30 ++++++++++++++------- src/server/model/auth.ts | 4 +++ src/server/utils/env.ts | 9 +++++++ 4 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/client/api/authjs/useAuth.ts b/src/client/api/authjs/useAuth.ts index 083489b..bcebeab 100644 --- a/src/client/api/authjs/useAuth.ts +++ b/src/client/api/authjs/useAuth.ts @@ -39,31 +39,33 @@ export function useAuth() { } ); - const loginWithOAuth = useEvent(async (provider: BuiltInProviderType) => { - let res: SignInResponse | undefined; - try { - res = await signIn(provider, { - redirect: false, - }); - console.log('res', res); - } catch (err) { - toast.error(t('Login failed')); - throw err; - } + const loginWithOAuth = useEvent( + async (provider: BuiltInProviderType | 'custom') => { + let res: SignInResponse | undefined; + try { + res = await signIn(provider, { + redirect: false, + }); + console.log('res', res); + } catch (err) { + toast.error(t('Login failed')); + throw err; + } - if (res?.error) { - toast.error(t('Login failed')); - throw new Error('Login failed'); - } + if (res?.error) { + toast.error(t('Login failed')); + throw new Error('Login failed'); + } - const userInfo = await trpcUtils.user.info.fetch(); - if (!userInfo) { - toast.error(t('Can not get current user info')); - throw new Error('Login failed, '); - } + const userInfo = await trpcUtils.user.info.fetch(); + if (!userInfo) { + toast.error(t('Can not get current user info')); + throw new Error('Login failed, '); + } - return userInfo; - }); + return userInfo; + } + ); const logout = useEvent(async () => { await signOut({ diff --git a/src/client/routes/login.tsx b/src/client/routes/login.tsx index 327d0f7..a616812 100644 --- a/src/client/routes/login.tsx +++ b/src/client/routes/login.tsx @@ -8,7 +8,7 @@ import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { useAuth } from '@/api/authjs/useAuth'; import { useEventWithLoading } from '@/hooks/useEvent'; -import { LuGithub } from 'react-icons/lu'; +import { LuGithub, LuLayers } from 'react-icons/lu'; export const Route = createFileRoute('/login')({ validateSearch: z.object({ @@ -102,14 +102,26 @@ function LoginComponent() { <> {t('Or')} -
- +
+ {authProvider.includes('github') && ( + + )} + + {authProvider.includes('custom') && ( + + )}
)} diff --git a/src/server/model/auth.ts b/src/server/model/auth.ts index 23e26dd..21c42eb 100644 --- a/src/server/model/auth.ts +++ b/src/server/model/auth.ts @@ -89,6 +89,10 @@ export const authConfig: Omit = { name: 'Google', ...env.auth.google, }), + env.auth.provider.includes('custom') && { + id: 'custom', + ...env.auth.custom, + }, ]), adapter: TianjiPrismaAdapter(prisma), secret: env.auth.secret, diff --git a/src/server/utils/env.ts b/src/server/utils/env.ts index 6fbd23b..e5fc08f 100644 --- a/src/server/utils/env.ts +++ b/src/server/utils/env.ts @@ -18,6 +18,7 @@ export const env = { !!process.env.EMAIL_SERVER && 'email', !!process.env.AUTH_GITHUB_ID && 'github', !!process.env.AUTH_GOOGLE_ID && 'google', + !!process.env.AUTH_CUSTOM_ID && 'custom', ]), restrict: { email: process.env.AUTH_RESTRICT_EMAIL, // for example: @example.com @@ -35,6 +36,14 @@ export const env = { clientId: process.env.AUTH_GOOGLE_ID, clientSecret: process.env.AUTH_GOOGLE_SECRET, }, + custom: { + // Reference: https://authjs.dev/guides/configuring-oauth-providers + name: process.env.AUTH_CUSTOM_NAME || 'Custom', + type: process.env.AUTH_CUSTOM_TYPE || 'oidc', // or oauth + issuer: process.env.AUTH_CUSTOM_ISSUR, + clientId: process.env.AUTH_CUSTOM_ID, + clientSecret: process.env.AUTH_CUSTOM_SECRET, + }, }, allowRegister: checkEnvTrusty(process.env.ALLOW_REGISTER), allowOpenapi: checkEnvTrusty(process.env.ALLOW_OPENAPI ?? 'true'),