Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create recoverable keys from dashboard #2783

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

harshsbhat
Copy link
Contributor

@harshsbhat harshsbhat commented Dec 28, 2024

What does this PR do?

Fixes #2097

This PR allows users to create recoverable keys through the dashboard, which is only possible through API as of now.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Test A:

Make sure you have store_encrypted_keys enabled. Head over to the dashboard and create a new key http://localhost:3000/apis/api_id/keys/ks_id/new with recoverable: true. Get the key_id of the newly created key and use it with getKey API like this ( make sure you have appropriate permissions to get the decrypted key ):

curl --request GET \
  --url 'http://localhost:8787/v1/keys.getKey?keyId=key_id123&decrypt=true' \
  --header 'Authorization: Bearer unkey_rootKey'

The decrypted key should be logged in the response

  • Test B (few edge cases that might be worth testing ):
  1. Without store_encrypted_keys the recoverable card is not visible.
  2. Added in the transaction so even if the encryption fails an extra key won't be added.

Checklist

https://www.loom.com/share/713ebadf169b43eb9055dda724dd7008?sid=82985e82-072f-4a10-9595-78c010d7484f

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

Summary by CodeRabbit

  • New Features

    • Added option to enable key recovery during key creation.
    • Introduced a configurable switch to store encrypted keys for future recovery.
    • Enhanced key management with optional encryption and recovery capabilities.
  • Bug Fixes

    • Improved validation and handling of key recovery settings.
  • Documentation

    • Updated user interface to explain key recovery implications.

Copy link

changeset-bot bot commented Dec 28, 2024

⚠️ No Changeset found

Latest commit: 6783bb6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Dec 28, 2024

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This pull request introduces functionality to allow setting recoverable keys when creating keys in the dashboard. The changes span multiple files in the dashboard application, adding a new recoverEnabled option to the key creation process. The implementation includes UI modifications in the CreateKey component, updates to the validation schema, and backend changes in the key creation procedure to support optional key encryption and recovery.

Changes

File Change Summary
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/client.tsx Added storeEncryptedKeys prop, introduced recoverEnabled state, updated form submission logic to handle key recoverability.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/page.tsx Passed storeEncryptedKeys prop to CreateKey component from keyAuth object.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/validation.ts Added recoverEnabled boolean field to form schema with default false.
apps/dashboard/lib/trpc/routers/key/create.ts Updated input schema with optional recoverEnabled, added conditional encryption logic for recoverable keys.
apps/dashboard/package.json Added dependency "@unkey/vault": "workspace:^" to project dependencies.

Assessment against linked issues

Objective Addressed Explanation
Add toggle to mark key as recoverable (2097)
Support recoverable keys in dashboard UI (2097)
Update trpc handler for key recovery (2097)

Possibly related PRs

Suggested labels

Bug, Needs Approval

Suggested Reviewers

  • mcstepp
  • perkinsjr
  • chronark
  • ogzhanolguncu

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

vercel bot commented Dec 28, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
dashboard ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 8, 2025 7:03am
engineering ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 8, 2025 7:03am
play ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 8, 2025 7:03am
www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 8, 2025 7:03am

Copy link

vercel bot commented Dec 28, 2024

@harshsbhat is attempting to deploy a commit to the Unkey Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions bot added the Feature New feature or request label Dec 28, 2024
Copy link
Contributor

github-actions bot commented Dec 28, 2024

Thank you for following the naming conventions for pull request titles! 🙏

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
apps/dashboard/lib/trpc/routers/key/create.ts (2)

3-7: Add relevant error logging for new imports
You have introduced new imports (env, EncryptRequest, RequestContext, and Vault). While everything looks fine, consider logging or re-throwing with error details when these modules fail to load to aid in debugging unexpected runtime issues.


116-145: Encryption logic and database insert
The addition of the encryption logic is well-structured:

  • Checking recoverEnabled and storeEncryptedKeys before using Vault.
  • Handling errors with TRPCError.
    A couple of suggestions:
  1. Logging: Consider logging the _err details to a secure or masked target so you have more insight into the failure root cause instead of discarding the caught error.
  2. Atomicity: The current transaction ensures atomic writes. If the Vault call times out or fails, the transaction is rolled back, which is good. Confirm that any partial failures are handled properly in logs for debugging.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/client.tsx (2)

186-215: Conditional messaging on recovery
Displaying context-dependent messaging ("This key can be recovered" vs. "cannot be recovered") provides clarity to the user. Great approach.


794-844: UI block for Recoverable Keys
The UI block is well-organized, with a switch for recoverEnabled and explanatory text about encrypted vault storage. A minor enhancement could be to clarify the data retention policy or accountability if there are multiple vault encryption keys across partitions.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1115fd5 and 3b36e6c.

📒 Files selected for processing (4)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/client.tsx (8 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/validation.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/key/create.ts (3 hunks)
🔇 Additional comments (7)
apps/dashboard/lib/trpc/routers/key/create.ts (1)

38-38: New optional field in input schema
The new recoverEnabled: z.boolean().optional() field is clear and well-typed. Ensure consumers of the createKey procedure are aware that omitting the field defaults it to undefined. This might require additional checks on the front-end if usage patterns vary.

apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/page.tsx (1)

65-65: Propagating storeEncryptedKeys
Passing storeEncryptedKeys={keyAuth.storeEncryptedKeys} is a neat integration point, ensuring the UI reacts accordingly. Verify that any edge cases—like missing or false values—are gracefully handled in the CreateKey component.

apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/validation.ts (1)

90-90: Default value for recoverEnabled
Setting recoverEnabled to false by default is a reasonable approach to ensuring users explicitly opt in to recoverability. This helps with best-practice security defaults.

apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/client.tsx (4)

49-60: New props in CreateKey
Introducing storeEncryptedKeys to the Props and handling them in the CreateKey component is clear. Great job ensuring default values are assigned for optional fields like prefix and bytes.


77-77: recoverEnabled: false
Defaulting recoverEnabled to false aligns with security best practices. Good choice to prevent accidental creation of recoverable keys.


116-118: Resetting recoverable state
This logic ensures recoverable toggles off on form submission if the user did not explicitly check recoverEnabled. Verify that partial form submissions or validations do not leave the component in an inconsistent state.


252-252: Resetting recoverEnabled after creation
Resetting the field ensures a fresh state for each subsequent key creation. Double-check that user preferences related to recoverability are appropriately re-initialized if they create multiple keys in succession.

@harshsbhat
Copy link
Contributor Author

third try 😔

hopefully, I get it this time

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3b36e6c and 3a66720.

📒 Files selected for processing (1)
  • apps/dashboard/lib/trpc/routers/key/create.ts (3 hunks)
🔇 Additional comments (2)
apps/dashboard/lib/trpc/routers/key/create.ts (2)

3-3: LGTM! Clean schema extension and imports.

The new imports and schema changes are well-structured and properly typed.

Also applies to: 7-7, 38-38


116-147: Verify security measures for recoverable keys

Please ensure the following security aspects are properly addressed:

  1. Verify that key material is properly cleaned up if the transaction fails
  2. Confirm that the vault's encryption meets security requirements
  3. Ensure audit logs capture the recovery-enabled status

Run the following script to check audit logging implementation:

✅ Verification successful

Security measures for recoverable keys are properly implemented

The implementation has appropriate security measures in place:

  1. Key material cleanup is handled through database transactions which ensure atomicity - if any part fails, the entire transaction is rolled back
  2. The vault encryption service:
    • Uses secure HTTPS communication
    • Requires authentication via bearer token
    • Includes request tracing via request IDs
    • Properly handles and reports encryption errors
  3. Errors during encryption or storage are properly caught and logged, with appropriate error messages
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if audit logs capture recovery-enabled status

# Check audit log schema and implementations
rg -A 5 "insertAuditLogs" 

# Check for any existing audit log patterns
ast-grep --pattern 'insertAuditLogs($_, {
  $$$
  description: $_,
  $$$
})'

Length of output: 66102


Script:

#!/bin/bash
# Check if audit logs capture recovery-enabled status in the create key router
rg -A 10 "key.create" apps/dashboard/lib/trpc/routers/key/create.ts

# Check if there are any audit logs related to key recovery
rg -A 10 "recovery" apps/dashboard/lib/trpc/routers/key/create.ts

Length of output: 431


Script:

#!/bin/bash
# Check the key creation implementation for cleanup on failure
rg -A 10 "catch\(" apps/dashboard/lib/trpc/routers/key/create.ts

# Check vault encryption implementation
rg -A 10 "class Vault" -g "*.ts"

Length of output: 3151


Script:

#!/bin/bash
# Check vault encryption implementation details
cat internal/vault/src/index.ts

# Check for transaction rollback handling
rg -A 10 "transaction" apps/dashboard/lib/trpc/routers/key/create.ts

Length of output: 2797

Comment on lines 131 to 146
await tx
.insert(schema.encryptedKeys)
.values({
keyId: keyId,
workspaceId: workspace?.id,
encrypted: vaultRes.encrypted,
encryptionKeyId: vaultRes.keyId,
})
.catch((err) => {
console.error(err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message:
"We are unable to store encrypted the key. Please contact support using [email protected]",
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve database operation safety

The database operations need similar improvements:

  1. Remove optional chaining for workspace.id
  2. Consider cleanup on failure
  3. Use consistent error messaging

Apply this diff:

   await tx
     .insert(schema.encryptedKeys)
     .values({
       keyId: keyId,
-      workspaceId: workspace?.id,
+      workspaceId: workspace.id,
       encrypted: vaultRes.encrypted,
       encryptionKeyId: vaultRes.keyId,
     })
     .catch((err) => {
       console.error(err);
+      // Consider cleanup of the key if encryption storage fails
       throw new TRPCError({
         code: "INTERNAL_SERVER_ERROR",
-        message:
-          "We are unable to store encrypted the key. Please contact support using [email protected]",
+        message: "Unable to process request. Please contact support.",
       });
     });

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 116 to 130
if (input.recoverEnabled && keyAuth?.storeEncryptedKeys) {
const vault = new Vault(env().AGENT_URL, env().AGENT_TOKEN);
const encryptReq: EncryptRequest = {
keyring: workspace?.id,
data: key,
};
const requestId = crypto.randomUUID();
const context: RequestContext = { requestId };
const vaultRes = await vault.encrypt(context, encryptReq).catch((err) => {
console.error(err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Encryption Failed. Please contact support using [email protected]",
});
});
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Strengthen error handling and null checks

A few suggestions to improve the robustness of the encryption implementation:

  1. Validate environment variables before vault initialization
  2. Replace optional chaining with explicit null check for workspace
  3. Consider using more user-friendly error messages

Apply this diff:

 if (input.recoverEnabled && keyAuth?.storeEncryptedKeys) {
+  if (!env().AGENT_URL || !env().AGENT_TOKEN) {
+    throw new TRPCError({
+      code: "INTERNAL_SERVER_ERROR",
+      message: "Unable to process request. Please contact support.",
+    });
+  }
+  if (!workspace) {
+    throw new TRPCError({
+      code: "INTERNAL_SERVER_ERROR",
+      message: "Unable to process request. Please contact support.",
+    });
+  }
   const vault = new Vault(env().AGENT_URL, env().AGENT_TOKEN);
   const encryptReq: EncryptRequest = {
-    keyring: workspace?.id,
+    keyring: workspace.id,
     data: key,
   };
   const requestId = crypto.randomUUID();
   const context: RequestContext = { requestId };
   const vaultRes = await vault.encrypt(context, encryptReq).catch((err) => {
     console.error(err);
     throw new TRPCError({
       code: "INTERNAL_SERVER_ERROR",
-      message: "Encryption Failed. Please contact support using [email protected]",
+      message: "Unable to process request. Please contact support.",
     });
   });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (input.recoverEnabled && keyAuth?.storeEncryptedKeys) {
const vault = new Vault(env().AGENT_URL, env().AGENT_TOKEN);
const encryptReq: EncryptRequest = {
keyring: workspace?.id,
data: key,
};
const requestId = crypto.randomUUID();
const context: RequestContext = { requestId };
const vaultRes = await vault.encrypt(context, encryptReq).catch((err) => {
console.error(err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Encryption Failed. Please contact support using [email protected]",
});
});
if (input.recoverEnabled && keyAuth?.storeEncryptedKeys) {
if (!env().AGENT_URL || !env().AGENT_TOKEN) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Unable to process request. Please contact support.",
});
}
if (!workspace) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Unable to process request. Please contact support.",
});
}
const vault = new Vault(env().AGENT_URL, env().AGENT_TOKEN);
const encryptReq: EncryptRequest = {
keyring: workspace.id,
data: key,
};
const requestId = crypto.randomUUID();
const context: RequestContext = { requestId };
const vaultRes = await vault.encrypt(context, encryptReq).catch((err) => {
console.error(err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Unable to process request. Please contact support.",
});
});

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine:

  • keyring: workspace?.id,
  • keyring: workspace.id,

I doubt the other two change requests tho. Let's wait for some maintainer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harshsbhat, understood! We'll defer to the maintainer's verdict on those additional changes. Let me know if you need anything else in the meantime.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
apps/dashboard/lib/trpc/routers/key/create.ts (1)

114-145: ⚠️ Potential issue

Strengthen error handling and encryption implementation.

The encryption logic needs improvements in several areas:

  1. The optional chaining on workspace?.id should be removed as workspace existence is already verified.
  2. Error messages expose internal details that should be abstracted.
  3. Consider cleanup if encryption succeeds but database insertion fails.

Apply this diff to address these issues:

-        if (input.recoverEnabled && keyAuth?.storeEncryptedKeys) {
+        if (input.recoverEnabled && keyAuth.storeEncryptedKeys) {
           const vault = new Vault(env().AGENT_URL, env().AGENT_TOKEN);
           const encryptReq: EncryptRequest = {
-            keyring: workspace?.id,
+            keyring: workspace.id,
             data: key,
           };
           const requestId = crypto.randomUUID();
           const context: RequestContext = { requestId };
           const vaultRes = await vault.encrypt(context, encryptReq).catch((err) => {
             console.error(err);
             throw new TRPCError({
               code: "INTERNAL_SERVER_ERROR",
-              message: "Encryption Failed. Please contact support using [email protected]",
+              message: "Unable to process request. Please contact support.",
             });
           });
           await tx
             .insert(schema.encryptedKeys)
             .values({
               keyId: keyId,
               workspaceId: workspace.id,
               encrypted: vaultRes.encrypted,
               encryptionKeyId: vaultRes.keyId,
             })
             .catch((err) => {
               console.error(err);
+              // Consider cleanup of the encrypted key from vault if db insertion fails
               throw new TRPCError({
                 code: "INTERNAL_SERVER_ERROR",
-                message:
-                  "We are unable to store encrypted the key. Please contact support using [email protected]",
+                message: "Unable to process request. Please contact support.",
               });
             });
         }
🧹 Nitpick comments (1)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/client.tsx (1)

803-853: Fix the documentation link.

The documentation link appears to be incorrect:

  1. The URL is missing the protocol (https://)
  2. The link text includes a period that should be outside the link

Apply this diff:

-              href={"unkey.com/docs/security/recovering-keys"}
+              href={"https://unkey.com/docs/security/recovering-keys"}
             >
-              unkey.com/docs/security/recovering-keys.
+              unkey.com/docs/security/recovering-keys
+            </Link>
+            .
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a66720 and d0756a1.

📒 Files selected for processing (3)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/client.tsx (8 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/validation.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/key/create.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/validation.ts
🔇 Additional comments (4)
apps/dashboard/lib/trpc/routers/key/create.ts (1)

37-37: LGTM!

The input schema change correctly adds the optional recoverEnabled field.

apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/new/client.tsx (3)

49-49: LGTM!

The Props type and component signature are correctly updated to include the storeEncryptedKeys property.

Also applies to: 54-60


77-77: LGTM!

The form state management for recoverEnabled is implemented correctly, including default values and submission handling.

Also applies to: 116-118, 134-134


192-221: LGTM!

The alert messages are well-crafted and provide clear information about key recoverability status.

@harshsbhat
Copy link
Contributor Author

It is building the dashboard correctly on the local setup.

Not sure why it is failing here. Can you send me the fail message if it is on my side?

@perkinsjr
Copy link
Collaborator

Yup it's failing for the @unkey/vault type import

@unkey/dashboard:build: Type error: Cannot find module '@unkey/vault' or its corresponding type declarations.
@unkey/dashboard:build: 
@unkey/dashboard:build:    5 | import { newId } from "@unkey/id";
@unkey/dashboard:build:    6 | import { newKey } from "@unkey/keys";
@unkey/dashboard:build: >  7 | import { type EncryptRequest, type RequestContext, Vault } from "@unkey/vault";
@unkey/dashboard:build:      |                                                                 ^
@unkey/dashboard:build:    8 | import { z } from "zod";
@unkey/dashboard:build:    9 | import { auth, t } from "../../trpc";
@unkey/dashboard:build:   10 |
@unkey/dashboard:build:  ELIFECYCLE  Command failed with exit code 1.
@unkey/dashboard:build: ERROR: command finished with error: command (/vercel/path0/apps/dashboard) /pnpm8/node_modules/.bin/pnpm run build exited (1)
@unkey/dashboard#build: command (/vercel/path0/apps/dashboard) /pnpm8/node_modules/.bin/pnpm run build exited (1)
  Tasks:    4 successful, 5 total

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/dashboard/package.json (1)

59-59: Consider removing the caret from the workspace dependency version.

The workspace:^ version specifier includes a caret which is unusual for workspace dependencies. Consider using just workspace:* or workspace: to avoid any potential versioning issues.

-    "@unkey/vault": "workspace:^",
+    "@unkey/vault": "workspace:*",
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8bfc8aa and 7741652.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • apps/dashboard/package.json (1 hunks)

@@ -56,6 +56,7 @@
"@unkey/ui": "workspace:^",
"@unkey/validation": "workspace:^",
"@unkey/vercel": "workspace:^",
"@unkey/vault": "workspace:^",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Workspace pattern doesn't include the vault package location

The build failure is occurring because the vault package is located at internal/vault/ but the workspace configuration in the root package.json only includes "apps/*" and "packages/*" patterns. The vault package needs to be moved to the packages/ directory or the workspace pattern needs to be updated to include the internal/* pattern.

  • Move internal/vault/ to packages/vault/
    OR
  • Add "internal/*" to the workspaces array in the root package.json
🔗 Analysis chain

Verify the workspace dependency setup.

The build failure mentioned in the PR comments suggests that the @unkey/vault module is not being found. Please ensure that:

  1. The vault package exists in the workspace
  2. The vault package is built before the dashboard
  3. Type declarations are properly generated and exported

Let's verify the workspace setup with the following script:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the workspace setup for @unkey/vault

# Check if the vault package exists in the workspace
echo "Checking for vault package..."
fd -t f "package.json" -x grep -l "@unkey/vault"

# Check for type declarations
echo "Checking for type declarations..."
fd -t f "index.d.ts" -x grep -l "vault"

# Check package.json files for build order dependencies
echo "Checking build dependencies..."
fd -t f "package.json" -x grep -l "\"build\".*@unkey/vault"

Length of output: 419


Script:

#!/bin/bash
# Description: Deep dive into vault package setup

# Check vault package.json contents
echo "=== Vault package.json contents ==="
cat ./internal/vault/package.json

# Check for TypeScript configuration
echo -e "\n=== TypeScript configuration files ==="
fd -t f "tsconfig.json|.d.ts$" -p internal/vault

# Check for workspace-level configuration
echo -e "\n=== Workspace configuration ==="
cat package.json

Length of output: 2340

@harshsbhat
Copy link
Contributor Author

Hey @perkinsjr, I added it in the package.json and also pushed the pnpm-lock. Can you check it now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow setting recoverable: true when creating keys in the dashboard
2 participants