Skip to content

Commit

Permalink
Merge branch 'main' into feat/typedsql
Browse files Browse the repository at this point in the history
  • Loading branch information
jharrell authored Aug 29, 2024
2 parents c3019d6 + d599ab0 commit b30bdaf
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 65 deletions.
2 changes: 1 addition & 1 deletion apps/marketing/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@documenso/marketing",
"version": "1.7.0-rc.1",
"version": "1.7.0-rc.2",
"private": true,
"license": "AGPL-3.0",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@documenso/web",
"version": "1.7.0-rc.1",
"version": "1.7.0-rc.2",
"private": true,
"license": "AGPL-3.0",
"scripts": {
Expand Down
114 changes: 82 additions & 32 deletions apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { trpc } from '@documenso/trpc/react';
import { Button } from '@documenso/ui/primitives/button';
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
Expand All @@ -28,13 +27,16 @@ import {
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@documenso/ui/primitives/form/form';
import { Input } from '@documenso/ui/primitives/input';
import { PinInput, PinInputGroup, PinInputSlot } from '@documenso/ui/primitives/pin-input';
import { useToast } from '@documenso/ui/primitives/use-toast';

export const ZDisable2FAForm = z.object({
token: z.string(),
totpCode: z.string().trim().optional(),
backupCode: z.string().trim().optional(),
});

export type TDisable2FAForm = z.infer<typeof ZDisable2FAForm>;
Expand All @@ -46,21 +48,43 @@ export const DisableAuthenticatorAppDialog = () => {
const { toast } = useToast();

const [isOpen, setIsOpen] = useState(false);
const [twoFactorDisableMethod, setTwoFactorDisableMethod] = useState<'totp' | 'backup'>('totp');

const { mutateAsync: disable2FA } = trpc.twoFactorAuthentication.disable.useMutation();

const disable2FAForm = useForm<TDisable2FAForm>({
defaultValues: {
token: '',
totpCode: '',
backupCode: '',
},
resolver: zodResolver(ZDisable2FAForm),
});

const onCloseTwoFactorDisableDialog = () => {
disable2FAForm.reset();

setIsOpen(!isOpen);
};

const onToggleTwoFactorDisableMethodClick = () => {
const method = twoFactorDisableMethod === 'totp' ? 'backup' : 'totp';

if (method === 'totp') {
disable2FAForm.setValue('backupCode', '');
}

if (method === 'backup') {
disable2FAForm.setValue('totpCode', '');
}

setTwoFactorDisableMethod(method);
};

const { isSubmitting: isDisable2FASubmitting } = disable2FAForm.formState;

const onDisable2FAFormSubmit = async ({ token }: TDisable2FAForm) => {
const onDisable2FAFormSubmit = async ({ totpCode, backupCode }: TDisable2FAForm) => {
try {
await disable2FA({ token });
await disable2FA({ totpCode, backupCode });

toast({
title: _(msg`Two-factor authentication disabled`),
Expand All @@ -70,7 +94,7 @@ export const DisableAuthenticatorAppDialog = () => {
});

flushSync(() => {
setIsOpen(false);
onCloseTwoFactorDisableDialog();
});

router.refresh();
Expand All @@ -86,7 +110,7 @@ export const DisableAuthenticatorAppDialog = () => {
};

return (
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<Dialog open={isOpen} onOpenChange={onCloseTwoFactorDisableDialog}>
<DialogTrigger asChild={true}>
<Button className="flex-shrink-0" variant="destructive">
<Trans>Disable 2FA</Trans>
Expand All @@ -110,33 +134,59 @@ export const DisableAuthenticatorAppDialog = () => {
<Form {...disable2FAForm}>
<form onSubmit={disable2FAForm.handleSubmit(onDisable2FAFormSubmit)}>
<fieldset className="flex flex-col gap-y-4" disabled={isDisable2FASubmitting}>
<FormField
name="token"
control={disable2FAForm.control}
render={({ field }) => (
<FormItem>
<FormControl>
<PinInput {...field} value={field.value ?? ''} maxLength={6}>
{Array(6)
.fill(null)
.map((_, i) => (
<PinInputGroup key={i}>
<PinInputSlot index={i} />
</PinInputGroup>
))}
</PinInput>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{twoFactorDisableMethod === 'totp' && (
<FormField
name="totpCode"
control={disable2FAForm.control}
render={({ field }) => (
<FormItem>
<FormControl>
<PinInput {...field} value={field.value ?? ''} maxLength={6}>
{Array(6)
.fill(null)
.map((_, i) => (
<PinInputGroup key={i}>
<PinInputSlot index={i} />
</PinInputGroup>
))}
</PinInput>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
)}

{twoFactorDisableMethod === 'backup' && (
<FormField
control={disable2FAForm.control}
name="backupCode"
render={({ field }) => (
<FormItem>
<FormLabel>
<Trans>Backup Code</Trans>
</FormLabel>
<FormControl>
<Input type="text" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
)}

<DialogFooter>
<DialogClose asChild>
<Button type="button" variant="secondary">
<Trans>Cancel</Trans>
</Button>
</DialogClose>
<Button
type="button"
variant="secondary"
onClick={onToggleTwoFactorDisableMethodClick}
>
{twoFactorDisableMethod === 'totp' ? (
<Trans>Use Backup Code</Trans>
) : (
<Trans>Use Authenticator</Trans>
)}
</Button>

<Button type="submit" variant="destructive" loading={isDisable2FASubmitting}>
<Trans>Disable 2FA</Trans>
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"private": true,
"version": "1.7.0-rc.1",
"version": "1.7.0-rc.2",
"scripts": {
"build": "turbo run build",
"build:web": "turbo run build --filter=@documenso/web",
Expand Down
20 changes: 14 additions & 6 deletions packages/lib/server-only/2fa/disable-2fa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,33 @@ import { prisma } from '@documenso/prisma';
import type { User } from '@documenso/prisma/client';
import { UserSecurityAuditLogType } from '@documenso/prisma/client';

import { AppError } from '../../errors/app-error';
import { AppError, AppErrorCode } from '../../errors/app-error';
import type { RequestMetadata } from '../../universal/extract-request-metadata';
import { validateTwoFactorAuthentication } from './validate-2fa';

type DisableTwoFactorAuthenticationOptions = {
user: User;
token: string;
totpCode?: string;
backupCode?: string;
requestMetadata?: RequestMetadata;
};

export const disableTwoFactorAuthentication = async ({
token,
totpCode,
backupCode,
user,
requestMetadata,
}: DisableTwoFactorAuthenticationOptions) => {
let isValid = await validateTwoFactorAuthentication({ totpCode: token, user });
let isValid = false;

if (!isValid) {
isValid = await validateTwoFactorAuthentication({ backupCode: token, user });
if (!totpCode && !backupCode) {
throw new AppError(AppErrorCode.INVALID_REQUEST);
}

if (totpCode) {
isValid = await validateTwoFactorAuthentication({ totpCode, user });
} else if (backupCode) {
isValid = await validateTwoFactorAuthentication({ backupCode, user });
}

if (!isValid) {
Expand Down
20 changes: 11 additions & 9 deletions packages/lib/translations/de/web.po
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ msgstr ""
msgid "Background Color"
msgstr ""

#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:167
#: apps/web/src/components/forms/signin.tsx:451
msgid "Backup Code"
msgstr ""
Expand Down Expand Up @@ -684,7 +685,6 @@ msgstr ""
#: apps/web/src/components/(teams)/dialogs/transfer-team-dialog.tsx:278
#: apps/web/src/components/(teams)/dialogs/update-team-email-dialog.tsx:162
#: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:187
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:137
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:257
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:163
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:452
Expand Down Expand Up @@ -1143,9 +1143,9 @@ msgstr ""
msgid "Disable"
msgstr ""

#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:92
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:99
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:142
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:116
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:123
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:192
msgid "Disable 2FA"
msgstr ""

Expand Down Expand Up @@ -2279,7 +2279,7 @@ msgstr ""
msgid "Please note that you will lose access to all documents associated with this team & all the members will be removed and notified"
msgstr ""

#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:103
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:127
msgid "Please provide a token from the authenticator, or a backup code. If you do not have a backup code available, please contact support."
msgstr ""

Expand Down Expand Up @@ -3453,15 +3453,15 @@ msgstr ""
msgid "Two-Factor Authentication"
msgstr ""

#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:66
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:90
msgid "Two-factor authentication disabled"
msgstr ""

#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:94
msgid "Two-factor authentication enabled"
msgstr ""

#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:68
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:92
msgid "Two-factor authentication has been disabled for your account. You will no longer be required to enter a code from your authenticator app when signing in."
msgstr ""

Expand Down Expand Up @@ -3506,7 +3506,7 @@ msgstr ""
msgid "Unable to delete team"
msgstr ""

#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:79
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:103
msgid "Unable to disable two-factor authentication"
msgstr ""

Expand Down Expand Up @@ -3654,10 +3654,12 @@ msgstr ""
msgid "Uploaded file not an allowed file type"
msgstr ""

#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:187
#: apps/web/src/components/forms/signin.tsx:471
msgid "Use Authenticator"
msgstr ""

#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:185
#: apps/web/src/components/forms/signin.tsx:469
msgid "Use Backup Code"
msgstr ""
Expand Down Expand Up @@ -3944,7 +3946,7 @@ msgstr ""
msgid "We were unable to create a checkout session. Please try again, or contact support"
msgstr ""

#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:81
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:105
msgid "We were unable to disable two-factor authentication for your account. Please ensure that you have entered your password and backup code correctly and try again."
msgstr ""

Expand Down
Loading

0 comments on commit b30bdaf

Please sign in to comment.