@@ -26,12 +26,28 @@ const IV_LENGTH = 12;
2626 */
2727const ENCRYPTION_SALT = "oidc_token_salt" ;
2828
29- // Derive encryption key once at module initialization to avoid blocking event loop
30- const DERIVED_KEY = crypto . scryptSync (
31- ENCRYPTION_KEY as string ,
32- ENCRYPTION_SALT ,
33- KEY_LENGTH ,
34- ) ;
29+ // Cache for derived key (lazy initialization)
30+ let DERIVED_KEY : Buffer | null = null ;
31+
32+ /**
33+ * Gets or derives the encryption key on first use.
34+ * Lazy initialization avoids build-time errors when env vars are not set.
35+ */
36+ function getDerivedKey ( ) : Buffer {
37+ if ( ! DERIVED_KEY ) {
38+ if ( ! ENCRYPTION_KEY ) {
39+ throw new Error (
40+ "BETTER_AUTH_SECRET environment variable is required for encryption" ,
41+ ) ;
42+ }
43+ DERIVED_KEY = crypto . scryptSync (
44+ ENCRYPTION_KEY ,
45+ ENCRYPTION_SALT ,
46+ KEY_LENGTH ,
47+ ) ;
48+ }
49+ return DERIVED_KEY ;
50+ }
3551
3652// Token expiration constants
3753const TOKEN_ONE_HOUR_MS = 60 * 60 * 1000 ; // milliseconds
@@ -84,7 +100,7 @@ function isOidcTokenData(data: unknown): data is OidcTokenData {
84100 */
85101export function encrypt ( text : string ) : string {
86102 const iv = crypto . randomBytes ( IV_LENGTH ) ;
87- const cipher = crypto . createCipheriv ( "aes-256-gcm" , DERIVED_KEY , iv ) ;
103+ const cipher = crypto . createCipheriv ( "aes-256-gcm" , getDerivedKey ( ) , iv ) ;
88104
89105 const encrypted = Buffer . concat ( [
90106 cipher . update ( text , "utf8" ) ,
@@ -117,7 +133,7 @@ export function decrypt(payload: string): string {
117133 const authTag = Buffer . from ( tagHex , "hex" ) ;
118134 const encrypted = Buffer . from ( encryptedHex , "hex" ) ;
119135
120- const decipher = crypto . createDecipheriv ( "aes-256-gcm" , DERIVED_KEY , iv ) ;
136+ const decipher = crypto . createDecipheriv ( "aes-256-gcm" , getDerivedKey ( ) , iv ) ;
121137 decipher . setAuthTag ( authTag ) ;
122138
123139 const decrypted = Buffer . concat ( [
0 commit comments