@etsoo/appscript 1.1.66 → 1.1.70
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 +124 -0
- package/lib/cjs/app/CoreApp.d.ts +72 -12
- package/lib/cjs/app/CoreApp.js +187 -8
- package/lib/cjs/dto/InitCallDto.d.ts +13 -0
- package/lib/cjs/dto/InitCallDto.js +2 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/result/IActionResult.d.ts +2 -2
- package/lib/cjs/result/InitCallResult.d.ts +12 -4
- package/lib/cjs/state/User.d.ts +0 -4
- package/lib/mjs/app/CoreApp.d.ts +72 -12
- package/lib/mjs/app/CoreApp.js +188 -9
- package/lib/mjs/dto/InitCallDto.d.ts +13 -0
- package/lib/mjs/dto/InitCallDto.js +1 -0
- package/lib/mjs/index.d.ts +1 -0
- package/lib/mjs/index.js +1 -0
- package/lib/mjs/result/IActionResult.d.ts +2 -2
- package/lib/mjs/result/InitCallResult.d.ts +12 -4
- package/lib/mjs/state/User.d.ts +0 -4
- package/package.json +8 -8
- package/src/app/CoreApp.ts +290 -27
- package/src/dto/InitCallDto.ts +14 -0
- package/src/index.ts +1 -0
- package/src/result/IActionResult.ts +2 -2
- package/src/result/InitCallResult.ts +14 -4
- package/src/state/User.ts +0 -5
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
INotificaseBase,
|
|
3
|
+
INotification,
|
|
4
|
+
Notification,
|
|
5
|
+
NotificationCallProps,
|
|
6
|
+
NotificationContainer,
|
|
7
|
+
NotificationRenderProps
|
|
8
|
+
} from '@etsoo/notificationbase';
|
|
9
|
+
import { ApiAuthorizationScheme, createClient } from '@etsoo/restclient';
|
|
10
|
+
import { DataTypes, DomUtils, Utils } from '@etsoo/shared';
|
|
11
|
+
import { AddressUtils } from '../../src/address/AddressUtils';
|
|
12
|
+
import { IAppSettings } from '../../src/app/AppSettings';
|
|
13
|
+
import { CoreApp } from '../../src/app/CoreApp';
|
|
14
|
+
import { zhCN } from '../../src/i18n/zhCN';
|
|
15
|
+
|
|
16
|
+
// Detected country or region
|
|
17
|
+
const { detectedCountry } = DomUtils;
|
|
18
|
+
|
|
19
|
+
// Detected culture
|
|
20
|
+
const { detectedCulture } = DomUtils;
|
|
21
|
+
|
|
22
|
+
// Supported cultures
|
|
23
|
+
const supportedCultures: DataTypes.CultureDefinition[] = [zhCN({})];
|
|
24
|
+
|
|
25
|
+
// Supported regions
|
|
26
|
+
const supportedRegions = ['CN'];
|
|
27
|
+
|
|
28
|
+
// Class implementation for tests
|
|
29
|
+
class NotificationTest extends Notification<any, NotificationCallProps> {
|
|
30
|
+
render(props: NotificationRenderProps, className?: string, options?: any) {
|
|
31
|
+
throw new Error('Method not implemented.');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
class NotificationContainerTest extends NotificationContainer<
|
|
36
|
+
any,
|
|
37
|
+
NotificationCallProps
|
|
38
|
+
> {
|
|
39
|
+
protected addRaw(
|
|
40
|
+
data: INotificaseBase<any, NotificationCallProps>
|
|
41
|
+
): INotification<any, NotificationCallProps> {
|
|
42
|
+
throw new Error('Method not implemented.');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Container
|
|
47
|
+
var container = new NotificationContainerTest((update) => {});
|
|
48
|
+
|
|
49
|
+
// Arrange
|
|
50
|
+
class CoreAppTest extends CoreApp<IAppSettings, {}, NotificationCallProps> {
|
|
51
|
+
/**
|
|
52
|
+
* Constructor
|
|
53
|
+
* @param settings Settings
|
|
54
|
+
* @param name Application name
|
|
55
|
+
*/
|
|
56
|
+
constructor() {
|
|
57
|
+
super(
|
|
58
|
+
{
|
|
59
|
+
/**
|
|
60
|
+
* Endpoint of the API service
|
|
61
|
+
*/
|
|
62
|
+
endpoint: 'http://{hostname}/com.etsoo.SmartERPApi/api/',
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* App root url
|
|
66
|
+
*/
|
|
67
|
+
homepage: '',
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Web url of the cloud
|
|
71
|
+
*/
|
|
72
|
+
webUrl: 'http://localhost',
|
|
73
|
+
|
|
74
|
+
// Authorization scheme
|
|
75
|
+
authScheme: ApiAuthorizationScheme.Bearer,
|
|
76
|
+
|
|
77
|
+
// Detected culture
|
|
78
|
+
detectedCulture,
|
|
79
|
+
|
|
80
|
+
// Supported cultures
|
|
81
|
+
cultures: supportedCultures,
|
|
82
|
+
|
|
83
|
+
// Supported regions
|
|
84
|
+
regions: supportedRegions,
|
|
85
|
+
|
|
86
|
+
// Browser's time zone
|
|
87
|
+
timeZone: Utils.getTimeZone(),
|
|
88
|
+
|
|
89
|
+
// Current country or region
|
|
90
|
+
currentRegion: AddressUtils.getRegion(
|
|
91
|
+
supportedRegions,
|
|
92
|
+
detectedCountry,
|
|
93
|
+
detectedCulture
|
|
94
|
+
),
|
|
95
|
+
|
|
96
|
+
// Current culture
|
|
97
|
+
currentCulture: DomUtils.getCulture(
|
|
98
|
+
supportedCultures,
|
|
99
|
+
detectedCulture
|
|
100
|
+
)!
|
|
101
|
+
},
|
|
102
|
+
createClient(),
|
|
103
|
+
container,
|
|
104
|
+
'SmartERP'
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
freshCountdownUI(callback?: () => PromiseLike<unknown>): void {
|
|
109
|
+
throw new Error('Method not implemented.');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const app = new CoreAppTest();
|
|
114
|
+
|
|
115
|
+
test('Tests for encrypt / decrypt', () => {
|
|
116
|
+
// Arrange
|
|
117
|
+
const input = 'Hello, world!';
|
|
118
|
+
const passphrase = 'My password';
|
|
119
|
+
|
|
120
|
+
// Act
|
|
121
|
+
const encrypted = app.encrypt(input, passphrase);
|
|
122
|
+
const plain = app.decrypt(encrypted, passphrase);
|
|
123
|
+
expect(plain).toEqual(input);
|
|
124
|
+
});
|
package/lib/cjs/app/CoreApp.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { ApiDataError, IApi, IPData } from '@etsoo/restclient';
|
|
|
3
3
|
import { DataTypes, DateUtils } from '@etsoo/shared';
|
|
4
4
|
import { AddressRegion } from '../address/AddressRegion';
|
|
5
5
|
import { IActionResult } from '../result/IActionResult';
|
|
6
|
+
import { InitCallResultData } from '../result/InitCallResult';
|
|
6
7
|
import { IUserData } from '../state/User';
|
|
7
8
|
import { IAppSettings } from './AppSettings';
|
|
8
9
|
import { UserRole } from './UserRole';
|
|
@@ -87,10 +88,6 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
|
|
|
87
88
|
* User data
|
|
88
89
|
*/
|
|
89
90
|
userData?: IUserData;
|
|
90
|
-
/**
|
|
91
|
-
* Passphrase for encryption
|
|
92
|
-
*/
|
|
93
|
-
passphrase?: string;
|
|
94
91
|
/**
|
|
95
92
|
* Search input element
|
|
96
93
|
*/
|
|
@@ -121,9 +118,10 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
|
|
|
121
118
|
* Decrypt message
|
|
122
119
|
* @param messageEncrypted Encrypted message
|
|
123
120
|
* @param passphrase Secret passphrase
|
|
121
|
+
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
124
122
|
* @returns Pure text
|
|
125
123
|
*/
|
|
126
|
-
decrypt(messageEncrypted: string, passphrase
|
|
124
|
+
decrypt(messageEncrypted: string, passphrase?: string, durationSeconds?: number): string | undefined;
|
|
127
125
|
/**
|
|
128
126
|
* Detect IP data, call only one time
|
|
129
127
|
* @param callback Callback will be called when the IP is ready
|
|
@@ -133,9 +131,10 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
|
|
|
133
131
|
* Encrypt message
|
|
134
132
|
* @param message Message
|
|
135
133
|
* @param passphrase Secret passphrase
|
|
134
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
136
135
|
* @returns Result
|
|
137
136
|
*/
|
|
138
|
-
encrypt(message: string, passphrase
|
|
137
|
+
encrypt(message: string, passphrase?: string, iterations?: number): string;
|
|
139
138
|
/**
|
|
140
139
|
* Format date to string
|
|
141
140
|
* @param input Input date
|
|
@@ -216,12 +215,32 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
|
|
|
216
215
|
* @returns Time zone
|
|
217
216
|
*/
|
|
218
217
|
getTimeZone(): string | undefined;
|
|
218
|
+
/**
|
|
219
|
+
* Hash message, SHA3 or HmacSHA512, 512 as Base64
|
|
220
|
+
* https://cryptojs.gitbook.io/docs/
|
|
221
|
+
* @param message Message
|
|
222
|
+
* @param passphrase Secret passphrase
|
|
223
|
+
*/
|
|
224
|
+
hash(message: string, passphrase?: string): string;
|
|
225
|
+
/**
|
|
226
|
+
* Hash message Hex, SHA3 or HmacSHA512, 512 as Base64
|
|
227
|
+
* https://cryptojs.gitbook.io/docs/
|
|
228
|
+
* @param message Message
|
|
229
|
+
* @param passphrase Secret passphrase
|
|
230
|
+
*/
|
|
231
|
+
hashHex(message: string, passphrase?: string): string;
|
|
219
232
|
/**
|
|
220
233
|
* Check use has the specific role permission or not
|
|
221
234
|
* @param roles Roles to check
|
|
222
235
|
* @returns Result
|
|
223
236
|
*/
|
|
224
237
|
hasPermission(roles: number | UserRole | number[] | UserRole[]): boolean;
|
|
238
|
+
/**
|
|
239
|
+
* Init call
|
|
240
|
+
* @param callback Callback
|
|
241
|
+
* @returns Result
|
|
242
|
+
*/
|
|
243
|
+
initCall(callback?: (result: boolean) => void): Promise<void>;
|
|
225
244
|
/**
|
|
226
245
|
* Callback where exit a page
|
|
227
246
|
*/
|
|
@@ -327,10 +346,6 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
327
346
|
* User data
|
|
328
347
|
*/
|
|
329
348
|
userData?: IUserData;
|
|
330
|
-
/**
|
|
331
|
-
* Passphrase for encryption
|
|
332
|
-
*/
|
|
333
|
-
passphrase?: string;
|
|
334
349
|
/**
|
|
335
350
|
* Response token header field name
|
|
336
351
|
*/
|
|
@@ -355,6 +370,18 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
355
370
|
* Token refresh count down seed
|
|
356
371
|
*/
|
|
357
372
|
protected refreshCountdownSeed: number;
|
|
373
|
+
/**
|
|
374
|
+
* Device id field name
|
|
375
|
+
*/
|
|
376
|
+
protected deviceIdField: string;
|
|
377
|
+
/**
|
|
378
|
+
* Device id
|
|
379
|
+
*/
|
|
380
|
+
protected deviceId: string;
|
|
381
|
+
/**
|
|
382
|
+
* Passphrase for encryption
|
|
383
|
+
*/
|
|
384
|
+
protected passphrase: string;
|
|
358
385
|
/**
|
|
359
386
|
* Protected constructor
|
|
360
387
|
* @param settings Settings
|
|
@@ -364,6 +391,23 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
364
391
|
*/
|
|
365
392
|
protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, name: string);
|
|
366
393
|
protected setApi(api: IApi): void;
|
|
394
|
+
/**
|
|
395
|
+
* Init call
|
|
396
|
+
* @param callback Callback
|
|
397
|
+
* @returns Result
|
|
398
|
+
*/
|
|
399
|
+
initCall(callback?: (result: boolean) => void): Promise<void>;
|
|
400
|
+
/**
|
|
401
|
+
* Init call update
|
|
402
|
+
* @param data Result data
|
|
403
|
+
* @param timestamp Timestamp
|
|
404
|
+
*/
|
|
405
|
+
protected initCallUpdate(data: InitCallResultData, timestamp: number): void;
|
|
406
|
+
/**
|
|
407
|
+
* Init call update fields in local storage
|
|
408
|
+
* @returns Fields
|
|
409
|
+
*/
|
|
410
|
+
protected initCallUpdateFields(): string[];
|
|
367
411
|
/**
|
|
368
412
|
* Alert action result
|
|
369
413
|
* @param result Action result
|
|
@@ -390,9 +434,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
390
434
|
* Decrypt message
|
|
391
435
|
* @param messageEncrypted Encrypted message
|
|
392
436
|
* @param passphrase Secret passphrase
|
|
437
|
+
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
393
438
|
* @returns Pure text
|
|
394
439
|
*/
|
|
395
|
-
decrypt(messageEncrypted: string, passphrase
|
|
440
|
+
decrypt(messageEncrypted: string, passphrase?: string, durationSeconds?: number): string | undefined;
|
|
396
441
|
/**
|
|
397
442
|
* Detect IP data, call only one time
|
|
398
443
|
* @param callback Callback will be called when the IP is ready
|
|
@@ -403,9 +448,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
403
448
|
* Encrypt message
|
|
404
449
|
* @param message Message
|
|
405
450
|
* @param passphrase Secret passphrase
|
|
451
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
406
452
|
* @returns Result
|
|
407
453
|
*/
|
|
408
|
-
encrypt(message: string, passphrase
|
|
454
|
+
encrypt(message: string, passphrase?: string, iterations?: number): string;
|
|
409
455
|
/**
|
|
410
456
|
* Enchance secret passphrase
|
|
411
457
|
* @param passphrase Secret passphrase
|
|
@@ -488,6 +534,20 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
|
|
|
488
534
|
* @returns Time zone
|
|
489
535
|
*/
|
|
490
536
|
getTimeZone(): string | undefined;
|
|
537
|
+
/**
|
|
538
|
+
* Hash message, SHA3 or HmacSHA512, 512 as Base64
|
|
539
|
+
* https://cryptojs.gitbook.io/docs/
|
|
540
|
+
* @param message Message
|
|
541
|
+
* @param passphrase Secret passphrase
|
|
542
|
+
*/
|
|
543
|
+
hash(message: string, passphrase?: string): string;
|
|
544
|
+
/**
|
|
545
|
+
* Hash message Hex, SHA3 or HmacSHA512, 512 as Base64
|
|
546
|
+
* https://cryptojs.gitbook.io/docs/
|
|
547
|
+
* @param message Message
|
|
548
|
+
* @param passphrase Secret passphrase
|
|
549
|
+
*/
|
|
550
|
+
hashHex(message: string, passphrase?: string): string;
|
|
491
551
|
/**
|
|
492
552
|
* Check use has the specific role permission or not
|
|
493
553
|
* @param roles Roles to check
|
package/lib/cjs/app/CoreApp.js
CHANGED
|
@@ -34,10 +34,19 @@ class CoreApp {
|
|
|
34
34
|
* Token refresh count down seed
|
|
35
35
|
*/
|
|
36
36
|
this.refreshCountdownSeed = 0;
|
|
37
|
+
/**
|
|
38
|
+
* Device id field name
|
|
39
|
+
*/
|
|
40
|
+
this.deviceIdField = 'SmartERPDeviceId';
|
|
41
|
+
/**
|
|
42
|
+
* Passphrase for encryption
|
|
43
|
+
*/
|
|
44
|
+
this.passphrase = '***';
|
|
37
45
|
this.settings = settings;
|
|
38
46
|
this.api = api;
|
|
39
47
|
this.notifier = notifier;
|
|
40
48
|
this.name = name;
|
|
49
|
+
this.deviceId = shared_1.StorageUtils.getLocalData(this.deviceIdField, '');
|
|
41
50
|
this.setApi(api);
|
|
42
51
|
const { currentCulture, currentRegion } = settings;
|
|
43
52
|
this.changeCulture(currentCulture);
|
|
@@ -108,6 +117,91 @@ class CoreApp {
|
|
|
108
117
|
}
|
|
109
118
|
};
|
|
110
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Init call
|
|
122
|
+
* @param callback Callback
|
|
123
|
+
* @returns Result
|
|
124
|
+
*/
|
|
125
|
+
async initCall(callback) {
|
|
126
|
+
var _a;
|
|
127
|
+
const data = {
|
|
128
|
+
timestamp: new Date().getTime(),
|
|
129
|
+
deviceId: this.deviceId === '' ? undefined : this.deviceId
|
|
130
|
+
};
|
|
131
|
+
const result = await this.api.put('Auth/WebInitCall', data);
|
|
132
|
+
if (result == null) {
|
|
133
|
+
if (callback)
|
|
134
|
+
callback(false);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (result.data == null) {
|
|
138
|
+
this.notifier.alert(this.get('noData'));
|
|
139
|
+
if (callback)
|
|
140
|
+
callback(false);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (!result.ok) {
|
|
144
|
+
const seconds = result.data.seconds;
|
|
145
|
+
const validSeconds = result.data.validSeconds;
|
|
146
|
+
if (result.title === 'timeDifferenceInvalid' &&
|
|
147
|
+
seconds != null &&
|
|
148
|
+
validSeconds != null) {
|
|
149
|
+
const title = (_a = this.get('timeDifferenceInvalid')) === null || _a === void 0 ? void 0 : _a.format(seconds.toString(), validSeconds.toString());
|
|
150
|
+
this.notifier.alert(title);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
this.alertResult(result);
|
|
154
|
+
}
|
|
155
|
+
if (callback)
|
|
156
|
+
callback(false);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
this.initCallUpdate(result.data, data.timestamp);
|
|
160
|
+
if (callback)
|
|
161
|
+
callback(true);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Init call update
|
|
165
|
+
* @param data Result data
|
|
166
|
+
* @param timestamp Timestamp
|
|
167
|
+
*/
|
|
168
|
+
initCallUpdate(data, timestamp) {
|
|
169
|
+
if (data.deviceId == null || data.passphrase == null)
|
|
170
|
+
return;
|
|
171
|
+
// Decrypt
|
|
172
|
+
// Should be done within 120 seconds after returning from the backend
|
|
173
|
+
const passphrase = this.decrypt(data.passphrase, timestamp.toString(), 120);
|
|
174
|
+
if (passphrase == null)
|
|
175
|
+
return;
|
|
176
|
+
// Update device id and cache it
|
|
177
|
+
this.deviceId = data.deviceId;
|
|
178
|
+
shared_1.StorageUtils.setLocalData(this.deviceIdField, this.deviceId);
|
|
179
|
+
// Current passphrase
|
|
180
|
+
this.passphrase = passphrase;
|
|
181
|
+
// Previous passphrase
|
|
182
|
+
if (data.previousPassphrase) {
|
|
183
|
+
const prev = this.decrypt(data.previousPassphrase, timestamp.toString(), 120);
|
|
184
|
+
// Update
|
|
185
|
+
const fields = this.initCallUpdateFields();
|
|
186
|
+
for (const field of fields) {
|
|
187
|
+
const currentValue = shared_1.StorageUtils.getLocalData(field, '');
|
|
188
|
+
if (currentValue === '' || currentValue.indexOf('+') === -1)
|
|
189
|
+
continue;
|
|
190
|
+
const newValueSource = this.decrypt(currentValue, prev, 12);
|
|
191
|
+
if (newValueSource == null)
|
|
192
|
+
continue;
|
|
193
|
+
const newValue = this.encrypt(newValueSource);
|
|
194
|
+
shared_1.StorageUtils.setLocalData(field, newValue);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Init call update fields in local storage
|
|
200
|
+
* @returns Fields
|
|
201
|
+
*/
|
|
202
|
+
initCallUpdateFields() {
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
111
205
|
/**
|
|
112
206
|
* Alert action result
|
|
113
207
|
* @param result Action result
|
|
@@ -200,13 +294,44 @@ class CoreApp {
|
|
|
200
294
|
* Decrypt message
|
|
201
295
|
* @param messageEncrypted Encrypted message
|
|
202
296
|
* @param passphrase Secret passphrase
|
|
297
|
+
* @param durationSeconds Duration seconds, <= 12 will be considered as month
|
|
203
298
|
* @returns Pure text
|
|
204
299
|
*/
|
|
205
|
-
decrypt(messageEncrypted, passphrase) {
|
|
300
|
+
decrypt(messageEncrypted, passphrase, durationSeconds) {
|
|
301
|
+
// Timestamp splitter
|
|
206
302
|
const pos = messageEncrypted.indexOf('+');
|
|
303
|
+
if (pos === -1 || messageEncrypted.length <= 66)
|
|
304
|
+
return undefined;
|
|
207
305
|
const timestamp = messageEncrypted.substring(0, pos);
|
|
208
306
|
const message = messageEncrypted.substring(pos + 1);
|
|
209
|
-
|
|
307
|
+
if (durationSeconds != null && durationSeconds > 0) {
|
|
308
|
+
const milseconds = shared_1.Utils.charsToNumber(timestamp);
|
|
309
|
+
if (isNaN(milseconds) || milseconds < 1)
|
|
310
|
+
return undefined;
|
|
311
|
+
const timespan = new Date().substract(new Date(milseconds));
|
|
312
|
+
if ((durationSeconds <= 12 &&
|
|
313
|
+
timespan.totalMonths > durationSeconds) ||
|
|
314
|
+
(durationSeconds > 12 &&
|
|
315
|
+
timespan.totalSeconds > durationSeconds))
|
|
316
|
+
return undefined;
|
|
317
|
+
}
|
|
318
|
+
// Iterations
|
|
319
|
+
const iterations = parseInt(message.substring(0, 2), 10);
|
|
320
|
+
if (isNaN(iterations))
|
|
321
|
+
return undefined;
|
|
322
|
+
const salt = crypto_js_1.enc.Hex.parse(message.substring(2, 34));
|
|
323
|
+
const iv = crypto_js_1.enc.Hex.parse(message.substring(34, 66));
|
|
324
|
+
const encrypted = message.substring(66);
|
|
325
|
+
const key = (0, crypto_js_1.PBKDF2)(this.encryptionEnhance(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, timestamp), salt, {
|
|
326
|
+
keySize: 8,
|
|
327
|
+
hasher: crypto_js_1.algo.SHA256,
|
|
328
|
+
iterations: 1000 * iterations
|
|
329
|
+
});
|
|
330
|
+
return crypto_js_1.AES.decrypt(encrypted, key, {
|
|
331
|
+
iv,
|
|
332
|
+
padding: crypto_js_1.pad.Pkcs7,
|
|
333
|
+
mode: crypto_js_1.mode.CBC
|
|
334
|
+
}).toString(crypto_js_1.enc.Utf8);
|
|
210
335
|
}
|
|
211
336
|
/**
|
|
212
337
|
* Detect IP data, call only one time
|
|
@@ -245,13 +370,33 @@ class CoreApp {
|
|
|
245
370
|
* Encrypt message
|
|
246
371
|
* @param message Message
|
|
247
372
|
* @param passphrase Secret passphrase
|
|
373
|
+
* @param iterations Iterations, 1000 times, 1 - 99
|
|
248
374
|
* @returns Result
|
|
249
375
|
*/
|
|
250
|
-
encrypt(message, passphrase) {
|
|
376
|
+
encrypt(message, passphrase, iterations) {
|
|
377
|
+
// Default 1 * 1000
|
|
378
|
+
iterations !== null && iterations !== void 0 ? iterations : (iterations = 1);
|
|
379
|
+
// Timestamp
|
|
251
380
|
const timestamp = shared_1.Utils.numberToChars(new Date().getTime());
|
|
381
|
+
const bits = 16; // 128 / 8
|
|
382
|
+
const salt = crypto_js_1.lib.WordArray.random(bits);
|
|
383
|
+
const key = (0, crypto_js_1.PBKDF2)(this.encryptionEnhance(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, timestamp), salt, {
|
|
384
|
+
keySize: 8,
|
|
385
|
+
hasher: crypto_js_1.algo.SHA256,
|
|
386
|
+
iterations: 1000 * iterations
|
|
387
|
+
});
|
|
388
|
+
const iv = crypto_js_1.lib.WordArray.random(bits);
|
|
252
389
|
return (timestamp +
|
|
253
390
|
'+' +
|
|
254
|
-
|
|
391
|
+
iterations.toString().padStart(2, '0') +
|
|
392
|
+
salt.toString(crypto_js_1.enc.Hex) +
|
|
393
|
+
iv.toString(crypto_js_1.enc.Hex) +
|
|
394
|
+
crypto_js_1.AES.encrypt(message, key, {
|
|
395
|
+
iv,
|
|
396
|
+
padding: crypto_js_1.pad.Pkcs7,
|
|
397
|
+
mode: crypto_js_1.mode.CBC
|
|
398
|
+
}).toString() // enc.Base64
|
|
399
|
+
);
|
|
255
400
|
}
|
|
256
401
|
/**
|
|
257
402
|
* Enchance secret passphrase
|
|
@@ -260,10 +405,9 @@ class CoreApp {
|
|
|
260
405
|
* @returns Enhanced passphrase
|
|
261
406
|
*/
|
|
262
407
|
encryptionEnhance(passphrase, timestamp) {
|
|
263
|
-
var _a;
|
|
264
408
|
passphrase += timestamp;
|
|
265
409
|
passphrase += passphrase.length.toString();
|
|
266
|
-
return passphrase
|
|
410
|
+
return passphrase;
|
|
267
411
|
}
|
|
268
412
|
/**
|
|
269
413
|
* Format date to string
|
|
@@ -325,7 +469,19 @@ class CoreApp {
|
|
|
325
469
|
* @param forceToLocal Force to local labels
|
|
326
470
|
*/
|
|
327
471
|
formatResult(result, forceToLocal) {
|
|
328
|
-
|
|
472
|
+
const title = result.title;
|
|
473
|
+
if (title && /^\w+$/.test(title)) {
|
|
474
|
+
const key = title.formatInitial(false);
|
|
475
|
+
const localTitle = this.get(key);
|
|
476
|
+
if (localTitle) {
|
|
477
|
+
result.title = localTitle;
|
|
478
|
+
// Hold the original title in type when type is null
|
|
479
|
+
if (result.type == null)
|
|
480
|
+
result.type = title;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
else if ((title == null || forceToLocal) && result.type != null) {
|
|
484
|
+
// Get label from type
|
|
329
485
|
const key = result.type.formatInitial(false);
|
|
330
486
|
result.title = this.get(key);
|
|
331
487
|
}
|
|
@@ -391,6 +547,30 @@ class CoreApp {
|
|
|
391
547
|
// settings.timeZone = Utils.getTimeZone()
|
|
392
548
|
return (_a = this.settings.timeZone) !== null && _a !== void 0 ? _a : (_b = this.ipData) === null || _b === void 0 ? void 0 : _b.timezone;
|
|
393
549
|
}
|
|
550
|
+
/**
|
|
551
|
+
* Hash message, SHA3 or HmacSHA512, 512 as Base64
|
|
552
|
+
* https://cryptojs.gitbook.io/docs/
|
|
553
|
+
* @param message Message
|
|
554
|
+
* @param passphrase Secret passphrase
|
|
555
|
+
*/
|
|
556
|
+
hash(message, passphrase) {
|
|
557
|
+
if (passphrase == null)
|
|
558
|
+
return (0, crypto_js_1.SHA3)(message, { outputLength: 512 }).toString(crypto_js_1.enc.Base64);
|
|
559
|
+
else
|
|
560
|
+
return (0, crypto_js_1.HmacSHA512)(message, passphrase).toString(crypto_js_1.enc.Base64);
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Hash message Hex, SHA3 or HmacSHA512, 512 as Base64
|
|
564
|
+
* https://cryptojs.gitbook.io/docs/
|
|
565
|
+
* @param message Message
|
|
566
|
+
* @param passphrase Secret passphrase
|
|
567
|
+
*/
|
|
568
|
+
hashHex(message, passphrase) {
|
|
569
|
+
if (passphrase == null)
|
|
570
|
+
return (0, crypto_js_1.SHA3)(message, { outputLength: 512 }).toString(crypto_js_1.enc.Hex);
|
|
571
|
+
else
|
|
572
|
+
return (0, crypto_js_1.HmacSHA512)(message, passphrase).toString(crypto_js_1.enc.Hex);
|
|
573
|
+
}
|
|
394
574
|
/**
|
|
395
575
|
* Check use has the specific role permission or not
|
|
396
576
|
* @param roles Roles to check
|
|
@@ -540,7 +720,6 @@ class CoreApp {
|
|
|
540
720
|
*/
|
|
541
721
|
userLogin(user, refreshToken, keep = false) {
|
|
542
722
|
this.userData = user;
|
|
543
|
-
this.passphrase = user.passphrase;
|
|
544
723
|
this.authorize(user.token, refreshToken, keep);
|
|
545
724
|
}
|
|
546
725
|
/**
|
package/lib/cjs/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export * from './def/ListItem';
|
|
|
16
16
|
export * from './dto/IdDto';
|
|
17
17
|
export * from './dto/IdLabelDto';
|
|
18
18
|
export * from './dto/IdLabelPrimaryDto';
|
|
19
|
+
export * from './dto/InitCallDto';
|
|
19
20
|
export * from './dto/UpdateDto';
|
|
20
21
|
export * from './i18n/enUS';
|
|
21
22
|
export * from './i18n/zhCN';
|
package/lib/cjs/index.js
CHANGED
|
@@ -35,6 +35,7 @@ __exportStar(require("./def/ListItem"), exports);
|
|
|
35
35
|
__exportStar(require("./dto/IdDto"), exports);
|
|
36
36
|
__exportStar(require("./dto/IdLabelDto"), exports);
|
|
37
37
|
__exportStar(require("./dto/IdLabelPrimaryDto"), exports);
|
|
38
|
+
__exportStar(require("./dto/InitCallDto"), exports);
|
|
38
39
|
__exportStar(require("./dto/UpdateDto"), exports);
|
|
39
40
|
// i18n
|
|
40
41
|
__exportStar(require("./i18n/enUS"), exports);
|
|
@@ -48,11 +48,11 @@ export interface IActionResult<D extends IResultData = IResultData> {
|
|
|
48
48
|
/**
|
|
49
49
|
* Trace id
|
|
50
50
|
*/
|
|
51
|
-
|
|
51
|
+
traceId?: string;
|
|
52
52
|
/**
|
|
53
53
|
* Type
|
|
54
54
|
*/
|
|
55
|
-
|
|
55
|
+
type: string;
|
|
56
56
|
/**
|
|
57
57
|
* Success or not
|
|
58
58
|
*/
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import { IActionResult, IResultData } from './IActionResult';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Init call result data
|
|
4
4
|
*/
|
|
5
5
|
export interface InitCallResultData extends IResultData {
|
|
6
|
+
/**
|
|
7
|
+
* Device id
|
|
8
|
+
*/
|
|
9
|
+
deviceId?: string;
|
|
6
10
|
/**
|
|
7
11
|
* Secret passphrase
|
|
8
12
|
*/
|
|
9
|
-
passphrase
|
|
13
|
+
passphrase?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Previous secret passphrase
|
|
16
|
+
*/
|
|
17
|
+
previousPassphrase?: string;
|
|
10
18
|
/**
|
|
11
19
|
* Actual seconds gap
|
|
12
20
|
*/
|
|
13
|
-
seconds
|
|
21
|
+
seconds?: number;
|
|
14
22
|
/**
|
|
15
23
|
* Valid seconds gap
|
|
16
24
|
*/
|
|
17
|
-
validSeconds
|
|
25
|
+
validSeconds?: number;
|
|
18
26
|
}
|
|
19
27
|
/**
|
|
20
28
|
* Init call result
|