mirror of
https://github.com/documenso/documenso.git
synced 2025-11-12 07:43:16 +10:00
## Description Add the following document action auth options: - 2FA - Passkey If the user does not have the required auth setup, we onboard them directly. ## Changes made Note: Added secondaryId to the VerificationToken schema ## Testing Performed Tested locally, pending preview tests ## Checklist - [X] I have tested these changes locally and they work as expected. - [X] I have added/updated tests that prove the effectiveness of these changes. - [X] I have followed the project's coding style guidelines. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced components for 2FA, account, and passkey authentication during document signing. - Added "Require passkey" option to document settings and signer authentication settings. - Enhanced form submission and loading states for improved user experience. - **Refactor** - Optimized authentication components to efficiently support multiple authentication methods. - **Chores** - Updated and renamed functions and components for clarity and consistency across the authentication system. - Refined sorting options and database schema to support new authentication features. - **Bug Fixes** - Adjusted SignInForm to verify browser support for WebAuthn before proceeding. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
import { P, match } from 'ts-pattern';
|
|
|
|
import {
|
|
DocumentAuth,
|
|
type TRecipientActionAuth,
|
|
type TRecipientActionAuthTypes,
|
|
} from '@documenso/lib/types/document-auth';
|
|
import type { FieldType } from '@documenso/prisma/client';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from '@documenso/ui/primitives/dialog';
|
|
|
|
import { DocumentActionAuth2FA } from './document-action-auth-2fa';
|
|
import { DocumentActionAuthAccount } from './document-action-auth-account';
|
|
import { DocumentActionAuthPasskey } from './document-action-auth-passkey';
|
|
import { useRequiredDocumentAuthContext } from './document-auth-provider';
|
|
|
|
export type DocumentActionAuthDialogProps = {
|
|
title?: string;
|
|
documentAuthType: TRecipientActionAuthTypes;
|
|
description?: string;
|
|
actionTarget: FieldType | 'DOCUMENT';
|
|
open: boolean;
|
|
onOpenChange: (value: boolean) => void;
|
|
|
|
/**
|
|
* The callback to run when the reauth form is filled out.
|
|
*/
|
|
onReauthFormSubmit: (values?: TRecipientActionAuth) => Promise<void> | void;
|
|
};
|
|
|
|
export const DocumentActionAuthDialog = ({
|
|
title,
|
|
description,
|
|
documentAuthType,
|
|
open,
|
|
onOpenChange,
|
|
onReauthFormSubmit,
|
|
}: DocumentActionAuthDialogProps) => {
|
|
const { recipient, user, isCurrentlyAuthenticating } = useRequiredDocumentAuthContext();
|
|
|
|
const handleOnOpenChange = (value: boolean) => {
|
|
if (isCurrentlyAuthenticating) {
|
|
return;
|
|
}
|
|
|
|
onOpenChange(value);
|
|
};
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={handleOnOpenChange}>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle>{title || 'Sign field'}</DialogTitle>
|
|
|
|
<DialogDescription>
|
|
{description || 'Reauthentication is required to sign this field'}
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
{match({ documentAuthType, user })
|
|
.with(
|
|
{ documentAuthType: DocumentAuth.ACCOUNT },
|
|
{ user: P.when((user) => !user || user.email !== recipient.email) }, // Assume all current auth methods requires them to be logged in.
|
|
() => <DocumentActionAuthAccount onOpenChange={onOpenChange} />,
|
|
)
|
|
.with({ documentAuthType: DocumentAuth.PASSKEY }, () => (
|
|
<DocumentActionAuthPasskey
|
|
open={open}
|
|
onOpenChange={onOpenChange}
|
|
onReauthFormSubmit={onReauthFormSubmit}
|
|
/>
|
|
))
|
|
.with({ documentAuthType: DocumentAuth.TWO_FACTOR_AUTH }, () => (
|
|
<DocumentActionAuth2FA
|
|
open={open}
|
|
onOpenChange={onOpenChange}
|
|
onReauthFormSubmit={onReauthFormSubmit}
|
|
/>
|
|
))
|
|
.with({ documentAuthType: DocumentAuth.EXPLICIT_NONE }, () => null)
|
|
.exhaustive()}
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
};
|