Skip to content

fix(root): generate encryption envs in scripts#10449

Open
VitorPorf wants to merge 6 commits intonovuhq:nextfrom
VitorPorf:fix/setup-env-generate-scripts
Open

fix(root): generate encryption envs in scripts#10449
VitorPorf wants to merge 6 commits intonovuhq:nextfrom
VitorPorf:fix/setup-env-generate-scripts

Conversation

@VitorPorf
Copy link
Copy Markdown

@VitorPorf VitorPorf commented Mar 24, 2026

What changed? Why was the change needed?
The setup-env-files.js script was copying .example.env files directly to .env without replacing encryption key placeholders. The literal value <ENCRYPTION_KEY_MUST_BE_32_LONG> was left in the generated environment files, causing service startup errors on local setup.

Changes:

Added the crypto module to generate random keys
The script now generates a single sharedEncryptionKey per run (32-char hex via randomBytes(16))
During .example.env copy, the <ENCRYPTION_KEY_MUST_BE_32_LONG> placeholder is automatically replaced with the generated key
The same key is shared across all apps (api, ws, worker, dashboard) to ensure consistency between services

I opened a new PR because I accidentally uploaded local code, my mistake, I apologize.

What changed

The setup-env-files.js script now automatically generates a random 32-character encryption key during startup and replaces the placeholder <ENCRYPTION_KEY_MUST_BE_32_LONG> in .example.env files when copying them to .env. Previously, the script copied example files verbatim, leaving the placeholder text in place and causing local startup failures. The same generated key is applied consistently across all services (api, ws, worker, dashboard) to ensure alignment between services during development setup.

Affected areas

  • scripts: The setup-env-files.js script now uses Node's crypto module to generate encryption keys and conditionally replace environment variable placeholders during .env file initialization.

Key technical decisions

  • Uses Node's built-in crypto.randomBytes(16).toString('hex') to generate secure random 32-character hex keys
  • Single shared key per script execution ensures consistency across all services instead of generating separate keys for each

Testing

No tests added. This is a local development setup script; manual verification during local environment initialization is sufficient.


Note

Low Risk
Low risk because changes are limited to a local dev setup script, but it alters generated .env contents and could affect local startup if placeholder replacement is incorrect.

Overview
The env setup script now generates a single random 32-character encryption key per run and injects it into newly created .env files by replacing the <ENCRYPTION_KEY_MUST_BE_32_LONG> placeholder when copying from .example.env.

It also switches from raw file copying to reading/writing the env file content so the same key is shared across api, ws, worker, and dashboard during local setup.

Reviewed by Cursor Bugbot for commit 1acbf11. Configure here.

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 24, 2026

👷 Deploy request for dashboard-v2-novu-staging pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 57973eb

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

📝 Walkthrough

Walkthrough

The setup script now generates a random encryption key once per run and injects it into environment files by replacing ENCRYPTION_KEY_PLACEHOLDER tokens. The prePopulateEnv function reads source files, conditionally replaces placeholders with the shared key, and writes the modified content to destination paths.

Changes

Cohort / File(s) Summary
Encryption Key Generation & Injection
scripts/setup-env-files.js
Added crypto module usage to generate encryption keys. Modified prePopulateEnv to read source file content, replace ENCRYPTION_KEY_PLACEHOLDER with provided key, and write result. Updated file path variables and invocation to pass encryption key across app groups.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title uses the correct Conventional Commits format with type 'fix' and scope 'root', but the scope conflicts with actual changes which target the setup-env-files.js script and should use scope 'js'. However, it accurately describes the main objective of generating encryption keys in the setup script.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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


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.

@VitorPorf VitorPorf force-pushed the fix/setup-env-generate-scripts branch from 6d39f92 to c58d2e4 Compare March 24, 2026 14:01
@VitorPorf VitorPorf changed the title fix(setup-env-files): generate encryption envs in scripts fix(root): generate encryption envs in scripts Mar 24, 2026
Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
scripts/setup-env-files.js (1)

18-19: Consider using replaceAll() for robustness.

String.prototype.replace() only replaces the first occurrence. While current .example.env files appear to have a single placeholder, using replaceAll() would be more defensive against future changes.

♻️ Suggested change
-      if (content.includes(ENCRYPTION_KEY_PLACEHOLDER) && sharedEncryptionKey) {
-        content = content.replace(ENCRYPTION_KEY_PLACEHOLDER, sharedEncryptionKey);
+      if (sharedEncryptionKey && content.includes(ENCRYPTION_KEY_PLACEHOLDER)) {
+        content = content.replaceAll(ENCRYPTION_KEY_PLACEHOLDER, sharedEncryptionKey);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/setup-env-files.js` around lines 18 - 19, The code currently uses
content.replace(ENCRYPTION_KEY_PLACEHOLDER, sharedEncryptionKey) which only
replaces the first occurrence; update the replacement to use
content.replaceAll(ENCRYPTION_KEY_PLACEHOLDER, sharedEncryptionKey) (or an
equivalent split/join fallback) so all placeholders in the content are replaced;
reference the variables content, ENCRYPTION_KEY_PLACEHOLDER and
sharedEncryptionKey in the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@scripts/setup-env-files.js`:
- Around line 18-19: The code currently uses
content.replace(ENCRYPTION_KEY_PLACEHOLDER, sharedEncryptionKey) which only
replaces the first occurrence; update the replacement to use
content.replaceAll(ENCRYPTION_KEY_PLACEHOLDER, sharedEncryptionKey) (or an
equivalent split/join fallback) so all placeholders in the content are replaced;
reference the variables content, ENCRYPTION_KEY_PLACEHOLDER and
sharedEncryptionKey in the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7aea6e74-1708-4163-bd13-399d16dc66b9

📥 Commits

Reviewing files that changed from the base of the PR and between 8e29c33 and c58d2e4.

📒 Files selected for processing (1)
  • scripts/setup-env-files.js

Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 1acbf11. Configure here.

const sourcePath = path.resolve(`${folderBasePath}/${folder}/${exampleEnvFilePath}`);
let content = fs.readFileSync(sourcePath, 'utf8');
if (content.includes(ENCRYPTION_KEY_PLACEHOLDER) && sharedEncryptionKey) {
content = content.replace(ENCRYPTION_KEY_PLACEHOLDER, sharedEncryptionKey);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

replace only substitutes first placeholder occurrence

Low Severity

content.replace(ENCRYPTION_KEY_PLACEHOLDER, sharedEncryptionKey) only replaces the first occurrence of the placeholder. If an .example.env file ever contains the <ENCRYPTION_KEY_MUST_BE_32_LONG> placeholder on more than one line, subsequent occurrences will be left as literal placeholder text, silently breaking those env vars. Using replaceAll (or split/join) would match the intent of replacing every occurrence.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1acbf11. Configure here.

…bstituting the <ENCRYPTION_KEY_MUST_BE_32_LONG> placeholder.
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