feat: added oidc auth plugin for better auth (#147)

* feat: added oidc auth plugin for better auth

* chore: remove unused code

* chore: revert change to pnpm workspace file

* chore: remove unused code

* chore: remove unused code

* chore: remove unused code

* chore: added requested changes
This commit is contained in:
Jyotirmoy Bandyopadhayaya
2025-08-18 17:13:35 +05:30
committed by GitHub
parent c7f7531b11
commit ba2fd7f695
9 changed files with 154 additions and 54 deletions

View File

@@ -4,7 +4,7 @@ import { t } from "@lingui/core/macro";
import { Trans } from "@lingui/react/macro";
import { useQuery } from "@tanstack/react-query";
import { env } from "next-runtime-env";
import { useState } from "react";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import {
FaApple,
@@ -16,6 +16,7 @@ import {
FaGoogle,
FaLinkedin,
FaMicrosoft,
FaOpenid,
FaReddit,
FaSpotify,
FaTiktok,
@@ -33,6 +34,8 @@ import Button from "~/components/Button";
import Input from "~/components/Input";
import { usePopup } from "~/providers/popup";
type AuthProvider = SocialProvider | "oidc";
interface FormValues {
name?: string;
email: string;
@@ -141,16 +144,28 @@ const availableSocialProviders = {
name: "Zoom",
icon: SiZoom,
},
oidc: {
id: "oidc",
name: "OIDC",
icon: FaOpenid,
},
};
export function Auth({ setIsMagicLinkSent, isSignUp }: AuthProps) {
const [isLoginWithProviderPending, setIsLoginWithProviderPending] =
useState<null | SocialProvider>(null);
const isCredentialsEnabled =
env("NEXT_PUBLIC_ALLOW_CREDENTIALS")?.toLowerCase() === "true";
useState<null | AuthProvider>(null);
const [isCredentialsEnabled, setIsCredentialsEnabled] = useState(false);
const [isLoginWithEmailPending, setIsLoginWithEmailPending] = useState(false);
const [loginError, setLoginError] = useState<string | null>(null);
const { showPopup } = usePopup();
const oidcProviderName = "OIDC";
// Safely get environment variables on client side to avoid hydration mismatch
useEffect(() => {
const credentialsAllowed =
env("NEXT_PUBLIC_ALLOW_CREDENTIALS")?.toLowerCase() === "true";
setIsCredentialsEnabled(credentialsAllowed);
}, []);
const {
register,
@@ -226,13 +241,26 @@ export function Auth({ setIsMagicLinkSent, isSignUp }: AuthProps) {
setIsLoginWithEmailPending(false);
};
const handleLoginWithProvider = async (provider: SocialProvider) => {
const handleLoginWithProvider = async (provider: AuthProvider) => {
setIsLoginWithProviderPending(provider);
setLoginError(null);
const { error } = await authClient.signIn.social({
provider,
callbackURL: "/boards",
});
let error;
if (provider === "oidc") {
// Use oauth2 signin for OIDC provider
const result = await authClient.signIn.oauth2({
providerId: "oidc",
callbackURL: "/boards",
});
error = result.error;
} else {
// Use social signin for traditional social providers
const result = await authClient.signIn.social({
provider,
callbackURL: "/boards",
});
error = result.error;
}
setIsLoginWithProviderPending(null);
@@ -260,13 +288,16 @@ export function Auth({ setIsMagicLinkSent, isSignUp }: AuthProps) {
return (
<Button
key={key}
onClick={() => handleLoginWithProvider(key as SocialProvider)}
onClick={() => handleLoginWithProvider(key as AuthProvider)}
isLoading={isLoginWithProviderPending === key}
iconLeft={<provider.icon />}
fullWidth
size="lg"
>
<Trans>Continue with {provider.name}</Trans>
<Trans>
Continue with{" "}
{key === "oidc" ? oidcProviderName : provider.name}
</Trans>
</Button>
);
})}