AINATIVEM-42 AES-256-GCM token encryption#8
Merged
Conversation
- generate src/crypto/encrypt.ts with encrypt/decrypt using node:crypto - wire CryptoStep into NodeProjectBuilder, add ENCRYPTION_KEY to .env.example - widen access_token/refresh_token columns to TEXT (varchar(768) too small for ciphertext) - encrypt on write, decrypt on read in tokenRepository for all db drivers - add RUN mkdir -p /app/data && chown in Dockerfile for sqlite volume permissions - replace docker compose with docker-compose in CLI next steps - add USER node to generated Dockerfile
dmitriyeff
approved these changes
May 14, 2026
There was a problem hiding this comment.
Pull request overview
This PR adds AES-256-GCM token encryption to the generated Node scaffold and updates related database, environment, Docker, CLI, and test coverage.
Changes:
- Adds generated
src/crypto/encrypt.tsand wires token encryption/decryption intotokenRepository. - Widens token columns to
TEXTfor Postgres/MySQL and addsENCRYPTION_KEYto generated env examples. - Updates Docker/CLI behavior and adds tests for crypto generation, schema changes, and Dockerfile updates.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
src/generators/node/projectBuilder.ts |
Adds crypto generation step and ENCRYPTION_KEY env example entry. |
src/generators/node/projectBuilder.test.ts |
Tests env example and crypto file generation via builder. |
src/generators/node/index.ts |
Includes crypto generation in the main Node generator pipeline. |
src/generators/node/database.ts |
Encrypts/decrypts tokens, widens token columns, and updates Dockerfile user/data ownership. |
src/generators/node/database.test.ts |
Adds coverage for token column type changes, crypto imports, and Dockerfile updates. |
src/generators/node/crypto.ts |
Adds generator for AES-256-GCM encrypt/decrypt helper. |
src/generators/node/crypto.test.ts |
Adds tests for generated crypto helper content and round-trip behavior. |
src/cli.ts |
Updates next-step command to docker-compose up. |
src/cli.test.ts |
Updates CLI next-step expectation. |
Comments suppressed due to low confidence (1)
src/generators/node/database.ts:400
- These update values re-encrypt the same access and refresh tokens that were already encrypted for the insert values above, so each upsert performs duplicate crypto work and sends two different ciphertexts for each token in one statement. Compute the encrypted tokens once and reuse them for both insert and update fields.
accessToken: encrypt(token.access_token),
refreshToken: encrypt(token.refresh_token),
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+16
to
+18
| const buf = Buffer.from(key, 'hex'); | ||
| if (buf.length !== 32) throw new Error('ENCRYPTION_KEY must be a 64-char hex string (32 bytes)'); | ||
| return buf; |
Comment on lines
+30
to
+31
| const [ivB64, authTagB64, dataB64] = ciphertext.split('.'); | ||
| if (!ivB64 || !authTagB64 || !dataB64) throw new Error('Invalid ciphertext format'); |
Comment on lines
+199
to
+200
| ENCRYPTION_KEY= | ||
| # generate with: openssl rand -hex 32 |
| await writeFile( | ||
| runner, | ||
| ` | ||
| import { encrypt, decrypt } from '${join(tmpDir, 'src/crypto/encrypt.ts')}'; |
| @@ -16,7 +16,7 @@ export function nextStepLines(options: NextStepOptions): string[] { | |||
| `cd ${options.nameOrPath}`, | |||
| 'cp .env.example .env', | |||
| '# fill in PIPEDRIVE_CLIENT_ID and PIPEDRIVE_CLIENT_SECRET', | |||
Comment on lines
+53
to
+54
| const { execSync } = await import('node:child_process'); | ||
| const out = execSync(`./node_modules/.bin/tsx ${runner}`, { |
Comment on lines
+320
to
+321
| accessToken: encrypt(token.access_token), | ||
| refreshToken: encrypt(token.refresh_token), |
Comment on lines
+199
to
+200
| ENCRYPTION_KEY= | ||
| # generate with: openssl rand -hex 32 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/crypto/encrypt.tsin the scaffolded app: AES-256-GCM encrypt/decrypt using Node.js built-innode:cryptotokenRepositoryaccess_tokenandrefresh_tokencolumns widened fromVARCHAR(768)toTEXT(ciphertext is larger than plaintext)ENCRYPTION_KEY=added to generated.env.examplewith a# generate with: openssl rand -hex 32hintdocker compose up→docker-compose upin CLI next stepsUSER nodeadded to generated Dockerfile; SQLite volume directory pre-created with correct ownershipTest plan
npm testpasses