@etsoo/appscript 1.5.39 → 1.5.41

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.
@@ -425,7 +425,7 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
425
425
  * @param initCallCallback InitCall callback
426
426
  * @param silent Silent without any popups
427
427
  */
428
- doRefreshTokenResult(result: RefreshTokenResult, initCallCallback?: (result: boolean) => void, silent?: boolean): void;
428
+ doRefreshTokenResult(result: RefreshTokenResult<IActionResult<U>>, initCallCallback?: (result: boolean) => void, silent?: boolean): void;
429
429
  /**
430
430
  * Format as full name
431
431
  * @param familyName Family name
@@ -437,7 +437,7 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
437
437
  * @param result Refresh token result
438
438
  * @returns Message
439
439
  */
440
- formatRefreshTokenResult(result: RefreshTokenResult): string | undefined;
440
+ formatRefreshTokenResult(result: RefreshTokenResult<IActionResult<U>>): string | undefined;
441
441
  private getFieldLabel;
442
442
  /**
443
443
  * Format result text
@@ -129,7 +129,6 @@ class CoreApp {
129
129
  this.pendings = [];
130
130
  this._authorized = false;
131
131
  this._isReady = false;
132
- this._embedded = false;
133
132
  this._isTryingLogin = false;
134
133
  /**
135
134
  * Last called with token refresh
@@ -186,6 +185,9 @@ class CoreApp {
186
185
  this.fields = IApp_1.appFields.reduce((a, v) => ({ ...a, [v]: 'smarterp-' + v + '-' + name }), {});
187
186
  // Device id
188
187
  this._deviceId = storage.getData(this.fields.deviceId, '');
188
+ // Embedded
189
+ this._embedded =
190
+ this.storage.getData(this.fields.embedded) ?? false;
189
191
  const { currentCulture, currentRegion } = settings;
190
192
  // Load resources
191
193
  Promise.all([loadCrypto(), this.changeCulture(currentCulture)]).then(([cj, _resources]) => {
@@ -1007,11 +1009,9 @@ class CoreApp {
1007
1009
  * @param silent Silent without any popups
1008
1010
  */
1009
1011
  doRefreshTokenResult(result, initCallCallback, silent = false) {
1010
- if (result === true)
1011
- return;
1012
- if (typeof result === 'object' &&
1012
+ if (Array.isArray(result) &&
1013
1013
  !(result instanceof restclient_1.ApiDataError) &&
1014
- this.checkDeviceResult(result)) {
1014
+ this.checkDeviceResult(result[1])) {
1015
1015
  initCallCallback ?? (initCallCallback = (result) => {
1016
1016
  if (!result)
1017
1017
  return;
@@ -1055,14 +1055,21 @@ class CoreApp {
1055
1055
  * @returns Message
1056
1056
  */
1057
1057
  formatRefreshTokenResult(result) {
1058
- // Undefined for boolean
1059
- if (typeof result === 'boolean')
1058
+ // Error message
1059
+ if (typeof result === 'string')
1060
+ return result;
1061
+ // API error
1062
+ if (result instanceof restclient_1.ApiDataError)
1063
+ return this.formatError(result);
1064
+ // Action result
1065
+ const [token, r] = result;
1066
+ // Success
1067
+ if (r.ok)
1060
1068
  return undefined;
1061
- return result instanceof restclient_1.ApiDataError
1062
- ? this.formatError(result)
1063
- : typeof result !== 'string'
1064
- ? ActionResultError_1.ActionResultError.format(result)
1065
- : result;
1069
+ // No token data
1070
+ if (token == null)
1071
+ return `${this.get('noData')} (token)`;
1072
+ return ActionResultError_1.ActionResultError.format(r);
1066
1073
  }
1067
1074
  getFieldLabel(field) {
1068
1075
  return this.get(field.formatInitial(false)) ?? field;
@@ -1278,6 +1285,8 @@ class CoreApp {
1278
1285
  */
1279
1286
  getResponseToken(rawResponse, tokenKey) {
1280
1287
  const response = this.api.transformResponse(rawResponse);
1288
+ if (!response.ok)
1289
+ return null;
1281
1290
  return this.api.getHeaderValue(response.headers, tokenKey ?? 'Smarterp-Refresh-Token');
1282
1291
  }
1283
1292
  /**
@@ -1398,8 +1407,6 @@ class CoreApp {
1398
1407
  * @param props Props
1399
1408
  */
1400
1409
  async refreshToken(props) {
1401
- if (props && props.callback)
1402
- props.callback(true, undefined);
1403
1410
  return true;
1404
1411
  }
1405
1412
  /**
@@ -24,10 +24,10 @@ export interface NavigateOptions {
24
24
  }
25
25
  /**
26
26
  * Refresh token result type
27
- * true means success, false means failed but no any message
27
+ * array means success, false means failed but no any message
28
28
  * other cases means failed with differnet message
29
29
  */
30
- export type RefreshTokenResult = boolean | string | ApiDataError | IActionResult;
30
+ export type RefreshTokenResult<R> = string | ApiDataError | [string | null, R];
31
31
  /**
32
32
  * Format result custom type
33
33
  */
@@ -45,13 +45,17 @@ export type FormatResultCustomCallback = ((data: FormatResultCustom) => string |
45
45
  */
46
46
  export interface RefreshTokenProps {
47
47
  /**
48
- * Callback
48
+ * API name
49
49
  */
50
- callback?: (result: RefreshTokenResult, successData?: string) => void;
50
+ api?: string;
51
51
  /**
52
52
  * Show loading bar or not
53
53
  */
54
54
  showLoading?: boolean;
55
+ /**
56
+ * Header token field name
57
+ */
58
+ tokenField?: string;
55
59
  }
56
60
  /**
57
61
  * App fields
@@ -331,7 +335,7 @@ export interface IApp {
331
335
  * @param initCallCallback InitCall callback
332
336
  * @param silent Silent without any popups
333
337
  */
334
- doRefreshTokenResult(result: RefreshTokenResult, initCallCallback?: (result: boolean) => void, silent?: boolean): void;
338
+ doRefreshTokenResult(result: RefreshTokenResult<IActionResult<IUser>>, initCallCallback?: (result: boolean) => void, silent?: boolean): void;
335
339
  /**
336
340
  * Format as full name
337
341
  * @param familyName Family name
@@ -343,7 +347,7 @@ export interface IApp {
343
347
  * @param result Refresh token result
344
348
  * @returns Message
345
349
  */
346
- formatRefreshTokenResult(result: RefreshTokenResult): string | undefined;
350
+ formatRefreshTokenResult(result: RefreshTokenResult<IActionResult<IUser>>): string | undefined;
347
351
  /**
348
352
  * Format result text
349
353
  * @param result Action result
@@ -9,6 +9,7 @@ import { SignoutRQ } from './rq/SignoutRQ';
9
9
  import { GetLogInUrlRQ } from './rq/GetLogInUrlRQ';
10
10
  import { TokenRQ } from './rq/TokenRQ';
11
11
  import { ApiRefreshTokenDto } from './dto/ApiRefreshTokenDto';
12
+ import { RefreshTokenProps, RefreshTokenResult } from '../app/IApp';
12
13
  /**
13
14
  * Authentication API
14
15
  */
@@ -49,6 +50,13 @@ export declare class AuthApi extends BaseApi {
49
50
  * @returns Result
50
51
  */
51
52
  loginId(id: string, payload?: ResultPayload): Promise<IActionResult<{}> | undefined>;
53
+ /**
54
+ * Refresh token
55
+ * @param token Refresh token
56
+ * @param props Props
57
+ * @returns Result
58
+ */
59
+ refreshToken<R>(token: string, props?: RefreshTokenProps): Promise<RefreshTokenResult<R>>;
52
60
  /**
53
61
  * Reset password
54
62
  * @param rq Request data
@@ -64,6 +64,39 @@ class AuthApi extends BaseApi_1.BaseApi {
64
64
  };
65
65
  return this.api.post('Auth/LoginId', rq, payload);
66
66
  }
67
+ /**
68
+ * Refresh token
69
+ * @param token Refresh token
70
+ * @param props Props
71
+ * @returns Result
72
+ */
73
+ async refreshToken(token, props) {
74
+ // Destruct
75
+ const { api = 'Auth/RefreshToken', showLoading = false, tokenField = 'Etsoo-Refresh-Token' } = props ?? {};
76
+ // Reqest data
77
+ const rq = {
78
+ deviceId: this.app.deviceId
79
+ };
80
+ // Payload
81
+ const payload = {
82
+ // No loading bar needed to avoid screen flicks
83
+ showLoading,
84
+ config: { headers: { [tokenField]: token } },
85
+ onError: () => {
86
+ // Prevent further processing
87
+ return false;
88
+ }
89
+ };
90
+ // Call API
91
+ const result = await this.api.put(api, rq, payload);
92
+ if (result == null) {
93
+ return this.api.lastError ?? this.app.get('unknownError');
94
+ }
95
+ // Token
96
+ const refreshToken = this.app.getResponseToken(payload.response, tokenField);
97
+ // Success
98
+ return [refreshToken, result];
99
+ }
67
100
  /**
68
101
  * Reset password
69
102
  * @param rq Request data
@@ -425,7 +425,7 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
425
425
  * @param initCallCallback InitCall callback
426
426
  * @param silent Silent without any popups
427
427
  */
428
- doRefreshTokenResult(result: RefreshTokenResult, initCallCallback?: (result: boolean) => void, silent?: boolean): void;
428
+ doRefreshTokenResult(result: RefreshTokenResult<IActionResult<U>>, initCallCallback?: (result: boolean) => void, silent?: boolean): void;
429
429
  /**
430
430
  * Format as full name
431
431
  * @param familyName Family name
@@ -437,7 +437,7 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
437
437
  * @param result Refresh token result
438
438
  * @returns Message
439
439
  */
440
- formatRefreshTokenResult(result: RefreshTokenResult): string | undefined;
440
+ formatRefreshTokenResult(result: RefreshTokenResult<IActionResult<U>>): string | undefined;
441
441
  private getFieldLabel;
442
442
  /**
443
443
  * Format result text
@@ -126,7 +126,6 @@ export class CoreApp {
126
126
  this.pendings = [];
127
127
  this._authorized = false;
128
128
  this._isReady = false;
129
- this._embedded = false;
130
129
  this._isTryingLogin = false;
131
130
  /**
132
131
  * Last called with token refresh
@@ -183,6 +182,9 @@ export class CoreApp {
183
182
  this.fields = appFields.reduce((a, v) => ({ ...a, [v]: 'smarterp-' + v + '-' + name }), {});
184
183
  // Device id
185
184
  this._deviceId = storage.getData(this.fields.deviceId, '');
185
+ // Embedded
186
+ this._embedded =
187
+ this.storage.getData(this.fields.embedded) ?? false;
186
188
  const { currentCulture, currentRegion } = settings;
187
189
  // Load resources
188
190
  Promise.all([loadCrypto(), this.changeCulture(currentCulture)]).then(([cj, _resources]) => {
@@ -1004,11 +1006,9 @@ export class CoreApp {
1004
1006
  * @param silent Silent without any popups
1005
1007
  */
1006
1008
  doRefreshTokenResult(result, initCallCallback, silent = false) {
1007
- if (result === true)
1008
- return;
1009
- if (typeof result === 'object' &&
1009
+ if (Array.isArray(result) &&
1010
1010
  !(result instanceof ApiDataError) &&
1011
- this.checkDeviceResult(result)) {
1011
+ this.checkDeviceResult(result[1])) {
1012
1012
  initCallCallback ?? (initCallCallback = (result) => {
1013
1013
  if (!result)
1014
1014
  return;
@@ -1052,14 +1052,21 @@ export class CoreApp {
1052
1052
  * @returns Message
1053
1053
  */
1054
1054
  formatRefreshTokenResult(result) {
1055
- // Undefined for boolean
1056
- if (typeof result === 'boolean')
1055
+ // Error message
1056
+ if (typeof result === 'string')
1057
+ return result;
1058
+ // API error
1059
+ if (result instanceof ApiDataError)
1060
+ return this.formatError(result);
1061
+ // Action result
1062
+ const [token, r] = result;
1063
+ // Success
1064
+ if (r.ok)
1057
1065
  return undefined;
1058
- return result instanceof ApiDataError
1059
- ? this.formatError(result)
1060
- : typeof result !== 'string'
1061
- ? ActionResultError.format(result)
1062
- : result;
1066
+ // No token data
1067
+ if (token == null)
1068
+ return `${this.get('noData')} (token)`;
1069
+ return ActionResultError.format(r);
1063
1070
  }
1064
1071
  getFieldLabel(field) {
1065
1072
  return this.get(field.formatInitial(false)) ?? field;
@@ -1275,6 +1282,8 @@ export class CoreApp {
1275
1282
  */
1276
1283
  getResponseToken(rawResponse, tokenKey) {
1277
1284
  const response = this.api.transformResponse(rawResponse);
1285
+ if (!response.ok)
1286
+ return null;
1278
1287
  return this.api.getHeaderValue(response.headers, tokenKey ?? 'Smarterp-Refresh-Token');
1279
1288
  }
1280
1289
  /**
@@ -1395,8 +1404,6 @@ export class CoreApp {
1395
1404
  * @param props Props
1396
1405
  */
1397
1406
  async refreshToken(props) {
1398
- if (props && props.callback)
1399
- props.callback(true, undefined);
1400
1407
  return true;
1401
1408
  }
1402
1409
  /**
@@ -24,10 +24,10 @@ export interface NavigateOptions {
24
24
  }
25
25
  /**
26
26
  * Refresh token result type
27
- * true means success, false means failed but no any message
27
+ * array means success, false means failed but no any message
28
28
  * other cases means failed with differnet message
29
29
  */
30
- export type RefreshTokenResult = boolean | string | ApiDataError | IActionResult;
30
+ export type RefreshTokenResult<R> = string | ApiDataError | [string | null, R];
31
31
  /**
32
32
  * Format result custom type
33
33
  */
@@ -45,13 +45,17 @@ export type FormatResultCustomCallback = ((data: FormatResultCustom) => string |
45
45
  */
46
46
  export interface RefreshTokenProps {
47
47
  /**
48
- * Callback
48
+ * API name
49
49
  */
50
- callback?: (result: RefreshTokenResult, successData?: string) => void;
50
+ api?: string;
51
51
  /**
52
52
  * Show loading bar or not
53
53
  */
54
54
  showLoading?: boolean;
55
+ /**
56
+ * Header token field name
57
+ */
58
+ tokenField?: string;
55
59
  }
56
60
  /**
57
61
  * App fields
@@ -331,7 +335,7 @@ export interface IApp {
331
335
  * @param initCallCallback InitCall callback
332
336
  * @param silent Silent without any popups
333
337
  */
334
- doRefreshTokenResult(result: RefreshTokenResult, initCallCallback?: (result: boolean) => void, silent?: boolean): void;
338
+ doRefreshTokenResult(result: RefreshTokenResult<IActionResult<IUser>>, initCallCallback?: (result: boolean) => void, silent?: boolean): void;
335
339
  /**
336
340
  * Format as full name
337
341
  * @param familyName Family name
@@ -343,7 +347,7 @@ export interface IApp {
343
347
  * @param result Refresh token result
344
348
  * @returns Message
345
349
  */
346
- formatRefreshTokenResult(result: RefreshTokenResult): string | undefined;
350
+ formatRefreshTokenResult(result: RefreshTokenResult<IActionResult<IUser>>): string | undefined;
347
351
  /**
348
352
  * Format result text
349
353
  * @param result Action result
@@ -9,6 +9,7 @@ import { SignoutRQ } from './rq/SignoutRQ';
9
9
  import { GetLogInUrlRQ } from './rq/GetLogInUrlRQ';
10
10
  import { TokenRQ } from './rq/TokenRQ';
11
11
  import { ApiRefreshTokenDto } from './dto/ApiRefreshTokenDto';
12
+ import { RefreshTokenProps, RefreshTokenResult } from '../app/IApp';
12
13
  /**
13
14
  * Authentication API
14
15
  */
@@ -49,6 +50,13 @@ export declare class AuthApi extends BaseApi {
49
50
  * @returns Result
50
51
  */
51
52
  loginId(id: string, payload?: ResultPayload): Promise<IActionResult<{}> | undefined>;
53
+ /**
54
+ * Refresh token
55
+ * @param token Refresh token
56
+ * @param props Props
57
+ * @returns Result
58
+ */
59
+ refreshToken<R>(token: string, props?: RefreshTokenProps): Promise<RefreshTokenResult<R>>;
52
60
  /**
53
61
  * Reset password
54
62
  * @param rq Request data
@@ -61,6 +61,39 @@ export class AuthApi extends BaseApi {
61
61
  };
62
62
  return this.api.post('Auth/LoginId', rq, payload);
63
63
  }
64
+ /**
65
+ * Refresh token
66
+ * @param token Refresh token
67
+ * @param props Props
68
+ * @returns Result
69
+ */
70
+ async refreshToken(token, props) {
71
+ // Destruct
72
+ const { api = 'Auth/RefreshToken', showLoading = false, tokenField = 'Etsoo-Refresh-Token' } = props ?? {};
73
+ // Reqest data
74
+ const rq = {
75
+ deviceId: this.app.deviceId
76
+ };
77
+ // Payload
78
+ const payload = {
79
+ // No loading bar needed to avoid screen flicks
80
+ showLoading,
81
+ config: { headers: { [tokenField]: token } },
82
+ onError: () => {
83
+ // Prevent further processing
84
+ return false;
85
+ }
86
+ };
87
+ // Call API
88
+ const result = await this.api.put(api, rq, payload);
89
+ if (result == null) {
90
+ return this.api.lastError ?? this.app.get('unknownError');
91
+ }
92
+ // Token
93
+ const refreshToken = this.app.getResponseToken(payload.response, tokenField);
94
+ // Success
95
+ return [refreshToken, result];
96
+ }
64
97
  /**
65
98
  * Reset password
66
99
  * @param rq Request data
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/appscript",
3
- "version": "1.5.39",
3
+ "version": "1.5.41",
4
4
  "description": "Applications shared TypeScript framework",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -248,7 +248,7 @@ export abstract class CoreApp<
248
248
  this.storage.setData(this.fields.cachedUrl, value);
249
249
  }
250
250
 
251
- private _embedded: boolean = false;
251
+ private _embedded: boolean;
252
252
  /**
253
253
  * Is embedded
254
254
  */
@@ -361,6 +361,10 @@ export abstract class CoreApp<
361
361
  // Device id
362
362
  this._deviceId = storage.getData(this.fields.deviceId, '');
363
363
 
364
+ // Embedded
365
+ this._embedded =
366
+ this.storage.getData<boolean>(this.fields.embedded) ?? false;
367
+
364
368
  const { currentCulture, currentRegion } = settings;
365
369
 
366
370
  // Load resources
@@ -1477,16 +1481,14 @@ export abstract class CoreApp<
1477
1481
  * @param silent Silent without any popups
1478
1482
  */
1479
1483
  doRefreshTokenResult(
1480
- result: RefreshTokenResult,
1484
+ result: RefreshTokenResult<IActionResult<U>>,
1481
1485
  initCallCallback?: (result: boolean) => void,
1482
1486
  silent: boolean = false
1483
1487
  ) {
1484
- if (result === true) return;
1485
-
1486
1488
  if (
1487
- typeof result === 'object' &&
1489
+ Array.isArray(result) &&
1488
1490
  !(result instanceof ApiDataError) &&
1489
- this.checkDeviceResult(result)
1491
+ this.checkDeviceResult(result[1])
1490
1492
  ) {
1491
1493
  initCallCallback ??= (result) => {
1492
1494
  if (!result) return;
@@ -1538,15 +1540,23 @@ export abstract class CoreApp<
1538
1540
  * @param result Refresh token result
1539
1541
  * @returns Message
1540
1542
  */
1541
- formatRefreshTokenResult(result: RefreshTokenResult) {
1542
- // Undefined for boolean
1543
- if (typeof result === 'boolean') return undefined;
1543
+ formatRefreshTokenResult(result: RefreshTokenResult<IActionResult<U>>) {
1544
+ // Error message
1545
+ if (typeof result === 'string') return result;
1546
+
1547
+ // API error
1548
+ if (result instanceof ApiDataError) return this.formatError(result);
1549
+
1550
+ // Action result
1551
+ const [token, r] = result;
1552
+
1553
+ // Success
1554
+ if (r.ok) return undefined;
1555
+
1556
+ // No token data
1557
+ if (token == null) return `${this.get('noData')} (token)`;
1544
1558
 
1545
- return result instanceof ApiDataError
1546
- ? this.formatError(result)
1547
- : typeof result !== 'string'
1548
- ? ActionResultError.format(result)
1549
- : result;
1559
+ return ActionResultError.format(r);
1550
1560
  }
1551
1561
 
1552
1562
  private getFieldLabel(field: string) {
@@ -1801,6 +1811,7 @@ export abstract class CoreApp<
1801
1811
  */
1802
1812
  getResponseToken(rawResponse: any, tokenKey?: string): string | null {
1803
1813
  const response = this.api.transformResponse(rawResponse);
1814
+ if (!response.ok) return null;
1804
1815
  return this.api.getHeaderValue(
1805
1816
  response.headers,
1806
1817
  tokenKey ?? 'Smarterp-Refresh-Token'
@@ -1938,7 +1949,6 @@ export abstract class CoreApp<
1938
1949
  * @param props Props
1939
1950
  */
1940
1951
  async refreshToken(props?: RefreshTokenProps) {
1941
- if (props && props.callback) props.callback(true, undefined);
1942
1952
  return true;
1943
1953
  }
1944
1954
 
package/src/app/IApp.ts CHANGED
@@ -42,14 +42,10 @@ export interface NavigateOptions {
42
42
 
43
43
  /**
44
44
  * Refresh token result type
45
- * true means success, false means failed but no any message
45
+ * array means success, false means failed but no any message
46
46
  * other cases means failed with differnet message
47
47
  */
48
- export type RefreshTokenResult =
49
- | boolean
50
- | string
51
- | ApiDataError
52
- | IActionResult;
48
+ export type RefreshTokenResult<R> = string | ApiDataError | [string | null, R];
53
49
 
54
50
  /**
55
51
  * Format result custom type
@@ -72,14 +68,19 @@ export type FormatResultCustomCallback =
72
68
  */
73
69
  export interface RefreshTokenProps {
74
70
  /**
75
- * Callback
71
+ * API name
76
72
  */
77
- callback?: (result: RefreshTokenResult, successData?: string) => void;
73
+ api?: string;
78
74
 
79
75
  /**
80
76
  * Show loading bar or not
81
77
  */
82
78
  showLoading?: boolean;
79
+
80
+ /**
81
+ * Header token field name
82
+ */
83
+ tokenField?: string;
83
84
  }
84
85
 
85
86
  /**
@@ -454,7 +455,7 @@ export interface IApp {
454
455
  * @param silent Silent without any popups
455
456
  */
456
457
  doRefreshTokenResult(
457
- result: RefreshTokenResult,
458
+ result: RefreshTokenResult<IActionResult<IUser>>,
458
459
  initCallCallback?: (result: boolean) => void,
459
460
  silent?: boolean
460
461
  ): void;
@@ -474,7 +475,9 @@ export interface IApp {
474
475
  * @param result Refresh token result
475
476
  * @returns Message
476
477
  */
477
- formatRefreshTokenResult(result: RefreshTokenResult): string | undefined;
478
+ formatRefreshTokenResult(
479
+ result: RefreshTokenResult<IActionResult<IUser>>
480
+ ): string | undefined;
478
481
 
479
482
  /**
480
483
  * Format result text
@@ -10,6 +10,8 @@ import { SignoutRQ } from './rq/SignoutRQ';
10
10
  import { GetLogInUrlRQ } from './rq/GetLogInUrlRQ';
11
11
  import { TokenRQ } from './rq/TokenRQ';
12
12
  import { ApiRefreshTokenDto } from './dto/ApiRefreshTokenDto';
13
+ import { RefreshTokenProps, RefreshTokenResult } from '../app/IApp';
14
+ import { RefreshTokenRQ } from './rq/RefreshTokenRQ';
13
15
 
14
16
  /**
15
17
  * Authentication API
@@ -82,6 +84,55 @@ export class AuthApi extends BaseApi {
82
84
  return this.api.post('Auth/LoginId', rq, payload);
83
85
  }
84
86
 
87
+ /**
88
+ * Refresh token
89
+ * @param token Refresh token
90
+ * @param props Props
91
+ * @returns Result
92
+ */
93
+ async refreshToken<R>(
94
+ token: string,
95
+ props?: RefreshTokenProps
96
+ ): Promise<RefreshTokenResult<R>> {
97
+ // Destruct
98
+ const {
99
+ api = 'Auth/RefreshToken',
100
+ showLoading = false,
101
+ tokenField = 'Etsoo-Refresh-Token'
102
+ } = props ?? {};
103
+
104
+ // Reqest data
105
+ const rq: RefreshTokenRQ = {
106
+ deviceId: this.app.deviceId
107
+ };
108
+
109
+ // Payload
110
+ const payload: IApiPayload<R, any> = {
111
+ // No loading bar needed to avoid screen flicks
112
+ showLoading,
113
+ config: { headers: { [tokenField]: token } },
114
+ onError: () => {
115
+ // Prevent further processing
116
+ return false;
117
+ }
118
+ };
119
+
120
+ // Call API
121
+ const result = await this.api.put(api, rq, payload);
122
+ if (result == null) {
123
+ return this.api.lastError ?? this.app.get('unknownError')!;
124
+ }
125
+
126
+ // Token
127
+ const refreshToken = this.app.getResponseToken(
128
+ payload.response,
129
+ tokenField
130
+ );
131
+
132
+ // Success
133
+ return [refreshToken, result];
134
+ }
135
+
85
136
  /**
86
137
  * Reset password
87
138
  * @param rq Request data