@@ -33,20 +33,21 @@ export interface EncryptedData {
33
33
}
34
34
35
35
/**
36
- * Decrypts the passed encrypted data using the passed password .
37
- * If the password is wrong, an error will be returned.
36
+ * Decrypts the passed encrypted data using the passed encryption key .
37
+ * If the encryption key is wrong, an error will be returned.
38
38
*
39
39
* @param cipherText the ciphertext that needs to be decrypted.
40
- * @param password the password for the encrypted data.
40
+ * @param encryptionKey the encryption key for the encrypted data.
41
+ * @param iv the initialization vector for the encrypted data.
41
42
*/
42
43
export function decryptData (
43
44
cipherText : string ,
44
- password : string | crypto . lib . WordArray ,
45
+ encryptionKey : string | crypto . lib . WordArray ,
45
46
iv : string | undefined ,
46
47
) : Result < PersistentData > {
47
48
try {
48
49
const ivWordArray = iv ? crypto . enc . Hex . parse ( iv ) : undefined ;
49
- const decryptedBytes = crypto . AES . decrypt ( cipherText , password , { iv : ivWordArray } ) ;
50
+ const decryptedBytes = crypto . AES . decrypt ( cipherText , encryptionKey , { iv : ivWordArray } ) ;
50
51
const decryptedText = decryptedBytes . toString ( crypto . enc . Utf8 ) ;
51
52
const data : PersistentData = JSON . parse ( decryptedText ) ;
52
53
return success ( data ) ;
@@ -55,14 +56,14 @@ export function decryptData(
55
56
}
56
57
}
57
58
58
- export function encryptData ( data : PersistentData , password : string | crypto . lib . WordArray ) : [ string , string ] {
59
+ export function encryptData ( data : PersistentData , encryptionKey : crypto . lib . WordArray ) : [ string , string ] {
59
60
const iv = crypto . lib . WordArray . random ( 16 ) ;
60
61
const ivText = iv . toString ( ) ;
61
- const encrypted = crypto . AES . encrypt ( JSON . stringify ( data ) , password , { iv } ) ;
62
+ const encrypted = crypto . AES . encrypt ( JSON . stringify ( data ) , encryptionKey , { iv } ) ;
62
63
return [ encrypted . toString ( ) , ivText ] ;
63
64
}
64
65
65
- export function deriveEncryptionSecret ( password : string , salt : string | undefined ) : string {
66
+ export function deriveEncryptionKey ( password : string , salt : string | undefined ) : string {
66
67
if ( salt === undefined ) {
67
68
return password ;
68
69
}
@@ -80,7 +81,7 @@ export function deriveEncryptionSecret(password: string, salt: string | undefine
80
81
export function reEncryptData (
81
82
data : EncryptedData ,
82
83
oldSecret : string | crypto . lib . WordArray ,
83
- newSecret : string | crypto . lib . WordArray ,
84
+ newSecret : crypto . lib . WordArray ,
84
85
) : Result < void > {
85
86
if ( data . cipherText === undefined ) {
86
87
return error ( "Cannot re-encrypt empty cipher text." ) ;
@@ -101,7 +102,7 @@ export function reEncryptData(
101
102
* Manages encrypted persistence of data that is held by the instance and bundle managers.
102
103
*/
103
104
export class PersistenceManager {
104
- private password : string | undefined ;
105
+ private encryptionKey : string | undefined ;
105
106
// We store the encrypted data in a replicant, because writing files in a NodeCG bundle isn't very clean
106
107
// and the bundle config is read-only. It is only in encrypted form, so it is OK to be accessible in the browser.
107
108
private encryptedData : ReplicantServer < EncryptedData > ;
@@ -120,38 +121,38 @@ export class PersistenceManager {
120
121
}
121
122
122
123
/**
123
- * Checks whether the passed password is correct. Only works if already loaded and a password is already set.
124
- * @param password the password which should be checked for correctness
124
+ * Checks whether the passed encryption key is correct. Only works if already loaded and a encryption key is already set.
125
+ * @param encryptionKey the encryption key which should be checked for correctness
125
126
*/
126
- checkPassword ( password : string ) : boolean {
127
+ checkEncryptionKey ( encryptionKey : string ) : boolean {
127
128
if ( this . isLoaded ( ) ) {
128
- return this . password === password ;
129
+ return this . encryptionKey === encryptionKey ;
129
130
} else {
130
131
return false ;
131
132
}
132
133
}
133
134
134
135
/**
135
- * Returns if the locally stored configuration has been loaded and a password has been set.
136
+ * Returns if the locally stored configuration has been loaded and a encryption key has been set.
136
137
*/
137
138
isLoaded ( ) : boolean {
138
- return this . password !== undefined ;
139
+ return this . encryptionKey !== undefined ;
139
140
}
140
141
141
142
/**
142
143
* Returns whether this is the first startup aka. whether any encrypted data has been saved.
143
- * If this returns true {{ @link load}} will accept any password and use it to encrypt the configuration.
144
+ * If this returns true {@link load} will accept any encryption key and use it to encrypt the configuration.
144
145
*/
145
146
isFirstStartup ( ) : boolean {
146
147
return this . encryptedData . value . cipherText === undefined ;
147
148
}
148
149
149
150
/**
150
- * Decrypts and loads the locally stored configuration using the passed password .
151
- * @param password the password of the encrypted config.
152
- * @return success if the password was correct and loading has been successful and an error if the password is wrong.
151
+ * Decrypts and loads the locally stored configuration using the passed encryption key .
152
+ * @param encryptionKey the encryption key of the encrypted config.
153
+ * @return success if the encryption key was correct and loading has been successful and an error if the encryption key is wrong.
153
154
*/
154
- async load ( password : string ) : Promise < Result < void > > {
155
+ async load ( encryptionKey : string ) : Promise < Result < void > > {
155
156
if ( this . isLoaded ( ) ) {
156
157
return error ( "Config has already been decrypted and loaded." ) ;
157
158
}
@@ -160,19 +161,19 @@ export class PersistenceManager {
160
161
// No encrypted data has been saved, probably because this is the first startup.
161
162
// Therefore nothing needs to be decrypted, and we write an empty config to disk.
162
163
this . nodecg . log . info ( "No saved configuration found, creating a empty one." ) ;
163
- this . password = password ;
164
+ this . encryptionKey = encryptionKey ;
164
165
this . save ( ) ;
165
166
} else {
166
167
// Decrypt config
167
168
this . nodecg . log . info ( "Decrypting and loading saved configuration." ) ;
168
- const passwordWordArray = crypto . enc . Hex . parse ( password ) ;
169
+ const encryptionKeyArr = crypto . enc . Hex . parse ( encryptionKey ) ;
169
170
const data = decryptData (
170
171
this . encryptedData . value . cipherText ,
171
- passwordWordArray ,
172
+ encryptionKeyArr ,
172
173
this . encryptedData . value . iv ,
173
174
) ;
174
175
if ( data . failed ) {
175
- this . nodecg . log . error ( "Could not decrypt configuration: password is invalid." ) ;
176
+ this . nodecg . log . error ( "Could not decrypt configuration: encryption key is invalid." ) ;
176
177
return data ;
177
178
}
178
179
@@ -183,8 +184,8 @@ export class PersistenceManager {
183
184
this . saveAfterServiceInstancesLoaded ( promises ) ;
184
185
}
185
186
186
- // Save password , used in save() function
187
- this . password = password ;
187
+ // Save encryption key , used in save() function
188
+ this . encryptionKey = encryptionKey ;
188
189
189
190
// Register handlers to save when something changes
190
191
this . instances . on ( "change" , ( ) => this . save ( ) ) ;
@@ -258,8 +259,8 @@ export class PersistenceManager {
258
259
* Encrypts and saves current state to the persistent replicant.
259
260
*/
260
261
save ( ) : void {
261
- // Check if we have a password to encrypt the data with.
262
- if ( this . password === undefined ) {
262
+ // Check if we have a encryption key to encrypt the data with.
263
+ if ( this . encryptionKey === undefined ) {
263
264
return ;
264
265
}
265
266
@@ -270,8 +271,8 @@ export class PersistenceManager {
270
271
} ;
271
272
272
273
// Encrypt and save data to persistent replicant.
273
- const passwordWordArray = crypto . enc . Hex . parse ( this . password ) ;
274
- const [ cipherText , iv ] = encryptData ( data , passwordWordArray ) ;
274
+ const encryptionKeyArr = crypto . enc . Hex . parse ( this . encryptionKey ) ;
275
+ const [ cipherText , iv ] = encryptData ( data , encryptionKeyArr ) ;
275
276
this . encryptedData . value . cipherText = cipherText ;
276
277
this . encryptedData . value . iv = iv ;
277
278
}
@@ -353,7 +354,7 @@ export class PersistenceManager {
353
354
const salt =
354
355
this . encryptedData . value . salt ?? crypto . lib . WordArray . random ( 128 / 8 ) . toString ( crypto . enc . Hex ) ;
355
356
if ( this . encryptedData . value . salt === undefined ) {
356
- const newSecret = deriveEncryptionSecret ( password , salt ) ;
357
+ const newSecret = deriveEncryptionKey ( password , salt ) ;
357
358
358
359
if ( this . encryptedData . value . cipherText !== undefined ) {
359
360
const newSecretWordArray = crypto . enc . Hex . parse ( newSecret ) ;
@@ -363,8 +364,8 @@ export class PersistenceManager {
363
364
this . encryptedData . value . salt = salt ;
364
365
}
365
366
366
- const encryptionSecret = deriveEncryptionSecret ( password , salt ) ;
367
- const loadResult = await this . load ( encryptionSecret ) ;
367
+ const encryptionKey = deriveEncryptionKey ( password , salt ) ;
368
+ const loadResult = await this . load ( encryptionKey ) ;
368
369
369
370
if ( ! loadResult . failed ) {
370
371
this . nodecg . log . info ( "Automatic login successful." ) ;
0 commit comments