'use client' import { useEffect, useState } from 'react' import { Button, cn, Input, Label } from '@sim/emcn' import { createLogger } from '@sim/logger' import Link from 'next/link' import { useRouter, useSearchParams } from 'next/navigation' import { client } from '@/lib/auth/auth-client' import { env, isFalsy } from '@/lib/core/config/env' import { validateCallbackUrl } from '@/lib/core/security/input-validation' import { quickValidateEmail } from '@/lib/messaging/email/validation' import { AuthSubmitButton } from '@/app/(auth)/components' const logger = createLogger('SSOForm') const validateEmailField = (emailValue: string): string[] => { const errors: string[] = [] if (!emailValue || !emailValue.trim()) { errors.push('Email is required.') return errors } const validation = quickValidateEmail(emailValue.trim().toLowerCase()) if (!validation.isValid) { errors.push(validation.reason || 'Please enter a valid email address.') } return errors } export default function SSOForm() { const router = useRouter() const searchParams = useSearchParams() const [isLoading, setIsLoading] = useState(false) const [email, setEmail] = useState('') const [emailErrors, setEmailErrors] = useState([]) const [showEmailValidationError, setShowEmailValidationError] = useState(false) const [callbackUrl, setCallbackUrl] = useState('/workspace') useEffect(() => { if (searchParams) { const callback = searchParams.get('callbackUrl') if (callback) { if (validateCallbackUrl(callback)) { setCallbackUrl(callback) } else { logger.warn('Invalid callback URL detected and blocked:', { url: callback }) } } const emailParam = searchParams.get('email') if (emailParam) { setEmail(emailParam) } const error = searchParams.get('error') if (error) { const errorMessages: Record = { account_not_found: 'No account found. Please contact your administrator to set up SSO access.', sso_failed: 'SSO authentication failed. Please try again.', invalid_provider: 'SSO provider not configured correctly.', } setEmailErrors([errorMessages[error] || 'SSO authentication failed. Please try again.']) setShowEmailValidationError(true) } } }, [searchParams]) const handleEmailChange = (e: React.ChangeEvent) => { const newEmail = e.target.value setEmail(newEmail) const errors = validateEmailField(newEmail) setEmailErrors(errors) setShowEmailValidationError(false) } async function onSubmit(e: React.FormEvent) { e.preventDefault() setIsLoading(true) const formData = new FormData(e.currentTarget) const emailRaw = formData.get('email') as string const emailValue = emailRaw.trim().toLowerCase() const emailValidationErrors = validateEmailField(emailValue) setEmailErrors(emailValidationErrors) setShowEmailValidationError(emailValidationErrors.length > 0) if (emailValidationErrors.length > 0) { setIsLoading(false) return } try { const safeCallbackUrl = callbackUrl await client.signIn.sso({ email: emailValue, callbackURL: safeCallbackUrl, errorCallbackURL: `/sso?error=sso_failed&callbackUrl=${encodeURIComponent(safeCallbackUrl)}`, }) } catch (err) { logger.error('SSO sign-in failed', { error: err, email: emailValue }) let errorMessage = 'SSO sign-in failed. Please try again.' if (err instanceof Error) { if (err.message.includes('NO_PROVIDER_FOUND')) { errorMessage = 'SSO provider not found. Please check your configuration.' } else if (err.message.includes('INVALID_EMAIL_DOMAIN')) { errorMessage = 'Email domain not configured for SSO. Please contact your administrator.' } else if (err.message.includes('network')) { errorMessage = 'Network error. Please check your connection and try again.' } else if (err.message.includes('rate limit')) { errorMessage = 'Too many requests. Please wait a moment before trying again.' } else if (err.message.includes('SSO_DISABLED')) { errorMessage = 'SSO authentication is disabled. Please use another sign-in method.' } else { errorMessage = err.message } } setEmailErrors([errorMessage]) setShowEmailValidationError(true) setIsLoading(false) } } return ( <>

Sign in with SSO

Enter your work email to continue

0 && 'border-[var(--text-error)] focus:border-[var(--text-error)]' )} /> {showEmailValidationError && emailErrors.length > 0 && (
{emailErrors.map((error) => (

{error}

))}
)}
Continue with SSO
{/* Only show divider and email signin button if email/password is enabled */} {!isFalsy(env.NEXT_PUBLIC_EMAIL_PASSWORD_SIGNUP_ENABLED) && ( <>
Or
)} {/* Only show signup link if email/password signup is enabled */} {!isFalsy(env.NEXT_PUBLIC_EMAIL_PASSWORD_SIGNUP_ENABLED) && (
Don't have an account? Sign up
)}
By signing in, you agree to our{' '} Terms of Service {' '} and{' '} Privacy Policy
) }