import { Plus, Shield, Link as LinkIcon, Link2 } from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; import { Button } from "~/client/components/ui/button"; import { CardContent, CardDescription, CardTitle } from "~/client/components/ui/card"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "~/client/components/ui/dialog"; import { Input } from "~/client/components/ui/input"; import { Label } from "~/client/components/ui/label"; import { authClient } from "~/client/lib/auth-client"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "~/client/components/ui/table"; interface SSOProvider { id: string; providerId: string; issuer: string; domain: string; } interface SSOSectionProps { providers: SSOProvider[]; userAccounts: { providerId: string; userId: string }[]; } export function SSOSection({ providers, userAccounts }: SSOSectionProps) { const [isRegistering, setIsRegistering] = useState(false); const [open, setOpen] = useState(false); const [providerId, setProviderId] = useState(""); const [issuer, setIssuer] = useState(""); const [domain, setDomain] = useState(""); const [clientId, setClientId] = useState(""); const [clientSecret, setClientSecret] = useState(""); const handleRegister = async (e: React.FormEvent) => { e.preventDefault(); await authClient.sso.register({ providerId, issuer, domain, oidcConfig: { clientId, clientSecret, }, fetchOptions: { onRequest: () => { setIsRegistering(true); }, onResponse: () => { setIsRegistering(false); }, onError: async ({ error }) => { toast.error("Failed to register SSO provider", { description: error.message }); }, onSuccess: async () => { toast.success("SSO provider registered successfully"); window.location.reload(); }, }, }); }; const callbackUrl = `${window.location.origin}/api/auth/sso/callback/${providerId || ":providerId"}`; const handleLink = async (providerId: string) => { await authClient.signIn.sso({ providerId, callbackURL: window.location.href, fetchOptions: { onError: async ({ error }) => { toast.error("Failed to link SSO provider", { description: error.message }); }, onSuccess: async () => { toast.success("SSO provider linked successfully"); window.location.reload(); }, }, }); }; const handleUnlink = async (providerId: string) => { await authClient.unlinkAccount({ providerId, fetchOptions: { onError: async ({ error }) => { toast.error("Failed to unlink SSO provider", { description: error.message }); }, onSuccess: async () => { toast.success("SSO provider unlinked successfully"); window.location.reload(); }, }, }); }; return ( <>
SSO Providers Manage Single Sign-On providers for your instance
Add SSO Provider Enter the details of your OIDC provider.
setProviderId(e.target.value)} placeholder="e.g. google, okta-work" required />
setIssuer(e.target.value)} placeholder="https://accounts.google.com" required />
setDomain(e.target.value)} placeholder="example.com" required />
setClientId(e.target.value)} required />
setClientSecret(e.target.value)} required />
{callbackUrl}

Copy this URL to your Identity Provider configuration.

{providers.length === 0 ? (

No SSO providers configured.

) : (
Provider ID Domain User id Actions {providers.map((p) => { const linkedAccount = userAccounts.find((ua) => ua.providerId === p.providerId); return ( {p.providerId} {p.domain} {linkedAccount ? linkedAccount.userId : "-"} {linkedAccount ? ( ) : ( )} ); })}
)}
); }