@vivinkv28/strapi-2fa-admin-plugin 0.1.9 → 0.1.12
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
CHANGED
|
@@ -122,6 +122,20 @@ host-patch/
|
|
|
122
122
|
|
|
123
123
|
These are the files you can copy into your Strapi project to get the same admin OTP UI pattern.
|
|
124
124
|
|
|
125
|
+
If you want to view the same host patch files on GitHub, use:
|
|
126
|
+
|
|
127
|
+
- [host-patch folder](https://github.com/vivinkv6/strapi-admin-2fa-plugin/tree/master/host-patch)
|
|
128
|
+
- [apply-strapi-admin-2fa-patch.js](https://github.com/vivinkv6/strapi-admin-2fa-plugin/blob/master/host-patch/apply-strapi-admin-2fa-patch.js)
|
|
129
|
+
- [services/auth.js](https://github.com/vivinkv6/strapi-admin-2fa-plugin/blob/master/host-patch/strapi-admin-2fa-patch/services/auth.js)
|
|
130
|
+
- [services/auth.mjs](https://github.com/vivinkv6/strapi-admin-2fa-plugin/blob/master/host-patch/strapi-admin-2fa-patch/services/auth.mjs)
|
|
131
|
+
- [pages/Auth/components/Login.js](https://github.com/vivinkv6/strapi-admin-2fa-plugin/blob/master/host-patch/strapi-admin-2fa-patch/pages/Auth/components/Login.js)
|
|
132
|
+
- [pages/Auth/components/Login.mjs](https://github.com/vivinkv6/strapi-admin-2fa-plugin/blob/master/host-patch/strapi-admin-2fa-patch/pages/Auth/components/Login.mjs)
|
|
133
|
+
|
|
134
|
+
That gives users both options:
|
|
135
|
+
|
|
136
|
+
- install from npm and copy the bundled files
|
|
137
|
+
- inspect the admin UI source directly on GitHub before integrating it
|
|
138
|
+
|
|
125
139
|
## What The UI Patch Does
|
|
126
140
|
|
|
127
141
|
The bundled host patch changes the Strapi admin login flow to:
|
package/dist/server/index.js
CHANGED
|
@@ -19149,21 +19149,21 @@ class ForbiddenError extends ApplicationError$1 {
|
|
|
19149
19149
|
this.message = message;
|
|
19150
19150
|
}
|
|
19151
19151
|
}
|
|
19152
|
-
class UnauthorizedError extends ApplicationError$1 {
|
|
19152
|
+
let UnauthorizedError$1 = class UnauthorizedError extends ApplicationError$1 {
|
|
19153
19153
|
constructor(message = "Unauthorized", details) {
|
|
19154
19154
|
super(message, details);
|
|
19155
19155
|
this.name = "UnauthorizedError";
|
|
19156
19156
|
this.message = message;
|
|
19157
19157
|
}
|
|
19158
|
-
}
|
|
19159
|
-
class RateLimitError extends ApplicationError$1 {
|
|
19158
|
+
};
|
|
19159
|
+
let RateLimitError$1 = class RateLimitError extends ApplicationError$1 {
|
|
19160
19160
|
constructor(message = "Too many requests, please try again later.", details) {
|
|
19161
19161
|
super(message, details);
|
|
19162
19162
|
this.name = "RateLimitError";
|
|
19163
19163
|
this.message = message;
|
|
19164
19164
|
this.details = details || {};
|
|
19165
19165
|
}
|
|
19166
|
-
}
|
|
19166
|
+
};
|
|
19167
19167
|
class PayloadTooLargeError extends ApplicationError$1 {
|
|
19168
19168
|
constructor(message = "Entity too large", details) {
|
|
19169
19169
|
super(message, details);
|
|
@@ -19196,8 +19196,8 @@ const errors$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
19196
19196
|
PaginationError,
|
|
19197
19197
|
PayloadTooLargeError,
|
|
19198
19198
|
PolicyError,
|
|
19199
|
-
RateLimitError,
|
|
19200
|
-
UnauthorizedError,
|
|
19199
|
+
RateLimitError: RateLimitError$1,
|
|
19200
|
+
UnauthorizedError: UnauthorizedError$1,
|
|
19201
19201
|
ValidationError: ValidationError$1,
|
|
19202
19202
|
YupValidationError
|
|
19203
19203
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -43795,7 +43795,7 @@ const require$$1 = /* @__PURE__ */ getAugmentedNamespace(dist);
|
|
|
43795
43795
|
const crypto = require$$1__default$1.default;
|
|
43796
43796
|
const { errors } = require$$1;
|
|
43797
43797
|
const sessionAuth = strapiSessionAuth;
|
|
43798
|
-
const { ApplicationError: ApplicationError2, ValidationError: ValidationError3 } = errors;
|
|
43798
|
+
const { ApplicationError: ApplicationError2, RateLimitError: RateLimitError2, UnauthorizedError: UnauthorizedError2, ValidationError: ValidationError3 } = errors;
|
|
43799
43799
|
const STORE_NAME = "admin-otp-login";
|
|
43800
43800
|
const STORE_KEY_PREFIX = "challenge:";
|
|
43801
43801
|
const RATE_LIMIT_KEY_PREFIX = "rate-limit:";
|
|
@@ -43914,11 +43914,11 @@ const deleteChallenge = async (store, challengeId) => {
|
|
|
43914
43914
|
const getChallenge = async (store, challengeId) => {
|
|
43915
43915
|
const challenge = await store.get({ key: getStoreKey(challengeId) });
|
|
43916
43916
|
if (!challenge) {
|
|
43917
|
-
throw new
|
|
43917
|
+
throw new UnauthorizedError2("OTP session not found. Please log in again.");
|
|
43918
43918
|
}
|
|
43919
43919
|
if (new Date(challenge.expiresAt).getTime() <= Date.now()) {
|
|
43920
43920
|
await deleteChallenge(store, challengeId);
|
|
43921
|
-
throw new
|
|
43921
|
+
throw new UnauthorizedError2("OTP expired. Please log in again.");
|
|
43922
43922
|
}
|
|
43923
43923
|
return challenge;
|
|
43924
43924
|
};
|
|
@@ -43941,7 +43941,7 @@ const registerRateLimitHit = async (store, config2, action, scope, identifier) =
|
|
|
43941
43941
|
return;
|
|
43942
43942
|
}
|
|
43943
43943
|
if (existing.count >= limit) {
|
|
43944
|
-
throw new
|
|
43944
|
+
throw new RateLimitError2("Too many authentication attempts. Please wait a few minutes and try again.");
|
|
43945
43945
|
}
|
|
43946
43946
|
await store.set({
|
|
43947
43947
|
key,
|
|
@@ -44020,7 +44020,7 @@ var auth$1 = () => ({
|
|
|
44020
44020
|
});
|
|
44021
44021
|
logDuration(config2, "checkCredentials", credentialsStartedAt);
|
|
44022
44022
|
if (!user) {
|
|
44023
|
-
throw new
|
|
44023
|
+
throw new UnauthorizedError2(info?.message ?? "Invalid credentials");
|
|
44024
44024
|
}
|
|
44025
44025
|
const challengeId = crypto.randomUUID();
|
|
44026
44026
|
const code = createOtpCode(config2.otpDigits);
|
|
@@ -44069,7 +44069,7 @@ var auth$1 = () => ({
|
|
|
44069
44069
|
await registerRateLimitHit(store, config2, "resend", "email", current.email);
|
|
44070
44070
|
if (current.resendCount >= config2.maxResends) {
|
|
44071
44071
|
await deleteChallenge(store, challengeId);
|
|
44072
|
-
throw new
|
|
44072
|
+
throw new RateLimitError2("Maximum OTP resend attempts exceeded. Please log in again.");
|
|
44073
44073
|
}
|
|
44074
44074
|
const code = createOtpCode(config2.otpDigits);
|
|
44075
44075
|
const salt = crypto.randomBytes(16).toString("hex");
|
|
@@ -44112,7 +44112,7 @@ var auth$1 = () => ({
|
|
|
44112
44112
|
await registerRateLimitHit(store, config2, "verify", "email", challenge.email);
|
|
44113
44113
|
if (challenge.attempts >= config2.maxAttempts) {
|
|
44114
44114
|
await deleteChallenge(store, challengeId);
|
|
44115
|
-
throw new
|
|
44115
|
+
throw new RateLimitError2("Maximum OTP attempts exceeded. Please log in again.");
|
|
44116
44116
|
}
|
|
44117
44117
|
const hashStartedAt = now();
|
|
44118
44118
|
const computedHash = await createOtpHash(challengeId, code, challenge.salt);
|
|
@@ -44125,7 +44125,7 @@ var auth$1 = () => ({
|
|
|
44125
44125
|
const nextAttempts = challenge.attempts + 1;
|
|
44126
44126
|
if (nextAttempts >= config2.maxAttempts) {
|
|
44127
44127
|
await deleteChallenge(store, challengeId);
|
|
44128
|
-
throw new
|
|
44128
|
+
throw new RateLimitError2("Maximum OTP attempts exceeded. Please log in again.");
|
|
44129
44129
|
}
|
|
44130
44130
|
const storeStartedAt = now();
|
|
44131
44131
|
await store.set({
|
|
@@ -44139,7 +44139,7 @@ var auth$1 = () => ({
|
|
|
44139
44139
|
challengeId,
|
|
44140
44140
|
attempts: nextAttempts
|
|
44141
44141
|
});
|
|
44142
|
-
throw new
|
|
44142
|
+
throw new UnauthorizedError2("Invalid OTP code");
|
|
44143
44143
|
}
|
|
44144
44144
|
const deleteStartedAt = now();
|
|
44145
44145
|
await deleteChallenge(store, challengeId);
|
package/dist/server/index.mjs
CHANGED
|
@@ -19135,21 +19135,21 @@ class ForbiddenError extends ApplicationError$1 {
|
|
|
19135
19135
|
this.message = message;
|
|
19136
19136
|
}
|
|
19137
19137
|
}
|
|
19138
|
-
class UnauthorizedError extends ApplicationError$1 {
|
|
19138
|
+
let UnauthorizedError$1 = class UnauthorizedError extends ApplicationError$1 {
|
|
19139
19139
|
constructor(message = "Unauthorized", details) {
|
|
19140
19140
|
super(message, details);
|
|
19141
19141
|
this.name = "UnauthorizedError";
|
|
19142
19142
|
this.message = message;
|
|
19143
19143
|
}
|
|
19144
|
-
}
|
|
19145
|
-
class RateLimitError extends ApplicationError$1 {
|
|
19144
|
+
};
|
|
19145
|
+
let RateLimitError$1 = class RateLimitError extends ApplicationError$1 {
|
|
19146
19146
|
constructor(message = "Too many requests, please try again later.", details) {
|
|
19147
19147
|
super(message, details);
|
|
19148
19148
|
this.name = "RateLimitError";
|
|
19149
19149
|
this.message = message;
|
|
19150
19150
|
this.details = details || {};
|
|
19151
19151
|
}
|
|
19152
|
-
}
|
|
19152
|
+
};
|
|
19153
19153
|
class PayloadTooLargeError extends ApplicationError$1 {
|
|
19154
19154
|
constructor(message = "Entity too large", details) {
|
|
19155
19155
|
super(message, details);
|
|
@@ -19182,8 +19182,8 @@ const errors$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
19182
19182
|
PaginationError,
|
|
19183
19183
|
PayloadTooLargeError,
|
|
19184
19184
|
PolicyError,
|
|
19185
|
-
RateLimitError,
|
|
19186
|
-
UnauthorizedError,
|
|
19185
|
+
RateLimitError: RateLimitError$1,
|
|
19186
|
+
UnauthorizedError: UnauthorizedError$1,
|
|
19187
19187
|
ValidationError: ValidationError$1,
|
|
19188
19188
|
YupValidationError
|
|
19189
19189
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -43781,7 +43781,7 @@ const require$$1 = /* @__PURE__ */ getAugmentedNamespace(dist);
|
|
|
43781
43781
|
const crypto = require$$1$2;
|
|
43782
43782
|
const { errors } = require$$1;
|
|
43783
43783
|
const sessionAuth = strapiSessionAuth;
|
|
43784
|
-
const { ApplicationError: ApplicationError2, ValidationError: ValidationError3 } = errors;
|
|
43784
|
+
const { ApplicationError: ApplicationError2, RateLimitError: RateLimitError2, UnauthorizedError: UnauthorizedError2, ValidationError: ValidationError3 } = errors;
|
|
43785
43785
|
const STORE_NAME = "admin-otp-login";
|
|
43786
43786
|
const STORE_KEY_PREFIX = "challenge:";
|
|
43787
43787
|
const RATE_LIMIT_KEY_PREFIX = "rate-limit:";
|
|
@@ -43900,11 +43900,11 @@ const deleteChallenge = async (store, challengeId) => {
|
|
|
43900
43900
|
const getChallenge = async (store, challengeId) => {
|
|
43901
43901
|
const challenge = await store.get({ key: getStoreKey(challengeId) });
|
|
43902
43902
|
if (!challenge) {
|
|
43903
|
-
throw new
|
|
43903
|
+
throw new UnauthorizedError2("OTP session not found. Please log in again.");
|
|
43904
43904
|
}
|
|
43905
43905
|
if (new Date(challenge.expiresAt).getTime() <= Date.now()) {
|
|
43906
43906
|
await deleteChallenge(store, challengeId);
|
|
43907
|
-
throw new
|
|
43907
|
+
throw new UnauthorizedError2("OTP expired. Please log in again.");
|
|
43908
43908
|
}
|
|
43909
43909
|
return challenge;
|
|
43910
43910
|
};
|
|
@@ -43927,7 +43927,7 @@ const registerRateLimitHit = async (store, config2, action, scope, identifier) =
|
|
|
43927
43927
|
return;
|
|
43928
43928
|
}
|
|
43929
43929
|
if (existing.count >= limit) {
|
|
43930
|
-
throw new
|
|
43930
|
+
throw new RateLimitError2("Too many authentication attempts. Please wait a few minutes and try again.");
|
|
43931
43931
|
}
|
|
43932
43932
|
await store.set({
|
|
43933
43933
|
key,
|
|
@@ -44006,7 +44006,7 @@ var auth$1 = () => ({
|
|
|
44006
44006
|
});
|
|
44007
44007
|
logDuration(config2, "checkCredentials", credentialsStartedAt);
|
|
44008
44008
|
if (!user) {
|
|
44009
|
-
throw new
|
|
44009
|
+
throw new UnauthorizedError2(info?.message ?? "Invalid credentials");
|
|
44010
44010
|
}
|
|
44011
44011
|
const challengeId = crypto.randomUUID();
|
|
44012
44012
|
const code = createOtpCode(config2.otpDigits);
|
|
@@ -44055,7 +44055,7 @@ var auth$1 = () => ({
|
|
|
44055
44055
|
await registerRateLimitHit(store, config2, "resend", "email", current.email);
|
|
44056
44056
|
if (current.resendCount >= config2.maxResends) {
|
|
44057
44057
|
await deleteChallenge(store, challengeId);
|
|
44058
|
-
throw new
|
|
44058
|
+
throw new RateLimitError2("Maximum OTP resend attempts exceeded. Please log in again.");
|
|
44059
44059
|
}
|
|
44060
44060
|
const code = createOtpCode(config2.otpDigits);
|
|
44061
44061
|
const salt = crypto.randomBytes(16).toString("hex");
|
|
@@ -44098,7 +44098,7 @@ var auth$1 = () => ({
|
|
|
44098
44098
|
await registerRateLimitHit(store, config2, "verify", "email", challenge.email);
|
|
44099
44099
|
if (challenge.attempts >= config2.maxAttempts) {
|
|
44100
44100
|
await deleteChallenge(store, challengeId);
|
|
44101
|
-
throw new
|
|
44101
|
+
throw new RateLimitError2("Maximum OTP attempts exceeded. Please log in again.");
|
|
44102
44102
|
}
|
|
44103
44103
|
const hashStartedAt = now();
|
|
44104
44104
|
const computedHash = await createOtpHash(challengeId, code, challenge.salt);
|
|
@@ -44111,7 +44111,7 @@ var auth$1 = () => ({
|
|
|
44111
44111
|
const nextAttempts = challenge.attempts + 1;
|
|
44112
44112
|
if (nextAttempts >= config2.maxAttempts) {
|
|
44113
44113
|
await deleteChallenge(store, challengeId);
|
|
44114
|
-
throw new
|
|
44114
|
+
throw new RateLimitError2("Maximum OTP attempts exceeded. Please log in again.");
|
|
44115
44115
|
}
|
|
44116
44116
|
const storeStartedAt = now();
|
|
44117
44117
|
await store.set({
|
|
@@ -44125,7 +44125,7 @@ var auth$1 = () => ({
|
|
|
44125
44125
|
challengeId,
|
|
44126
44126
|
attempts: nextAttempts
|
|
44127
44127
|
});
|
|
44128
|
-
throw new
|
|
44128
|
+
throw new UnauthorizedError2("Invalid OTP code");
|
|
44129
44129
|
}
|
|
44130
44130
|
const deleteStartedAt = now();
|
|
44131
44131
|
await deleteChallenge(store, challengeId);
|
|
@@ -35,8 +35,23 @@ function _interopNamespaceDefault(e) {
|
|
|
35
35
|
return Object.freeze(n);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
39
|
-
var yup__namespace = /*#__PURE__*/_interopNamespaceDefault(yup);
|
|
38
|
+
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
39
|
+
var yup__namespace = /*#__PURE__*/_interopNamespaceDefault(yup);
|
|
40
|
+
|
|
41
|
+
const getApiErrorMessage = (error, fallback = 'Something went wrong')=>{
|
|
42
|
+
if (!error || typeof error !== 'object') {
|
|
43
|
+
return fallback;
|
|
44
|
+
}
|
|
45
|
+
const candidates = [
|
|
46
|
+
error?.data?.error?.message,
|
|
47
|
+
error?.data?.message,
|
|
48
|
+
error?.error?.message,
|
|
49
|
+
error?.message,
|
|
50
|
+
typeof error?.error === 'string' ? error.error : undefined
|
|
51
|
+
];
|
|
52
|
+
const message = candidates.find((value)=>typeof value === 'string' && value.trim().length > 0);
|
|
53
|
+
return message ?? fallback;
|
|
54
|
+
};
|
|
40
55
|
|
|
41
56
|
const OTP_LENGTH = 6;
|
|
42
57
|
const OTP_DIGIT_INPUT_STYLE = {
|
|
@@ -240,18 +255,18 @@ const Login = ({ children })=>{
|
|
|
240
255
|
React__namespace.useEffect(()=>{
|
|
241
256
|
document.title = 'Admin Dashboard';
|
|
242
257
|
}, []);
|
|
243
|
-
const handleLogin = async (body)=>{
|
|
244
|
-
setApiError(undefined);
|
|
245
|
-
const res = await adminLoginWithOtp({
|
|
246
|
-
...body,
|
|
247
|
-
deviceId: deviceId.getOrCreateDeviceId()
|
|
248
|
-
});
|
|
249
|
-
if ('error' in res) {
|
|
250
|
-
const message = res.error
|
|
251
|
-
if (camelCase(message).toLowerCase() === 'usernotactive') {
|
|
252
|
-
navigate('/auth/oops');
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
258
|
+
const handleLogin = async (body)=>{
|
|
259
|
+
setApiError(undefined);
|
|
260
|
+
const res = await adminLoginWithOtp({
|
|
261
|
+
...body,
|
|
262
|
+
deviceId: deviceId.getOrCreateDeviceId()
|
|
263
|
+
});
|
|
264
|
+
if ('error' in res) {
|
|
265
|
+
const message = getApiErrorMessage(res.error);
|
|
266
|
+
if (camelCase(message).toLowerCase() === 'usernotactive') {
|
|
267
|
+
navigate('/auth/oops');
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
255
270
|
setApiError(message);
|
|
256
271
|
} else {
|
|
257
272
|
setOtpStep({
|
|
@@ -267,15 +282,15 @@ const Login = ({ children })=>{
|
|
|
267
282
|
return;
|
|
268
283
|
}
|
|
269
284
|
setApiError(undefined);
|
|
270
|
-
const res = await verifyAdminLoginOtp({
|
|
271
|
-
challengeId: otpStep.challengeId,
|
|
272
|
-
code
|
|
273
|
-
});
|
|
274
|
-
if ('error' in res) {
|
|
275
|
-
setApiError(res.error
|
|
276
|
-
} else {
|
|
277
|
-
toggleNotification({
|
|
278
|
-
type: 'success',
|
|
285
|
+
const res = await verifyAdminLoginOtp({
|
|
286
|
+
challengeId: otpStep.challengeId,
|
|
287
|
+
code
|
|
288
|
+
});
|
|
289
|
+
if ('error' in res) {
|
|
290
|
+
setApiError(getApiErrorMessage(res.error));
|
|
291
|
+
} else {
|
|
292
|
+
toggleNotification({
|
|
293
|
+
type: 'success',
|
|
279
294
|
title: formatMessage({
|
|
280
295
|
id: 'Auth.notification.authenticated.title',
|
|
281
296
|
defaultMessage: 'Successfully authenticated'
|
|
@@ -295,14 +310,14 @@ const Login = ({ children })=>{
|
|
|
295
310
|
return;
|
|
296
311
|
}
|
|
297
312
|
setApiError(undefined);
|
|
298
|
-
const res = await resendAdminLoginOtp({
|
|
299
|
-
challengeId: otpStep.challengeId
|
|
300
|
-
});
|
|
301
|
-
if ('error' in res) {
|
|
302
|
-
setApiError(res.error
|
|
303
|
-
} else {
|
|
304
|
-
setOtpStep({
|
|
305
|
-
...otpStep,
|
|
313
|
+
const res = await resendAdminLoginOtp({
|
|
314
|
+
challengeId: otpStep.challengeId
|
|
315
|
+
});
|
|
316
|
+
if ('error' in res) {
|
|
317
|
+
setApiError(getApiErrorMessage(res.error));
|
|
318
|
+
} else {
|
|
319
|
+
setOtpStep({
|
|
320
|
+
...otpStep,
|
|
306
321
|
expiresAt: res.data.expiresAt,
|
|
307
322
|
maskedEmail: res.data.maskedEmail
|
|
308
323
|
});
|
|
@@ -13,8 +13,23 @@ import { useTypedDispatch } from '../../../core/store/hooks.mjs';
|
|
|
13
13
|
import { useNotification } from '../../../features/Notifications.mjs';
|
|
14
14
|
import { login as loginAction } from '../../../reducer.mjs';
|
|
15
15
|
import { useAdminLoginWithOtpMutation, useVerifyAdminLoginOtpMutation, useResendAdminLoginOtpMutation } from '../../../services/auth.mjs';
|
|
16
|
-
import { getOrCreateDeviceId } from '../../../utils/deviceId.mjs';
|
|
17
|
-
import { translatedErrors as errorsTrads } from '../../../utils/translatedErrors.mjs';
|
|
16
|
+
import { getOrCreateDeviceId } from '../../../utils/deviceId.mjs';
|
|
17
|
+
import { translatedErrors as errorsTrads } from '../../../utils/translatedErrors.mjs';
|
|
18
|
+
|
|
19
|
+
const getApiErrorMessage = (error, fallback = 'Something went wrong')=>{
|
|
20
|
+
if (!error || typeof error !== 'object') {
|
|
21
|
+
return fallback;
|
|
22
|
+
}
|
|
23
|
+
const candidates = [
|
|
24
|
+
error?.data?.error?.message,
|
|
25
|
+
error?.data?.message,
|
|
26
|
+
error?.error?.message,
|
|
27
|
+
error?.message,
|
|
28
|
+
typeof error?.error === 'string' ? error.error : undefined
|
|
29
|
+
];
|
|
30
|
+
const message = candidates.find((value)=>typeof value === 'string' && value.trim().length > 0);
|
|
31
|
+
return message ?? fallback;
|
|
32
|
+
};
|
|
18
33
|
|
|
19
34
|
const OTP_LENGTH = 6;
|
|
20
35
|
const OTP_DIGIT_INPUT_STYLE = {
|
|
@@ -218,18 +233,18 @@ const Login = ({ children })=>{
|
|
|
218
233
|
React.useEffect(()=>{
|
|
219
234
|
document.title = 'Admin Dashboard';
|
|
220
235
|
}, []);
|
|
221
|
-
const handleLogin = async (body)=>{
|
|
222
|
-
setApiError(undefined);
|
|
223
|
-
const res = await adminLoginWithOtp({
|
|
224
|
-
...body,
|
|
225
|
-
deviceId: getOrCreateDeviceId()
|
|
226
|
-
});
|
|
227
|
-
if ('error' in res) {
|
|
228
|
-
const message = res.error
|
|
229
|
-
if (camelCase(message).toLowerCase() === 'usernotactive') {
|
|
230
|
-
navigate('/auth/oops');
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
236
|
+
const handleLogin = async (body)=>{
|
|
237
|
+
setApiError(undefined);
|
|
238
|
+
const res = await adminLoginWithOtp({
|
|
239
|
+
...body,
|
|
240
|
+
deviceId: getOrCreateDeviceId()
|
|
241
|
+
});
|
|
242
|
+
if ('error' in res) {
|
|
243
|
+
const message = getApiErrorMessage(res.error);
|
|
244
|
+
if (camelCase(message).toLowerCase() === 'usernotactive') {
|
|
245
|
+
navigate('/auth/oops');
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
233
248
|
setApiError(message);
|
|
234
249
|
} else {
|
|
235
250
|
setOtpStep({
|
|
@@ -245,15 +260,15 @@ const Login = ({ children })=>{
|
|
|
245
260
|
return;
|
|
246
261
|
}
|
|
247
262
|
setApiError(undefined);
|
|
248
|
-
const res = await verifyAdminLoginOtp({
|
|
249
|
-
challengeId: otpStep.challengeId,
|
|
250
|
-
code
|
|
251
|
-
});
|
|
252
|
-
if ('error' in res) {
|
|
253
|
-
setApiError(res.error
|
|
254
|
-
} else {
|
|
255
|
-
toggleNotification({
|
|
256
|
-
type: 'success',
|
|
263
|
+
const res = await verifyAdminLoginOtp({
|
|
264
|
+
challengeId: otpStep.challengeId,
|
|
265
|
+
code
|
|
266
|
+
});
|
|
267
|
+
if ('error' in res) {
|
|
268
|
+
setApiError(getApiErrorMessage(res.error));
|
|
269
|
+
} else {
|
|
270
|
+
toggleNotification({
|
|
271
|
+
type: 'success',
|
|
257
272
|
title: formatMessage({
|
|
258
273
|
id: 'Auth.notification.authenticated.title',
|
|
259
274
|
defaultMessage: 'Successfully authenticated'
|
|
@@ -273,14 +288,14 @@ const Login = ({ children })=>{
|
|
|
273
288
|
return;
|
|
274
289
|
}
|
|
275
290
|
setApiError(undefined);
|
|
276
|
-
const res = await resendAdminLoginOtp({
|
|
277
|
-
challengeId: otpStep.challengeId
|
|
278
|
-
});
|
|
279
|
-
if ('error' in res) {
|
|
280
|
-
setApiError(res.error
|
|
281
|
-
} else {
|
|
282
|
-
setOtpStep({
|
|
283
|
-
...otpStep,
|
|
291
|
+
const res = await resendAdminLoginOtp({
|
|
292
|
+
challengeId: otpStep.challengeId
|
|
293
|
+
});
|
|
294
|
+
if ('error' in res) {
|
|
295
|
+
setApiError(getApiErrorMessage(res.error));
|
|
296
|
+
} else {
|
|
297
|
+
setOtpStep({
|
|
298
|
+
...otpStep,
|
|
284
299
|
expiresAt: res.data.expiresAt,
|
|
285
300
|
maskedEmail: res.data.maskedEmail
|
|
286
301
|
});
|