@peassoft/mnr-web-topline 4.0.1 → 4.2.0
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/dist/en/modules/env/index.d.ts +8 -0
- package/dist/en/modules/env/index.js +15 -0
- package/dist/en/modules/local-db/create-request-error.d.ts +2 -2
- package/dist/en/modules/local-db/create-request-error.js +2 -2
- package/dist/en/modules/local-db/init-db.js +3 -3
- package/dist/en/modules/logger/index.d.ts +1 -1
- package/dist/en/modules/logger/index.js +19 -2
- package/dist/en/modules/request/index.js +5 -5
- package/dist/en/modules/topline-service/inner-service.js +3 -3
- package/dist/en/modules/ui-lang/index.d.ts +4 -8
- package/dist/en/modules/ui-lang/index.js +6 -18
- package/dist/en/modules/websocket/index.js +2 -2
- package/dist/en/parts/logout/actions/perform-logout/index.d.ts +1 -20
- package/dist/en/parts/logout/actions/perform-logout/index.js +9 -22
- package/dist/en/parts/password-recovery/actions/create-claim/index.d.ts +1 -13
- package/dist/en/parts/password-recovery/actions/create-claim/index.js +5 -14
- package/dist/en/parts/profile/actions/change-password/index.js +2 -2
- package/dist/en/parts/profile/ui/root/has-changes.js +1 -1
- package/dist/en/parts/profile/ui/root/index.js +3 -3
- package/dist/en/parts/shell/actions/refresh-user/index.d.ts +1 -22
- package/dist/en/parts/shell/actions/refresh-user/index.js +13 -27
- package/dist/en/parts/signup/actions/perform-signup/index.d.ts +2 -1
- package/dist/en/parts/signup/ui/signup/index.js +17 -3
- package/dist/en/shared/procedures/process-response.js +3 -3
- package/dist/ru/modules/env/index.d.ts +8 -0
- package/dist/ru/modules/env/index.js +15 -0
- package/dist/ru/modules/local-db/create-request-error.d.ts +2 -2
- package/dist/ru/modules/local-db/create-request-error.js +2 -2
- package/dist/ru/modules/local-db/init-db.js +3 -3
- package/dist/ru/modules/logger/index.d.ts +1 -1
- package/dist/ru/modules/logger/index.js +19 -2
- package/dist/ru/modules/request/index.js +5 -5
- package/dist/ru/modules/topline-service/inner-service.js +3 -3
- package/dist/ru/modules/ui-lang/index.d.ts +4 -8
- package/dist/ru/modules/ui-lang/index.js +6 -18
- package/dist/ru/modules/websocket/index.js +2 -2
- package/dist/ru/parts/logout/actions/perform-logout/index.d.ts +1 -20
- package/dist/ru/parts/logout/actions/perform-logout/index.js +9 -22
- package/dist/ru/parts/password-recovery/actions/create-claim/index.d.ts +1 -13
- package/dist/ru/parts/password-recovery/actions/create-claim/index.js +5 -14
- package/dist/ru/parts/profile/actions/change-password/index.js +2 -2
- package/dist/ru/parts/profile/ui/root/has-changes.js +1 -1
- package/dist/ru/parts/profile/ui/root/index.js +3 -3
- package/dist/ru/parts/shell/actions/refresh-user/index.d.ts +1 -22
- package/dist/ru/parts/shell/actions/refresh-user/index.js +13 -27
- package/dist/ru/parts/signup/actions/perform-signup/index.d.ts +2 -1
- package/dist/ru/parts/signup/ui/signup/index.js +17 -3
- package/dist/ru/shared/procedures/process-response.js +3 -3
- package/package.json +9 -9
- package/dist/en/parts/profile/ui/root/get-initial-ui-lang.d.ts +0 -2
- package/dist/en/parts/profile/ui/root/get-initial-ui-lang.js +0 -4
- package/dist/ru/parts/profile/ui/root/get-initial-ui-lang.d.ts +0 -2
- package/dist/ru/parts/profile/ui/root/get-initial-ui-lang.js +0 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import VError from '@peassoft/verror';
|
|
2
2
|
import { updateUser, updateGrantToken, updateRefreshToken, updateIsUserKnown } from '../../modules/local-db/index.js';
|
|
3
3
|
import { setGrantToken, setRefreshToken } from '../../modules/tokens/index.js';
|
|
4
4
|
import { openWebsocket } from '../../modules/websocket/index.js';
|
|
@@ -28,7 +28,7 @@ export default async function processResponse(response, url, eventName) {
|
|
|
28
28
|
error: null
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
-
logError(new
|
|
31
|
+
logError(new VError({
|
|
32
32
|
name: 'UnexpectedError'
|
|
33
33
|
}, `unexpected payload of response to request to ${url}`));
|
|
34
34
|
return {
|
|
@@ -36,7 +36,7 @@ export default async function processResponse(response, url, eventName) {
|
|
|
36
36
|
error: 'network'
|
|
37
37
|
};
|
|
38
38
|
} catch (e) {
|
|
39
|
-
logError(new
|
|
39
|
+
logError(new VError({
|
|
40
40
|
name: 'UnexpectedError',
|
|
41
41
|
...(e instanceof Error ? {
|
|
42
42
|
cause: e
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect whether the app is running in local environment
|
|
3
|
+
*/
|
|
4
|
+
export declare function isLocal(): boolean;
|
|
1
5
|
/**
|
|
2
6
|
* Return base URL for requests to backend API
|
|
3
7
|
*/
|
|
4
8
|
export declare function getApiBaseUrl(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Return URL for logs backend
|
|
11
|
+
*/
|
|
12
|
+
export declare function getLogsUrl(): string;
|
|
5
13
|
/**
|
|
6
14
|
* Return URL for websocket connection
|
|
7
15
|
*/
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect whether the app is running in local environment
|
|
3
|
+
*/
|
|
4
|
+
export function isLocal() {
|
|
5
|
+
return window.location.hostname === 'localhost';
|
|
6
|
+
}
|
|
1
7
|
/**
|
|
2
8
|
* Return base URL for requests to backend API
|
|
3
9
|
*/
|
|
@@ -7,6 +13,15 @@ export function getApiBaseUrl() {
|
|
|
7
13
|
}
|
|
8
14
|
return '/api';
|
|
9
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Return URL for logs backend
|
|
18
|
+
*/
|
|
19
|
+
export function getLogsUrl() {
|
|
20
|
+
if (window.location.hostname === 'localhost') {
|
|
21
|
+
return 'http://localhost:5005/logs';
|
|
22
|
+
}
|
|
23
|
+
return '/front-logs/logs';
|
|
24
|
+
}
|
|
10
25
|
/**
|
|
11
26
|
* Return URL for websocket connection
|
|
12
27
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import VError from '@peassoft/verror';
|
|
2
2
|
/**
|
|
3
3
|
* Create error for failed request to local database
|
|
4
4
|
*/
|
|
5
|
-
export default function createRequestError(reason: string):
|
|
5
|
+
export default function createRequestError(reason: string): VError;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import VError from '@peassoft/verror';
|
|
2
2
|
/**
|
|
3
3
|
* Create error for failed request to local database
|
|
4
4
|
*/
|
|
5
5
|
export default function createRequestError(reason) {
|
|
6
|
-
return new
|
|
6
|
+
return new VError({
|
|
7
7
|
name: 'LocalDbRequestError'
|
|
8
8
|
}, `request to local database failed (${reason})`);
|
|
9
9
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import VError from '@peassoft/verror';
|
|
2
2
|
const DB_NAME = 'mnr_topline';
|
|
3
3
|
const DB_VERSION = 2;
|
|
4
4
|
// Main store data is deleted when a user logs out.
|
|
@@ -27,7 +27,7 @@ export function initDb() {
|
|
|
27
27
|
return new Promise((resolve, reject) => {
|
|
28
28
|
const openDbReq = window.indexedDB.open(DB_NAME, DB_VERSION);
|
|
29
29
|
openDbReq.onerror = function (_e) {
|
|
30
|
-
reject(new
|
|
30
|
+
reject(new VError({
|
|
31
31
|
name: 'LocalDbInitializationError'
|
|
32
32
|
}, 'opening local database failed'));
|
|
33
33
|
};
|
|
@@ -53,7 +53,7 @@ export function initDb() {
|
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
55
|
openDbReq.onblocked = function () {
|
|
56
|
-
reject(new
|
|
56
|
+
reject(new VError({
|
|
57
57
|
name: 'LocalDbInitializationError'
|
|
58
58
|
}, 'failed upgrading local database due to it is blocked'));
|
|
59
59
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function logError(err: Error): void;
|
|
1
|
+
export declare function logError(err: Error | DOMException): void;
|
|
2
2
|
export declare function logInvariant(msg: string): void;
|
|
@@ -1,6 +1,23 @@
|
|
|
1
|
+
import { WebLogger } from '@peassoft/web-logger';
|
|
2
|
+
import { getLogsUrl, isLocal } from '../env/index.js';
|
|
3
|
+
let _logger = null;
|
|
1
4
|
export function logError(err) {
|
|
2
|
-
|
|
5
|
+
if (!_logger) {
|
|
6
|
+
_logger = createLogger();
|
|
7
|
+
}
|
|
8
|
+
_logger.error(err);
|
|
9
|
+
if (isLocal()) console.error(err);
|
|
3
10
|
}
|
|
4
11
|
export function logInvariant(msg) {
|
|
5
|
-
|
|
12
|
+
if (!_logger) {
|
|
13
|
+
_logger = createLogger();
|
|
14
|
+
}
|
|
15
|
+
_logger.info(msg);
|
|
16
|
+
if (isLocal()) console.log(msg);
|
|
17
|
+
}
|
|
18
|
+
function createLogger() {
|
|
19
|
+
return new WebLogger({
|
|
20
|
+
appName: 'mnr-web-topline',
|
|
21
|
+
url: getLogsUrl()
|
|
22
|
+
});
|
|
6
23
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import VError from '@peassoft/verror';
|
|
2
2
|
import normalizeRequestOpts from './normalize-request-opts.js';
|
|
3
3
|
import { logError } from '../logger/index.js';
|
|
4
4
|
import shouldRetry from './should-retry.js';
|
|
@@ -37,11 +37,11 @@ export default async function request(url, fetchApiOpts, requestOpts = {}) {
|
|
|
37
37
|
} catch (e) {
|
|
38
38
|
if (e instanceof Error) {
|
|
39
39
|
if (e.name === 'AbortError') {
|
|
40
|
-
logError(new
|
|
40
|
+
logError(new VError({
|
|
41
41
|
name: 'RequestError'
|
|
42
42
|
}, `request to ${url} was aborted due to timeout`));
|
|
43
43
|
} else {
|
|
44
|
-
logError(new
|
|
44
|
+
logError(new VError({
|
|
45
45
|
name: 'RequestError',
|
|
46
46
|
cause: e
|
|
47
47
|
}, `request to ${url} failed`));
|
|
@@ -65,12 +65,12 @@ export default async function request(url, fetchApiOpts, requestOpts = {}) {
|
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
67
|
if (response.status >= 500 && response.status < 600) {
|
|
68
|
-
logError(new
|
|
68
|
+
logError(new VError({
|
|
69
69
|
name: 'ServiceUnavailable'
|
|
70
70
|
}, `request to ${url} failed with ${response.status} status code`));
|
|
71
71
|
return null;
|
|
72
72
|
}
|
|
73
|
-
logError(new
|
|
73
|
+
logError(new VError({
|
|
74
74
|
name: 'UnexpectedError'
|
|
75
75
|
}, `request to ${url} returned unexpected status code ${response.status}`));
|
|
76
76
|
return null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import VError from '@peassoft/verror';
|
|
2
2
|
import { getGrantToken, getRefreshToken, setGrantToken, setRefreshToken } from '../tokens/index.js';
|
|
3
3
|
import { deleteAllData as deleteAllDataFromDb, updateGrantToken as updateGrantTokenInDb, updateRefreshToken as updateRefreshTokenInDb, updateUser as updateUserInDb } from '../local-db/index.js';
|
|
4
4
|
import { getApiBaseUrl } from '../env/index.js';
|
|
@@ -143,13 +143,13 @@ export class InnerService {
|
|
|
143
143
|
}
|
|
144
144
|
return grantToken;
|
|
145
145
|
} else {
|
|
146
|
-
this.#logError(new
|
|
146
|
+
this.#logError(new VError({
|
|
147
147
|
name: 'UnexpectedError'
|
|
148
148
|
}, `unexpected payload of response to request to ${url}`));
|
|
149
149
|
return null;
|
|
150
150
|
}
|
|
151
151
|
} catch (err) {
|
|
152
|
-
this.#logError(new
|
|
152
|
+
this.#logError(new VError({
|
|
153
153
|
name: 'UnexpectedError',
|
|
154
154
|
cause: err
|
|
155
155
|
}, `parsing 200 response of request to ${url} failed`));
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import type
|
|
2
|
-
type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
export declare function getSupportedUiLangs(): NonEmptyArray<UiLangDescriptor>;
|
|
7
|
-
export declare function getDefaultUiLangForUser(): UiLangDescriptor;
|
|
8
|
-
export {};
|
|
1
|
+
import { type SupportedLanguage } from '@peassoft/mnr-langs';
|
|
2
|
+
import type { ToplineUser } from '../../types/data.js';
|
|
3
|
+
export declare function getPageLang(): SupportedLanguage;
|
|
4
|
+
export declare function getInitialUiLang(user: ToplineUser): string;
|
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
code: 'ru',
|
|
6
|
-
name: 'Русский'
|
|
7
|
-
}];
|
|
8
|
-
export function getSupportedUiLangs() {
|
|
9
|
-
return window.structuredClone(supportedUiLangs);
|
|
1
|
+
import { defaultLanguage, validateLanguage } from '@peassoft/mnr-langs';
|
|
2
|
+
export function getPageLang() {
|
|
3
|
+
const currPageLang = document.querySelector('html')?.lang;
|
|
4
|
+
return validateLanguage(currPageLang) || defaultLanguage;
|
|
10
5
|
}
|
|
11
|
-
export function
|
|
12
|
-
|
|
13
|
-
const normalizedLangCode = lang.slice(0, 2).toLowerCase();
|
|
14
|
-
const matchedDescriptor = supportedUiLangs.find(x => x.code === normalizedLangCode);
|
|
15
|
-
if (matchedDescriptor) {
|
|
16
|
-
return window.structuredClone(matchedDescriptor);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return supportedUiLangs[0];
|
|
6
|
+
export function getInitialUiLang(user) {
|
|
7
|
+
return user.uiLang ?? getPageLang();
|
|
20
8
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import VError from '@peassoft/verror';
|
|
2
2
|
import { getWebsocketUrl } from '../env/index.js';
|
|
3
3
|
import { getGrantToken } from '../tokens/index.js';
|
|
4
4
|
import { logError } from '../logger/index.js';
|
|
@@ -97,7 +97,7 @@ async function handleSocketClose(e) {
|
|
|
97
97
|
break;
|
|
98
98
|
default:
|
|
99
99
|
// Unexpected closing code
|
|
100
|
-
logError(new
|
|
100
|
+
logError(new VError({
|
|
101
101
|
name: 'UnexpectedWsClosingCode'
|
|
102
102
|
}, `websocket was closed with unexpected code ${e.code}`));
|
|
103
103
|
reconnect();
|
|
@@ -1,23 +1,4 @@
|
|
|
1
|
-
import stampit from 'stampit';
|
|
2
|
-
import { closeWebsocket } from '../../../../modules/websocket/index.js';
|
|
3
|
-
import { getGrantToken } from '../../../../modules/tokens/index.js';
|
|
4
|
-
import { type InnerService } from '../../../../modules/topline-service/index.js';
|
|
5
|
-
import { getApiBaseUrl } from '../../../../modules/env/index.js';
|
|
6
|
-
import request from '../../../../modules/request/index.js';
|
|
7
|
-
import makeSecondAttempt from './make-second-attempt.js';
|
|
8
|
-
export type This = {
|
|
9
|
-
closeWebsocket: typeof closeWebsocket;
|
|
10
|
-
getGrantToken: typeof getGrantToken;
|
|
11
|
-
innerToplineService: Pick<InnerService, 'processLogout' | 'upgradeGrantToken'>;
|
|
12
|
-
getApiBaseUrl: typeof getApiBaseUrl;
|
|
13
|
-
request: typeof request;
|
|
14
|
-
makeSecondAttempt: typeof makeSecondAttempt;
|
|
15
|
-
performLogout: typeof performLogout;
|
|
16
|
-
};
|
|
17
|
-
export declare const PerformLogout: stampit.Stamp<This>;
|
|
18
|
-
declare const self: () => Promise<void>;
|
|
19
|
-
export default self;
|
|
20
1
|
/**
|
|
21
2
|
* Make logout request to api
|
|
22
3
|
*/
|
|
23
|
-
|
|
4
|
+
export default function performLogout(): Promise<void>;
|
|
@@ -1,33 +1,20 @@
|
|
|
1
|
-
import stampit from 'stampit';
|
|
2
1
|
import { closeWebsocket } from '../../../../modules/websocket/index.js';
|
|
3
2
|
import { getGrantToken } from '../../../../modules/tokens/index.js';
|
|
4
3
|
import { innerToplineService } from '../../../../modules/topline-service/index.js';
|
|
5
4
|
import { getApiBaseUrl } from '../../../../modules/env/index.js';
|
|
6
5
|
import request from '../../../../modules/request/index.js';
|
|
7
6
|
import makeSecondAttempt from './make-second-attempt.js';
|
|
8
|
-
export const PerformLogout = stampit().props({
|
|
9
|
-
closeWebsocket,
|
|
10
|
-
getGrantToken,
|
|
11
|
-
innerToplineService,
|
|
12
|
-
getApiBaseUrl,
|
|
13
|
-
request,
|
|
14
|
-
makeSecondAttempt
|
|
15
|
-
}).methods({
|
|
16
|
-
performLogout
|
|
17
|
-
});
|
|
18
|
-
const self = performLogout.bind(PerformLogout());
|
|
19
|
-
export default self;
|
|
20
7
|
/**
|
|
21
8
|
* Make logout request to api
|
|
22
9
|
*/
|
|
23
|
-
async function performLogout() {
|
|
24
|
-
|
|
25
|
-
const grantToken =
|
|
10
|
+
export default async function performLogout() {
|
|
11
|
+
closeWebsocket();
|
|
12
|
+
const grantToken = getGrantToken();
|
|
26
13
|
if (!grantToken) {
|
|
27
|
-
|
|
14
|
+
innerToplineService.processLogout();
|
|
28
15
|
return;
|
|
29
16
|
}
|
|
30
|
-
const url = `${
|
|
17
|
+
const url = `${getApiBaseUrl()}/private/log-out`;
|
|
31
18
|
const options = {
|
|
32
19
|
method: 'POST',
|
|
33
20
|
headers: {
|
|
@@ -36,19 +23,19 @@ async function performLogout() {
|
|
|
36
23
|
cache: 'no-store',
|
|
37
24
|
redirect: 'error'
|
|
38
25
|
};
|
|
39
|
-
const response = await
|
|
26
|
+
const response = await request(url, options, {
|
|
40
27
|
maxRetries: 1
|
|
41
28
|
});
|
|
42
29
|
if (!response || response.status !== 401) {
|
|
43
|
-
|
|
30
|
+
innerToplineService.processLogout();
|
|
44
31
|
return;
|
|
45
32
|
}
|
|
46
33
|
if (response.status === 401) {
|
|
47
34
|
// innerToplineService.upgradeGrantToken() makes all necessary clean-up in case
|
|
48
35
|
// the upgrade fails
|
|
49
|
-
const grantToken = await
|
|
36
|
+
const grantToken = await innerToplineService.upgradeGrantToken();
|
|
50
37
|
if (grantToken) {
|
|
51
|
-
await
|
|
38
|
+
await makeSecondAttempt(performLogout);
|
|
52
39
|
}
|
|
53
40
|
}
|
|
54
41
|
}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import stampit from 'stampit';
|
|
2
|
-
import { getApiBaseUrl, getRequestCredentialsMode } from '../../../../modules/env/index.js';
|
|
3
|
-
import request from '../../../../modules/request/index.js';
|
|
4
1
|
export type ReturnValue = {
|
|
5
2
|
error: 'network' | null;
|
|
6
3
|
};
|
|
@@ -10,13 +7,4 @@ export type ReturnValue = {
|
|
|
10
7
|
* Returns `null` if claim creation succeeds; otherwise:
|
|
11
8
|
* - on network error or if backend responds with 5xx - "network".
|
|
12
9
|
*/
|
|
13
|
-
|
|
14
|
-
export type This = {
|
|
15
|
-
getApiBaseUrl: typeof getApiBaseUrl;
|
|
16
|
-
getRequestCredentialsMode: typeof getRequestCredentialsMode;
|
|
17
|
-
request: typeof request;
|
|
18
|
-
createClaim: typeof createClaim;
|
|
19
|
-
};
|
|
20
|
-
export declare const CreateClaim: stampit.Stamp<This>;
|
|
21
|
-
declare const _default: (email: string) => Promise<ReturnValue>;
|
|
22
|
-
export default _default;
|
|
10
|
+
export default function createClaim(email: string): Promise<ReturnValue>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import stampit from 'stampit';
|
|
2
1
|
import { getApiBaseUrl, getRequestCredentialsMode } from '../../../../modules/env/index.js';
|
|
3
2
|
import request from '../../../../modules/request/index.js';
|
|
4
3
|
/**
|
|
@@ -7,8 +6,8 @@ import request from '../../../../modules/request/index.js';
|
|
|
7
6
|
* Returns `null` if claim creation succeeds; otherwise:
|
|
8
7
|
* - on network error or if backend responds with 5xx - "network".
|
|
9
8
|
*/
|
|
10
|
-
async function createClaim(email) {
|
|
11
|
-
const url = `${
|
|
9
|
+
export default async function createClaim(email) {
|
|
10
|
+
const url = `${getApiBaseUrl()}/public/create-password-recovery-claim`;
|
|
12
11
|
const options = {
|
|
13
12
|
method: 'POST',
|
|
14
13
|
headers: {
|
|
@@ -17,11 +16,11 @@ async function createClaim(email) {
|
|
|
17
16
|
body: JSON.stringify({
|
|
18
17
|
email
|
|
19
18
|
}),
|
|
20
|
-
credentials:
|
|
19
|
+
credentials: getRequestCredentialsMode(),
|
|
21
20
|
cache: 'no-store',
|
|
22
21
|
redirect: 'error'
|
|
23
22
|
};
|
|
24
|
-
const response = await
|
|
23
|
+
const response = await request(url, options);
|
|
25
24
|
if (!response) {
|
|
26
25
|
return {
|
|
27
26
|
error: 'network'
|
|
@@ -30,12 +29,4 @@ async function createClaim(email) {
|
|
|
30
29
|
return {
|
|
31
30
|
error: null
|
|
32
31
|
};
|
|
33
|
-
}
|
|
34
|
-
export const CreateClaim = stampit().props({
|
|
35
|
-
getApiBaseUrl,
|
|
36
|
-
getRequestCredentialsMode,
|
|
37
|
-
request
|
|
38
|
-
}).methods({
|
|
39
|
-
createClaim
|
|
40
|
-
});
|
|
41
|
-
export default createClaim.bind(CreateClaim());
|
|
32
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import VError from '@peassoft/verror';
|
|
2
2
|
import { getGrantToken, setGrantToken, setRefreshToken } from '../../../../modules/tokens/index.js';
|
|
3
3
|
import { logInvariant, logError } from '../../../../modules/logger/index.js';
|
|
4
4
|
import { getApiBaseUrl, getRequestCredentialsMode } from '../../../../modules/env/index.js';
|
|
@@ -65,7 +65,7 @@ export default async function changePassword(beacon, oldPassword, newPassword) {
|
|
|
65
65
|
try {
|
|
66
66
|
payload = await response.json();
|
|
67
67
|
} catch (e) {
|
|
68
|
-
logError(new
|
|
68
|
+
logError(new VError({
|
|
69
69
|
name: 'UnexpectedError',
|
|
70
70
|
...(e instanceof Error ? {
|
|
71
71
|
cause: e
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import getInitialUserName from './get-initial-user-name.js';
|
|
2
|
-
import getInitialUiLang from '
|
|
2
|
+
import { getInitialUiLang } from '../../../../modules/ui-lang/index.js';
|
|
3
3
|
export default function hasChanges(user, currData) {
|
|
4
4
|
if (getInitialUserName(user) !== currData.userName) {
|
|
5
5
|
return true;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useMemo, useCallback } from 'react';
|
|
3
|
+
import { supportedLanguagesDescriptors } from '@peassoft/mnr-langs';
|
|
3
4
|
import { InputField } from '@peassoft/mnr-web-ui-kit/input-field/index.js';
|
|
4
5
|
import { Select } from '@peassoft/mnr-web-ui-kit/select/index.js';
|
|
5
6
|
import { TextButton } from '@peassoft/mnr-web-ui-kit/text-button/index.js';
|
|
6
7
|
import { Button } from '@peassoft/mnr-web-ui-kit/button/index.js';
|
|
7
8
|
import { ErrorMessage } from '@peassoft/mnr-web-ui-kit/error-message/index.js';
|
|
8
9
|
import { createUserDataChangeBeacon } from '../../../../modules/user-data-change-beacon/index.js';
|
|
9
|
-
import { getSupportedUiLangs } from '../../../../modules/ui-lang/index.js';
|
|
10
10
|
import { updateUser } from '../../../../modules/local-db/index.js';
|
|
11
11
|
import { innerToplineService, ToplineEventName } from '../../../../modules/topline-service/index.js';
|
|
12
12
|
import saveUserData from '../../actions/save-user-data/index.js';
|
|
13
|
+
import { getInitialUiLang } from '../../../../modules/ui-lang/index.js';
|
|
13
14
|
import getInitialUserName from './get-initial-user-name.js';
|
|
14
|
-
import getInitialUiLang from './get-initial-ui-lang.js';
|
|
15
15
|
import hasChanges from './has-changes.js';
|
|
16
16
|
export default function Root(props) {
|
|
17
17
|
const {
|
|
@@ -23,7 +23,7 @@ export default function Root(props) {
|
|
|
23
23
|
const [uiLang, setUiLang] = useState(getInitialUiLang(user));
|
|
24
24
|
const [isInProgress, setIsInProgress] = useState(false);
|
|
25
25
|
const [hasSavingError, setHasSavingError] = useState(false);
|
|
26
|
-
const uiLangOptions = useMemo(() =>
|
|
26
|
+
const uiLangOptions = useMemo(() => supportedLanguagesDescriptors().map(langDescriptor => ({
|
|
27
27
|
id: langDescriptor.code,
|
|
28
28
|
value: langDescriptor.name
|
|
29
29
|
})), []);
|
|
@@ -1,28 +1,7 @@
|
|
|
1
|
-
import stampit from 'stampit';
|
|
2
|
-
import { getGrantToken } from '../../../../modules/tokens/index.js';
|
|
3
|
-
import { type InnerService } from '../../../../modules/topline-service/index.js';
|
|
4
|
-
import { getApiBaseUrl } from '../../../../modules/env/index.js';
|
|
5
|
-
import request from '../../../../modules/request/index.js';
|
|
6
|
-
import hasUserBeenChanged from './has-user-been-changed.js';
|
|
7
|
-
import { logError } from '../../../../modules/logger/index.js';
|
|
8
|
-
import makeSecondAttempt from './make-second-attempt.js';
|
|
9
1
|
import { type ToplineUser } from '../../../../types/data.js';
|
|
10
|
-
export type This = {
|
|
11
|
-
getGrantToken: typeof getGrantToken;
|
|
12
|
-
innerToplineService: Pick<InnerService, 'processLogout' | 'updateUser' | 'upgradeGrantToken'>;
|
|
13
|
-
getApiBaseUrl: typeof getApiBaseUrl;
|
|
14
|
-
request: typeof request;
|
|
15
|
-
hasUserBeenChanged: typeof hasUserBeenChanged;
|
|
16
|
-
logError: typeof logError;
|
|
17
|
-
makeSecondAttempt: typeof makeSecondAttempt;
|
|
18
|
-
refreshUser: typeof refreshUser;
|
|
19
|
-
};
|
|
20
|
-
export declare const RefreshUser: stampit.Stamp<This>;
|
|
21
|
-
declare const self: (currUser: ToplineUser) => Promise<void>;
|
|
22
|
-
export default self;
|
|
23
2
|
/**
|
|
24
3
|
* Try to refresh user data after initialization
|
|
25
4
|
*
|
|
26
5
|
* @param currUser User data fetched from local DB on initialization
|
|
27
6
|
*/
|
|
28
|
-
|
|
7
|
+
export default function refreshUser(currUser: ToplineUser): Promise<void>;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import WebError from '@memnrev/web-error';
|
|
1
|
+
import VError from '@peassoft/verror';
|
|
3
2
|
import { getGrantToken } from '../../../../modules/tokens/index.js';
|
|
4
3
|
import { innerToplineService } from '../../../../modules/topline-service/index.js';
|
|
5
4
|
import { getApiBaseUrl } from '../../../../modules/env/index.js';
|
|
@@ -9,28 +8,15 @@ import { logError } from '../../../../modules/logger/index.js';
|
|
|
9
8
|
import makeSecondAttempt from './make-second-attempt.js';
|
|
10
9
|
import { isToplineUser } from '../../../../types/data.js';
|
|
11
10
|
import { isObject } from '../../../../types/helpers.js';
|
|
12
|
-
export const RefreshUser = stampit().props({
|
|
13
|
-
getGrantToken,
|
|
14
|
-
innerToplineService,
|
|
15
|
-
getApiBaseUrl,
|
|
16
|
-
request,
|
|
17
|
-
hasUserBeenChanged,
|
|
18
|
-
logError,
|
|
19
|
-
makeSecondAttempt
|
|
20
|
-
}).methods({
|
|
21
|
-
refreshUser
|
|
22
|
-
});
|
|
23
|
-
const self = refreshUser.bind(RefreshUser());
|
|
24
|
-
export default self;
|
|
25
11
|
/**
|
|
26
12
|
* Try to refresh user data after initialization
|
|
27
13
|
*
|
|
28
14
|
* @param currUser User data fetched from local DB on initialization
|
|
29
15
|
*/
|
|
30
|
-
async function refreshUser(currUser) {
|
|
31
|
-
const grantToken =
|
|
16
|
+
export default async function refreshUser(currUser) {
|
|
17
|
+
const grantToken = getGrantToken();
|
|
32
18
|
if (!grantToken) return;
|
|
33
|
-
const url = `${
|
|
19
|
+
const url = `${getApiBaseUrl()}/private/user`;
|
|
34
20
|
const options = {
|
|
35
21
|
method: 'GET',
|
|
36
22
|
headers: {
|
|
@@ -39,7 +25,7 @@ async function refreshUser(currUser) {
|
|
|
39
25
|
cache: 'no-store',
|
|
40
26
|
redirect: 'error'
|
|
41
27
|
};
|
|
42
|
-
const response = await
|
|
28
|
+
const response = await request(url, options, {
|
|
43
29
|
maxRetries: 1
|
|
44
30
|
});
|
|
45
31
|
if (!response) return;
|
|
@@ -50,12 +36,12 @@ async function refreshUser(currUser) {
|
|
|
50
36
|
if (isObject(responsePayload) && 'user' in responsePayload && (isToplineUser(responsePayload.user) || responsePayload.user === null)) {
|
|
51
37
|
newUser = responsePayload.user;
|
|
52
38
|
} else {
|
|
53
|
-
|
|
39
|
+
logError(new VError({
|
|
54
40
|
name: 'UnexpectedPayload'
|
|
55
|
-
}, `unexpected payload of request to ${url}`));
|
|
41
|
+
}, `unexpected payload of response to request to ${url}`));
|
|
56
42
|
}
|
|
57
43
|
} catch (err) {
|
|
58
|
-
|
|
44
|
+
logError(new VError({
|
|
59
45
|
name: 'UnexpectedError',
|
|
60
46
|
...(err instanceof Error ? {
|
|
61
47
|
cause: err
|
|
@@ -64,16 +50,16 @@ async function refreshUser(currUser) {
|
|
|
64
50
|
return;
|
|
65
51
|
}
|
|
66
52
|
if (!newUser) {
|
|
67
|
-
|
|
53
|
+
innerToplineService.processLogout();
|
|
68
54
|
return;
|
|
69
55
|
}
|
|
70
|
-
if (
|
|
71
|
-
await
|
|
56
|
+
if (hasUserBeenChanged(currUser, newUser)) {
|
|
57
|
+
await innerToplineService.updateUser(newUser);
|
|
72
58
|
}
|
|
73
59
|
return;
|
|
74
60
|
}
|
|
75
61
|
if (response.status === 401) {
|
|
76
|
-
await
|
|
77
|
-
await
|
|
62
|
+
await innerToplineService.upgradeGrantToken();
|
|
63
|
+
await makeSecondAttempt(currUser, refreshUser);
|
|
78
64
|
}
|
|
79
65
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import type { SupportedLanguage } from '@peassoft/mnr-langs';
|
|
1
2
|
import type { ToplineUser } from '../../../../types/data.js';
|
|
2
3
|
export type UserData = {
|
|
3
4
|
email: string;
|
|
4
5
|
password: string;
|
|
5
6
|
userName?: string;
|
|
6
|
-
uiLang
|
|
7
|
+
uiLang: SupportedLanguage;
|
|
7
8
|
};
|
|
8
9
|
export type ReturnValue = {
|
|
9
10
|
user: ToplineUser | null;
|