1
0
Fork 0
mirror of https://codeberg.org/MarkusThielker/next-ory.git synced 2025-04-10 11:58:41 +00:00

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'; 'use client';
import { Identity } from '@ory/client'; import { Identity } from '@ory/client';
import { Button } from '@/components/ui/button'; import { Button, buttonVariants } from '@/components/ui/button';
import { Key, Link, Trash, UserCheck, UserMinus, UserX } from 'lucide-react'; import { Copy, Key, Link, Trash, UserCheck, UserMinus, UserX } from 'lucide-react';
import { ConfirmationDialogWrapper } from '@/components/confirmation-dialog-wrapper'; import { ConfirmationDialogWrapper } from '@/components/confirmation-dialog-wrapper';
import { import {
blockIdentity, blockIdentity,
@ -14,6 +14,18 @@ import {
} from '@/lib/action/identity'; } from '@/lib/action/identity';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { useRouter } from 'next/navigation'; 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 { interface IdentityActionProps {
identity: Identity; identity: Identity;
@ -24,14 +36,84 @@ export function IdentityActions({ identity }: IdentityActionProps,
const router = useRouter(); const router = useRouter();
const [dialogVisible, setDialogVisible] = useState(false);
const [dialogLink, setDialogLink] = useState<string>('');
const [dialogCode, setDialogCode] = useState<string | undefined>(undefined);
return ( 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 <ConfirmationDialogWrapper
onSubmit={async () => { onSubmit={async () => {
await createRecoveryCode(identity.id) await createRecoveryCode(identity.id)
.then((response) => { .then((response) => {
console.log('recovery code created', response); setDialogLink(response.recovery_link);
toast.success(response.recovery_code); setDialogCode(response.recovery_code);
setDialogVisible(true);
}) })
.catch(() => toast.error('Creating recovery code failed')); .catch(() => toast.error('Creating recovery code failed'));
}} }}
@ -49,8 +131,9 @@ export function IdentityActions({ identity }: IdentityActionProps,
onSubmit={async () => { onSubmit={async () => {
await createRecoveryLink(identity.id) await createRecoveryLink(identity.id)
.then((response) => { .then((response) => {
console.log('recovery link created', response); setDialogLink(response.recovery_link);
toast.success(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.')); .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"/> <Trash className="h-4"/>
</Button> </Button>
</ConfirmationDialogWrapper> </ConfirmationDialogWrapper>
</> </>
); );
} }