From 792158c2cba1aecb6357448ccd48214adeebf71c Mon Sep 17 00:00:00 2001 From: Nafees Nazik <84864519+G3root@users.noreply.github.com> Date: Fri, 1 Dec 2023 05:52:16 +0530 Subject: [PATCH] feat: add two factor auth (#643) Add two factor authentication for users who wish to enhance the security of their accounts. --- .env.example | 5 + apps/web/package.json | 1 + .../app/(dashboard)/settings/billing/page.tsx | 2 +- .../(dashboard)/settings/password/page.tsx | 20 +- .../app/(dashboard)/settings/profile/page.tsx | 2 +- .../(dashboard)/settings/security/page.tsx | 46 ++ .../(dashboard)/layout/profile-dropdown.tsx | 8 +- .../settings/layout/desktop-nav.tsx | 10 +- .../settings/layout/mobile-nav.tsx | 10 +- .../forms/2fa/authenticator-app.tsx | 58 +++ .../2fa/disable-authenticator-app-dialog.tsx | 161 ++++++ .../2fa/enable-authenticator-app-dialog.tsx | 283 +++++++++++ .../forms/2fa/recovery-code-list.tsx | 57 +++ .../components/forms/2fa/recovery-codes.tsx | 43 ++ .../forms/2fa/view-recovery-codes-dialog.tsx | 151 ++++++ apps/web/src/components/forms/signin.tsx | 167 ++++-- package-lock.json | 480 +++++++++++++++++- packages/lib/constants/crypto.ts | 1 + packages/lib/next-auth/auth-options.ts | 24 +- packages/lib/next-auth/error-codes.ts | 11 + packages/lib/package.json | 3 + packages/lib/server-only/2fa/disable-2fa.ts | 48 ++ packages/lib/server-only/2fa/enable-2fa.ts | 47 ++ .../lib/server-only/2fa/get-backup-code.ts | 38 ++ .../lib/server-only/2fa/is-2fa-availble.ts | 17 + packages/lib/server-only/2fa/setup-2fa.ts | 76 +++ packages/lib/server-only/2fa/validate-2fa.ts | 35 ++ .../lib/server-only/2fa/verify-2fa-token.ts | 33 ++ .../lib/server-only/2fa/verify-backup-code.ts | 18 + packages/lib/server-only/auth/hash.ts | 6 +- packages/lib/universal/crypto.ts | 32 ++ .../20231105184518_add_2fa/migration.sql | 4 + packages/prisma/schema.prisma | 41 +- packages/trpc/package.json | 3 +- packages/trpc/server/auth-router/router.ts | 25 +- packages/trpc/server/auth-router/schema.ts | 2 + packages/trpc/server/router.ts | 2 + .../router.ts | 105 ++++ .../schema.ts | 32 ++ packages/tsconfig/process-env.d.ts | 1 + packages/ui/primitives/input.tsx | 39 +- turbo.json | 1 + 42 files changed, 2056 insertions(+), 92 deletions(-) create mode 100644 apps/web/src/app/(dashboard)/settings/security/page.tsx create mode 100644 apps/web/src/components/forms/2fa/authenticator-app.tsx create mode 100644 apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx create mode 100644 apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx create mode 100644 apps/web/src/components/forms/2fa/recovery-code-list.tsx create mode 100644 apps/web/src/components/forms/2fa/recovery-codes.tsx create mode 100644 apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx create mode 100644 packages/lib/constants/crypto.ts create mode 100644 packages/lib/server-only/2fa/disable-2fa.ts create mode 100644 packages/lib/server-only/2fa/enable-2fa.ts create mode 100644 packages/lib/server-only/2fa/get-backup-code.ts create mode 100644 packages/lib/server-only/2fa/is-2fa-availble.ts create mode 100644 packages/lib/server-only/2fa/setup-2fa.ts create mode 100644 packages/lib/server-only/2fa/validate-2fa.ts create mode 100644 packages/lib/server-only/2fa/verify-2fa-token.ts create mode 100644 packages/lib/server-only/2fa/verify-backup-code.ts create mode 100644 packages/lib/universal/crypto.ts create mode 100644 packages/prisma/migrations/20231105184518_add_2fa/migration.sql create mode 100644 packages/trpc/server/two-factor-authentication-router/router.ts create mode 100644 packages/trpc/server/two-factor-authentication-router/schema.ts diff --git a/.env.example b/.env.example index 7bd71c04b..45c26f6be 100644 --- a/.env.example +++ b/.env.example @@ -2,6 +2,11 @@ NEXTAUTH_URL="http://localhost:3000" NEXTAUTH_SECRET="secret" +# [[CRYPTO]] +# Application Key for symmetric encryption and decryption +# This should be a random string of at least 32 characters +NEXT_PRIVATE_ENCRYPTION_KEY="CAFEBABE" + # [[AUTH OPTIONAL]] NEXT_PRIVATE_GOOGLE_CLIENT_ID="" NEXT_PRIVATE_GOOGLE_CLIENT_SECRET="" diff --git a/apps/web/package.json b/apps/web/package.json index aed5aef06..b5bb1c218 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -44,6 +44,7 @@ "sharp": "0.32.5", "ts-pattern": "^5.0.5", "typescript": "5.2.2", + "uqr": "^0.1.2", "zod": "^3.22.4" }, "devDependencies": { diff --git a/apps/web/src/app/(dashboard)/settings/billing/page.tsx b/apps/web/src/app/(dashboard)/settings/billing/page.tsx index c7161f4ae..61dff3216 100644 --- a/apps/web/src/app/(dashboard)/settings/billing/page.tsx +++ b/apps/web/src/app/(dashboard)/settings/billing/page.tsx @@ -41,7 +41,7 @@ export default async function BillingSettingsPage() { return (
Here you can update your password.
- -Here you can edit your personal details.
diff --git a/apps/web/src/app/(dashboard)/settings/security/page.tsx b/apps/web/src/app/(dashboard)/settings/security/page.tsx new file mode 100644 index 000000000..9e99b73e8 --- /dev/null +++ b/apps/web/src/app/(dashboard)/settings/security/page.tsx @@ -0,0 +1,46 @@ +import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session'; + +import { AuthenticatorApp } from '~/components/forms/2fa/authenticator-app'; +import { RecoveryCodes } from '~/components/forms/2fa/recovery-codes'; +import { PasswordForm } from '~/components/forms/password'; + +export default async function SecuritySettingsPage() { + const { user } = await getRequiredServerComponentSession(); + + return ( ++ Here you can manage your password and security settings. +
+ ++ Add and manage your two factor security settings to add an extra layer of security to your + account! +
+ +Authenticator app
+ ++ Create one-time passwords that serve as a secondary authentication method for confirming + your identity when requested during the sign-in process. +
+Recovery Codes
+ ++ Recovery codes are used to access your account in the event that you lose access to your + authenticator app. +
+