feat: add custom oidc/oauth provider support

This commit is contained in:
moonrailgun 2024-09-19 23:33:22 +08:00
parent 90953e490c
commit d0afdf5c91
4 changed files with 58 additions and 31 deletions

View File

@ -39,31 +39,33 @@ export function useAuth() {
} }
); );
const loginWithOAuth = useEvent(async (provider: BuiltInProviderType) => { const loginWithOAuth = useEvent(
let res: SignInResponse | undefined; async (provider: BuiltInProviderType | 'custom') => {
try { let res: SignInResponse | undefined;
res = await signIn(provider, { try {
redirect: false, res = await signIn(provider, {
}); redirect: false,
console.log('res', res); });
} catch (err) { console.log('res', res);
toast.error(t('Login failed')); } catch (err) {
throw err; toast.error(t('Login failed'));
} throw err;
}
if (res?.error) { if (res?.error) {
toast.error(t('Login failed')); toast.error(t('Login failed'));
throw new Error('Login failed'); throw new Error('Login failed');
} }
const userInfo = await trpcUtils.user.info.fetch(); const userInfo = await trpcUtils.user.info.fetch();
if (!userInfo) { if (!userInfo) {
toast.error(t('Can not get current user info')); toast.error(t('Can not get current user info'));
throw new Error('Login failed, '); throw new Error('Login failed, ');
} }
return userInfo; return userInfo;
}); }
);
const logout = useEvent(async () => { const logout = useEvent(async () => {
await signOut({ await signOut({

View File

@ -8,7 +8,7 @@ import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { useAuth } from '@/api/authjs/useAuth'; import { useAuth } from '@/api/authjs/useAuth';
import { useEventWithLoading } from '@/hooks/useEvent'; import { useEventWithLoading } from '@/hooks/useEvent';
import { LuGithub } from 'react-icons/lu'; import { LuGithub, LuLayers } from 'react-icons/lu';
export const Route = createFileRoute('/login')({ export const Route = createFileRoute('/login')({
validateSearch: z.object({ validateSearch: z.object({
@ -102,14 +102,26 @@ function LoginComponent() {
<> <>
<Divider>{t('Or')}</Divider> <Divider>{t('Or')}</Divider>
<div className="flex justify-center"> <div className="flex justify-center gap-2">
<Button {authProvider.includes('github') && (
variant="secondary" <Button
className="h-12 w-12 p-3" variant="secondary"
onClick={() => loginWithOAuth('github')} className="h-12 w-12 p-3"
> onClick={() => loginWithOAuth('github')}
<LuGithub size={24} /> >
</Button> <LuGithub size={24} />
</Button>
)}
{authProvider.includes('custom') && (
<Button
variant="secondary"
className="h-12 w-12 p-3"
onClick={() => loginWithOAuth('custom')}
>
<LuLayers size={24} />
</Button>
)}
</div> </div>
</> </>
)} )}

View File

@ -89,6 +89,10 @@ export const authConfig: Omit<AuthConfig, 'raw'> = {
name: 'Google', name: 'Google',
...env.auth.google, ...env.auth.google,
}), }),
env.auth.provider.includes('custom') && {
id: 'custom',
...env.auth.custom,
},
]), ]),
adapter: TianjiPrismaAdapter(prisma), adapter: TianjiPrismaAdapter(prisma),
secret: env.auth.secret, secret: env.auth.secret,

View File

@ -18,6 +18,7 @@ export const env = {
!!process.env.EMAIL_SERVER && 'email', !!process.env.EMAIL_SERVER && 'email',
!!process.env.AUTH_GITHUB_ID && 'github', !!process.env.AUTH_GITHUB_ID && 'github',
!!process.env.AUTH_GOOGLE_ID && 'google', !!process.env.AUTH_GOOGLE_ID && 'google',
!!process.env.AUTH_CUSTOM_ID && 'custom',
]), ]),
restrict: { restrict: {
email: process.env.AUTH_RESTRICT_EMAIL, // for example: @example.com email: process.env.AUTH_RESTRICT_EMAIL, // for example: @example.com
@ -35,6 +36,14 @@ export const env = {
clientId: process.env.AUTH_GOOGLE_ID, clientId: process.env.AUTH_GOOGLE_ID,
clientSecret: process.env.AUTH_GOOGLE_SECRET, 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), allowRegister: checkEnvTrusty(process.env.ALLOW_REGISTER),
allowOpenapi: checkEnvTrusty(process.env.ALLOW_OPENAPI ?? 'true'), allowOpenapi: checkEnvTrusty(process.env.ALLOW_OPENAPI ?? 'true'),