@peassoft/mnr-web-topline 0.1.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/README.md +44 -0
- package/dist/css/index.css +192 -0
- package/dist/en/hooks/use-topline/index.d.ts +11 -0
- package/dist/en/hooks/use-topline/index.js +14 -0
- package/dist/en/index.d.ts +8 -0
- package/dist/en/index.js +5 -0
- package/dist/en/modules/env/index.d.ts +12 -0
- package/dist/en/modules/env/index.js +27 -0
- package/dist/en/modules/focus-marshal/index.d.ts +6 -0
- package/dist/en/modules/focus-marshal/index.js +6 -0
- package/dist/en/modules/keyboard-navigation/key-codes.d.ts +18 -0
- package/dist/en/modules/keyboard-navigation/key-codes.js +18 -0
- package/dist/en/modules/keyboard-navigation/vertical-menu.d.ts +14 -0
- package/dist/en/modules/keyboard-navigation/vertical-menu.js +45 -0
- package/dist/en/modules/local-db/actions/delete-all-data/index.d.ts +4 -0
- package/dist/en/modules/local-db/actions/delete-all-data/index.js +21 -0
- package/dist/en/modules/local-db/actions/get-all-data/index.d.ts +11 -0
- package/dist/en/modules/local-db/actions/get-all-data/index.js +51 -0
- package/dist/en/modules/local-db/actions/update-grant-token/index.d.ts +4 -0
- package/dist/en/modules/local-db/actions/update-grant-token/index.js +26 -0
- package/dist/en/modules/local-db/actions/update-refresh-token/index.d.ts +4 -0
- package/dist/en/modules/local-db/actions/update-refresh-token/index.js +26 -0
- package/dist/en/modules/local-db/actions/update-user/index.d.ts +5 -0
- package/dist/en/modules/local-db/actions/update-user/index.js +26 -0
- package/dist/en/modules/local-db/create-request-error.d.ts +5 -0
- package/dist/en/modules/local-db/create-request-error.js +9 -0
- package/dist/en/modules/local-db/index.d.ts +6 -0
- package/dist/en/modules/local-db/index.js +6 -0
- package/dist/en/modules/local-db/init-db.d.ts +17 -0
- package/dist/en/modules/local-db/init-db.js +52 -0
- package/dist/en/modules/logger/index.d.ts +1 -0
- package/dist/en/modules/logger/index.js +3 -0
- package/dist/en/modules/request/index.d.ts +20 -0
- package/dist/en/modules/request/index.js +78 -0
- package/dist/en/modules/request/normalize-request-opts.d.ts +5 -0
- package/dist/en/modules/request/normalize-request-opts.js +11 -0
- package/dist/en/modules/request/should-retry.d.ts +6 -0
- package/dist/en/modules/request/should-retry.js +16 -0
- package/dist/en/modules/request/types.d.ts +20 -0
- package/dist/en/modules/request/types.js +1 -0
- package/dist/en/modules/tokens/index.d.ts +4 -0
- package/dist/en/modules/tokens/index.js +14 -0
- package/dist/en/modules/topline-service/index.d.ts +24 -0
- package/dist/en/modules/topline-service/index.js +46 -0
- package/dist/en/modules/topline-service/inner-service.d.ts +45 -0
- package/dist/en/modules/topline-service/inner-service.js +219 -0
- package/dist/en/modules/topline-service/types.d.ts +32 -0
- package/dist/en/modules/topline-service/types.js +19 -0
- package/dist/en/modules/validators/email.d.ts +4 -0
- package/dist/en/modules/validators/email.js +7 -0
- package/dist/en/modules/validators/password-recovery-code.d.ts +4 -0
- package/dist/en/modules/validators/password-recovery-code.js +6 -0
- package/dist/en/modules/validators/password.d.ts +4 -0
- package/dist/en/modules/validators/password.js +6 -0
- package/dist/en/modules/websocket/index.d.ts +4 -0
- package/dist/en/modules/websocket/index.js +92 -0
- package/dist/en/parts/login/actions/perform-login/index.d.ts +27 -0
- package/dist/en/parts/login/actions/perform-login/index.js +60 -0
- package/dist/en/parts/login/index.d.ts +1 -0
- package/dist/en/parts/login/index.js +1 -0
- package/dist/en/parts/login/ui/login/index.d.ts +8 -0
- package/dist/en/parts/login/ui/login/index.js +138 -0
- package/dist/en/parts/logout/actions/perform-logout/index.d.ts +23 -0
- package/dist/en/parts/logout/actions/perform-logout/index.js +54 -0
- package/dist/en/parts/logout/actions/perform-logout/make-second-attempt.d.ts +1 -0
- package/dist/en/parts/logout/actions/perform-logout/make-second-attempt.js +3 -0
- package/dist/en/parts/logout/index.d.ts +1 -0
- package/dist/en/parts/logout/index.js +1 -0
- package/dist/en/parts/password-recovery/actions/create-claim/index.d.ts +22 -0
- package/dist/en/parts/password-recovery/actions/create-claim/index.js +41 -0
- package/dist/en/parts/password-recovery/actions/save-password/index.d.ts +27 -0
- package/dist/en/parts/password-recovery/actions/save-password/index.js +61 -0
- package/dist/en/parts/password-recovery/index.d.ts +1 -0
- package/dist/en/parts/password-recovery/index.js +1 -0
- package/dist/en/parts/password-recovery/ui/password-recovery/index.d.ts +6 -0
- package/dist/en/parts/password-recovery/ui/password-recovery/index.js +33 -0
- package/dist/en/parts/password-recovery/ui/step-one/index.d.ts +7 -0
- package/dist/en/parts/password-recovery/ui/step-one/index.js +82 -0
- package/dist/en/parts/password-recovery/ui/step-two/index.d.ts +7 -0
- package/dist/en/parts/password-recovery/ui/step-two/index.js +134 -0
- package/dist/en/parts/shell/actions/refresh-user/has-user-been-changed.d.ts +5 -0
- package/dist/en/parts/shell/actions/refresh-user/has-user-been-changed.js +6 -0
- package/dist/en/parts/shell/actions/refresh-user/index.d.ts +28 -0
- package/dist/en/parts/shell/actions/refresh-user/index.js +79 -0
- package/dist/en/parts/shell/actions/refresh-user/make-second-attempt.d.ts +2 -0
- package/dist/en/parts/shell/actions/refresh-user/make-second-attempt.js +3 -0
- package/dist/en/parts/shell/context.d.ts +12 -0
- package/dist/en/parts/shell/context.js +8 -0
- package/dist/en/parts/shell/index.d.ts +2 -0
- package/dist/en/parts/shell/index.js +2 -0
- package/dist/en/parts/shell/ui/logged-out-user-menu/index.d.ts +8 -0
- package/dist/en/parts/shell/ui/logged-out-user-menu/index.js +42 -0
- package/dist/en/parts/shell/ui/loggeg-in-user-menu/index.d.ts +8 -0
- package/dist/en/parts/shell/ui/loggeg-in-user-menu/index.js +42 -0
- package/dist/en/parts/shell/ui/logo/index.d.ts +1 -0
- package/dist/en/parts/shell/ui/logo/index.js +8 -0
- package/dist/en/parts/shell/ui/logo/logo-full.d.ts +2 -0
- package/dist/en/parts/shell/ui/logo/logo-full.js +26 -0
- package/dist/en/parts/shell/ui/logo/logo-short.d.ts +2 -0
- package/dist/en/parts/shell/ui/logo/logo-short.js +26 -0
- package/dist/en/parts/shell/ui/shell/index.d.ts +2 -0
- package/dist/en/parts/shell/ui/shell/index.js +187 -0
- package/dist/en/parts/shell/ui/user-avatar/index.d.ts +7 -0
- package/dist/en/parts/shell/ui/user-avatar/index.js +48 -0
- package/dist/en/parts/shell/ui/user-menu/index.d.ts +8 -0
- package/dist/en/parts/shell/ui/user-menu/index.js +37 -0
- package/dist/en/parts/shell/ui/user-menu-item/index.d.ts +10 -0
- package/dist/en/parts/shell/ui/user-menu-item/index.js +19 -0
- package/dist/en/parts/signup/actions/perform-signup/index.d.ts +33 -0
- package/dist/en/parts/signup/actions/perform-signup/index.js +58 -0
- package/dist/en/parts/signup/index.d.ts +1 -0
- package/dist/en/parts/signup/index.js +1 -0
- package/dist/en/parts/signup/ui/signup/index.d.ts +8 -0
- package/dist/en/parts/signup/ui/signup/index.js +163 -0
- package/dist/en/shared/components/alternative/index.d.ts +7 -0
- package/dist/en/shared/components/alternative/index.js +3 -0
- package/dist/en/shared/components/modal/index.d.ts +8 -0
- package/dist/en/shared/components/modal/index.js +32 -0
- package/dist/en/shared/procedures/process-successful-response/index.d.ts +30 -0
- package/dist/en/shared/procedures/process-successful-response/index.js +66 -0
- package/dist/en/topline.d.ts +24 -0
- package/dist/en/topline.js +33 -0
- package/dist/en/types/app.d.ts +1 -0
- package/dist/en/types/app.js +1 -0
- package/dist/en/types/data.d.ts +10 -0
- package/dist/en/types/data.js +4 -0
- package/dist/en/types/helpers.d.ts +2 -0
- package/dist/en/types/helpers.js +3 -0
- package/dist/ru/hooks/use-topline/index.d.ts +11 -0
- package/dist/ru/hooks/use-topline/index.js +14 -0
- package/dist/ru/index.d.ts +8 -0
- package/dist/ru/index.js +5 -0
- package/dist/ru/modules/env/index.d.ts +12 -0
- package/dist/ru/modules/env/index.js +27 -0
- package/dist/ru/modules/focus-marshal/index.d.ts +6 -0
- package/dist/ru/modules/focus-marshal/index.js +6 -0
- package/dist/ru/modules/keyboard-navigation/key-codes.d.ts +18 -0
- package/dist/ru/modules/keyboard-navigation/key-codes.js +18 -0
- package/dist/ru/modules/keyboard-navigation/vertical-menu.d.ts +14 -0
- package/dist/ru/modules/keyboard-navigation/vertical-menu.js +45 -0
- package/dist/ru/modules/local-db/actions/delete-all-data/index.d.ts +4 -0
- package/dist/ru/modules/local-db/actions/delete-all-data/index.js +21 -0
- package/dist/ru/modules/local-db/actions/get-all-data/index.d.ts +11 -0
- package/dist/ru/modules/local-db/actions/get-all-data/index.js +51 -0
- package/dist/ru/modules/local-db/actions/update-grant-token/index.d.ts +4 -0
- package/dist/ru/modules/local-db/actions/update-grant-token/index.js +26 -0
- package/dist/ru/modules/local-db/actions/update-refresh-token/index.d.ts +4 -0
- package/dist/ru/modules/local-db/actions/update-refresh-token/index.js +26 -0
- package/dist/ru/modules/local-db/actions/update-user/index.d.ts +5 -0
- package/dist/ru/modules/local-db/actions/update-user/index.js +26 -0
- package/dist/ru/modules/local-db/create-request-error.d.ts +5 -0
- package/dist/ru/modules/local-db/create-request-error.js +9 -0
- package/dist/ru/modules/local-db/index.d.ts +6 -0
- package/dist/ru/modules/local-db/index.js +6 -0
- package/dist/ru/modules/local-db/init-db.d.ts +17 -0
- package/dist/ru/modules/local-db/init-db.js +52 -0
- package/dist/ru/modules/logger/index.d.ts +1 -0
- package/dist/ru/modules/logger/index.js +3 -0
- package/dist/ru/modules/request/index.d.ts +20 -0
- package/dist/ru/modules/request/index.js +78 -0
- package/dist/ru/modules/request/normalize-request-opts.d.ts +5 -0
- package/dist/ru/modules/request/normalize-request-opts.js +11 -0
- package/dist/ru/modules/request/should-retry.d.ts +6 -0
- package/dist/ru/modules/request/should-retry.js +16 -0
- package/dist/ru/modules/request/types.d.ts +20 -0
- package/dist/ru/modules/request/types.js +1 -0
- package/dist/ru/modules/tokens/index.d.ts +4 -0
- package/dist/ru/modules/tokens/index.js +14 -0
- package/dist/ru/modules/topline-service/index.d.ts +24 -0
- package/dist/ru/modules/topline-service/index.js +46 -0
- package/dist/ru/modules/topline-service/inner-service.d.ts +45 -0
- package/dist/ru/modules/topline-service/inner-service.js +219 -0
- package/dist/ru/modules/topline-service/types.d.ts +32 -0
- package/dist/ru/modules/topline-service/types.js +19 -0
- package/dist/ru/modules/validators/email.d.ts +4 -0
- package/dist/ru/modules/validators/email.js +7 -0
- package/dist/ru/modules/validators/password-recovery-code.d.ts +4 -0
- package/dist/ru/modules/validators/password-recovery-code.js +6 -0
- package/dist/ru/modules/validators/password.d.ts +4 -0
- package/dist/ru/modules/validators/password.js +6 -0
- package/dist/ru/modules/websocket/index.d.ts +4 -0
- package/dist/ru/modules/websocket/index.js +92 -0
- package/dist/ru/parts/login/actions/perform-login/index.d.ts +27 -0
- package/dist/ru/parts/login/actions/perform-login/index.js +60 -0
- package/dist/ru/parts/login/index.d.ts +1 -0
- package/dist/ru/parts/login/index.js +1 -0
- package/dist/ru/parts/login/ui/login/index.d.ts +8 -0
- package/dist/ru/parts/login/ui/login/index.js +138 -0
- package/dist/ru/parts/logout/actions/perform-logout/index.d.ts +23 -0
- package/dist/ru/parts/logout/actions/perform-logout/index.js +54 -0
- package/dist/ru/parts/logout/actions/perform-logout/make-second-attempt.d.ts +1 -0
- package/dist/ru/parts/logout/actions/perform-logout/make-second-attempt.js +3 -0
- package/dist/ru/parts/logout/index.d.ts +1 -0
- package/dist/ru/parts/logout/index.js +1 -0
- package/dist/ru/parts/password-recovery/actions/create-claim/index.d.ts +22 -0
- package/dist/ru/parts/password-recovery/actions/create-claim/index.js +41 -0
- package/dist/ru/parts/password-recovery/actions/save-password/index.d.ts +27 -0
- package/dist/ru/parts/password-recovery/actions/save-password/index.js +61 -0
- package/dist/ru/parts/password-recovery/index.d.ts +1 -0
- package/dist/ru/parts/password-recovery/index.js +1 -0
- package/dist/ru/parts/password-recovery/ui/password-recovery/index.d.ts +6 -0
- package/dist/ru/parts/password-recovery/ui/password-recovery/index.js +33 -0
- package/dist/ru/parts/password-recovery/ui/step-one/index.d.ts +7 -0
- package/dist/ru/parts/password-recovery/ui/step-one/index.js +82 -0
- package/dist/ru/parts/password-recovery/ui/step-two/index.d.ts +7 -0
- package/dist/ru/parts/password-recovery/ui/step-two/index.js +134 -0
- package/dist/ru/parts/shell/actions/refresh-user/has-user-been-changed.d.ts +5 -0
- package/dist/ru/parts/shell/actions/refresh-user/has-user-been-changed.js +6 -0
- package/dist/ru/parts/shell/actions/refresh-user/index.d.ts +28 -0
- package/dist/ru/parts/shell/actions/refresh-user/index.js +79 -0
- package/dist/ru/parts/shell/actions/refresh-user/make-second-attempt.d.ts +2 -0
- package/dist/ru/parts/shell/actions/refresh-user/make-second-attempt.js +3 -0
- package/dist/ru/parts/shell/context.d.ts +12 -0
- package/dist/ru/parts/shell/context.js +8 -0
- package/dist/ru/parts/shell/index.d.ts +2 -0
- package/dist/ru/parts/shell/index.js +2 -0
- package/dist/ru/parts/shell/ui/logged-out-user-menu/index.d.ts +8 -0
- package/dist/ru/parts/shell/ui/logged-out-user-menu/index.js +42 -0
- package/dist/ru/parts/shell/ui/loggeg-in-user-menu/index.d.ts +8 -0
- package/dist/ru/parts/shell/ui/loggeg-in-user-menu/index.js +42 -0
- package/dist/ru/parts/shell/ui/logo/index.d.ts +1 -0
- package/dist/ru/parts/shell/ui/logo/index.js +8 -0
- package/dist/ru/parts/shell/ui/logo/logo-full.d.ts +2 -0
- package/dist/ru/parts/shell/ui/logo/logo-full.js +26 -0
- package/dist/ru/parts/shell/ui/logo/logo-short.d.ts +2 -0
- package/dist/ru/parts/shell/ui/logo/logo-short.js +26 -0
- package/dist/ru/parts/shell/ui/shell/index.d.ts +2 -0
- package/dist/ru/parts/shell/ui/shell/index.js +187 -0
- package/dist/ru/parts/shell/ui/user-avatar/index.d.ts +7 -0
- package/dist/ru/parts/shell/ui/user-avatar/index.js +48 -0
- package/dist/ru/parts/shell/ui/user-menu/index.d.ts +8 -0
- package/dist/ru/parts/shell/ui/user-menu/index.js +37 -0
- package/dist/ru/parts/shell/ui/user-menu-item/index.d.ts +10 -0
- package/dist/ru/parts/shell/ui/user-menu-item/index.js +19 -0
- package/dist/ru/parts/signup/actions/perform-signup/index.d.ts +33 -0
- package/dist/ru/parts/signup/actions/perform-signup/index.js +58 -0
- package/dist/ru/parts/signup/index.d.ts +1 -0
- package/dist/ru/parts/signup/index.js +1 -0
- package/dist/ru/parts/signup/ui/signup/index.d.ts +8 -0
- package/dist/ru/parts/signup/ui/signup/index.js +163 -0
- package/dist/ru/shared/components/alternative/index.d.ts +7 -0
- package/dist/ru/shared/components/alternative/index.js +3 -0
- package/dist/ru/shared/components/modal/index.d.ts +8 -0
- package/dist/ru/shared/components/modal/index.js +32 -0
- package/dist/ru/shared/procedures/process-successful-response/index.d.ts +30 -0
- package/dist/ru/shared/procedures/process-successful-response/index.js +66 -0
- package/dist/ru/topline.d.ts +24 -0
- package/dist/ru/topline.js +33 -0
- package/dist/ru/types/app.d.ts +1 -0
- package/dist/ru/types/app.js +1 -0
- package/dist/ru/types/data.d.ts +10 -0
- package/dist/ru/types/data.js +4 -0
- package/dist/ru/types/helpers.d.ts +2 -0
- package/dist/ru/types/helpers.js +3 -0
- package/package.json +75 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import WebError from '@memnrev/web-error';
|
|
2
|
+
import { getWebsocketUrl } from '../env/index.js';
|
|
3
|
+
import { getGrantToken } from '../tokens/index.js';
|
|
4
|
+
import { logError } from '../logger/index.js';
|
|
5
|
+
import { innerToplineService, ToplineEventName } from '../topline-service/index.js';
|
|
6
|
+
import { isObject } from '../../types/helpers.js';
|
|
7
|
+
let activeSocket = null;
|
|
8
|
+
let currConnectionRetries = 0;
|
|
9
|
+
const MAX_RECONNECTION_DELAY_MS = 30000;
|
|
10
|
+
const closeCodes = {
|
|
11
|
+
// We have closed the connection by ourselves
|
|
12
|
+
INITIATED_BY_OURSELVES: 1000,
|
|
13
|
+
// Connection is closed by server
|
|
14
|
+
INITIATED_BY_SERVER: 1001,
|
|
15
|
+
// No status code is actually present in a Close control frame
|
|
16
|
+
WITHOUT_STATUS_CODE: 1005,
|
|
17
|
+
// Connection was closed abnormally, e.g., without sending or receiving a Close control frame.
|
|
18
|
+
// This includes the case of connection handshake failure.
|
|
19
|
+
NETWORK_PROBLEM: 1006,
|
|
20
|
+
// Grant token is not verified/expired
|
|
21
|
+
BY_SERVER_INVALID_GRANT_TOKEN: 4401
|
|
22
|
+
};
|
|
23
|
+
/** Handle incoming message from websocket */
|
|
24
|
+
function handleSocketMessage(e) {
|
|
25
|
+
if (e.data === 'logout') {
|
|
26
|
+
innerToplineService.processLogout();
|
|
27
|
+
closeWebsocket();
|
|
28
|
+
} else {
|
|
29
|
+
const message = JSON.parse(e.data);
|
|
30
|
+
if (isObject(message) && 'syncId' in message && typeof message.syncId === 'string') {
|
|
31
|
+
innerToplineService.emit(ToplineEventName.SyncNotification, message.syncId);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Open websocket */
|
|
36
|
+
export function openWebsocket() {
|
|
37
|
+
closeWebsocket();
|
|
38
|
+
const wsUrl = getWebsocketUrl();
|
|
39
|
+
const socket = new window.WebSocket(wsUrl);
|
|
40
|
+
socket.addEventListener('open', handleSocketOpen);
|
|
41
|
+
socket.addEventListener('close', e => void handleSocketClose(e));
|
|
42
|
+
socket.addEventListener('message', handleSocketMessage);
|
|
43
|
+
activeSocket = socket;
|
|
44
|
+
currConnectionRetries = 0;
|
|
45
|
+
}
|
|
46
|
+
/** Close websocket */
|
|
47
|
+
export function closeWebsocket() {
|
|
48
|
+
if (activeSocket) {
|
|
49
|
+
activeSocket.close(closeCodes.INITIATED_BY_OURSELVES);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Handle for websocket "open" event */
|
|
53
|
+
function handleSocketOpen() {
|
|
54
|
+
this.send(JSON.stringify({
|
|
55
|
+
type: 'connection',
|
|
56
|
+
data: {
|
|
57
|
+
grantToken: getGrantToken()
|
|
58
|
+
}
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
/** Handle websocket "close" event */
|
|
62
|
+
async function handleSocketClose(e) {
|
|
63
|
+
activeSocket = null;
|
|
64
|
+
switch (e.code) {
|
|
65
|
+
case closeCodes.INITIATED_BY_OURSELVES:
|
|
66
|
+
break;
|
|
67
|
+
case closeCodes.INITIATED_BY_SERVER:
|
|
68
|
+
case closeCodes.WITHOUT_STATUS_CODE:
|
|
69
|
+
case closeCodes.NETWORK_PROBLEM:
|
|
70
|
+
reconnect();
|
|
71
|
+
break;
|
|
72
|
+
case closeCodes.BY_SERVER_INVALID_GRANT_TOKEN:
|
|
73
|
+
if (await innerToplineService.upgradeGrantToken()) {
|
|
74
|
+
reconnect();
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
// Unexpected closing code
|
|
79
|
+
logError(new WebError({
|
|
80
|
+
name: 'UnexpectedWsClosingCode'
|
|
81
|
+
}, `websocket was closed with unexpected code ${e.code}`));
|
|
82
|
+
reconnect();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Make re-connection try */
|
|
86
|
+
function reconnect() {
|
|
87
|
+
let delay = 2 ** ++currConnectionRetries * 2000;
|
|
88
|
+
if (delay > MAX_RECONNECTION_DELAY_MS) {
|
|
89
|
+
delay = MAX_RECONNECTION_DELAY_MS;
|
|
90
|
+
}
|
|
91
|
+
setTimeout(openWebsocket, delay);
|
|
92
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import stampit from 'stampit';
|
|
2
|
+
import { getApiBaseUrl, getRequestCredentialsMode } from '../../../../modules/env/index.js';
|
|
3
|
+
import request from '../../../../modules/request/index.js';
|
|
4
|
+
import processSuccessfulResponse from '../../../../shared/procedures/process-successful-response/index.js';
|
|
5
|
+
import type { ToplineUser } from '../../../../types/data.js';
|
|
6
|
+
export type ReturnValue = {
|
|
7
|
+
user: ToplineUser | null;
|
|
8
|
+
error: 'network' | 'incorrect-credentials' | null;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Perform logging-in
|
|
12
|
+
*
|
|
13
|
+
* Return `null` if login succeeds; otherwise:
|
|
14
|
+
* - on network error or if backend responds with 5xx - "network";
|
|
15
|
+
* - on login failure - "incorrect-credentials".
|
|
16
|
+
*/
|
|
17
|
+
declare function performLogin(this: This, email: string, password: string): Promise<ReturnValue>;
|
|
18
|
+
export type This = {
|
|
19
|
+
getApiBaseUrl: typeof getApiBaseUrl;
|
|
20
|
+
getRequestCredentialsMode: typeof getRequestCredentialsMode;
|
|
21
|
+
request: typeof request;
|
|
22
|
+
processSuccessfulResponse: typeof processSuccessfulResponse;
|
|
23
|
+
performLogin: typeof performLogin;
|
|
24
|
+
};
|
|
25
|
+
export declare const PerformLogin: stampit.Stamp<This>;
|
|
26
|
+
declare const _default: (email: string, password: string) => Promise<ReturnValue>;
|
|
27
|
+
export default _default;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import stampit from 'stampit';
|
|
2
|
+
import { getApiBaseUrl, getRequestCredentialsMode } from '../../../../modules/env/index.js';
|
|
3
|
+
import request from '../../../../modules/request/index.js';
|
|
4
|
+
import processSuccessfulResponse from '../../../../shared/procedures/process-successful-response/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* Perform logging-in
|
|
7
|
+
*
|
|
8
|
+
* Return `null` if login succeeds; otherwise:
|
|
9
|
+
* - on network error or if backend responds with 5xx - "network";
|
|
10
|
+
* - on login failure - "incorrect-credentials".
|
|
11
|
+
*/
|
|
12
|
+
async function performLogin(email, password) {
|
|
13
|
+
const url = `${this.getApiBaseUrl()}/public/login-with-credentials`;
|
|
14
|
+
const options = {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
headers: {
|
|
17
|
+
'Content-Type': 'application/json; charset=utf-8'
|
|
18
|
+
},
|
|
19
|
+
body: JSON.stringify({
|
|
20
|
+
email,
|
|
21
|
+
password
|
|
22
|
+
}),
|
|
23
|
+
credentials: this.getRequestCredentialsMode(),
|
|
24
|
+
cache: 'no-store',
|
|
25
|
+
redirect: 'error'
|
|
26
|
+
};
|
|
27
|
+
const response = await this.request(url, options, {
|
|
28
|
+
maxRetries: 1
|
|
29
|
+
});
|
|
30
|
+
if (!response) {
|
|
31
|
+
return {
|
|
32
|
+
user: null,
|
|
33
|
+
error: 'network'
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (response.status === 200) {
|
|
37
|
+
return await this.processSuccessfulResponse(response, url);
|
|
38
|
+
}
|
|
39
|
+
if (response.status === 401) {
|
|
40
|
+
return {
|
|
41
|
+
user: null,
|
|
42
|
+
error: 'incorrect-credentials'
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// This code is actually unreachable as `request` returns `null` in case of unexpected
|
|
46
|
+
// status code. The code is added to preserve formal function API.
|
|
47
|
+
return {
|
|
48
|
+
user: null,
|
|
49
|
+
error: 'network'
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export const PerformLogin = stampit().props({
|
|
53
|
+
getApiBaseUrl,
|
|
54
|
+
getRequestCredentialsMode,
|
|
55
|
+
request,
|
|
56
|
+
processSuccessfulResponse
|
|
57
|
+
}).methods({
|
|
58
|
+
performLogin
|
|
59
|
+
});
|
|
60
|
+
export default performLogin.bind(PerformLogin());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Login } from './ui/login/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Login } from './ui/login/index.js';
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useContext, useState, useCallback, useEffect, createRef } from 'react';
|
|
3
|
+
import Modal from '../../../../shared/components/modal/index.js';
|
|
4
|
+
import Alternative from '../../../../shared/components/alternative/index.js';
|
|
5
|
+
import { InputField } from '@peassoft/mnr-web-ui-kit/input-field/index.js';
|
|
6
|
+
import { Button } from '@peassoft/mnr-web-ui-kit/button/index.js';
|
|
7
|
+
import { ErrorMessage } from '@peassoft/mnr-web-ui-kit/error-message/index.js';
|
|
8
|
+
import { ToplineContext } from '../../../shell/index.js';
|
|
9
|
+
import { globalRefs } from '../../../../modules/focus-marshal/index.js';
|
|
10
|
+
import validateEmail from '../../../../modules/validators/email.js';
|
|
11
|
+
import validatePassword from '../../../../modules/validators/password.js';
|
|
12
|
+
import performLogin from '../../actions/perform-login/index.js';
|
|
13
|
+
export default function Login(props) {
|
|
14
|
+
const {
|
|
15
|
+
onClose,
|
|
16
|
+
onMoveToPasswordRecovery,
|
|
17
|
+
onMoveToSignUp
|
|
18
|
+
} = props;
|
|
19
|
+
const lastElementRef = createRef();
|
|
20
|
+
const [email, setEmail] = useState('');
|
|
21
|
+
const [isEmailValid, setIsEmailValid] = useState(true);
|
|
22
|
+
const [password, setPassword] = useState('');
|
|
23
|
+
const [isPasswordValid, setIsPasswordValid] = useState(true);
|
|
24
|
+
const [isMakingRequest, setIsMakingRequest] = useState(false);
|
|
25
|
+
const [errorMessage, setErrorMessage] = useState('');
|
|
26
|
+
const {
|
|
27
|
+
handleUserChange
|
|
28
|
+
} = useContext(ToplineContext);
|
|
29
|
+
const handleEmailChange = useCallback(newValue => setEmail(newValue.trim()), []);
|
|
30
|
+
const handlePasswordChange = useCallback(newValue => setPassword(newValue.trim()), []);
|
|
31
|
+
const handleEmailBlur = useCallback(() => setIsEmailValid(validateEmail(email)), [email]);
|
|
32
|
+
const handlePasswordBlur = useCallback(() => setIsPasswordValid(validatePassword(password)), [password]);
|
|
33
|
+
const handleLogInBtnClick = useCallback(async () => {
|
|
34
|
+
let hasFormValidationFailed = false;
|
|
35
|
+
if (!validateEmail(email)) {
|
|
36
|
+
setIsEmailValid(false);
|
|
37
|
+
hasFormValidationFailed = true;
|
|
38
|
+
}
|
|
39
|
+
if (!validatePassword(password)) {
|
|
40
|
+
setIsPasswordValid(false);
|
|
41
|
+
hasFormValidationFailed = true;
|
|
42
|
+
}
|
|
43
|
+
if (hasFormValidationFailed) return;
|
|
44
|
+
setIsMakingRequest(true);
|
|
45
|
+
const {
|
|
46
|
+
user,
|
|
47
|
+
error
|
|
48
|
+
} = await performLogin(email, password);
|
|
49
|
+
if (user && !error) {
|
|
50
|
+
onClose();
|
|
51
|
+
handleUserChange(user);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
setIsMakingRequest(false);
|
|
55
|
+
switch (error) {
|
|
56
|
+
case 'network':
|
|
57
|
+
setErrorMessage("Сервер недоступен. Попробуйте повторить позже.");
|
|
58
|
+
break;
|
|
59
|
+
case 'incorrect-credentials':
|
|
60
|
+
setErrorMessage("Неправильное имя пользователя и/или пароль.");
|
|
61
|
+
break;
|
|
62
|
+
default:
|
|
63
|
+
throw new Error('Unknown error of a login request');
|
|
64
|
+
}
|
|
65
|
+
}, [email, password, onClose, handleUserChange]);
|
|
66
|
+
const handleTabOnLastElement = useCallback(() => globalRefs.modalFirstItem.current?.focus(), []);
|
|
67
|
+
const handleShiftTabOnFirstElement = useCallback(() => lastElementRef.current?.focus(), [lastElementRef]);
|
|
68
|
+
useEffect(() => globalRefs.modalFirstItem.current?.focus(), []);
|
|
69
|
+
return _jsxs(Modal, {
|
|
70
|
+
title: "Войти в аккаунт",
|
|
71
|
+
onClose: onClose,
|
|
72
|
+
children: [_jsxs("form", {
|
|
73
|
+
children: [_jsx(InputField, {
|
|
74
|
+
ref: globalRefs.modalFirstItem,
|
|
75
|
+
type: 'email',
|
|
76
|
+
autocompleteAttribute: 'username',
|
|
77
|
+
label: "Email. Обязательное поле",
|
|
78
|
+
errorMessage: isEmailValid ? '' : "Введите корректный адрес email",
|
|
79
|
+
value: email,
|
|
80
|
+
onChange: handleEmailChange,
|
|
81
|
+
onBlur: handleEmailBlur,
|
|
82
|
+
onShiftTab: handleShiftTabOnFirstElement
|
|
83
|
+
}), _jsx(InputField, {
|
|
84
|
+
type: 'password',
|
|
85
|
+
autocompleteAttribute: 'current-password',
|
|
86
|
+
label: "Пароль. Обязательное поле",
|
|
87
|
+
errorMessage: isPasswordValid ? '' : "Пароль не может быть пустым",
|
|
88
|
+
value: password,
|
|
89
|
+
onChange: handlePasswordChange,
|
|
90
|
+
onBlur: handlePasswordBlur
|
|
91
|
+
}), _jsx(Alternative, {
|
|
92
|
+
condition: () => Boolean(errorMessage),
|
|
93
|
+
true: _jsx(ErrorMessage, {
|
|
94
|
+
variant: 'standalone',
|
|
95
|
+
children: errorMessage
|
|
96
|
+
}),
|
|
97
|
+
false: null
|
|
98
|
+
}), _jsxs("div", {
|
|
99
|
+
className: 'topline_login_btnsCont',
|
|
100
|
+
children: [_jsx(Button, {
|
|
101
|
+
label: "Войти",
|
|
102
|
+
stretched: true,
|
|
103
|
+
isInProgress: isMakingRequest,
|
|
104
|
+
onClick: handleLogInBtnClick
|
|
105
|
+
}), _jsx(Button, {
|
|
106
|
+
label: "Отменить",
|
|
107
|
+
variant: 'secondary',
|
|
108
|
+
stretched: true,
|
|
109
|
+
onClick: onClose
|
|
110
|
+
})]
|
|
111
|
+
})]
|
|
112
|
+
}), _jsxs("div", {
|
|
113
|
+
className: 'topline_login_extraBlock',
|
|
114
|
+
children: [_jsx("p", {
|
|
115
|
+
className: 'topline_login_extraBlockLabel',
|
|
116
|
+
children: "Забыли пароль?"
|
|
117
|
+
}), _jsx(Button, {
|
|
118
|
+
label: "Восстановить пароль",
|
|
119
|
+
variant: 'secondary',
|
|
120
|
+
size: 'small',
|
|
121
|
+
onClick: onMoveToPasswordRecovery
|
|
122
|
+
})]
|
|
123
|
+
}), _jsxs("div", {
|
|
124
|
+
className: 'topline_login_extraBlock',
|
|
125
|
+
children: [_jsx("p", {
|
|
126
|
+
className: 'topline_login_extraBlockLabel',
|
|
127
|
+
children: "Нужен аккаунт?"
|
|
128
|
+
}), _jsx(Button, {
|
|
129
|
+
ref: lastElementRef,
|
|
130
|
+
label: "Создай его сейчас!",
|
|
131
|
+
variant: 'secondary',
|
|
132
|
+
size: 'small',
|
|
133
|
+
onClick: onMoveToSignUp,
|
|
134
|
+
onTab: handleTabOnLastElement
|
|
135
|
+
})]
|
|
136
|
+
})]
|
|
137
|
+
});
|
|
138
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
/**
|
|
21
|
+
* Make logout request to api
|
|
22
|
+
*/
|
|
23
|
+
declare function performLogout(this: This): Promise<void>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import stampit from 'stampit';
|
|
2
|
+
import { closeWebsocket } from '../../../../modules/websocket/index.js';
|
|
3
|
+
import { getGrantToken } from '../../../../modules/tokens/index.js';
|
|
4
|
+
import { innerToplineService } 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 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
|
+
/**
|
|
21
|
+
* Make logout request to api
|
|
22
|
+
*/
|
|
23
|
+
async function performLogout() {
|
|
24
|
+
this.closeWebsocket();
|
|
25
|
+
const grantToken = this.getGrantToken();
|
|
26
|
+
if (!grantToken) {
|
|
27
|
+
this.innerToplineService.processLogout();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const url = `${this.getApiBaseUrl()}/private/log-out`;
|
|
31
|
+
const options = {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: {
|
|
34
|
+
Authorization: `Bearer ${grantToken}`
|
|
35
|
+
},
|
|
36
|
+
cache: 'no-store',
|
|
37
|
+
redirect: 'error'
|
|
38
|
+
};
|
|
39
|
+
const response = await this.request(url, options, {
|
|
40
|
+
maxRetries: 1
|
|
41
|
+
});
|
|
42
|
+
if (!response || response.status !== 401) {
|
|
43
|
+
this.innerToplineService.processLogout();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (response.status === 401) {
|
|
47
|
+
// innerToplineService.upgradeGrantToken() makes all necessary clean-up in case
|
|
48
|
+
// the upgrade fails
|
|
49
|
+
const grantToken = await this.innerToplineService.upgradeGrantToken();
|
|
50
|
+
if (grantToken) {
|
|
51
|
+
await this.makeSecondAttempt(self);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function makeSecondAttempt(self: () => Promise<void>): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as performLogout } from './actions/perform-logout/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as performLogout } from './actions/perform-logout/index.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import stampit from 'stampit';
|
|
2
|
+
import { getApiBaseUrl, getRequestCredentialsMode } from '../../../../modules/env/index.js';
|
|
3
|
+
import request from '../../../../modules/request/index.js';
|
|
4
|
+
export type ReturnValue = {
|
|
5
|
+
error: 'network' | null;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Create password recovery claim
|
|
9
|
+
*
|
|
10
|
+
* Returns `null` if claim creation succeeds; otherwise:
|
|
11
|
+
* - on network error or if backend responds with 5xx - "network".
|
|
12
|
+
*/
|
|
13
|
+
declare function createClaim(this: This, email: string): Promise<ReturnValue>;
|
|
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;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import stampit from 'stampit';
|
|
2
|
+
import { getApiBaseUrl, getRequestCredentialsMode } from '../../../../modules/env/index.js';
|
|
3
|
+
import request from '../../../../modules/request/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Create password recovery claim
|
|
6
|
+
*
|
|
7
|
+
* Returns `null` if claim creation succeeds; otherwise:
|
|
8
|
+
* - on network error or if backend responds with 5xx - "network".
|
|
9
|
+
*/
|
|
10
|
+
async function createClaim(email) {
|
|
11
|
+
const url = `${this.getApiBaseUrl()}/public/create-password-recovery-claim`;
|
|
12
|
+
const options = {
|
|
13
|
+
method: 'POST',
|
|
14
|
+
headers: {
|
|
15
|
+
'Content-Type': 'application/json; charset=utf-8'
|
|
16
|
+
},
|
|
17
|
+
body: JSON.stringify({
|
|
18
|
+
email
|
|
19
|
+
}),
|
|
20
|
+
credentials: this.getRequestCredentialsMode(),
|
|
21
|
+
cache: 'no-store',
|
|
22
|
+
redirect: 'error'
|
|
23
|
+
};
|
|
24
|
+
const response = await this.request(url, options);
|
|
25
|
+
if (!response) {
|
|
26
|
+
return {
|
|
27
|
+
error: 'network'
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
error: null
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export const CreateClaim = stampit().props({
|
|
35
|
+
getApiBaseUrl,
|
|
36
|
+
getRequestCredentialsMode,
|
|
37
|
+
request
|
|
38
|
+
}).methods({
|
|
39
|
+
createClaim
|
|
40
|
+
});
|
|
41
|
+
export default createClaim.bind(CreateClaim());
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import stampit from 'stampit';
|
|
2
|
+
import { getApiBaseUrl, getRequestCredentialsMode } from '../../../../modules/env/index.js';
|
|
3
|
+
import request from '../../../../modules/request/index.js';
|
|
4
|
+
import processSuccessfulResponse from '../../../../shared/procedures/process-successful-response/index.js';
|
|
5
|
+
import type { ToplineUser } from '../../../../types/data.js';
|
|
6
|
+
export type ReturnValue = {
|
|
7
|
+
user: ToplineUser | null;
|
|
8
|
+
error: 'network' | 'no-claim' | null;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Save new password
|
|
12
|
+
*
|
|
13
|
+
* Returns `null` if sign-up succeeds; otherwise:
|
|
14
|
+
* - on network error or if backend responds with 5xx - "network";
|
|
15
|
+
* - on 403 Forbidden response - "no-claim".
|
|
16
|
+
*/
|
|
17
|
+
declare function savePassword(this: This, email: string, password: string, secretCode: string): Promise<ReturnValue>;
|
|
18
|
+
export type This = {
|
|
19
|
+
getApiBaseUrl: typeof getApiBaseUrl;
|
|
20
|
+
getRequestCredentialsMode: typeof getRequestCredentialsMode;
|
|
21
|
+
request: typeof request;
|
|
22
|
+
processSuccessfulResponse: typeof processSuccessfulResponse;
|
|
23
|
+
savePassword: typeof savePassword;
|
|
24
|
+
};
|
|
25
|
+
export declare const SavePassword: stampit.Stamp<This>;
|
|
26
|
+
declare const _default: (email: string, password: string, secretCode: string) => Promise<ReturnValue>;
|
|
27
|
+
export default _default;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import stampit from 'stampit';
|
|
2
|
+
import { getApiBaseUrl, getRequestCredentialsMode } from '../../../../modules/env/index.js';
|
|
3
|
+
import request from '../../../../modules/request/index.js';
|
|
4
|
+
import processSuccessfulResponse from '../../../../shared/procedures/process-successful-response/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* Save new password
|
|
7
|
+
*
|
|
8
|
+
* Returns `null` if sign-up succeeds; otherwise:
|
|
9
|
+
* - on network error or if backend responds with 5xx - "network";
|
|
10
|
+
* - on 403 Forbidden response - "no-claim".
|
|
11
|
+
*/
|
|
12
|
+
async function savePassword(email, password, secretCode) {
|
|
13
|
+
const url = `${this.getApiBaseUrl()}/public/create-new-password`;
|
|
14
|
+
const options = {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
headers: {
|
|
17
|
+
'Content-Type': 'application/json; charset=utf-8'
|
|
18
|
+
},
|
|
19
|
+
body: JSON.stringify({
|
|
20
|
+
email,
|
|
21
|
+
password,
|
|
22
|
+
secretCode
|
|
23
|
+
}),
|
|
24
|
+
credentials: this.getRequestCredentialsMode(),
|
|
25
|
+
cache: 'no-store',
|
|
26
|
+
redirect: 'error'
|
|
27
|
+
};
|
|
28
|
+
const response = await this.request(url, options, {
|
|
29
|
+
expectedStatusCodes: [200, 403]
|
|
30
|
+
});
|
|
31
|
+
if (!response) {
|
|
32
|
+
return {
|
|
33
|
+
user: null,
|
|
34
|
+
error: 'network'
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (response.status === 200) {
|
|
38
|
+
return await this.processSuccessfulResponse(response, url);
|
|
39
|
+
}
|
|
40
|
+
if (response.status === 403) {
|
|
41
|
+
return {
|
|
42
|
+
user: null,
|
|
43
|
+
error: 'no-claim'
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// This code is actually unreachable as `request` returns `null` in case of unexpected
|
|
47
|
+
// status code. The code is added to preserve formal function API.
|
|
48
|
+
return {
|
|
49
|
+
user: null,
|
|
50
|
+
error: 'network'
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export const SavePassword = stampit().props({
|
|
54
|
+
getApiBaseUrl,
|
|
55
|
+
getRequestCredentialsMode,
|
|
56
|
+
request,
|
|
57
|
+
processSuccessfulResponse
|
|
58
|
+
}).methods({
|
|
59
|
+
savePassword
|
|
60
|
+
});
|
|
61
|
+
export default savePassword.bind(SavePassword());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PasswordRecovery } from './ui/password-recovery/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as PasswordRecovery } from './ui/password-recovery/index.js';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useCallback } from 'react';
|
|
3
|
+
import Modal from '../../../../shared/components/modal/index.js';
|
|
4
|
+
import Alternative from '../../../../shared/components/alternative/index.js';
|
|
5
|
+
import StepOne from '../step-one/index.js';
|
|
6
|
+
import StepTwo from '../step-two/index.js';
|
|
7
|
+
export default function PasswordRecovery(props) {
|
|
8
|
+
const {
|
|
9
|
+
onClose
|
|
10
|
+
} = props;
|
|
11
|
+
const [step, setStep] = useState(1);
|
|
12
|
+
const [email, setEmail] = useState('');
|
|
13
|
+
const condition = useCallback(() => step === 1, [step]);
|
|
14
|
+
const onNext = useCallback(email => {
|
|
15
|
+
setEmail(email);
|
|
16
|
+
setStep(2);
|
|
17
|
+
}, []);
|
|
18
|
+
return _jsx(Modal, {
|
|
19
|
+
title: "Восстановление пароля",
|
|
20
|
+
onClose: onClose,
|
|
21
|
+
children: _jsx(Alternative, {
|
|
22
|
+
condition: condition,
|
|
23
|
+
true: _jsx(StepOne, {
|
|
24
|
+
onNext: onNext,
|
|
25
|
+
onClose: onClose
|
|
26
|
+
}),
|
|
27
|
+
false: _jsx(StepTwo, {
|
|
28
|
+
email: email,
|
|
29
|
+
onClose: onClose
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
}
|