diff --git a/app/actions/_userActions.ts b/app/actions/_userActions.ts index 68a87d8..5a47bdd 100644 --- a/app/actions/_userActions.ts +++ b/app/actions/_userActions.ts @@ -9,6 +9,7 @@ import { NotFoundError, } from "@/lib/errors"; import { prisma } from "@/lib/prisma"; +import { createVault } from "./_vaultActions"; export const finishOnboarding = withErrorHandling( withAuth( @@ -18,6 +19,7 @@ export const finishOnboarding = withErrorHandling( salt: string; publicKey: string; wrappedPrivateKey: string; + wrappedDefaultVaultKey: string; } ) => { const client = await clerkClient(); @@ -26,7 +28,8 @@ export const finishOnboarding = withErrorHandling( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const email = user.primaryEmailAddress!.emailAddress; - const { salt, publicKey, wrappedPrivateKey } = data; + const { salt, publicKey, wrappedPrivateKey, wrappedDefaultVaultKey } = + data; try { // Check if user already exists @@ -54,6 +57,11 @@ export const finishOnboarding = withErrorHandling( }, }); + await createVault({ + name: "Private", + wrappedKey: wrappedDefaultVaultKey, + }); + await client.users.updateUser(user.id, { publicMetadata: { onboardingComplete: true, diff --git a/components/auth/onboarding-form.tsx b/components/auth/onboarding-form.tsx index f7ad8fe..d9b7eda 100644 --- a/components/auth/onboarding-form.tsx +++ b/components/auth/onboarding-form.tsx @@ -44,13 +44,14 @@ export function SignUpForm({ } try { - const { publicKey, wrappedPrivateKey, salt } = + const { publicKey, wrappedPrivateKey, salt, wrappedDefaultVaultKey } = await cryptoService.onboarding(password); const response = await finishOnboarding({ salt, publicKey, wrappedPrivateKey, + wrappedDefaultVaultKey, }); // Handle error responses diff --git a/lib/crypto.ts b/lib/crypto.ts index 86d7c5e..15413fc 100644 --- a/lib/crypto.ts +++ b/lib/crypto.ts @@ -1,17 +1,24 @@ export class CryptoService { - public async onboarding( - password: string - ): Promise<{ publicKey: string; wrappedPrivateKey: string; salt: string }> { + public async onboarding(password: string): Promise<{ + publicKey: string; + wrappedPrivateKey: string; + salt: string; + wrappedDefaultVaultKey: string; + }> { const { publicKey, privateKey } = await this.generateKeyPair(); const salt = crypto.getRandomValues(new Uint8Array(16)); const kek = await this.deriveKek(password, salt); const wrappedPrivateKey = await this.wrapPrivateKey(privateKey, kek); const publicKeyBuffer = await crypto.subtle.exportKey("spki", publicKey); + const { wrappedKey: wrappedDefaultVaultKey } = + await this.generateAndWrapVaultKey(publicKey); + return { publicKey: BufferTransformer.arrayBufferToBase64(publicKeyBuffer), wrappedPrivateKey: BufferTransformer.arrayBufferToBase64(wrappedPrivateKey), salt: BufferTransformer.arrayBufferToBase64(salt.buffer), + wrappedDefaultVaultKey, }; } @@ -184,7 +191,7 @@ export class CryptoService { hash: "SHA-256", }, true, - ["encrypt", "decrypt"] + ["encrypt", "decrypt", "wrapKey"] ); }