feat(sso): implement SSO provider registration and update related components

- Refactored SSO registration logic in `register-oidc-dialog` and `register-saml-dialog` to use a new mutation method.
- Removed unused imports and error handling for registration failures.
- Added foreign key constraint for `organization_id` in the `sso_provider` table.
- Introduced new SSO schema and updated user relations to include SSO providers.
- Enhanced authentication flow to support SSO provider registration.
This commit is contained in:
Mauricio Siu
2026-01-31 04:43:47 -06:00
parent d22d96105c
commit d5de5b8ad7
11 changed files with 7348 additions and 50 deletions

View File

@@ -1,7 +1,7 @@
"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import { Loader2, Plus, Trash2 } from "lucide-react";
import { Plus, Trash2 } from "lucide-react";
import { useState } from "react";
import type { FieldArrayPath } from "react-hook-form";
import { useFieldArray, useForm } from "react-hook-form";
@@ -27,7 +27,6 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { authClient } from "@/lib/auth-client";
import { api } from "@/utils/api";
const DEFAULT_SCOPES = ["openid", "email", "profile"];
@@ -74,6 +73,7 @@ const formDefaultValues = {
export function RegisterOidcDialog({ children }: RegisterOidcDialogProps) {
const utils = api.useUtils();
const [open, setOpen] = useState(false);
const { mutateAsync, isLoading } = api.sso.register.useMutation();
const form = useForm<OidcProviderForm>({
resolver: zodResolver(oidcProviderSchema),
@@ -105,7 +105,7 @@ export function RegisterOidcDialog({ children }: RegisterOidcDialogProps) {
.map((d) => d.trim())
.filter(Boolean)
.join(",");
const { error } = await authClient.sso.register({
await mutateAsync({
providerId: data.providerId,
issuer: data.issuer,
domain,
@@ -125,11 +125,6 @@ export function RegisterOidcDialog({ children }: RegisterOidcDialogProps) {
},
});
if (error) {
toast.error(error.message ?? "Failed to register SSO provider");
return;
}
toast.success("OIDC provider registered successfully");
form.reset(formDefaultValues);
setOpen(false);
@@ -340,10 +335,7 @@ export function RegisterOidcDialog({ children }: RegisterOidcDialogProps) {
>
Cancel
</Button>
<Button type="submit" disabled={isSubmitting}>
{isSubmitting && (
<Loader2 className="mr-2 size-4 animate-spin" />
)}
<Button type="submit" isLoading={isLoading}>
Register provider
</Button>
</DialogFooter>

View File

@@ -1,7 +1,7 @@
"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import { Loader2, Plus, Trash2 } from "lucide-react";
import { Plus, Trash2 } from "lucide-react";
import { useState } from "react";
import { type FieldArrayPath, useFieldArray, useForm } from "react-hook-form";
import { toast } from "sonner";
@@ -27,7 +27,6 @@ import {
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { authClient } from "@/lib/auth-client";
import { api } from "@/utils/api";
const domainsArraySchema = z
@@ -80,6 +79,7 @@ const formDefaultValues: SamlProviderForm = {
export function RegisterSamlDialog({ children }: RegisterSamlDialogProps) {
const utils = api.useUtils();
const [open, setOpen] = useState(false);
const { mutateAsync, isLoading } = api.sso.register.useMutation();
const form = useForm<SamlProviderForm>({
resolver: zodResolver(samlProviderSchema),
@@ -99,7 +99,7 @@ export function RegisterSamlDialog({ children }: RegisterSamlDialogProps) {
.map((d) => d.trim())
.filter(Boolean)
.join(",");
const { error } = await authClient.sso.register({
await mutateAsync({
providerId: data.providerId,
issuer: data.issuer,
domain,
@@ -117,11 +117,6 @@ export function RegisterSamlDialog({ children }: RegisterSamlDialogProps) {
},
});
if (error) {
toast.error(error.message ?? "Failed to register SAML provider");
return;
}
toast.success("SAML provider registered successfully");
form.reset(formDefaultValues);
setOpen(false);
@@ -315,10 +310,7 @@ export function RegisterSamlDialog({ children }: RegisterSamlDialogProps) {
>
Cancel
</Button>
<Button type="submit" disabled={isSubmitting}>
{isSubmitting && (
<Loader2 className="mr-2 size-4 animate-spin" />
)}
<Button type="submit" isLoading={isLoading}>
Register provider
</Button>
</DialogFooter>