Skip to content

Commit 60769cb

Browse files
committed
refactor: caching the derived key
1 parent 8ac4d8f commit 60769cb

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

src/lib/__tests__/auth.test.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,16 @@ const ENCRYPTION_SALT = "oidc_token_salt";
3232
const KEY_LENGTH = 32;
3333
const IV_LENGTH = 12;
3434

35+
// Cache derived key to match auth.ts behavior
36+
const TEST_DERIVED_KEY = crypto.scryptSync(
37+
process.env.BETTER_AUTH_SECRET as string,
38+
ENCRYPTION_SALT,
39+
KEY_LENGTH,
40+
);
41+
3542
function encryptTestData(text: string): string {
36-
const key = crypto.scryptSync(
37-
process.env.BETTER_AUTH_SECRET as string,
38-
ENCRYPTION_SALT,
39-
KEY_LENGTH,
40-
);
4143
const iv = crypto.randomBytes(IV_LENGTH);
42-
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
44+
const cipher = crypto.createCipheriv("aes-256-gcm", TEST_DERIVED_KEY, iv);
4345

4446
const encrypted = Buffer.concat([
4547
cipher.update(text, "utf8"),

src/lib/auth.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ const ENCRYPTION_SALT = "oidc_token_salt";
1717
const KEY_LENGTH = 32;
1818
const IV_LENGTH = 12;
1919

20+
// Derive encryption key once at module initialization to avoid blocking event loop
21+
const DERIVED_KEY = crypto.scryptSync(
22+
ENCRYPTION_KEY,
23+
ENCRYPTION_SALT,
24+
KEY_LENGTH,
25+
);
26+
2027
// Token expiration constants
2128
const TOKEN_ONE_HOUR_MS = 60 * 60 * 1000; // milliseconds
2229
const TOKEN_SEVEN_DAYS_SECONDS = 7 * 24 * 60 * 60; // seconds
@@ -66,9 +73,8 @@ function isOidcTokenData(data: unknown): data is OidcTokenData {
6673
* Returns encrypted data in format: iv:authTag:encrypted (all hex-encoded).
6774
*/
6875
function encrypt(text: string): string {
69-
const key = crypto.scryptSync(ENCRYPTION_KEY, ENCRYPTION_SALT, KEY_LENGTH);
7076
const iv = crypto.randomBytes(IV_LENGTH);
71-
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
77+
const cipher = crypto.createCipheriv("aes-256-gcm", DERIVED_KEY, iv);
7278

7379
const encrypted = Buffer.concat([
7480
cipher.update(text, "utf8"),
@@ -90,7 +96,6 @@ function encrypt(text: string): string {
9096
* Expects data in format: iv:authTag:encrypted (all hex-encoded).
9197
*/
9298
function decrypt(payload: string): string {
93-
const key = crypto.scryptSync(ENCRYPTION_KEY, ENCRYPTION_SALT, KEY_LENGTH);
9499
const [ivHex, tagHex, encryptedHex] = payload.split(":");
95100

96101
if (!ivHex || !tagHex || !encryptedHex) {
@@ -101,7 +106,7 @@ function decrypt(payload: string): string {
101106
const authTag = Buffer.from(tagHex, "hex");
102107
const encrypted = Buffer.from(encryptedHex, "hex");
103108

104-
const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
109+
const decipher = crypto.createDecipheriv("aes-256-gcm", DERIVED_KEY, iv);
105110
decipher.setAuthTag(authTag);
106111

107112
const decrypted = Buffer.concat([

0 commit comments

Comments
 (0)