NORY-47: add dialog to show recovery information

This commit is contained in:
Markus Thielker 2025-01-03 22:52:45 +01:00
parent 21ff2ad8f8
commit afab5645c2
No known key found for this signature in database

View file

@ -1,8 +1,8 @@
'use client';
import { Identity } from '@ory/client';
import { Button } from '@/components/ui/button';
import { Key, Link, Trash, UserCheck, UserMinus, UserX } from 'lucide-react';
import { Button, buttonVariants } from '@/components/ui/button';
import { Copy, Key, Link, Trash, UserCheck, UserMinus, UserX } from 'lucide-react';
import { ConfirmationDialogWrapper } from '@/components/confirmation-dialog-wrapper';
import {
blockIdentity,
@ -14,6 +14,18 @@ import {
} from '@/lib/action/identity';
import { toast } from 'sonner';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import {
AlertDialog,
AlertDialogAction,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
interface IdentityActionProps {
identity: Identity;
@ -24,14 +36,84 @@ export function IdentityActions({ identity }: IdentityActionProps,
const router = useRouter();
const [dialogVisible, setDialogVisible] = useState(false);
const [dialogLink, setDialogLink] = useState<string>('');
const [dialogCode, setDialogCode] = useState<string | undefined>(undefined);
return (
<>
<AlertDialog open={dialogVisible} onOpenChange={(value) => setDialogVisible(value)}>
<AlertDialogContent className="space-y-1">
<AlertDialogHeader>
<AlertDialogTitle>Recovery account</AlertDialogTitle>
<AlertDialogDescription>
You created a recovery flow. Provide the user with the following information so they can
access their account again.
</AlertDialogDescription>
</AlertDialogHeader>
<div>
<Label>Link</Label>
<div className="flex relative">
<Input value={dialogLink} readOnly/>
<Button
className="absolute right-0"
variant="outline"
onClick={() => {
toast.info('Link copied to clipboard');
navigator.clipboard.writeText(dialogLink);
}}
>
<Copy/>
</Button>
</div>
<p className="mt-1 text-xs text-neutral-500">
{
dialogCode ?
'The user will need this link to access the recovery flow.'
:
'This magic link will authenticate the user automatically'
}
</p>
</div>
{
dialogCode ?
<div>
<Label>Code</Label>
<div className="flex relative">
<Input value={dialogCode} readOnly/>
<Button
className="absolute right-0"
variant="outline"
onClick={() => {
toast.info('Code copied to clipboard');
navigator.clipboard.writeText(dialogCode);
}}
>
<Copy/>
</Button>
</div>
<p className="mt-1 text-xs text-neutral-500">
The user will need to enter this code on the recovery page.
</p>
</div>
:
<></>
}
<AlertDialogFooter>
<AlertDialogAction className={buttonVariants({ variant: 'destructive' })}>
Close
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<ConfirmationDialogWrapper
onSubmit={async () => {
await createRecoveryCode(identity.id)
.then((response) => {
console.log('recovery code created', response);
toast.success(response.recovery_code);
setDialogLink(response.recovery_link);
setDialogCode(response.recovery_code);
setDialogVisible(true);
})
.catch(() => toast.error('Creating recovery code failed'));
}}
@ -49,8 +131,9 @@ export function IdentityActions({ identity }: IdentityActionProps,
onSubmit={async () => {
await createRecoveryLink(identity.id)
.then((response) => {
console.log('recovery link created', response);
toast.success(response.recovery_link);
setDialogLink(response.recovery_link);
setDialogCode(undefined);
setDialogVisible(true);
})
.catch(() => toast.error('Creating recovery link failed. It is likely magic-links are disabled on your Ory Kratos instance.'));
}}
@ -135,7 +218,6 @@ export function IdentityActions({ identity }: IdentityActionProps,
<Trash className="h-4"/>
</Button>
</ConfirmationDialogWrapper>
</>
);
}