Implement Auth0 migration

This commit is contained in:
gpt-engineer-app[bot]
2025-11-01 01:08:11 +00:00
parent 858320cd03
commit b2bf9a6e20
17 changed files with 1430 additions and 7 deletions

View File

@@ -0,0 +1,176 @@
/**
* Auth0 MFA Settings Component
*
* Display MFA status and provide enrollment/unenrollment options via Auth0
*/
import { useState, useEffect } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Badge } from '@/components/ui/badge';
import { Shield, Loader2, CheckCircle, AlertCircle } from 'lucide-react';
import { useAuth0 } from '@auth0/auth0-react';
import { getMFAStatus, triggerMFAEnrollment } from '@/lib/auth0Management';
import { useToast } from '@/hooks/use-toast';
import type { Auth0MFAStatus } from '@/types/auth0';
export function Auth0MFASettings() {
const { user, isAuthenticated } = useAuth0();
const [mfaStatus, setMfaStatus] = useState<Auth0MFAStatus | null>(null);
const [loading, setLoading] = useState(true);
const { toast } = useToast();
useEffect(() => {
const fetchMFAStatus = async () => {
if (!isAuthenticated || !user?.sub) {
setLoading(false);
return;
}
try {
const status = await getMFAStatus(user.sub);
setMfaStatus(status);
} catch (error) {
console.error('Error fetching MFA status:', error);
toast({
variant: 'destructive',
title: 'Error',
description: 'Failed to load MFA status',
});
} finally {
setLoading(false);
}
};
fetchMFAStatus();
}, [isAuthenticated, user, toast]);
const handleEnroll = async () => {
try {
await triggerMFAEnrollment('/settings?tab=security');
} catch (error) {
toast({
variant: 'destructive',
title: 'Error',
description: 'Failed to start MFA enrollment',
});
}
};
if (loading) {
return (
<Card>
<CardHeader>
<div className="flex items-center gap-2">
<Shield className="h-5 w-5" />
<CardTitle>Multi-Factor Authentication (MFA)</CardTitle>
</div>
<CardDescription>
Add an extra layer of security to your account
</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center justify-center p-8">
<Loader2 className="h-6 w-6 animate-spin" />
</div>
</CardContent>
</Card>
);
}
return (
<Card>
<CardHeader>
<div className="flex items-center gap-2">
<Shield className="h-5 w-5" />
<CardTitle>Multi-Factor Authentication (MFA)</CardTitle>
</div>
<CardDescription>
Add an extra layer of security to your account with two-factor authentication
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
{/* MFA Status */}
<div className="flex items-center justify-between p-4 border rounded-lg">
<div className="flex items-center gap-3">
{mfaStatus?.enrolled ? (
<CheckCircle className="h-5 w-5 text-green-500" />
) : (
<AlertCircle className="h-5 w-5 text-amber-500" />
)}
<div>
<p className="font-medium">
MFA Status
</p>
<p className="text-sm text-muted-foreground">
{mfaStatus?.enrolled
? 'Multi-factor authentication is active'
: 'MFA is not enabled on your account'}
</p>
</div>
</div>
<Badge variant={mfaStatus?.enrolled ? 'default' : 'secondary'}>
{mfaStatus?.enrolled ? 'Enabled' : 'Disabled'}
</Badge>
</div>
{/* Enrolled Methods */}
{mfaStatus?.enrolled && mfaStatus.methods.length > 0 && (
<div className="space-y-2">
<p className="text-sm font-medium">Active Methods:</p>
<div className="space-y-2">
{mfaStatus.methods.map((method) => (
<div
key={method.id}
className="flex items-center justify-between p-3 border rounded-lg"
>
<div>
<p className="text-sm font-medium capitalize">{method.type}</p>
{method.name && (
<p className="text-xs text-muted-foreground">{method.name}</p>
)}
</div>
<Badge variant={method.confirmed ? 'default' : 'secondary'}>
{method.confirmed ? 'Active' : 'Pending'}
</Badge>
</div>
))}
</div>
</div>
)}
{/* Info Alert */}
<Alert>
<AlertCircle className="h-4 w-4" />
<AlertDescription className="text-sm">
{mfaStatus?.enrolled ? (
<>
MFA is managed through Auth0. To add or remove authentication methods,
click the button below to manage your MFA settings.
</>
) : (
<>
Enable MFA to protect your account with an additional security layer.
You'll be redirected to Auth0 to set up your preferred authentication method.
</>
)}
</AlertDescription>
</Alert>
{/* Action Buttons */}
<div className="flex gap-2">
{!mfaStatus?.enrolled ? (
<Button onClick={handleEnroll} className="w-full">
Enable MFA
</Button>
) : (
<Button onClick={handleEnroll} variant="outline" className="w-full">
Manage MFA Settings
</Button>
)}
</div>
</CardContent>
</Card>
);
}