Skip to content

Add Server Secret Generator tool and update sitemap#529

Merged
softmarshmallow merged 1 commit intomainfrom
canary
Feb 5, 2026
Merged

Add Server Secret Generator tool and update sitemap#529
softmarshmallow merged 1 commit intomainfrom
canary

Conversation

@softmarshmallow
Copy link
Member

@softmarshmallow softmarshmallow commented Feb 5, 2026

https://grida.co/tools/keygen

Introduce a new Server Secret Generator tool that allows users to generate secure server secrets, including S2S API keys and JWT keys. Update the sitemap to include the new tool's URL for better accessibility. Enhance the tools page metadata to reflect the new functionality and improve keyword targeting.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added Server Secret Generator tool to the tools menu, enabling users to generate various secret types including byte sequences, PKCE keys, and cryptographic keypairs
    • Multiple output formats (plain, env, header, JSON) with encoding options and algorithm selection (ES256, RS256)
    • Copy-to-clipboard and quick regeneration capabilities with optional server-side generation support

Introduce a new Server Secret Generator tool that allows users to generate secure server secrets, including S2S API keys and JWT keys. Update the sitemap to include the new tool's URL for better accessibility. Enhance the tools page metadata to reflect the new functionality and improve keyword targeting.
@vercel
Copy link

vercel bot commented Feb 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Feb 5, 2026 2:08pm
grida Ready Ready Preview, Comment Feb 5, 2026 2:08pm
5 Skipped Deployments
Project Deployment Actions Updated (UTC)
code Ignored Ignored Feb 5, 2026 2:08pm
legacy Ignored Ignored Feb 5, 2026 2:08pm
backgrounds Skipped Skipped Feb 5, 2026 2:08pm
blog Skipped Skipped Feb 5, 2026 2:08pm
viewer Skipped Skipped Feb 5, 2026 2:08pm

Request Review

@coderabbitai
Copy link

coderabbitai bot commented Feb 5, 2026

Walkthrough

A new server secret and key generator tool is introduced as a client-side React application with Web Crypto API support for generating secrets, PKCE pairs, and keypairs, complemented by a server-side action for RSA/EC keypair generation, along with supporting pages and navigation updates.

Changes

Cohort / File(s) Summary
Keygen Tool Implementation
editor/app/(tools)/tools/keygen/_page.tsx, editor/app/(tools)/tools/keygen/actions.ts, editor/app/(tools)/tools/keygen/page.tsx
Introduces a comprehensive server secret generator with client-side generation using Web Crypto APIs for bytes, PKCE, and keypairs; supports multiple output formats (plain, env, header, JSON); includes server-side keypair generation action for ES256 and RS256 algorithms; features UI with scenario catalog, quick picks, advanced options, and copy-to-clipboard functionality.
Navigation & Discovery
editor/app/(tools)/tools/page.tsx, editor/app/sitemap.ts
Adds Server Secret Generator tool entry to the tools index page with KeyRoundIcon; updates metadata to reference server secrets; includes new sitemap entry for the keygen tool route.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant UI as Client-Side UI<br/>(React Component)
    participant WebCrypto as Web Crypto API
    participant Server as Server Action
    participant Output as Output Handler

    User->>UI: Select secret scenario & options
    
    alt Client-side generation (bytes, PKCE)
        UI->>WebCrypto: Generate random bytes
        WebCrypto-->>UI: Raw bytes
        UI->>UI: Encode (base64url/hex)
        UI->>Output: Format output (plain/env/header/JSON)
    else Server-side keypair generation
        UI->>Server: generateKeypairAction(algorithm)
        Server->>WebCrypto: crypto.generateKeyPair()
        WebCrypto-->>Server: Public/Private key pair
        Server->>Server: Convert to PEM format
        Server-->>UI: PEM-encoded keypair
        UI->>Output: Format keypair output
    end
    
    Output-->>UI: Formatted secret(s)
    UI->>User: Display with copy-to-clipboard
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A keyring of secrets now springs to life,
With bytes and with pairs, and no digital strife!
The Web Crypto dances, the server returns,
As our bunny's new tool sparkles and burns! ✨🔑

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main changes: adding a new Server Secret Generator tool and updating the sitemap.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch canary

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8330d475da

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1184 to +1188
const payload = await generateKeypairAction(keypairAlgorithm);
setGenerated({
kind: "keypair",
privateKeyPem: payload.privateKeyPem,
publicKeyPem: payload.publicKeyPem,

Choose a reason for hiding this comment

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

P2 Badge Ignore stale async generation results

This async branch writes to generated after awaiting generateKeypairAction, but it never verifies that the request still matches the currently selected scenario/options. If a user starts keypair generation (especially slower RS256/server fallback) and switches scenarios before it resolves, the older promise can overwrite the newer state, causing the output panel to show the wrong secret type for the current UI selection. Add request-versioning/cancellation (or compare current scenario before setGenerated) so out-of-order completions are dropped.

Useful? React with 👍 / 👎.

Copy link

@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

🤖 Fix all issues with AI agents
In `@editor/app/`(tools)/tools/keygen/_page.tsx:
- Around line 917-928: The JSON-LD construction in FAQ_JSON_LD uses raw strings
that can contain "<" and triggers the Next.js security lint; instead build the
JSON string from the FAQ_JSON_LD object, replace all "<" with "\\u003c" (e.g.,
JSON.stringify(FAQ_JSON_LD).replace(/</g, '\\u003c')) and use that escaped
string where you inject the script; also add a biome-ignore suppression comment
(with a short justification) immediately above the code that injects the JSON-LD
to suppress the security lint rule. Locate FAQ_JSON_LD and any other similar
JSON-LD blocks (e.g., the other occurrence around where FAQ_ITEMS is used) and
apply the same escaping + biome-ignore pattern.

Comment on lines +917 to +928
const FAQ_JSON_LD = {
"@context": "https://schema.org",
"@type": "FAQPage",
mainEntity: FAQ_ITEMS.map((item) => ({
"@type": "Question",
name: item.question,
acceptedAnswer: {
"@type": "Answer",
text: item.answer,
},
})),
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

head -n 950 editor/app/\(tools\)/tools/keygen/_page.tsx | tail -n 50

Repository: gridaco/grida

Length of output: 1740


🏁 Script executed:

sed -n '917,928p' editor/app/\(tools\)/tools/keygen/_page.tsx

Repository: gridaco/grida

Length of output: 316


🏁 Script executed:

sed -n '1758,1761p' editor/app/\(tools\)/tools/keygen/_page.tsx

Repository: gridaco/grida

Length of output: 188


🌐 Web query:

Next.js 16 JSON-LD structured data implementation best practices dangerouslySetInnerHTML

💡 Result:

Best practices (Next.js App Router / “Next.js 16”)

  1. Render JSON-LD as a plain <script type="application/ld+json"> in page.tsx or layout.tsx (SSR)—this is Next.js’s current recommendation. [1]
  2. Use dangerouslySetInnerHTML with JSON.stringify (required for JSON-LD), but prevent XSS: JSON.stringify doesn’t sanitize; at minimum, escape < (e.g. replace with \\u003c) or use a safer serializer (e.g. serialize-javascript). [1]
  3. Keep structured data truthful and aligned with visible page content (don’t mark up entities/info the user can’t see), and include all required properties for the rich-result type you’re targeting. [5]
  4. Placement: Google supports JSON-LD in <head> or <body> and can also read JSON-LD injected by JS, but SSR is typically simplest/most reliable. [4]
  5. Validate: use Google’s Rich Results Test and/or Schema Markup Validator. [1]

Recommended pattern (App Router)

// app/products/[id]/page.tsx
export default async function Page({ params }: { params: { id: string } }) {
  const product = await getProduct(params.id)

  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "Product",
    name: product.name,
    image: product.image,
    description: product.description,
  }

  return (
    <section>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{
          __html: JSON.stringify(jsonLd).replace(/</g, "\\u003c"),
        }}
      />
      {/* page content */}
    </section>
  )
}

This matches Next.js guidance (including the < escaping). [1]


🌐 Web query:

Biome ESLint security rule noDangerouslySetInnerHtml JSON-LD recommended approach

💡 Result:

What Biome is flagging

Biome’s lint/security/noDangerouslySetInnerHtml is a recommended (default-on) security rule that reports any dangerouslySetInnerHTML usage because it can enable XSS if untrusted strings reach it. [1]

Recommended JSON-LD approach (avoid dangerouslySetInnerHTML)

If you’re emitting JSON-LD, you can usually avoid dangerouslySetInnerHTML entirely by rendering the JSON as a normal text child of a <script type="application/ld+json"> tag:

const jsonLd = { /* ... */ };

<script type="application/ld+json">
  {JSON.stringify(jsonLd).replace(/</g, "\\u003c")}
</script>

Google’s recommended structured-data format is JSON-LD inside a <script> tag. [2]

If you’re following Next.js’ official guide (it uses dangerouslySetInnerHTML)

Next.js’ JSON-LD guide shows dangerouslySetInnerHTML and explicitly warns that JSON.stringify doesn’t sanitize malicious strings; it suggests scrubbing < (e.g. replace(/</g, '\\u003c')) or using safer serializers. [3]

In that case, keep the rule enabled globally and add a targeted suppression with an explanation:

// biome-ignore lint/security/noDangerouslySetInnerHtml: JSON-LD is emitted in a <script type="application/ld+json">; payload is sanitized (< -> \u003c)
<script
  type="application/ld+json"
  dangerouslySetInnerHTML={{
    __html: JSON.stringify(jsonLd).replace(/</g, "\\u003c"),
  }}
/>

Biome’s suppression comment syntax is documented here. [4]


Sources: Biome rule docs [1], Google structured data docs [2], Next.js JSON-LD guide [3], Biome suppressions docs [4].

[1] (biomejs.dev)
[2] (developers.google.com)
[3] (nextjs.org)
[4] (biomejs.dev)

Citations:


Add JSON-LD escaping and suppress the security lint rule.

The current code missing the < character escaping required by the security rule. Per Next.js 16 guidance, escape < as \\u003c in the JSON string and add a biome-ignore suppression with justification. This prevents lint failures and addresses the XSS vulnerability concern:

Suggested fix
+const FAQ_JSON_LD_STRING = JSON.stringify(FAQ_JSON_LD).replace(/</g, "\\u003c");
+      {/* biome-ignore lint/security/noDangerouslySetInnerHtml: JSON-LD is static and pre-escaped */}
       <script
         type="application/ld+json"
-        dangerouslySetInnerHTML={{ __html: JSON.stringify(FAQ_JSON_LD) }}
+        dangerouslySetInnerHTML={{ __html: FAQ_JSON_LD_STRING }}
       />

Also applies to: 1758-1761

🤖 Prompt for AI Agents
In `@editor/app/`(tools)/tools/keygen/_page.tsx around lines 917 - 928, The
JSON-LD construction in FAQ_JSON_LD uses raw strings that can contain "<" and
triggers the Next.js security lint; instead build the JSON string from the
FAQ_JSON_LD object, replace all "<" with "\\u003c" (e.g.,
JSON.stringify(FAQ_JSON_LD).replace(/</g, '\\u003c')) and use that escaped
string where you inject the script; also add a biome-ignore suppression comment
(with a short justification) immediately above the code that injects the JSON-LD
to suppress the security lint rule. Locate FAQ_JSON_LD and any other similar
JSON-LD blocks (e.g., the other occurrence around where FAQ_ITEMS is used) and
apply the same escaping + biome-ignore pattern.

@softmarshmallow softmarshmallow merged commit 416afc2 into main Feb 5, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant