@etsoo/appscript 1.1.68 → 1.1.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/app/CoreApp.ts +20 -0
- package/lib/cjs/app/CoreApp.d.ts +40 -3
- package/lib/cjs/app/CoreApp.js +63 -33
- package/lib/mjs/app/CoreApp.d.ts +40 -3
- package/lib/mjs/app/CoreApp.js +63 -33
- package/package.json +4 -4
- package/src/app/CoreApp.ts +110 -51
package/__tests__/app/CoreApp.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { AddressUtils } from '../../src/address/AddressUtils';
|
|
|
12
12
|
import { IAppSettings } from '../../src/app/AppSettings';
|
|
13
13
|
import { CoreApp } from '../../src/app/CoreApp';
|
|
14
14
|
import { zhCN } from '../../src/i18n/zhCN';
|
|
15
|
+
import { InitCallResultData } from '../../src/result/InitCallResult';
|
|
15
16
|
|
|
16
17
|
// Detected country or region
|
|
17
18
|
const { detectedCountry } = DomUtils;
|
|
@@ -108,6 +109,11 @@ class CoreAppTest extends CoreApp<IAppSettings, {}, NotificationCallProps> {
|
|
|
108
109
|
freshCountdownUI(callback?: () => PromiseLike<unknown>): void {
|
|
109
110
|
throw new Error('Method not implemented.');
|
|
110
111
|
}
|
|
112
|
+
|
|
113
|
+
initCallUpdateLocal(data: InitCallResultData, timestamp: number) {
|
|
114
|
+
this.initCallUpdate(data, timestamp);
|
|
115
|
+
return this.passphrase;
|
|
116
|
+
}
|
|
111
117
|
}
|
|
112
118
|
|
|
113
119
|
const app = new CoreAppTest();
|
|
@@ -122,3 +128,17 @@ test('Tests for encrypt / decrypt', () => {
|
|
|
122
128
|
const plain = app.decrypt(encrypted, passphrase);
|
|
123
129
|
expect(plain).toEqual(input);
|
|
124
130
|
});
|
|
131
|
+
|
|
132
|
+
test('Tests for initCallUpdateLocal', () => {
|
|
133
|
+
// Act
|
|
134
|
+
const passphrase = app.initCallUpdateLocal(
|
|
135
|
+
{
|
|
136
|
+
deviceId:
|
|
137
|
+
'ZmNjZlov+10067A1520126643352C2022735B85DC8F380088468402C98A5631A8CFBE14E134zXfxmw77lFopTTlbqOfsK2KUqPSsTAQb35Ejrm1BAvUaQH3SuZcwGYu3+PQ/Rd56',
|
|
138
|
+
passphrase:
|
|
139
|
+
'01397BF28A93FC031BC8B9B808F880F12C398AB792DF2ADE7A8768CADD2259EB50HJuKhqGuLQO+SmvCVzuEGUN4TdkUuPMWR0E6lliszbNiXboCziXx5SdfX3lMpoBX'
|
|
140
|
+
},
|
|
141
|
+
1639282438620
|
|
142
|
+
);
|
|
143
|
+
expect(passphrase).not.toBeNull();
|
|
144
|
+
});
|
package/lib/cjs/app/CoreApp.d.ts
CHANGED
|
@@ -118,10 +118,17 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
|
|
|
118
118
|
* Decrypt message
|
|
119
119
|
* @param messageEncrypted Encrypted message
|
|
120
120
|
* @param passphrase Secret passphrase
|
|
121
|
+
* @returns Pure text
|
|
122
|
+
*/
|
|
123
|
+
decrypt(messageEncrypted: string, passphrase?: string): string | undefined;
|
|
124
|
+
/**
|
|
125
|
+
* Enhanced decrypt message
|
|
126
|
+
* @param messageEncrypted Encrypted message
|
|
127
|
+
* @param passphrase Secret passphrase
|
|
121
128
|
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
122
129
|
* @returns Pure text
|
|
123
130
|
*/
|
|
124
|
-
|
|
131
|
+
decryptEnhanced(messageEncrypted: string, passphrase?: string, durationSeconds?: number): string | undefined;
|
|
125
132
|
/**
|
|
126
133
|
* Detect IP data, call only one time
|
|
127
134
|
* @param callback Callback will be called when the IP is ready
|
|
@@ -135,6 +142,14 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
|
|
|
135
142
|
* @returns Result
|
|
136
143
|
*/
|
|
137
144
|
encrypt(message: string, passphrase?: string, iterations?: number): string;
|
|
145
|
+
/**
|
|
146
|
+
* Enhanced encrypt message
|
|
147
|
+
* @param message Message
|
|
148
|
+
* @param passphrase Secret passphrase
|
|
149
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
150
|
+
* @returns Result
|
|
151
|
+
*/
|
|
152
|
+
encryptEnhanced(message: string, passphrase?: string, iterations?: number): string;
|
|
138
153
|
/**
|
|
139
154
|
* Format date to string
|
|
140
155
|
* @param input Input date
|
|
@@ -235,6 +250,12 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
|
|
|
235
250
|
* @returns Result
|
|
236
251
|
*/
|
|
237
252
|
hasPermission(roles: number | UserRole | number[] | UserRole[]): boolean;
|
|
253
|
+
/**
|
|
254
|
+
* Init call
|
|
255
|
+
* @param callback Callback
|
|
256
|
+
* @returns Result
|
|
257
|
+
*/
|
|
258
|
+
initCall(callback?: (result: boolean) => void): Promise<void>;
|
|
238
259
|
/**
|
|
239
260
|
* Callback where exit a page
|
|
240
261
|
*/
|
|
@@ -387,9 +408,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
387
408
|
protected setApi(api: IApi): void;
|
|
388
409
|
/**
|
|
389
410
|
* Init call
|
|
411
|
+
* @param callback Callback
|
|
390
412
|
* @returns Result
|
|
391
413
|
*/
|
|
392
|
-
|
|
414
|
+
initCall(callback?: (result: boolean) => void): Promise<void>;
|
|
393
415
|
/**
|
|
394
416
|
* Init call update
|
|
395
417
|
* @param data Result data
|
|
@@ -427,10 +449,17 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
427
449
|
* Decrypt message
|
|
428
450
|
* @param messageEncrypted Encrypted message
|
|
429
451
|
* @param passphrase Secret passphrase
|
|
452
|
+
* @returns Pure text
|
|
453
|
+
*/
|
|
454
|
+
decrypt(messageEncrypted: string, passphrase?: string): string | undefined;
|
|
455
|
+
/**
|
|
456
|
+
* Enhanced decrypt message
|
|
457
|
+
* @param messageEncrypted Encrypted message
|
|
458
|
+
* @param passphrase Secret passphrase
|
|
430
459
|
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
431
460
|
* @returns Pure text
|
|
432
461
|
*/
|
|
433
|
-
|
|
462
|
+
decryptEnhanced(messageEncrypted: string, passphrase?: string, durationSeconds?: number): string | undefined;
|
|
434
463
|
/**
|
|
435
464
|
* Detect IP data, call only one time
|
|
436
465
|
* @param callback Callback will be called when the IP is ready
|
|
@@ -445,6 +474,14 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
445
474
|
* @returns Result
|
|
446
475
|
*/
|
|
447
476
|
encrypt(message: string, passphrase?: string, iterations?: number): string;
|
|
477
|
+
/**
|
|
478
|
+
* Enhanced encrypt message
|
|
479
|
+
* @param message Message
|
|
480
|
+
* @param passphrase Secret passphrase
|
|
481
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
482
|
+
* @returns Result
|
|
483
|
+
*/
|
|
484
|
+
encryptEnhanced(message: string, passphrase?: string, iterations?: number): string;
|
|
448
485
|
/**
|
|
449
486
|
* Enchance secret passphrase
|
|
450
487
|
* @param passphrase Secret passphrase
|
package/lib/cjs/app/CoreApp.js
CHANGED
|
@@ -119,19 +119,25 @@ class CoreApp {
|
|
|
119
119
|
}
|
|
120
120
|
/**
|
|
121
121
|
* Init call
|
|
122
|
+
* @param callback Callback
|
|
122
123
|
* @returns Result
|
|
123
124
|
*/
|
|
124
|
-
async initCall() {
|
|
125
|
+
async initCall(callback) {
|
|
125
126
|
var _a;
|
|
126
127
|
const data = {
|
|
127
128
|
timestamp: new Date().getTime(),
|
|
128
129
|
deviceId: this.deviceId === '' ? undefined : this.deviceId
|
|
129
130
|
};
|
|
130
131
|
const result = await this.api.put('Auth/WebInitCall', data);
|
|
131
|
-
if (result == null)
|
|
132
|
+
if (result == null) {
|
|
133
|
+
if (callback)
|
|
134
|
+
callback(false);
|
|
132
135
|
return;
|
|
136
|
+
}
|
|
133
137
|
if (result.data == null) {
|
|
134
138
|
this.notifier.alert(this.get('noData'));
|
|
139
|
+
if (callback)
|
|
140
|
+
callback(false);
|
|
135
141
|
return;
|
|
136
142
|
}
|
|
137
143
|
if (!result.ok) {
|
|
@@ -146,9 +152,13 @@ class CoreApp {
|
|
|
146
152
|
else {
|
|
147
153
|
this.alertResult(result);
|
|
148
154
|
}
|
|
155
|
+
if (callback)
|
|
156
|
+
callback(false);
|
|
149
157
|
return;
|
|
150
158
|
}
|
|
151
159
|
this.initCallUpdate(result.data, data.timestamp);
|
|
160
|
+
if (callback)
|
|
161
|
+
callback(true);
|
|
152
162
|
}
|
|
153
163
|
/**
|
|
154
164
|
* Init call update
|
|
@@ -160,7 +170,7 @@ class CoreApp {
|
|
|
160
170
|
return;
|
|
161
171
|
// Decrypt
|
|
162
172
|
// Should be done within 120 seconds after returning from the backend
|
|
163
|
-
const passphrase = this.decrypt(data.passphrase, timestamp.toString()
|
|
173
|
+
const passphrase = this.decrypt(data.passphrase, timestamp.toString());
|
|
164
174
|
if (passphrase == null)
|
|
165
175
|
return;
|
|
166
176
|
// Update device id and cache it
|
|
@@ -170,17 +180,17 @@ class CoreApp {
|
|
|
170
180
|
this.passphrase = passphrase;
|
|
171
181
|
// Previous passphrase
|
|
172
182
|
if (data.previousPassphrase) {
|
|
173
|
-
const prev = this.decrypt(data.previousPassphrase, timestamp.toString()
|
|
183
|
+
const prev = this.decrypt(data.previousPassphrase, timestamp.toString());
|
|
174
184
|
// Update
|
|
175
185
|
const fields = this.initCallUpdateFields();
|
|
176
186
|
for (const field of fields) {
|
|
177
187
|
const currentValue = shared_1.StorageUtils.getLocalData(field, '');
|
|
178
188
|
if (currentValue === '' || currentValue.indexOf('+') === -1)
|
|
179
189
|
continue;
|
|
180
|
-
const newValueSource = this.
|
|
190
|
+
const newValueSource = this.decryptEnhanced(currentValue, prev, 12);
|
|
181
191
|
if (newValueSource == null)
|
|
182
192
|
continue;
|
|
183
|
-
const newValue = this.
|
|
193
|
+
const newValue = this.encryptEnhanced(newValueSource);
|
|
184
194
|
shared_1.StorageUtils.setLocalData(field, newValue);
|
|
185
195
|
}
|
|
186
196
|
}
|
|
@@ -284,16 +294,41 @@ class CoreApp {
|
|
|
284
294
|
* Decrypt message
|
|
285
295
|
* @param messageEncrypted Encrypted message
|
|
286
296
|
* @param passphrase Secret passphrase
|
|
297
|
+
* @returns Pure text
|
|
298
|
+
*/
|
|
299
|
+
decrypt(messageEncrypted, passphrase) {
|
|
300
|
+
// Iterations
|
|
301
|
+
const iterations = parseInt(messageEncrypted.substring(0, 2), 10);
|
|
302
|
+
if (isNaN(iterations))
|
|
303
|
+
return undefined;
|
|
304
|
+
const salt = crypto_js_1.enc.Hex.parse(messageEncrypted.substring(2, 34));
|
|
305
|
+
const iv = crypto_js_1.enc.Hex.parse(messageEncrypted.substring(34, 66));
|
|
306
|
+
const encrypted = messageEncrypted.substring(66);
|
|
307
|
+
const key = (0, crypto_js_1.PBKDF2)(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, salt, {
|
|
308
|
+
keySize: 8,
|
|
309
|
+
hasher: crypto_js_1.algo.SHA256,
|
|
310
|
+
iterations: 1000 * iterations
|
|
311
|
+
});
|
|
312
|
+
return crypto_js_1.AES.decrypt(encrypted, key, {
|
|
313
|
+
iv,
|
|
314
|
+
padding: crypto_js_1.pad.Pkcs7,
|
|
315
|
+
mode: crypto_js_1.mode.CBC
|
|
316
|
+
}).toString(crypto_js_1.enc.Utf8);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Enhanced decrypt message
|
|
320
|
+
* @param messageEncrypted Encrypted message
|
|
321
|
+
* @param passphrase Secret passphrase
|
|
287
322
|
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
288
323
|
* @returns Pure text
|
|
289
324
|
*/
|
|
290
|
-
|
|
325
|
+
decryptEnhanced(messageEncrypted, passphrase, durationSeconds) {
|
|
291
326
|
// Timestamp splitter
|
|
292
|
-
const pos = messageEncrypted.indexOf('
|
|
293
|
-
|
|
327
|
+
const pos = messageEncrypted.indexOf('!');
|
|
328
|
+
// Miliseconds chars are longer than 8
|
|
329
|
+
if (pos < 8 || messageEncrypted.length <= 66)
|
|
294
330
|
return undefined;
|
|
295
331
|
const timestamp = messageEncrypted.substring(0, pos);
|
|
296
|
-
const message = messageEncrypted.substring(pos + 1);
|
|
297
332
|
if (durationSeconds != null && durationSeconds > 0) {
|
|
298
333
|
const milseconds = shared_1.Utils.charsToNumber(timestamp);
|
|
299
334
|
if (isNaN(milseconds) || milseconds < 1)
|
|
@@ -305,23 +340,9 @@ class CoreApp {
|
|
|
305
340
|
timespan.totalSeconds > durationSeconds))
|
|
306
341
|
return undefined;
|
|
307
342
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
return undefined;
|
|
312
|
-
const salt = crypto_js_1.enc.Hex.parse(message.substring(2, 34));
|
|
313
|
-
const iv = crypto_js_1.enc.Hex.parse(message.substring(34, 66));
|
|
314
|
-
const encrypted = message.substring(66);
|
|
315
|
-
const key = (0, crypto_js_1.PBKDF2)(this.encryptionEnhance(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, timestamp), salt, {
|
|
316
|
-
keySize: 8,
|
|
317
|
-
hasher: crypto_js_1.algo.SHA256,
|
|
318
|
-
iterations: 1000 * iterations
|
|
319
|
-
});
|
|
320
|
-
return crypto_js_1.AES.decrypt(encrypted, key, {
|
|
321
|
-
iv,
|
|
322
|
-
padding: crypto_js_1.pad.Pkcs7,
|
|
323
|
-
mode: crypto_js_1.mode.CBC
|
|
324
|
-
}).toString(crypto_js_1.enc.Utf8);
|
|
343
|
+
const message = messageEncrypted.substring(pos + 1);
|
|
344
|
+
passphrase = this.encryptionEnhance(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, timestamp);
|
|
345
|
+
return this.decrypt(message, passphrase);
|
|
325
346
|
}
|
|
326
347
|
/**
|
|
327
348
|
* Detect IP data, call only one time
|
|
@@ -366,19 +387,15 @@ class CoreApp {
|
|
|
366
387
|
encrypt(message, passphrase, iterations) {
|
|
367
388
|
// Default 1 * 1000
|
|
368
389
|
iterations !== null && iterations !== void 0 ? iterations : (iterations = 1);
|
|
369
|
-
// Timestamp
|
|
370
|
-
const timestamp = shared_1.Utils.numberToChars(new Date().getTime());
|
|
371
390
|
const bits = 16; // 128 / 8
|
|
372
391
|
const salt = crypto_js_1.lib.WordArray.random(bits);
|
|
373
|
-
const key = (0, crypto_js_1.PBKDF2)(
|
|
392
|
+
const key = (0, crypto_js_1.PBKDF2)(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, salt, {
|
|
374
393
|
keySize: 8,
|
|
375
394
|
hasher: crypto_js_1.algo.SHA256,
|
|
376
395
|
iterations: 1000 * iterations
|
|
377
396
|
});
|
|
378
397
|
const iv = crypto_js_1.lib.WordArray.random(bits);
|
|
379
|
-
return (
|
|
380
|
-
'+' +
|
|
381
|
-
iterations.toString().padStart(2, '0') +
|
|
398
|
+
return (iterations.toString().padStart(2, '0') +
|
|
382
399
|
salt.toString(crypto_js_1.enc.Hex) +
|
|
383
400
|
iv.toString(crypto_js_1.enc.Hex) +
|
|
384
401
|
crypto_js_1.AES.encrypt(message, key, {
|
|
@@ -388,6 +405,19 @@ class CoreApp {
|
|
|
388
405
|
}).toString() // enc.Base64
|
|
389
406
|
);
|
|
390
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* Enhanced encrypt message
|
|
410
|
+
* @param message Message
|
|
411
|
+
* @param passphrase Secret passphrase
|
|
412
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
413
|
+
* @returns Result
|
|
414
|
+
*/
|
|
415
|
+
encryptEnhanced(message, passphrase, iterations) {
|
|
416
|
+
// Timestamp
|
|
417
|
+
const timestamp = shared_1.Utils.numberToChars(new Date().getTime());
|
|
418
|
+
passphrase = this.encryptionEnhance(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, timestamp);
|
|
419
|
+
return timestamp + '!' + this.encrypt(message, passphrase, iterations);
|
|
420
|
+
}
|
|
391
421
|
/**
|
|
392
422
|
* Enchance secret passphrase
|
|
393
423
|
* @param passphrase Secret passphrase
|
package/lib/mjs/app/CoreApp.d.ts
CHANGED
|
@@ -118,10 +118,17 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
|
|
|
118
118
|
* Decrypt message
|
|
119
119
|
* @param messageEncrypted Encrypted message
|
|
120
120
|
* @param passphrase Secret passphrase
|
|
121
|
+
* @returns Pure text
|
|
122
|
+
*/
|
|
123
|
+
decrypt(messageEncrypted: string, passphrase?: string): string | undefined;
|
|
124
|
+
/**
|
|
125
|
+
* Enhanced decrypt message
|
|
126
|
+
* @param messageEncrypted Encrypted message
|
|
127
|
+
* @param passphrase Secret passphrase
|
|
121
128
|
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
122
129
|
* @returns Pure text
|
|
123
130
|
*/
|
|
124
|
-
|
|
131
|
+
decryptEnhanced(messageEncrypted: string, passphrase?: string, durationSeconds?: number): string | undefined;
|
|
125
132
|
/**
|
|
126
133
|
* Detect IP data, call only one time
|
|
127
134
|
* @param callback Callback will be called when the IP is ready
|
|
@@ -135,6 +142,14 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
|
|
|
135
142
|
* @returns Result
|
|
136
143
|
*/
|
|
137
144
|
encrypt(message: string, passphrase?: string, iterations?: number): string;
|
|
145
|
+
/**
|
|
146
|
+
* Enhanced encrypt message
|
|
147
|
+
* @param message Message
|
|
148
|
+
* @param passphrase Secret passphrase
|
|
149
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
150
|
+
* @returns Result
|
|
151
|
+
*/
|
|
152
|
+
encryptEnhanced(message: string, passphrase?: string, iterations?: number): string;
|
|
138
153
|
/**
|
|
139
154
|
* Format date to string
|
|
140
155
|
* @param input Input date
|
|
@@ -235,6 +250,12 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
|
|
|
235
250
|
* @returns Result
|
|
236
251
|
*/
|
|
237
252
|
hasPermission(roles: number | UserRole | number[] | UserRole[]): boolean;
|
|
253
|
+
/**
|
|
254
|
+
* Init call
|
|
255
|
+
* @param callback Callback
|
|
256
|
+
* @returns Result
|
|
257
|
+
*/
|
|
258
|
+
initCall(callback?: (result: boolean) => void): Promise<void>;
|
|
238
259
|
/**
|
|
239
260
|
* Callback where exit a page
|
|
240
261
|
*/
|
|
@@ -387,9 +408,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
387
408
|
protected setApi(api: IApi): void;
|
|
388
409
|
/**
|
|
389
410
|
* Init call
|
|
411
|
+
* @param callback Callback
|
|
390
412
|
* @returns Result
|
|
391
413
|
*/
|
|
392
|
-
|
|
414
|
+
initCall(callback?: (result: boolean) => void): Promise<void>;
|
|
393
415
|
/**
|
|
394
416
|
* Init call update
|
|
395
417
|
* @param data Result data
|
|
@@ -427,10 +449,17 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
427
449
|
* Decrypt message
|
|
428
450
|
* @param messageEncrypted Encrypted message
|
|
429
451
|
* @param passphrase Secret passphrase
|
|
452
|
+
* @returns Pure text
|
|
453
|
+
*/
|
|
454
|
+
decrypt(messageEncrypted: string, passphrase?: string): string | undefined;
|
|
455
|
+
/**
|
|
456
|
+
* Enhanced decrypt message
|
|
457
|
+
* @param messageEncrypted Encrypted message
|
|
458
|
+
* @param passphrase Secret passphrase
|
|
430
459
|
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
431
460
|
* @returns Pure text
|
|
432
461
|
*/
|
|
433
|
-
|
|
462
|
+
decryptEnhanced(messageEncrypted: string, passphrase?: string, durationSeconds?: number): string | undefined;
|
|
434
463
|
/**
|
|
435
464
|
* Detect IP data, call only one time
|
|
436
465
|
* @param callback Callback will be called when the IP is ready
|
|
@@ -445,6 +474,14 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
445
474
|
* @returns Result
|
|
446
475
|
*/
|
|
447
476
|
encrypt(message: string, passphrase?: string, iterations?: number): string;
|
|
477
|
+
/**
|
|
478
|
+
* Enhanced encrypt message
|
|
479
|
+
* @param message Message
|
|
480
|
+
* @param passphrase Secret passphrase
|
|
481
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
482
|
+
* @returns Result
|
|
483
|
+
*/
|
|
484
|
+
encryptEnhanced(message: string, passphrase?: string, iterations?: number): string;
|
|
448
485
|
/**
|
|
449
486
|
* Enchance secret passphrase
|
|
450
487
|
* @param passphrase Secret passphrase
|
package/lib/mjs/app/CoreApp.js
CHANGED
|
@@ -116,19 +116,25 @@ export class CoreApp {
|
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
118
118
|
* Init call
|
|
119
|
+
* @param callback Callback
|
|
119
120
|
* @returns Result
|
|
120
121
|
*/
|
|
121
|
-
async initCall() {
|
|
122
|
+
async initCall(callback) {
|
|
122
123
|
var _a;
|
|
123
124
|
const data = {
|
|
124
125
|
timestamp: new Date().getTime(),
|
|
125
126
|
deviceId: this.deviceId === '' ? undefined : this.deviceId
|
|
126
127
|
};
|
|
127
128
|
const result = await this.api.put('Auth/WebInitCall', data);
|
|
128
|
-
if (result == null)
|
|
129
|
+
if (result == null) {
|
|
130
|
+
if (callback)
|
|
131
|
+
callback(false);
|
|
129
132
|
return;
|
|
133
|
+
}
|
|
130
134
|
if (result.data == null) {
|
|
131
135
|
this.notifier.alert(this.get('noData'));
|
|
136
|
+
if (callback)
|
|
137
|
+
callback(false);
|
|
132
138
|
return;
|
|
133
139
|
}
|
|
134
140
|
if (!result.ok) {
|
|
@@ -143,9 +149,13 @@ export class CoreApp {
|
|
|
143
149
|
else {
|
|
144
150
|
this.alertResult(result);
|
|
145
151
|
}
|
|
152
|
+
if (callback)
|
|
153
|
+
callback(false);
|
|
146
154
|
return;
|
|
147
155
|
}
|
|
148
156
|
this.initCallUpdate(result.data, data.timestamp);
|
|
157
|
+
if (callback)
|
|
158
|
+
callback(true);
|
|
149
159
|
}
|
|
150
160
|
/**
|
|
151
161
|
* Init call update
|
|
@@ -157,7 +167,7 @@ export class CoreApp {
|
|
|
157
167
|
return;
|
|
158
168
|
// Decrypt
|
|
159
169
|
// Should be done within 120 seconds after returning from the backend
|
|
160
|
-
const passphrase = this.decrypt(data.passphrase, timestamp.toString()
|
|
170
|
+
const passphrase = this.decrypt(data.passphrase, timestamp.toString());
|
|
161
171
|
if (passphrase == null)
|
|
162
172
|
return;
|
|
163
173
|
// Update device id and cache it
|
|
@@ -167,17 +177,17 @@ export class CoreApp {
|
|
|
167
177
|
this.passphrase = passphrase;
|
|
168
178
|
// Previous passphrase
|
|
169
179
|
if (data.previousPassphrase) {
|
|
170
|
-
const prev = this.decrypt(data.previousPassphrase, timestamp.toString()
|
|
180
|
+
const prev = this.decrypt(data.previousPassphrase, timestamp.toString());
|
|
171
181
|
// Update
|
|
172
182
|
const fields = this.initCallUpdateFields();
|
|
173
183
|
for (const field of fields) {
|
|
174
184
|
const currentValue = StorageUtils.getLocalData(field, '');
|
|
175
185
|
if (currentValue === '' || currentValue.indexOf('+') === -1)
|
|
176
186
|
continue;
|
|
177
|
-
const newValueSource = this.
|
|
187
|
+
const newValueSource = this.decryptEnhanced(currentValue, prev, 12);
|
|
178
188
|
if (newValueSource == null)
|
|
179
189
|
continue;
|
|
180
|
-
const newValue = this.
|
|
190
|
+
const newValue = this.encryptEnhanced(newValueSource);
|
|
181
191
|
StorageUtils.setLocalData(field, newValue);
|
|
182
192
|
}
|
|
183
193
|
}
|
|
@@ -281,16 +291,41 @@ export class CoreApp {
|
|
|
281
291
|
* Decrypt message
|
|
282
292
|
* @param messageEncrypted Encrypted message
|
|
283
293
|
* @param passphrase Secret passphrase
|
|
294
|
+
* @returns Pure text
|
|
295
|
+
*/
|
|
296
|
+
decrypt(messageEncrypted, passphrase) {
|
|
297
|
+
// Iterations
|
|
298
|
+
const iterations = parseInt(messageEncrypted.substring(0, 2), 10);
|
|
299
|
+
if (isNaN(iterations))
|
|
300
|
+
return undefined;
|
|
301
|
+
const salt = enc.Hex.parse(messageEncrypted.substring(2, 34));
|
|
302
|
+
const iv = enc.Hex.parse(messageEncrypted.substring(34, 66));
|
|
303
|
+
const encrypted = messageEncrypted.substring(66);
|
|
304
|
+
const key = PBKDF2(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, salt, {
|
|
305
|
+
keySize: 8,
|
|
306
|
+
hasher: algo.SHA256,
|
|
307
|
+
iterations: 1000 * iterations
|
|
308
|
+
});
|
|
309
|
+
return AES.decrypt(encrypted, key, {
|
|
310
|
+
iv,
|
|
311
|
+
padding: pad.Pkcs7,
|
|
312
|
+
mode: mode.CBC
|
|
313
|
+
}).toString(enc.Utf8);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Enhanced decrypt message
|
|
317
|
+
* @param messageEncrypted Encrypted message
|
|
318
|
+
* @param passphrase Secret passphrase
|
|
284
319
|
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
285
320
|
* @returns Pure text
|
|
286
321
|
*/
|
|
287
|
-
|
|
322
|
+
decryptEnhanced(messageEncrypted, passphrase, durationSeconds) {
|
|
288
323
|
// Timestamp splitter
|
|
289
|
-
const pos = messageEncrypted.indexOf('
|
|
290
|
-
|
|
324
|
+
const pos = messageEncrypted.indexOf('!');
|
|
325
|
+
// Miliseconds chars are longer than 8
|
|
326
|
+
if (pos < 8 || messageEncrypted.length <= 66)
|
|
291
327
|
return undefined;
|
|
292
328
|
const timestamp = messageEncrypted.substring(0, pos);
|
|
293
|
-
const message = messageEncrypted.substring(pos + 1);
|
|
294
329
|
if (durationSeconds != null && durationSeconds > 0) {
|
|
295
330
|
const milseconds = Utils.charsToNumber(timestamp);
|
|
296
331
|
if (isNaN(milseconds) || milseconds < 1)
|
|
@@ -302,23 +337,9 @@ export class CoreApp {
|
|
|
302
337
|
timespan.totalSeconds > durationSeconds))
|
|
303
338
|
return undefined;
|
|
304
339
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
return undefined;
|
|
309
|
-
const salt = enc.Hex.parse(message.substring(2, 34));
|
|
310
|
-
const iv = enc.Hex.parse(message.substring(34, 66));
|
|
311
|
-
const encrypted = message.substring(66);
|
|
312
|
-
const key = PBKDF2(this.encryptionEnhance(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, timestamp), salt, {
|
|
313
|
-
keySize: 8,
|
|
314
|
-
hasher: algo.SHA256,
|
|
315
|
-
iterations: 1000 * iterations
|
|
316
|
-
});
|
|
317
|
-
return AES.decrypt(encrypted, key, {
|
|
318
|
-
iv,
|
|
319
|
-
padding: pad.Pkcs7,
|
|
320
|
-
mode: mode.CBC
|
|
321
|
-
}).toString(enc.Utf8);
|
|
340
|
+
const message = messageEncrypted.substring(pos + 1);
|
|
341
|
+
passphrase = this.encryptionEnhance(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, timestamp);
|
|
342
|
+
return this.decrypt(message, passphrase);
|
|
322
343
|
}
|
|
323
344
|
/**
|
|
324
345
|
* Detect IP data, call only one time
|
|
@@ -363,19 +384,15 @@ export class CoreApp {
|
|
|
363
384
|
encrypt(message, passphrase, iterations) {
|
|
364
385
|
// Default 1 * 1000
|
|
365
386
|
iterations !== null && iterations !== void 0 ? iterations : (iterations = 1);
|
|
366
|
-
// Timestamp
|
|
367
|
-
const timestamp = Utils.numberToChars(new Date().getTime());
|
|
368
387
|
const bits = 16; // 128 / 8
|
|
369
388
|
const salt = lib.WordArray.random(bits);
|
|
370
|
-
const key = PBKDF2(
|
|
389
|
+
const key = PBKDF2(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, salt, {
|
|
371
390
|
keySize: 8,
|
|
372
391
|
hasher: algo.SHA256,
|
|
373
392
|
iterations: 1000 * iterations
|
|
374
393
|
});
|
|
375
394
|
const iv = lib.WordArray.random(bits);
|
|
376
|
-
return (
|
|
377
|
-
'+' +
|
|
378
|
-
iterations.toString().padStart(2, '0') +
|
|
395
|
+
return (iterations.toString().padStart(2, '0') +
|
|
379
396
|
salt.toString(enc.Hex) +
|
|
380
397
|
iv.toString(enc.Hex) +
|
|
381
398
|
AES.encrypt(message, key, {
|
|
@@ -385,6 +402,19 @@ export class CoreApp {
|
|
|
385
402
|
}).toString() // enc.Base64
|
|
386
403
|
);
|
|
387
404
|
}
|
|
405
|
+
/**
|
|
406
|
+
* Enhanced encrypt message
|
|
407
|
+
* @param message Message
|
|
408
|
+
* @param passphrase Secret passphrase
|
|
409
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
410
|
+
* @returns Result
|
|
411
|
+
*/
|
|
412
|
+
encryptEnhanced(message, passphrase, iterations) {
|
|
413
|
+
// Timestamp
|
|
414
|
+
const timestamp = Utils.numberToChars(new Date().getTime());
|
|
415
|
+
passphrase = this.encryptionEnhance(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, timestamp);
|
|
416
|
+
return timestamp + '!' + this.encrypt(message, passphrase, iterations);
|
|
417
|
+
}
|
|
388
418
|
/**
|
|
389
419
|
* Enchance secret passphrase
|
|
390
420
|
* @param passphrase Secret passphrase
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/appscript",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.72",
|
|
4
4
|
"description": "Applications shared TypeScript framework",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/mjs/index.js",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"eslint": "^8.4.1",
|
|
71
71
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
72
72
|
"eslint-plugin-import": "^2.25.3",
|
|
73
|
-
"jest": "^27.4.
|
|
74
|
-
"ts-jest": "^27.1.
|
|
75
|
-
"typescript": "^4.5.
|
|
73
|
+
"jest": "^27.4.4",
|
|
74
|
+
"ts-jest": "^27.1.1",
|
|
75
|
+
"typescript": "^4.5.3"
|
|
76
76
|
}
|
|
77
77
|
}
|
package/src/app/CoreApp.ts
CHANGED
|
@@ -177,10 +177,18 @@ export interface ICoreApp<
|
|
|
177
177
|
* Decrypt message
|
|
178
178
|
* @param messageEncrypted Encrypted message
|
|
179
179
|
* @param passphrase Secret passphrase
|
|
180
|
+
* @returns Pure text
|
|
181
|
+
*/
|
|
182
|
+
decrypt(messageEncrypted: string, passphrase?: string): string | undefined;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Enhanced decrypt message
|
|
186
|
+
* @param messageEncrypted Encrypted message
|
|
187
|
+
* @param passphrase Secret passphrase
|
|
180
188
|
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
181
189
|
* @returns Pure text
|
|
182
190
|
*/
|
|
183
|
-
|
|
191
|
+
decryptEnhanced(
|
|
184
192
|
messageEncrypted: string,
|
|
185
193
|
passphrase?: string,
|
|
186
194
|
durationSeconds?: number
|
|
@@ -201,6 +209,19 @@ export interface ICoreApp<
|
|
|
201
209
|
*/
|
|
202
210
|
encrypt(message: string, passphrase?: string, iterations?: number): string;
|
|
203
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Enhanced encrypt message
|
|
214
|
+
* @param message Message
|
|
215
|
+
* @param passphrase Secret passphrase
|
|
216
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
217
|
+
* @returns Result
|
|
218
|
+
*/
|
|
219
|
+
encryptEnhanced(
|
|
220
|
+
message: string,
|
|
221
|
+
passphrase?: string,
|
|
222
|
+
iterations?: number
|
|
223
|
+
): string;
|
|
224
|
+
|
|
204
225
|
/**
|
|
205
226
|
* Format date to string
|
|
206
227
|
* @param input Input date
|
|
@@ -326,6 +347,13 @@ export interface ICoreApp<
|
|
|
326
347
|
*/
|
|
327
348
|
hasPermission(roles: number | UserRole | number[] | UserRole[]): boolean;
|
|
328
349
|
|
|
350
|
+
/**
|
|
351
|
+
* Init call
|
|
352
|
+
* @param callback Callback
|
|
353
|
+
* @returns Result
|
|
354
|
+
*/
|
|
355
|
+
initCall(callback?: (result: boolean) => void): Promise<void>;
|
|
356
|
+
|
|
329
357
|
/**
|
|
330
358
|
* Callback where exit a page
|
|
331
359
|
*/
|
|
@@ -588,9 +616,10 @@ export abstract class CoreApp<
|
|
|
588
616
|
|
|
589
617
|
/**
|
|
590
618
|
* Init call
|
|
619
|
+
* @param callback Callback
|
|
591
620
|
* @returns Result
|
|
592
621
|
*/
|
|
593
|
-
|
|
622
|
+
async initCall(callback?: (result: boolean) => void) {
|
|
594
623
|
const data: InitCallDto = {
|
|
595
624
|
timestamp: new Date().getTime(),
|
|
596
625
|
deviceId: this.deviceId === '' ? undefined : this.deviceId
|
|
@@ -599,10 +628,14 @@ export abstract class CoreApp<
|
|
|
599
628
|
'Auth/WebInitCall',
|
|
600
629
|
data
|
|
601
630
|
);
|
|
602
|
-
if (result == null)
|
|
631
|
+
if (result == null) {
|
|
632
|
+
if (callback) callback(false);
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
603
635
|
|
|
604
636
|
if (result.data == null) {
|
|
605
637
|
this.notifier.alert(this.get<string>('noData')!);
|
|
638
|
+
if (callback) callback(false);
|
|
606
639
|
return;
|
|
607
640
|
}
|
|
608
641
|
|
|
@@ -623,10 +656,14 @@ export abstract class CoreApp<
|
|
|
623
656
|
this.alertResult(result);
|
|
624
657
|
}
|
|
625
658
|
|
|
659
|
+
if (callback) callback(false);
|
|
660
|
+
|
|
626
661
|
return;
|
|
627
662
|
}
|
|
628
663
|
|
|
629
664
|
this.initCallUpdate(result.data, data.timestamp);
|
|
665
|
+
|
|
666
|
+
if (callback) callback(true);
|
|
630
667
|
}
|
|
631
668
|
|
|
632
669
|
/**
|
|
@@ -639,11 +676,7 @@ export abstract class CoreApp<
|
|
|
639
676
|
|
|
640
677
|
// Decrypt
|
|
641
678
|
// Should be done within 120 seconds after returning from the backend
|
|
642
|
-
const passphrase = this.decrypt(
|
|
643
|
-
data.passphrase,
|
|
644
|
-
timestamp.toString(),
|
|
645
|
-
120
|
|
646
|
-
);
|
|
679
|
+
const passphrase = this.decrypt(data.passphrase, timestamp.toString());
|
|
647
680
|
if (passphrase == null) return;
|
|
648
681
|
|
|
649
682
|
// Update device id and cache it
|
|
@@ -657,8 +690,7 @@ export abstract class CoreApp<
|
|
|
657
690
|
if (data.previousPassphrase) {
|
|
658
691
|
const prev = this.decrypt(
|
|
659
692
|
data.previousPassphrase,
|
|
660
|
-
timestamp.toString()
|
|
661
|
-
120
|
|
693
|
+
timestamp.toString()
|
|
662
694
|
);
|
|
663
695
|
|
|
664
696
|
// Update
|
|
@@ -671,10 +703,14 @@ export abstract class CoreApp<
|
|
|
671
703
|
if (currentValue === '' || currentValue.indexOf('+') === -1)
|
|
672
704
|
continue;
|
|
673
705
|
|
|
674
|
-
const newValueSource = this.
|
|
706
|
+
const newValueSource = this.decryptEnhanced(
|
|
707
|
+
currentValue,
|
|
708
|
+
prev,
|
|
709
|
+
12
|
|
710
|
+
);
|
|
675
711
|
if (newValueSource == null) continue;
|
|
676
712
|
|
|
677
|
-
const newValue = this.
|
|
713
|
+
const newValue = this.encryptEnhanced(newValueSource);
|
|
678
714
|
StorageUtils.setLocalData(field, newValue);
|
|
679
715
|
}
|
|
680
716
|
}
|
|
@@ -803,20 +839,49 @@ export abstract class CoreApp<
|
|
|
803
839
|
* Decrypt message
|
|
804
840
|
* @param messageEncrypted Encrypted message
|
|
805
841
|
* @param passphrase Secret passphrase
|
|
842
|
+
* @returns Pure text
|
|
843
|
+
*/
|
|
844
|
+
decrypt(messageEncrypted: string, passphrase?: string) {
|
|
845
|
+
// Iterations
|
|
846
|
+
const iterations = parseInt(messageEncrypted.substring(0, 2), 10);
|
|
847
|
+
if (isNaN(iterations)) return undefined;
|
|
848
|
+
|
|
849
|
+
const salt = enc.Hex.parse(messageEncrypted.substring(2, 34));
|
|
850
|
+
const iv = enc.Hex.parse(messageEncrypted.substring(34, 66));
|
|
851
|
+
const encrypted = messageEncrypted.substring(66);
|
|
852
|
+
|
|
853
|
+
const key = PBKDF2(passphrase ?? this.passphrase, salt, {
|
|
854
|
+
keySize: 8, // 256 / 32
|
|
855
|
+
hasher: algo.SHA256,
|
|
856
|
+
iterations: 1000 * iterations
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
return AES.decrypt(encrypted, key, {
|
|
860
|
+
iv,
|
|
861
|
+
padding: pad.Pkcs7,
|
|
862
|
+
mode: mode.CBC
|
|
863
|
+
}).toString(enc.Utf8);
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* Enhanced decrypt message
|
|
868
|
+
* @param messageEncrypted Encrypted message
|
|
869
|
+
* @param passphrase Secret passphrase
|
|
806
870
|
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
807
871
|
* @returns Pure text
|
|
808
872
|
*/
|
|
809
|
-
|
|
873
|
+
decryptEnhanced(
|
|
810
874
|
messageEncrypted: string,
|
|
811
875
|
passphrase?: string,
|
|
812
876
|
durationSeconds?: number
|
|
813
877
|
) {
|
|
814
878
|
// Timestamp splitter
|
|
815
|
-
const pos = messageEncrypted.indexOf('
|
|
816
|
-
|
|
879
|
+
const pos = messageEncrypted.indexOf('!');
|
|
880
|
+
|
|
881
|
+
// Miliseconds chars are longer than 8
|
|
882
|
+
if (pos < 8 || messageEncrypted.length <= 66) return undefined;
|
|
817
883
|
|
|
818
884
|
const timestamp = messageEncrypted.substring(0, pos);
|
|
819
|
-
const message = messageEncrypted.substring(pos + 1);
|
|
820
885
|
|
|
821
886
|
if (durationSeconds != null && durationSeconds > 0) {
|
|
822
887
|
const milseconds = Utils.charsToNumber(timestamp);
|
|
@@ -831,29 +896,13 @@ export abstract class CoreApp<
|
|
|
831
896
|
return undefined;
|
|
832
897
|
}
|
|
833
898
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
const salt = enc.Hex.parse(message.substring(2, 34));
|
|
839
|
-
const iv = enc.Hex.parse(message.substring(34, 66));
|
|
840
|
-
const encrypted = message.substring(66);
|
|
841
|
-
|
|
842
|
-
const key = PBKDF2(
|
|
843
|
-
this.encryptionEnhance(passphrase ?? this.passphrase, timestamp),
|
|
844
|
-
salt,
|
|
845
|
-
{
|
|
846
|
-
keySize: 8, // 256 / 32
|
|
847
|
-
hasher: algo.SHA256,
|
|
848
|
-
iterations: 1000 * iterations
|
|
849
|
-
}
|
|
899
|
+
const message = messageEncrypted.substring(pos + 1);
|
|
900
|
+
passphrase = this.encryptionEnhance(
|
|
901
|
+
passphrase ?? this.passphrase,
|
|
902
|
+
timestamp
|
|
850
903
|
);
|
|
851
904
|
|
|
852
|
-
return
|
|
853
|
-
iv,
|
|
854
|
-
padding: pad.Pkcs7,
|
|
855
|
-
mode: mode.CBC
|
|
856
|
-
}).toString(enc.Utf8);
|
|
905
|
+
return this.decrypt(message, passphrase);
|
|
857
906
|
}
|
|
858
907
|
|
|
859
908
|
/**
|
|
@@ -907,25 +956,16 @@ export abstract class CoreApp<
|
|
|
907
956
|
// Default 1 * 1000
|
|
908
957
|
iterations ??= 1;
|
|
909
958
|
|
|
910
|
-
// Timestamp
|
|
911
|
-
const timestamp = Utils.numberToChars(new Date().getTime());
|
|
912
|
-
|
|
913
959
|
const bits = 16; // 128 / 8
|
|
914
960
|
const salt = lib.WordArray.random(bits);
|
|
915
|
-
const key = PBKDF2(
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
hasher: algo.SHA256,
|
|
921
|
-
iterations: 1000 * iterations
|
|
922
|
-
}
|
|
923
|
-
);
|
|
961
|
+
const key = PBKDF2(passphrase ?? this.passphrase, salt, {
|
|
962
|
+
keySize: 8, // 256 / 32
|
|
963
|
+
hasher: algo.SHA256,
|
|
964
|
+
iterations: 1000 * iterations
|
|
965
|
+
});
|
|
924
966
|
const iv = lib.WordArray.random(bits);
|
|
925
967
|
|
|
926
968
|
return (
|
|
927
|
-
timestamp +
|
|
928
|
-
'+' +
|
|
929
969
|
iterations.toString().padStart(2, '0') +
|
|
930
970
|
salt.toString(enc.Hex) +
|
|
931
971
|
iv.toString(enc.Hex) +
|
|
@@ -937,6 +977,25 @@ export abstract class CoreApp<
|
|
|
937
977
|
);
|
|
938
978
|
}
|
|
939
979
|
|
|
980
|
+
/**
|
|
981
|
+
* Enhanced encrypt message
|
|
982
|
+
* @param message Message
|
|
983
|
+
* @param passphrase Secret passphrase
|
|
984
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
985
|
+
* @returns Result
|
|
986
|
+
*/
|
|
987
|
+
encryptEnhanced(message: string, passphrase?: string, iterations?: number) {
|
|
988
|
+
// Timestamp
|
|
989
|
+
const timestamp = Utils.numberToChars(new Date().getTime());
|
|
990
|
+
|
|
991
|
+
passphrase = this.encryptionEnhance(
|
|
992
|
+
passphrase ?? this.passphrase,
|
|
993
|
+
timestamp
|
|
994
|
+
);
|
|
995
|
+
|
|
996
|
+
return timestamp + '!' + this.encrypt(message, passphrase, iterations);
|
|
997
|
+
}
|
|
998
|
+
|
|
940
999
|
/**
|
|
941
1000
|
* Enchance secret passphrase
|
|
942
1001
|
* @param passphrase Secret passphrase
|