@everymatrix/player-step-up-auth 0.1.1 → 1.64.2
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/cjs/index.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{player-step-up-auth-2fac8df5.js → player-step-up-auth-f18f2787.js} +66 -7
- package/dist/cjs/player-step-up-auth.cjs.entry.js +1 -1
- package/dist/cjs/player-step-up-auth.cjs.js +1 -1
- package/dist/collection/components/player-step-up-auth/player-step-up-auth.js +73 -7
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{player-step-up-auth-009badea.js → player-step-up-auth-62cf8fb9.js} +66 -7
- package/dist/esm/player-step-up-auth.entry.js +1 -1
- package/dist/esm/player-step-up-auth.js +1 -1
- package/dist/player-step-up-auth/index.esm.js +1 -1
- package/dist/player-step-up-auth/p-849e390a.entry.js +1 -0
- package/dist/player-step-up-auth/p-f8171a4e.js +1 -0
- package/dist/player-step-up-auth/player-step-up-auth.esm.js +1 -1
- package/dist/types/components/player-step-up-auth/player-step-up-auth.d.ts +33 -0
- package/package.json +2 -3
- package/dist/player-step-up-auth/p-3b187b6e.entry.js +0 -1
- package/dist/player-step-up-auth/p-f97ac666.js +0 -1
package/dist/cjs/index.cjs.js
CHANGED
package/dist/cjs/loader.cjs.js
CHANGED
|
@@ -8,7 +8,7 @@ const appGlobals = require('./app-globals-3a1e7e63.js');
|
|
|
8
8
|
const defineCustomElements = async (win, options) => {
|
|
9
9
|
if (typeof window === 'undefined') return undefined;
|
|
10
10
|
await appGlobals.globalScripts();
|
|
11
|
-
return index.bootstrapLazy([["player-step-up-auth.cjs",[[1,"player-step-up-auth",{"mbSource":[513,"mb-source"],"clientStyling":[513,"client-styling"],"clientStylingUrl":[513,"client-styling-url"],"language":[513],"endpoint":[513],"userSession":[513,"user-session"],"translationUrl":[513,"translation-url"],"showPopup":[32],"otp":[32],"isLoading":[32],"config":[32],"timeLeft":[32],"expirationTime":[32],"serverTime":[32],"hasErrors":[32],"hasConfigErrors":[32],"errorMessage":[32],"token":[32],"showResendOtp":[32]},[[8,"stepUpAuthRequired","handleStepUpAuthEvent"]],{"translationUrl":["handleNewTranslations"],"clientStyling":["handleClientStylingChange"],"clientStylingUrl":["handleClientStylingUrlChange"]}]]]], options);
|
|
11
|
+
return index.bootstrapLazy([["player-step-up-auth.cjs",[[1,"player-step-up-auth",{"mbSource":[513,"mb-source"],"clientStyling":[513,"client-styling"],"clientStylingUrl":[513,"client-styling-url"],"language":[513],"endpoint":[513],"userSession":[513,"user-session"],"translationUrl":[513,"translation-url"],"showPopup":[32],"otp":[32],"isLoading":[32],"config":[32],"timeLeft":[32],"expirationTime":[32],"serverTime":[32],"hasErrors":[32],"hasConfigErrors":[32],"errorMessage":[32],"token":[32],"flow":[32],"showResendOtp":[32]},[[8,"stepUpAuthRequired","handleStepUpAuthEvent"],[8,"closePopup","handleCloseWidget"]],{"translationUrl":["handleNewTranslations"],"clientStyling":["handleClientStylingChange"],"clientStylingUrl":["handleClientStylingUrlChange"]}]]]], options);
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
exports.setNonce = index.setNonce;
|
|
@@ -270,6 +270,19 @@ const PlayerStepUpAuth = class {
|
|
|
270
270
|
setClientStylingURL(this.stylingContainer, this.clientStylingUrl);
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Handles the custom `stepUpAuthRequired` event fired on the window.
|
|
275
|
+
* This event typically signals that step-up authentication is required.
|
|
276
|
+
*
|
|
277
|
+
* @param event - A CustomEvent that contains authentication-related details.
|
|
278
|
+
*
|
|
279
|
+
* Expected `event.detail` structure:
|
|
280
|
+
* {
|
|
281
|
+
* 'x-step-up-required': true,
|
|
282
|
+
* 'x-step-up-token': string,
|
|
283
|
+
* 'flow': string
|
|
284
|
+
* }
|
|
285
|
+
*/
|
|
273
286
|
async handleStepUpAuthEvent(event) {
|
|
274
287
|
var _a;
|
|
275
288
|
if ((_a = event.detail) === null || _a === void 0 ? void 0 : _a['x-step-up-required']) {
|
|
@@ -278,9 +291,24 @@ const PlayerStepUpAuth = class {
|
|
|
278
291
|
this.errorMessage = '';
|
|
279
292
|
this.showPopup = true;
|
|
280
293
|
this.token = event.detail['x-step-up-token'];
|
|
294
|
+
this.flow = event.detail['flow'];
|
|
295
|
+
if (!this.token || !this.flow) {
|
|
296
|
+
this.isLoading = false;
|
|
297
|
+
this.hasConfigErrors = true;
|
|
298
|
+
this.errorMessage = translate('configError', this.language);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
281
301
|
await this.getConfig();
|
|
282
302
|
}
|
|
283
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Listens for the 'closePopup' event dispatched on the window
|
|
306
|
+
* and triggers popup closing logic. This allows other components
|
|
307
|
+
* or scripts to close the popup via a custom event.
|
|
308
|
+
*/
|
|
309
|
+
handleCloseWidget() {
|
|
310
|
+
this.closePopup();
|
|
311
|
+
}
|
|
284
312
|
/**
|
|
285
313
|
* Class constructor
|
|
286
314
|
*/
|
|
@@ -306,6 +334,7 @@ const PlayerStepUpAuth = class {
|
|
|
306
334
|
this.hasConfigErrors = false;
|
|
307
335
|
this.errorMessage = '';
|
|
308
336
|
this.token = '';
|
|
337
|
+
this.flow = '';
|
|
309
338
|
this.showResendOtp = false;
|
|
310
339
|
this.closePopup = this.closePopup.bind(this);
|
|
311
340
|
this.handleResendOtp = this.handleResendOtp.bind(this);
|
|
@@ -331,6 +360,14 @@ const PlayerStepUpAuth = class {
|
|
|
331
360
|
this.showResendOtp = false;
|
|
332
361
|
this.expirationTime = this.config.expirationTime;
|
|
333
362
|
this.serverTime = this.config.serverTime;
|
|
363
|
+
/**
|
|
364
|
+
* `numberOfValidateAttempts` indicates how many times the user has previously attempted to enter the OTP.
|
|
365
|
+
* A non-zero value means at least one failed attempt occurred, so an error message should be displayed.
|
|
366
|
+
*/
|
|
367
|
+
if (this.config.numberOfValidateAttempts !== 0) {
|
|
368
|
+
this.hasErrors = true;
|
|
369
|
+
this.errorMessage = translate('invalidOtp', this.language);
|
|
370
|
+
}
|
|
334
371
|
this.calculateTimeLeft();
|
|
335
372
|
this.startCountdown();
|
|
336
373
|
}
|
|
@@ -475,9 +512,7 @@ const PlayerStepUpAuth = class {
|
|
|
475
512
|
*/
|
|
476
513
|
handleResendOtp() {
|
|
477
514
|
// Emit an event to notify the system that OTP should be resent
|
|
478
|
-
const event = new CustomEvent('otpResendRequested'
|
|
479
|
-
detail: { message: 'User requested OTP resend' }
|
|
480
|
-
});
|
|
515
|
+
const event = new CustomEvent('otpResendRequested');
|
|
481
516
|
window.dispatchEvent(event);
|
|
482
517
|
}
|
|
483
518
|
/**
|
|
@@ -494,6 +529,30 @@ const PlayerStepUpAuth = class {
|
|
|
494
529
|
this.hasErrors = false;
|
|
495
530
|
this.errorMessage = '';
|
|
496
531
|
const otpValue = this.otp.join('');
|
|
532
|
+
if (this.flow === 'stateless') {
|
|
533
|
+
this.handleOtpStateless(otpValue);
|
|
534
|
+
}
|
|
535
|
+
if (this.flow === 'stateful') {
|
|
536
|
+
await this.handleOtpStateful(otpValue);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Handle stateless mode where we just need to send the otp value and the template will
|
|
541
|
+
* recall the endpoint with X-Step-Up-Token and X-Step-Up-Value (otp value)
|
|
542
|
+
*
|
|
543
|
+
* @param otpValue - Otp code.
|
|
544
|
+
*/
|
|
545
|
+
handleOtpStateless(otpValue) {
|
|
546
|
+
window.dispatchEvent(new CustomEvent('otpSubmitted', {
|
|
547
|
+
detail: { code: otpValue }
|
|
548
|
+
}));
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Handle the stateful mode where we need to call validate endpoint.
|
|
552
|
+
*
|
|
553
|
+
* @param otpValue - Otp code.
|
|
554
|
+
*/
|
|
555
|
+
async handleOtpStateful(otpValue) {
|
|
497
556
|
const url = new URL(`/api/v1/mfa/challenge/${this.token}/validate`, this.endpoint);
|
|
498
557
|
url.searchParams.append('input', otpValue);
|
|
499
558
|
try {
|
|
@@ -556,10 +615,10 @@ const PlayerStepUpAuth = class {
|
|
|
556
615
|
* Resets the authentication UI state.
|
|
557
616
|
*/
|
|
558
617
|
closePopup() {
|
|
618
|
+
this.hasErrors = false;
|
|
619
|
+
this.hasConfigErrors = false;
|
|
620
|
+
this.errorMessage = '';
|
|
559
621
|
this.showPopup = false;
|
|
560
|
-
window.dispatchEvent(new CustomEvent('popupClosed', {
|
|
561
|
-
detail: { message: 'User closed the popup' }
|
|
562
|
-
}));
|
|
563
622
|
}
|
|
564
623
|
/**
|
|
565
624
|
* Lifecycle method: Clean up event listeners when the component is removed
|
|
@@ -600,7 +659,7 @@ const PlayerStepUpAuth = class {
|
|
|
600
659
|
* Displays the OTP popup, input fields, timer, and action buttons.
|
|
601
660
|
*/
|
|
602
661
|
render() {
|
|
603
|
-
return (index.h("div", { key: '
|
|
662
|
+
return (index.h("div", { key: '737e607eec48c578b6714930c7b4a4df33949b67', ref: el => this.stylingContainer = el }, this.showPopup && (index.h("div", { key: '0edf00aceccbf267a7c026510e751787e423975b', class: "OtpPopupOverlay" }, index.h("div", { key: '6a410ac15a1db1eebff9e406a6ebb89bba398764', class: "OtpPopupContent" }, this.isLoading ? (index.h("div", { class: "OtpLoaderContainer" }, index.h("span", { class: "OtpLoader" }))) : (this.hasConfigErrors ? (index.h("div", { class: "OtpError" }, index.h("div", { class: "OtpErrorHeader" }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512" }, index.h("path", { d: "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" })), index.h("h2", null, translate('errorHeader', this.language))), index.h("p", null, this.errorMessage), index.h("button", { class: "OtpButton error", onClick: this.closePopup }, translate('close', this.language)))) : (index.h(index.Fragment, null, index.h("div", { class: "otp-description" }, index.h("p", null, translate('popupMessage', this.language)), this.hasErrors && index.h("p", { class: "OtpErrorMessage" }, this.errorMessage)), index.h("div", { class: "OtpFieldWrapper" }, index.h("h2", null, translate('otpHeading', this.language)), index.h("div", { class: "OtpField", ref: this.setOtpContainerRef }, this.otp.map((char, index$1) => {
|
|
604
663
|
const isHalfway = this.config.inputLength % 2 === 0 && index$1 === (this.config.inputLength / 2) - 1;
|
|
605
664
|
return (index.h("input", { key: index$1, ref: el => this.setOtpInputRef(el, index$1), id: `otp-input-${index$1}`, type: "text", class: `otp-box ${isHalfway ? 'space' : ''}`, maxLength: 1, value: char, onInput: (event) => this.handleOtpInput(event, index$1), onKeyDown: (event) => this.handleKeyDown(event, index$1), onPaste: (event) => this.handleOnPasteOtp(event), disabled: this.timeLeft <= 0 }));
|
|
606
665
|
})), index.h("div", { class: "otp-timer" }, this.formatTime(this.timeLeft), " ", translate('minutes', this.language))), index.h("div", { class: "OtpActionButtons" }, this.showResendOtp ? (index.h("button", { class: "OtpButton", onClick: this.handleResendOtp }, translate('resendOtp', this.language))) : (index.h("button", { class: "OtpButton", onClick: this.submitOtp, disabled: this.otp.join('').length !== this.config.inputLength }, translate('submit', this.language))), index.h("button", { class: "OtpButton", onClick: this.closePopup }, translate('close', this.language)))))))))));
|
|
@@ -19,7 +19,7 @@ var patchBrowser = () => {
|
|
|
19
19
|
|
|
20
20
|
patchBrowser().then(async (options) => {
|
|
21
21
|
await appGlobals.globalScripts();
|
|
22
|
-
return index.bootstrapLazy([["player-step-up-auth.cjs",[[1,"player-step-up-auth",{"mbSource":[513,"mb-source"],"clientStyling":[513,"client-styling"],"clientStylingUrl":[513,"client-styling-url"],"language":[513],"endpoint":[513],"userSession":[513,"user-session"],"translationUrl":[513,"translation-url"],"showPopup":[32],"otp":[32],"isLoading":[32],"config":[32],"timeLeft":[32],"expirationTime":[32],"serverTime":[32],"hasErrors":[32],"hasConfigErrors":[32],"errorMessage":[32],"token":[32],"showResendOtp":[32]},[[8,"stepUpAuthRequired","handleStepUpAuthEvent"]],{"translationUrl":["handleNewTranslations"],"clientStyling":["handleClientStylingChange"],"clientStylingUrl":["handleClientStylingUrlChange"]}]]]], options);
|
|
22
|
+
return index.bootstrapLazy([["player-step-up-auth.cjs",[[1,"player-step-up-auth",{"mbSource":[513,"mb-source"],"clientStyling":[513,"client-styling"],"clientStylingUrl":[513,"client-styling-url"],"language":[513],"endpoint":[513],"userSession":[513,"user-session"],"translationUrl":[513,"translation-url"],"showPopup":[32],"otp":[32],"isLoading":[32],"config":[32],"timeLeft":[32],"expirationTime":[32],"serverTime":[32],"hasErrors":[32],"hasConfigErrors":[32],"errorMessage":[32],"token":[32],"flow":[32],"showResendOtp":[32]},[[8,"stepUpAuthRequired","handleStepUpAuthEvent"],[8,"closePopup","handleCloseWidget"]],{"translationUrl":["handleNewTranslations"],"clientStyling":["handleClientStylingChange"],"clientStylingUrl":["handleClientStylingUrlChange"]}]]]], options);
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
exports.setNonce = index.setNonce;
|
|
@@ -31,6 +31,19 @@ export class PlayerStepUpAuth {
|
|
|
31
31
|
setClientStylingURL(this.stylingContainer, this.clientStylingUrl);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Handles the custom `stepUpAuthRequired` event fired on the window.
|
|
36
|
+
* This event typically signals that step-up authentication is required.
|
|
37
|
+
*
|
|
38
|
+
* @param event - A CustomEvent that contains authentication-related details.
|
|
39
|
+
*
|
|
40
|
+
* Expected `event.detail` structure:
|
|
41
|
+
* {
|
|
42
|
+
* 'x-step-up-required': true,
|
|
43
|
+
* 'x-step-up-token': string,
|
|
44
|
+
* 'flow': string
|
|
45
|
+
* }
|
|
46
|
+
*/
|
|
34
47
|
async handleStepUpAuthEvent(event) {
|
|
35
48
|
var _a;
|
|
36
49
|
if ((_a = event.detail) === null || _a === void 0 ? void 0 : _a['x-step-up-required']) {
|
|
@@ -39,9 +52,24 @@ export class PlayerStepUpAuth {
|
|
|
39
52
|
this.errorMessage = '';
|
|
40
53
|
this.showPopup = true;
|
|
41
54
|
this.token = event.detail['x-step-up-token'];
|
|
55
|
+
this.flow = event.detail['flow'];
|
|
56
|
+
if (!this.token || !this.flow) {
|
|
57
|
+
this.isLoading = false;
|
|
58
|
+
this.hasConfigErrors = true;
|
|
59
|
+
this.errorMessage = translate('configError', this.language);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
42
62
|
await this.getConfig();
|
|
43
63
|
}
|
|
44
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Listens for the 'closePopup' event dispatched on the window
|
|
67
|
+
* and triggers popup closing logic. This allows other components
|
|
68
|
+
* or scripts to close the popup via a custom event.
|
|
69
|
+
*/
|
|
70
|
+
handleCloseWidget() {
|
|
71
|
+
this.closePopup();
|
|
72
|
+
}
|
|
45
73
|
/**
|
|
46
74
|
* Class constructor
|
|
47
75
|
*/
|
|
@@ -66,6 +94,7 @@ export class PlayerStepUpAuth {
|
|
|
66
94
|
this.hasConfigErrors = false;
|
|
67
95
|
this.errorMessage = '';
|
|
68
96
|
this.token = '';
|
|
97
|
+
this.flow = '';
|
|
69
98
|
this.showResendOtp = false;
|
|
70
99
|
this.closePopup = this.closePopup.bind(this);
|
|
71
100
|
this.handleResendOtp = this.handleResendOtp.bind(this);
|
|
@@ -91,6 +120,14 @@ export class PlayerStepUpAuth {
|
|
|
91
120
|
this.showResendOtp = false;
|
|
92
121
|
this.expirationTime = this.config.expirationTime;
|
|
93
122
|
this.serverTime = this.config.serverTime;
|
|
123
|
+
/**
|
|
124
|
+
* `numberOfValidateAttempts` indicates how many times the user has previously attempted to enter the OTP.
|
|
125
|
+
* A non-zero value means at least one failed attempt occurred, so an error message should be displayed.
|
|
126
|
+
*/
|
|
127
|
+
if (this.config.numberOfValidateAttempts !== 0) {
|
|
128
|
+
this.hasErrors = true;
|
|
129
|
+
this.errorMessage = translate('invalidOtp', this.language);
|
|
130
|
+
}
|
|
94
131
|
this.calculateTimeLeft();
|
|
95
132
|
this.startCountdown();
|
|
96
133
|
}
|
|
@@ -235,9 +272,7 @@ export class PlayerStepUpAuth {
|
|
|
235
272
|
*/
|
|
236
273
|
handleResendOtp() {
|
|
237
274
|
// Emit an event to notify the system that OTP should be resent
|
|
238
|
-
const event = new CustomEvent('otpResendRequested'
|
|
239
|
-
detail: { message: 'User requested OTP resend' }
|
|
240
|
-
});
|
|
275
|
+
const event = new CustomEvent('otpResendRequested');
|
|
241
276
|
window.dispatchEvent(event);
|
|
242
277
|
}
|
|
243
278
|
/**
|
|
@@ -254,6 +289,30 @@ export class PlayerStepUpAuth {
|
|
|
254
289
|
this.hasErrors = false;
|
|
255
290
|
this.errorMessage = '';
|
|
256
291
|
const otpValue = this.otp.join('');
|
|
292
|
+
if (this.flow === 'stateless') {
|
|
293
|
+
this.handleOtpStateless(otpValue);
|
|
294
|
+
}
|
|
295
|
+
if (this.flow === 'stateful') {
|
|
296
|
+
await this.handleOtpStateful(otpValue);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Handle stateless mode where we just need to send the otp value and the template will
|
|
301
|
+
* recall the endpoint with X-Step-Up-Token and X-Step-Up-Value (otp value)
|
|
302
|
+
*
|
|
303
|
+
* @param otpValue - Otp code.
|
|
304
|
+
*/
|
|
305
|
+
handleOtpStateless(otpValue) {
|
|
306
|
+
window.dispatchEvent(new CustomEvent('otpSubmitted', {
|
|
307
|
+
detail: { code: otpValue }
|
|
308
|
+
}));
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Handle the stateful mode where we need to call validate endpoint.
|
|
312
|
+
*
|
|
313
|
+
* @param otpValue - Otp code.
|
|
314
|
+
*/
|
|
315
|
+
async handleOtpStateful(otpValue) {
|
|
257
316
|
const url = new URL(`/api/v1/mfa/challenge/${this.token}/validate`, this.endpoint);
|
|
258
317
|
url.searchParams.append('input', otpValue);
|
|
259
318
|
try {
|
|
@@ -316,10 +375,10 @@ export class PlayerStepUpAuth {
|
|
|
316
375
|
* Resets the authentication UI state.
|
|
317
376
|
*/
|
|
318
377
|
closePopup() {
|
|
378
|
+
this.hasErrors = false;
|
|
379
|
+
this.hasConfigErrors = false;
|
|
380
|
+
this.errorMessage = '';
|
|
319
381
|
this.showPopup = false;
|
|
320
|
-
window.dispatchEvent(new CustomEvent('popupClosed', {
|
|
321
|
-
detail: { message: 'User closed the popup' }
|
|
322
|
-
}));
|
|
323
382
|
}
|
|
324
383
|
/**
|
|
325
384
|
* Lifecycle method: Clean up event listeners when the component is removed
|
|
@@ -360,7 +419,7 @@ export class PlayerStepUpAuth {
|
|
|
360
419
|
* Displays the OTP popup, input fields, timer, and action buttons.
|
|
361
420
|
*/
|
|
362
421
|
render() {
|
|
363
|
-
return (h("div", { key: '
|
|
422
|
+
return (h("div", { key: '737e607eec48c578b6714930c7b4a4df33949b67', ref: el => this.stylingContainer = el }, this.showPopup && (h("div", { key: '0edf00aceccbf267a7c026510e751787e423975b', class: "OtpPopupOverlay" }, h("div", { key: '6a410ac15a1db1eebff9e406a6ebb89bba398764', class: "OtpPopupContent" }, this.isLoading ? (h("div", { class: "OtpLoaderContainer" }, h("span", { class: "OtpLoader" }))) : (this.hasConfigErrors ? (h("div", { class: "OtpError" }, h("div", { class: "OtpErrorHeader" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512" }, h("path", { d: "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" })), h("h2", null, translate('errorHeader', this.language))), h("p", null, this.errorMessage), h("button", { class: "OtpButton error", onClick: this.closePopup }, translate('close', this.language)))) : (h(Fragment, null, h("div", { class: "otp-description" }, h("p", null, translate('popupMessage', this.language)), this.hasErrors && h("p", { class: "OtpErrorMessage" }, this.errorMessage)), h("div", { class: "OtpFieldWrapper" }, h("h2", null, translate('otpHeading', this.language)), h("div", { class: "OtpField", ref: this.setOtpContainerRef }, this.otp.map((char, index) => {
|
|
364
423
|
const isHalfway = this.config.inputLength % 2 === 0 && index === (this.config.inputLength / 2) - 1;
|
|
365
424
|
return (h("input", { key: index, ref: el => this.setOtpInputRef(el, index), id: `otp-input-${index}`, type: "text", class: `otp-box ${isHalfway ? 'space' : ''}`, maxLength: 1, value: char, onInput: (event) => this.handleOtpInput(event, index), onKeyDown: (event) => this.handleKeyDown(event, index), onPaste: (event) => this.handleOnPasteOtp(event), disabled: this.timeLeft <= 0 }));
|
|
366
425
|
})), h("div", { class: "otp-timer" }, this.formatTime(this.timeLeft), " ", translate('minutes', this.language))), h("div", { class: "OtpActionButtons" }, this.showResendOtp ? (h("button", { class: "OtpButton", onClick: this.handleResendOtp }, translate('resendOtp', this.language))) : (h("button", { class: "OtpButton", onClick: this.submitOtp, disabled: this.otp.join('').length !== this.config.inputLength }, translate('submit', this.language))), h("button", { class: "OtpButton", onClick: this.closePopup }, translate('close', this.language)))))))))));
|
|
@@ -515,6 +574,7 @@ export class PlayerStepUpAuth {
|
|
|
515
574
|
"hasConfigErrors": {},
|
|
516
575
|
"errorMessage": {},
|
|
517
576
|
"token": {},
|
|
577
|
+
"flow": {},
|
|
518
578
|
"showResendOtp": {}
|
|
519
579
|
};
|
|
520
580
|
}
|
|
@@ -538,6 +598,12 @@ export class PlayerStepUpAuth {
|
|
|
538
598
|
"target": "window",
|
|
539
599
|
"capture": false,
|
|
540
600
|
"passive": false
|
|
601
|
+
}, {
|
|
602
|
+
"name": "closePopup",
|
|
603
|
+
"method": "handleCloseWidget",
|
|
604
|
+
"target": "window",
|
|
605
|
+
"capture": false,
|
|
606
|
+
"passive": false
|
|
541
607
|
}];
|
|
542
608
|
}
|
|
543
609
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { P as PlayerStepUpAuth } from './player-step-up-auth-
|
|
1
|
+
export { P as PlayerStepUpAuth } from './player-step-up-auth-62cf8fb9.js';
|
|
2
2
|
import './index-c6eee6d8.js';
|
package/dist/esm/loader.js
CHANGED
|
@@ -5,7 +5,7 @@ import { g as globalScripts } from './app-globals-0f993ce5.js';
|
|
|
5
5
|
const defineCustomElements = async (win, options) => {
|
|
6
6
|
if (typeof window === 'undefined') return undefined;
|
|
7
7
|
await globalScripts();
|
|
8
|
-
return bootstrapLazy([["player-step-up-auth",[[1,"player-step-up-auth",{"mbSource":[513,"mb-source"],"clientStyling":[513,"client-styling"],"clientStylingUrl":[513,"client-styling-url"],"language":[513],"endpoint":[513],"userSession":[513,"user-session"],"translationUrl":[513,"translation-url"],"showPopup":[32],"otp":[32],"isLoading":[32],"config":[32],"timeLeft":[32],"expirationTime":[32],"serverTime":[32],"hasErrors":[32],"hasConfigErrors":[32],"errorMessage":[32],"token":[32],"showResendOtp":[32]},[[8,"stepUpAuthRequired","handleStepUpAuthEvent"]],{"translationUrl":["handleNewTranslations"],"clientStyling":["handleClientStylingChange"],"clientStylingUrl":["handleClientStylingUrlChange"]}]]]], options);
|
|
8
|
+
return bootstrapLazy([["player-step-up-auth",[[1,"player-step-up-auth",{"mbSource":[513,"mb-source"],"clientStyling":[513,"client-styling"],"clientStylingUrl":[513,"client-styling-url"],"language":[513],"endpoint":[513],"userSession":[513,"user-session"],"translationUrl":[513,"translation-url"],"showPopup":[32],"otp":[32],"isLoading":[32],"config":[32],"timeLeft":[32],"expirationTime":[32],"serverTime":[32],"hasErrors":[32],"hasConfigErrors":[32],"errorMessage":[32],"token":[32],"flow":[32],"showResendOtp":[32]},[[8,"stepUpAuthRequired","handleStepUpAuthEvent"],[8,"closePopup","handleCloseWidget"]],{"translationUrl":["handleNewTranslations"],"clientStyling":["handleClientStylingChange"],"clientStylingUrl":["handleClientStylingUrlChange"]}]]]], options);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export { defineCustomElements };
|
|
@@ -268,6 +268,19 @@ const PlayerStepUpAuth = class {
|
|
|
268
268
|
setClientStylingURL(this.stylingContainer, this.clientStylingUrl);
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Handles the custom `stepUpAuthRequired` event fired on the window.
|
|
273
|
+
* This event typically signals that step-up authentication is required.
|
|
274
|
+
*
|
|
275
|
+
* @param event - A CustomEvent that contains authentication-related details.
|
|
276
|
+
*
|
|
277
|
+
* Expected `event.detail` structure:
|
|
278
|
+
* {
|
|
279
|
+
* 'x-step-up-required': true,
|
|
280
|
+
* 'x-step-up-token': string,
|
|
281
|
+
* 'flow': string
|
|
282
|
+
* }
|
|
283
|
+
*/
|
|
271
284
|
async handleStepUpAuthEvent(event) {
|
|
272
285
|
var _a;
|
|
273
286
|
if ((_a = event.detail) === null || _a === void 0 ? void 0 : _a['x-step-up-required']) {
|
|
@@ -276,9 +289,24 @@ const PlayerStepUpAuth = class {
|
|
|
276
289
|
this.errorMessage = '';
|
|
277
290
|
this.showPopup = true;
|
|
278
291
|
this.token = event.detail['x-step-up-token'];
|
|
292
|
+
this.flow = event.detail['flow'];
|
|
293
|
+
if (!this.token || !this.flow) {
|
|
294
|
+
this.isLoading = false;
|
|
295
|
+
this.hasConfigErrors = true;
|
|
296
|
+
this.errorMessage = translate('configError', this.language);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
279
299
|
await this.getConfig();
|
|
280
300
|
}
|
|
281
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* Listens for the 'closePopup' event dispatched on the window
|
|
304
|
+
* and triggers popup closing logic. This allows other components
|
|
305
|
+
* or scripts to close the popup via a custom event.
|
|
306
|
+
*/
|
|
307
|
+
handleCloseWidget() {
|
|
308
|
+
this.closePopup();
|
|
309
|
+
}
|
|
282
310
|
/**
|
|
283
311
|
* Class constructor
|
|
284
312
|
*/
|
|
@@ -304,6 +332,7 @@ const PlayerStepUpAuth = class {
|
|
|
304
332
|
this.hasConfigErrors = false;
|
|
305
333
|
this.errorMessage = '';
|
|
306
334
|
this.token = '';
|
|
335
|
+
this.flow = '';
|
|
307
336
|
this.showResendOtp = false;
|
|
308
337
|
this.closePopup = this.closePopup.bind(this);
|
|
309
338
|
this.handleResendOtp = this.handleResendOtp.bind(this);
|
|
@@ -329,6 +358,14 @@ const PlayerStepUpAuth = class {
|
|
|
329
358
|
this.showResendOtp = false;
|
|
330
359
|
this.expirationTime = this.config.expirationTime;
|
|
331
360
|
this.serverTime = this.config.serverTime;
|
|
361
|
+
/**
|
|
362
|
+
* `numberOfValidateAttempts` indicates how many times the user has previously attempted to enter the OTP.
|
|
363
|
+
* A non-zero value means at least one failed attempt occurred, so an error message should be displayed.
|
|
364
|
+
*/
|
|
365
|
+
if (this.config.numberOfValidateAttempts !== 0) {
|
|
366
|
+
this.hasErrors = true;
|
|
367
|
+
this.errorMessage = translate('invalidOtp', this.language);
|
|
368
|
+
}
|
|
332
369
|
this.calculateTimeLeft();
|
|
333
370
|
this.startCountdown();
|
|
334
371
|
}
|
|
@@ -473,9 +510,7 @@ const PlayerStepUpAuth = class {
|
|
|
473
510
|
*/
|
|
474
511
|
handleResendOtp() {
|
|
475
512
|
// Emit an event to notify the system that OTP should be resent
|
|
476
|
-
const event = new CustomEvent('otpResendRequested'
|
|
477
|
-
detail: { message: 'User requested OTP resend' }
|
|
478
|
-
});
|
|
513
|
+
const event = new CustomEvent('otpResendRequested');
|
|
479
514
|
window.dispatchEvent(event);
|
|
480
515
|
}
|
|
481
516
|
/**
|
|
@@ -492,6 +527,30 @@ const PlayerStepUpAuth = class {
|
|
|
492
527
|
this.hasErrors = false;
|
|
493
528
|
this.errorMessage = '';
|
|
494
529
|
const otpValue = this.otp.join('');
|
|
530
|
+
if (this.flow === 'stateless') {
|
|
531
|
+
this.handleOtpStateless(otpValue);
|
|
532
|
+
}
|
|
533
|
+
if (this.flow === 'stateful') {
|
|
534
|
+
await this.handleOtpStateful(otpValue);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Handle stateless mode where we just need to send the otp value and the template will
|
|
539
|
+
* recall the endpoint with X-Step-Up-Token and X-Step-Up-Value (otp value)
|
|
540
|
+
*
|
|
541
|
+
* @param otpValue - Otp code.
|
|
542
|
+
*/
|
|
543
|
+
handleOtpStateless(otpValue) {
|
|
544
|
+
window.dispatchEvent(new CustomEvent('otpSubmitted', {
|
|
545
|
+
detail: { code: otpValue }
|
|
546
|
+
}));
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Handle the stateful mode where we need to call validate endpoint.
|
|
550
|
+
*
|
|
551
|
+
* @param otpValue - Otp code.
|
|
552
|
+
*/
|
|
553
|
+
async handleOtpStateful(otpValue) {
|
|
495
554
|
const url = new URL(`/api/v1/mfa/challenge/${this.token}/validate`, this.endpoint);
|
|
496
555
|
url.searchParams.append('input', otpValue);
|
|
497
556
|
try {
|
|
@@ -554,10 +613,10 @@ const PlayerStepUpAuth = class {
|
|
|
554
613
|
* Resets the authentication UI state.
|
|
555
614
|
*/
|
|
556
615
|
closePopup() {
|
|
616
|
+
this.hasErrors = false;
|
|
617
|
+
this.hasConfigErrors = false;
|
|
618
|
+
this.errorMessage = '';
|
|
557
619
|
this.showPopup = false;
|
|
558
|
-
window.dispatchEvent(new CustomEvent('popupClosed', {
|
|
559
|
-
detail: { message: 'User closed the popup' }
|
|
560
|
-
}));
|
|
561
620
|
}
|
|
562
621
|
/**
|
|
563
622
|
* Lifecycle method: Clean up event listeners when the component is removed
|
|
@@ -598,7 +657,7 @@ const PlayerStepUpAuth = class {
|
|
|
598
657
|
* Displays the OTP popup, input fields, timer, and action buttons.
|
|
599
658
|
*/
|
|
600
659
|
render() {
|
|
601
|
-
return (h("div", { key: '
|
|
660
|
+
return (h("div", { key: '737e607eec48c578b6714930c7b4a4df33949b67', ref: el => this.stylingContainer = el }, this.showPopup && (h("div", { key: '0edf00aceccbf267a7c026510e751787e423975b', class: "OtpPopupOverlay" }, h("div", { key: '6a410ac15a1db1eebff9e406a6ebb89bba398764', class: "OtpPopupContent" }, this.isLoading ? (h("div", { class: "OtpLoaderContainer" }, h("span", { class: "OtpLoader" }))) : (this.hasConfigErrors ? (h("div", { class: "OtpError" }, h("div", { class: "OtpErrorHeader" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512" }, h("path", { d: "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" })), h("h2", null, translate('errorHeader', this.language))), h("p", null, this.errorMessage), h("button", { class: "OtpButton error", onClick: this.closePopup }, translate('close', this.language)))) : (h(Fragment, null, h("div", { class: "otp-description" }, h("p", null, translate('popupMessage', this.language)), this.hasErrors && h("p", { class: "OtpErrorMessage" }, this.errorMessage)), h("div", { class: "OtpFieldWrapper" }, h("h2", null, translate('otpHeading', this.language)), h("div", { class: "OtpField", ref: this.setOtpContainerRef }, this.otp.map((char, index) => {
|
|
602
661
|
const isHalfway = this.config.inputLength % 2 === 0 && index === (this.config.inputLength / 2) - 1;
|
|
603
662
|
return (h("input", { key: index, ref: el => this.setOtpInputRef(el, index), id: `otp-input-${index}`, type: "text", class: `otp-box ${isHalfway ? 'space' : ''}`, maxLength: 1, value: char, onInput: (event) => this.handleOtpInput(event, index), onKeyDown: (event) => this.handleKeyDown(event, index), onPaste: (event) => this.handleOnPasteOtp(event), disabled: this.timeLeft <= 0 }));
|
|
604
663
|
})), h("div", { class: "otp-timer" }, this.formatTime(this.timeLeft), " ", translate('minutes', this.language))), h("div", { class: "OtpActionButtons" }, this.showResendOtp ? (h("button", { class: "OtpButton", onClick: this.handleResendOtp }, translate('resendOtp', this.language))) : (h("button", { class: "OtpButton", onClick: this.submitOtp, disabled: this.otp.join('').length !== this.config.inputLength }, translate('submit', this.language))), h("button", { class: "OtpButton", onClick: this.closePopup }, translate('close', this.language)))))))))));
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { P as player_step_up_auth } from './player-step-up-auth-
|
|
1
|
+
export { P as player_step_up_auth } from './player-step-up-auth-62cf8fb9.js';
|
|
2
2
|
import './index-c6eee6d8.js';
|
|
@@ -16,5 +16,5 @@ var patchBrowser = () => {
|
|
|
16
16
|
|
|
17
17
|
patchBrowser().then(async (options) => {
|
|
18
18
|
await globalScripts();
|
|
19
|
-
return bootstrapLazy([["player-step-up-auth",[[1,"player-step-up-auth",{"mbSource":[513,"mb-source"],"clientStyling":[513,"client-styling"],"clientStylingUrl":[513,"client-styling-url"],"language":[513],"endpoint":[513],"userSession":[513,"user-session"],"translationUrl":[513,"translation-url"],"showPopup":[32],"otp":[32],"isLoading":[32],"config":[32],"timeLeft":[32],"expirationTime":[32],"serverTime":[32],"hasErrors":[32],"hasConfigErrors":[32],"errorMessage":[32],"token":[32],"showResendOtp":[32]},[[8,"stepUpAuthRequired","handleStepUpAuthEvent"]],{"translationUrl":["handleNewTranslations"],"clientStyling":["handleClientStylingChange"],"clientStylingUrl":["handleClientStylingUrlChange"]}]]]], options);
|
|
19
|
+
return bootstrapLazy([["player-step-up-auth",[[1,"player-step-up-auth",{"mbSource":[513,"mb-source"],"clientStyling":[513,"client-styling"],"clientStylingUrl":[513,"client-styling-url"],"language":[513],"endpoint":[513],"userSession":[513,"user-session"],"translationUrl":[513,"translation-url"],"showPopup":[32],"otp":[32],"isLoading":[32],"config":[32],"timeLeft":[32],"expirationTime":[32],"serverTime":[32],"hasErrors":[32],"hasConfigErrors":[32],"errorMessage":[32],"token":[32],"flow":[32],"showResendOtp":[32]},[[8,"stepUpAuthRequired","handleStepUpAuthEvent"],[8,"closePopup","handleCloseWidget"]],{"translationUrl":["handleNewTranslations"],"clientStyling":["handleClientStylingChange"],"clientStylingUrl":["handleClientStylingUrlChange"]}]]]], options);
|
|
20
20
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{P as PlayerStepUpAuth}from"./p-
|
|
1
|
+
export{P as PlayerStepUpAuth}from"./p-f8171a4e.js";import"./p-c6a4faff.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{P as player_step_up_auth}from"./p-f8171a4e.js";import"./p-c6a4faff.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e,h as t,F as i,g as r}from"./p-c6a4faff.js";function o(e,t){if(e){const i=document.createElement("style");i.innerHTML=t,e.appendChild(i)}}function s(e,t){const i=new URL(t);fetch(i.href).then((e=>e.text())).then((t=>{const i=document.createElement("style");i.innerHTML=t,e&&e.appendChild(i)})).catch((e=>{console.error("There was an error while trying to load client styling from URL",e)}))}const n={en:{popupMessage:"Please enter the security code received on your email address to perform the update.",minutes:"minutes",errorHeader:"Error",configError:"Unable to load OTP data. Please try again later.",otpHeading:"Enter OTP",resendOtp:"Resent OTP",submit:"Submit",close:"Close",invalidOtp:"The code you've sent is not valid. Please try again.",accountBlocked:"Too many attempts for OTP. Your account has been blocked for one hour.",submissionError:"Something went wrong. Please try again."},ro:{popupMessage:"Introduceți codul de securitate primit pe adresa dvs. de e-mail pentru a efectua actualizarea.",minutes:"minute",errorHeader:"Eroare",configError:"Nu s-a putut încărca datele OTP. Vă rugăm să încercați din nou mai târziu.",otpHeading:"Introduceți OTP",resendOtp:"Retrimitere OTP",submit:"Trimite",close:"Închide",invalidOtp:"Codul introdus nu este valid. Vă rugăm să încercați din nou.",accountBlocked:"Prea multe încercări de OTP. Contul dvs. a fost blocat timp de o oră.",submissionError:"Ceva a mers prost. Vă rugăm să încercați din nou."},fr:{popupMessage:"Veuillez entrer le code de sécurité reçu sur votre adresse e-mail pour effectuer la mise à jour.",minutes:"minutes",errorHeader:"Erreur",configError:"Impossible de charger les données OTP. Veuillez réessayer plus tard.",otpHeading:"Entrez OTP",resendOtp:"Renvoyer OTP",submit:"Soumettre",close:"Fermer",invalidOtp:"Le code que vous avez saisi n’est pas valide. Veuillez réessayer.",accountBlocked:"Trop de tentatives OTP. Votre compte a été bloqué pendant une heure.",submissionError:"Quelque chose s'est mal passé. Veuillez réessayer."},hu:{popupMessage:"Kérjük, adja meg az e-mail címére küldött biztonsági kódot a frissítés végrehajtásához.",minutes:"perc",errorHeader:"Hiba",configError:"Nem sikerült betölteni az OTP adatokat. Kérjük, próbálja újra később.",otpHeading:"OTP megadása",resendOtp:"Újraküldés",submit:"Beküldés",close:"Bezárás",invalidOtp:"A megadott kód érvénytelen. Kérjük, próbálja újra.",accountBlocked:"Túl sok OTP próbálkozás. A fiókja egy órára zárolva lett.",submissionError:"Valami hiba történt. Kérjük, próbálja újra."},tr:{popupMessage:"Güncellemeyi gerçekleştirmek için e-posta adresinize gelen güvenlik kodunu girin.",minutes:"dakika",errorHeader:"Hata",configError:"OTP verisi yüklenemedi. Lütfen daha sonra tekrar deneyin.",otpHeading:"OTP Girin",resendOtp:"OTP'yi Yeniden Gönder",submit:"Gönder",close:"Kapat",invalidOtp:"Gönderdiğiniz kod geçersiz. Lütfen tekrar deneyin.",accountBlocked:"Çok fazla OTP denemesi yapıldı. Hesabınız bir saat boyunca kilitlendi.",submissionError:"Bir şeyler yanlış gitti. Lütfen tekrar deneyin."},el:{popupMessage:"Παρακαλώ εισάγετε τον κωδικό ασφαλείας που λάβατε στο email σας για να ολοκληρώσετε την ενημέρωση.",minutes:"λεπτά",errorHeader:"Σφάλμα",configError:"Δεν ήταν δυνατή η φόρτωση των δεδομένων OTP. Παρακαλούμε προσπαθήστε ξανά αργότερα.",otpHeading:"Εισαγωγή OTP",resendOtp:"Αποστολή ξανά OTP",submit:"Υποβολή",close:"Κλείσιμο",invalidOtp:"Ο κωδικός που εισαγάγατε δεν είναι έγκυρος. Παρακαλώ προσπαθήστε ξανά.",accountBlocked:"Πάρα πολλές προσπάθειες OTP. Ο λογαριασμός σας έχει αποκλειστεί για μία ώρα.",submissionError:"Κάτι πήγε στραβά. Παρακαλώ προσπαθήστε ξανά."},es:{popupMessage:"Por favor, introduzca el código de seguridad recibido en su correo electrónico para realizar la actualización.",minutes:"minutos",errorHeader:"Error",configError:"No se pudo cargar los datos del OTP. Por favor, inténtelo de nuevo más tarde.",otpHeading:"Introducir OTP",resendOtp:"Reenviar OTP",submit:"Enviar",close:"Cerrar",invalidOtp:"El código que ingresaste no es válido. Por favor, inténtalo de nuevo.",accountBlocked:"Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.",submissionError:"Algo salió mal. Por favor, inténtelo de nuevo."},pt:{popupMessage:"Por favor, insira o código de segurança recebido no seu e-mail para realizar a atualização.",minutes:"minutos",errorHeader:"Erro",configError:"Não foi possível carregar os dados do OTP. Tente novamente mais tarde.",otpHeading:"Insira o OTP",resendOtp:"Reenviar OTP",submit:"Enviar",close:"Fechar",invalidOtp:"O código inserido não é válido. Por favor, tente novamente.",accountBlocked:"Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.",submissionError:"Algo deu errado. Por favor, tente novamente."},hr:{popupMessage:"Unesite sigurnosni kod primljen na vašu e-mail adresu kako biste izvršili ažuriranje.",minutes:"minute",errorHeader:"Greška",configError:"Nije moguće učitati OTP podatke. Pokušajte ponovno kasnije.",otpHeading:"Unesite OTP",resendOtp:"Ponovno pošalji OTP",submit:"Pošalji",close:"Zatvori",invalidOtp:"Uneseni kod nije valjan. Molimo pokušajte ponovo.",accountBlocked:"Previše pokušaja unosa OTP-a. Vaš račun je blokiran na jedan sat.",submissionError:"Nešto je pošlo po zlu. Molimo pokušajte ponovo."},de:{popupMessage:"Bitte geben Sie den Sicherheitscode ein, den Sie an Ihre E-Mail-Adresse erhalten haben, um das Update durchzuführen.",minutes:"Minuten",errorHeader:"Fehler",configError:"OTP-Daten konnten nicht geladen werden. Bitte versuchen Sie es später erneut.",otpHeading:"OTP eingeben",resendOtp:"OTP erneut senden",submit:"Absenden",close:"Schließen",invalidOtp:"Der eingegebene Code ist ungültig. Bitte versuchen Sie es erneut.",accountBlocked:"Zu viele OTP-Versuche. Ihr Konto wurde für eine Stunde gesperrt.",submissionError:"Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut."},"es-mx":{popupMessage:"Por favor, ingrese el código de seguridad recibido en su correo electrónico para realizar la actualización.",minutes:"minutos",errorHeader:"Error",configError:"No se pudieron cargar los datos del OTP. Inténtelo de nuevo más tarde.",otpHeading:"Ingrese OTP",resendOtp:"Reenviar OTP",submit:"Enviar",close:"Cerrar",invalidOtp:"El código que ingresó no es válido. Inténtelo de nuevo.",accountBlocked:"Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.",submissionError:"Algo salió mal. Por favor, inténtelo de nuevo."},"pt-br":{popupMessage:"Por favor, digite o código de segurança recebido no seu e-mail para realizar a atualização.",minutes:"minutos",errorHeader:"Erro",configError:"Não foi possível carregar os dados do OTP. Tente novamente mais tarde.",otpHeading:"Digite o OTP",resendOtp:"Reenviar OTP",submit:"Enviar",close:"Fechar",invalidOtp:"O código informado não é válido. Tente novamente.",accountBlocked:"Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.",submissionError:"Algo deu errado. Por favor, tente novamente."}},a=e=>new Promise((t=>{fetch(e).then((e=>e.json())).then((e=>{Object.keys(e).forEach((t=>{for(let i in e[t])n[t][i]=e[t][i]})),t(!0)}))})),l=(e,t)=>n[void 0!==t?t:"en"][e],d=class{handleNewTranslations(){a(this.translationUrl)}handleClientStylingChange(e,t){e!==t&&o(this.el,this.clientStyling)}handleClientStylingUrlChange(e,t){e!=t&&this.clientStylingUrl&&s(this.stylingContainer,this.clientStylingUrl)}async handleStepUpAuthEvent(e){var t;if(null===(t=e.detail)||void 0===t?void 0:t["x-step-up-required"]){if(this.hasConfigErrors=!1,this.hasErrors=!1,this.errorMessage="",this.showPopup=!0,this.token=e.detail["x-step-up-token"],this.flow=e.detail.flow,!this.token||!this.flow)return this.isLoading=!1,this.hasConfigErrors=!0,void(this.errorMessage=l("configError",this.language));await this.getConfig()}}handleCloseWidget(){this.closePopup()}constructor(t){e(this,t),this.otpInputs=[],this.countdownTimer=null,this.mbSource=void 0,this.clientStyling=void 0,this.clientStylingUrl=void 0,this.language="en",this.endpoint=void 0,this.userSession=void 0,this.translationUrl="",this.showPopup=!1,this.otp=void 0,this.isLoading=!0,this.config=null,this.timeLeft=0,this.expirationTime="",this.serverTime="",this.hasErrors=!1,this.hasConfigErrors=!1,this.errorMessage="",this.token="",this.flow="",this.showResendOtp=!1,this.closePopup=this.closePopup.bind(this),this.handleResendOtp=this.handleResendOtp.bind(this),this.submitOtp=this.submitOtp.bind(this),this.setOtpContainerRef=this.setOtpContainerRef.bind(this)}async getConfig(){if(this.endpoint)try{const e=new URL(`/api/v1/mfa/challenge/${this.token}/config`,this.endpoint);this.isLoading=!0;const t=await fetch(e.href);if(!t.ok)throw new Error(`HTTP error! Status: ${t.status}`);this.config=await t.json(),this.otp=new Array(this.config.inputLength).fill(""),this.isLoading=!1,this.showResendOtp=!1,this.expirationTime=this.config.expirationTime,this.serverTime=this.config.serverTime,0!==this.config.numberOfValidateAttempts&&(this.hasErrors=!0,this.errorMessage=l("invalidOtp",this.language)),this.calculateTimeLeft(),this.startCountdown()}catch(e){this.isLoading=!1,this.hasConfigErrors=!0,this.errorMessage=l("configError",this.language),console.error("Error loading 2FA config:",e)}}calculateTimeLeft(){const e=new Date(this.expirationTime),t=new Date(this.serverTime);this.currentTime||(this.currentTime=new Date);const i=t.getTime()-this.currentTime.getTime(),r=new Date(this.currentTime.getTime()+i);this.timeLeft=Math.floor((e.getTime()-r.getTime())/1e3)}startCountdown(){this.countdownTimer&&clearInterval(this.countdownTimer),this.countdownTimer=setInterval((()=>{this.timeLeft>0?this.timeLeft-=1:(clearInterval(this.countdownTimer),this.countdownTimer=null,this.showResendOtp=!0)}),1e3)}formatTime(e){const t=e%60;return`${Math.floor(e/60).toString().padStart(2,"0")}:${t.toString().padStart(2,"0")}`}setOtpContainerRef(e){e&&(this.otpContainer=e)}setOtpInputRef(e,t){e&&(this.otpInputs[t]=e)}handleOnPasteOtp(e){var t;e.preventDefault();const i=null===(t=e.clipboardData)||void 0===t?void 0:t.getData("text").trim();if(!i)return;const r=i.slice(0,this.config.inputLength).split("");this.otp=[...r,...new Array(this.config.inputLength-r.length).fill("")];const o=Array.from(this.otpContainer.children);if(o){r.forEach(((e,t)=>{o[t].value=e}));const e=o[r.length-1];null==e||e.focus(),r.length===this.config.inputLength&&this.submitOtp()}}handleOtpInput(e,t){const i=e.target;let r=i.value.replace(/[^0-9a-zA-Z]/gi,"").toUpperCase();if(i.value=r.charAt(0),!r)return;this.otp[t]=r[0];const o=this.otpInputs[t+1];null==o||o.focus()}handleKeyDown(e,t){if("Backspace"===e.key){this.otp[t]="",this.otpInputs[t].value="";const e=this.otpInputs[t-1];null==e||e.focus()}}handleResendOtp(){const e=new CustomEvent("otpResendRequested");window.dispatchEvent(e)}async submitOtp(){if(this.otp.join("").length!==this.config.inputLength)return this.hasErrors=!0,void(this.errorMessage=l("invalidOtp",this.language));this.isLoading=!0,this.hasErrors=!1,this.errorMessage="";const e=this.otp.join("");"stateless"===this.flow&&this.handleOtpStateless(e),"stateful"===this.flow&&await this.handleOtpStateful(e)}handleOtpStateless(e){window.dispatchEvent(new CustomEvent("otpSubmitted",{detail:{code:e}}))}async handleOtpStateful(e){const t=new URL(`/api/v1/mfa/challenge/${this.token}/validate`,this.endpoint);t.searchParams.append("input",e);try{const e=await fetch(t.href,{method:"POST"});if(200===e.status)return void this.handleSuccess();const i=await e.json();throw new Error(i.message)}catch(e){if("gm.multifactorauthentication.challenge"===e.message){if(this.config.numberOfValidateAttempts===this.config.maxValidationAttempts-1){const e=new Date(this.serverTime);e.setHours(e.getHours()+1);const t=e.toISOString().slice(0,16).replace("T"," ");return window.postMessage({type:"SetPlayerAccountTimeout",timeoutSelected:"CoolOffUntilSelectedDate",timeoutExpiryDate:t},window.location.href),window.postMessage({type:"WidgetNotification",data:{type:"error",message:l("accountBlocked",this.language)}},window.location.href),void this.closePopup()}return this.hasErrors=!0,this.errorMessage=l("invalidOtp",this.language),void this.getConfig()}console.error("OTP submission failed:",e),this.hasErrors=!0,this.errorMessage=l("submissionError",this.language)}finally{this.isLoading=!1}}handleSuccess(){window.dispatchEvent(new CustomEvent("otpSuccess",{detail:{message:"User successfully authenticated"}})),this.closePopup()}closePopup(){this.hasErrors=!1,this.hasConfigErrors=!1,this.errorMessage="",this.showPopup=!1}disconnectedCallback(){var e;this.countdownTimer&&clearInterval(this.countdownTimer),null===(e=this.stylingSubscription)||void 0===e||e.unsubscribe()}async componentWillLoad(){this.translationUrl.length>2&&await a(this.translationUrl)}componentDidLoad(){this.stylingContainer&&(null!=window.emMessageBuss?function(e,t){if(window.emMessageBus){const i=document.createElement("style");window.emMessageBus.subscribe(t,(t=>{i.innerHTML=t,e&&e.appendChild(i)}))}}(this.stylingContainer,`${this.mbSource}.Style`):(this.clientStyling&&o(this.stylingContainer,this.clientStyling),this.clientStylingUrl&&s(this.stylingContainer,this.clientStylingUrl)))}render(){return t("div",{key:"737e607eec48c578b6714930c7b4a4df33949b67",ref:e=>this.stylingContainer=e},this.showPopup&&t("div",{key:"0edf00aceccbf267a7c026510e751787e423975b",class:"OtpPopupOverlay"},t("div",{key:"6a410ac15a1db1eebff9e406a6ebb89bba398764",class:"OtpPopupContent"},this.isLoading?t("div",{class:"OtpLoaderContainer"},t("span",{class:"OtpLoader"})):this.hasConfigErrors?t("div",{class:"OtpError"},t("div",{class:"OtpErrorHeader"},t("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512"},t("path",{d:"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"})),t("h2",null,l("errorHeader",this.language))),t("p",null,this.errorMessage),t("button",{class:"OtpButton error",onClick:this.closePopup},l("close",this.language))):t(i,null,t("div",{class:"otp-description"},t("p",null,l("popupMessage",this.language)),this.hasErrors&&t("p",{class:"OtpErrorMessage"},this.errorMessage)),t("div",{class:"OtpFieldWrapper"},t("h2",null,l("otpHeading",this.language)),t("div",{class:"OtpField",ref:this.setOtpContainerRef},this.otp.map(((e,i)=>t("input",{key:i,ref:e=>this.setOtpInputRef(e,i),id:`otp-input-${i}`,type:"text",class:"otp-box "+(this.config.inputLength%2==0&&i===this.config.inputLength/2-1?"space":""),maxLength:1,value:e,onInput:e=>this.handleOtpInput(e,i),onKeyDown:e=>this.handleKeyDown(e,i),onPaste:e=>this.handleOnPasteOtp(e),disabled:this.timeLeft<=0})))),t("div",{class:"otp-timer"},this.formatTime(this.timeLeft)," ",l("minutes",this.language))),t("div",{class:"OtpActionButtons"},this.showResendOtp?t("button",{class:"OtpButton",onClick:this.handleResendOtp},l("resendOtp",this.language)):t("button",{class:"OtpButton",onClick:this.submitOtp,disabled:this.otp.join("").length!==this.config.inputLength},l("submit",this.language)),t("button",{class:"OtpButton",onClick:this.closePopup},l("close",this.language)))))))}get el(){return r(this)}static get watchers(){return{translationUrl:["handleNewTranslations"],clientStyling:["handleClientStylingChange"],clientStylingUrl:["handleClientStylingUrlChange"]}}};d.style=".OtpPopupOverlay{position:fixed;top:0;left:0;width:100%;height:100%;background:var(--emw--color-overlay, rgba(0, 0, 0, 0.5));display:flex;align-items:center;justify-content:center}.OtpButton{font-family:var(--emw--button-typography);border:var(--emw--button-border, none);border-radius:var(--emw--button-border-radius, 3px);border-color:var(--emw--button-border-color);background-color:var(--emw--button-background-color, var(--emw--color-primary, #007bff));color:var(--emw--button-typography, var(--emw--color-white, #fff));padding:10px 20px;cursor:pointer;font-size:16px}.OtpButton.error{background:var(--emw--color-error, #dd3434)}.OtpPopupContent{position:relative;background:var(--emw--color-white, #fff);padding:20px;border-radius:5px;text-align:center;min-width:25%;min-height:200px;display:flex;flex-direction:column;justify-content:center;gap:20px}.OtpPopupContent .OtpError{display:flex;flex-direction:column;gap:20px;align-items:center}.OtpPopupContent .OtpError .OtpErrorHeader{display:flex;justify-content:center;gap:5px}.OtpPopupContent .OtpError h2{margin:0}.OtpPopupContent .OtpError svg{width:25px;fill:var(--emw--color-error, #dd3434)}.OtpFieldWrapper{display:flex;flex-direction:column;gap:10px}.OtpFieldWrapper h2{margin:0}.OtpField{display:flex;justify-content:center}.OtpField input{width:24px;font-size:32px;padding:10px;text-align:center;border-radius:5px;margin:2px;border:2px solid var(--emw--otp-border-color, #55525c);font-weight:bold;outline:none;transition:all 0.1s}.OtpField input.space{margin-right:1rem !important}.OtpField input:focus{border:2px solid var(--emw--color-primary, #007bff);box-shadow:0 0 2px 2px var(--emw--color-primary, #007bff)}.OtpActionButtons{display:flex;justify-content:space-between}.OtpErrorMessage{color:var(--emw--color-error, #dd3434);font-weight:bold}.OtpLoaderContainer{width:100%;height:100%;display:flex;justify-content:center;align-items:center}.OtpLoader{width:48px;height:48px;border:5px solid var(--emw--color-secondary, #b3d8ff);border-bottom-color:var(--emw--color-primary, #007bff);border-radius:50%;display:inline-block;box-sizing:border-box;animation:rotation 1s linear infinite}@keyframes rotation{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}";export{d as P}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{p as e,b as n}from"./p-c6a4faff.js";export{s as setNonce}from"./p-c6a4faff.js";import{g as t}from"./p-e1255160.js";(()=>{const n=import.meta.url,t={};return""!==n&&(t.resourcesUrl=new URL(".",n).href),e(t)})().then((async e=>(await t(),n([["p-
|
|
1
|
+
import{p as e,b as n}from"./p-c6a4faff.js";export{s as setNonce}from"./p-c6a4faff.js";import{g as t}from"./p-e1255160.js";(()=>{const n=import.meta.url,t={};return""!==n&&(t.resourcesUrl=new URL(".",n).href),e(t)})().then((async e=>(await t(),n([["p-849e390a",[[1,"player-step-up-auth",{mbSource:[513,"mb-source"],clientStyling:[513,"client-styling"],clientStylingUrl:[513,"client-styling-url"],language:[513],endpoint:[513],userSession:[513,"user-session"],translationUrl:[513,"translation-url"],showPopup:[32],otp:[32],isLoading:[32],config:[32],timeLeft:[32],expirationTime:[32],serverTime:[32],hasErrors:[32],hasConfigErrors:[32],errorMessage:[32],token:[32],flow:[32],showResendOtp:[32]},[[8,"stepUpAuthRequired","handleStepUpAuthEvent"],[8,"closePopup","handleCloseWidget"]],{translationUrl:["handleNewTranslations"],clientStyling:["handleClientStylingChange"],clientStylingUrl:["handleClientStylingUrlChange"]}]]]],e))));
|
|
@@ -39,6 +39,7 @@ export declare class PlayerStepUpAuth {
|
|
|
39
39
|
hasConfigErrors: boolean;
|
|
40
40
|
errorMessage: string;
|
|
41
41
|
token: string;
|
|
42
|
+
flow: string;
|
|
42
43
|
showResendOtp: boolean;
|
|
43
44
|
private stylingContainer;
|
|
44
45
|
private stylingSubscription;
|
|
@@ -64,7 +65,26 @@ export declare class PlayerStepUpAuth {
|
|
|
64
65
|
* @param oldValue - previous client styling URL
|
|
65
66
|
*/
|
|
66
67
|
handleClientStylingUrlChange(newValue: string, oldValue: string): void;
|
|
68
|
+
/**
|
|
69
|
+
* Handles the custom `stepUpAuthRequired` event fired on the window.
|
|
70
|
+
* This event typically signals that step-up authentication is required.
|
|
71
|
+
*
|
|
72
|
+
* @param event - A CustomEvent that contains authentication-related details.
|
|
73
|
+
*
|
|
74
|
+
* Expected `event.detail` structure:
|
|
75
|
+
* {
|
|
76
|
+
* 'x-step-up-required': true,
|
|
77
|
+
* 'x-step-up-token': string,
|
|
78
|
+
* 'flow': string
|
|
79
|
+
* }
|
|
80
|
+
*/
|
|
67
81
|
handleStepUpAuthEvent(event: CustomEvent): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Listens for the 'closePopup' event dispatched on the window
|
|
84
|
+
* and triggers popup closing logic. This allows other components
|
|
85
|
+
* or scripts to close the popup via a custom event.
|
|
86
|
+
*/
|
|
87
|
+
handleCloseWidget(): void;
|
|
68
88
|
/**
|
|
69
89
|
* Class constructor
|
|
70
90
|
*/
|
|
@@ -138,6 +158,19 @@ export declare class PlayerStepUpAuth {
|
|
|
138
158
|
* Sends a request to the endpoint with the OTP and handles the response.
|
|
139
159
|
*/
|
|
140
160
|
submitOtp(): Promise<void>;
|
|
161
|
+
/**
|
|
162
|
+
* Handle stateless mode where we just need to send the otp value and the template will
|
|
163
|
+
* recall the endpoint with X-Step-Up-Token and X-Step-Up-Value (otp value)
|
|
164
|
+
*
|
|
165
|
+
* @param otpValue - Otp code.
|
|
166
|
+
*/
|
|
167
|
+
handleOtpStateless(otpValue: string): void;
|
|
168
|
+
/**
|
|
169
|
+
* Handle the stateful mode where we need to call validate endpoint.
|
|
170
|
+
*
|
|
171
|
+
* @param otpValue - Otp code.
|
|
172
|
+
*/
|
|
173
|
+
handleOtpStateful(otpValue: string): Promise<void>;
|
|
141
174
|
/**
|
|
142
175
|
* Handles successful OTP validation.
|
|
143
176
|
* Closes the popup upon successful authentication.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@everymatrix/player-step-up-auth",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.64.2",
|
|
4
4
|
"main": "./dist/index.cjs.js",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"es2015": "./dist/esm/index.mjs",
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"loader/"
|
|
22
22
|
],
|
|
23
23
|
"publishConfig": {
|
|
24
|
-
"access": "public"
|
|
25
|
-
"registry": "https://everymatrix.jfrog.io/artifactory/api/npm/everymatrix-widgets/"
|
|
24
|
+
"access": "public"
|
|
26
25
|
}
|
|
27
26
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export{P as player_step_up_auth}from"./p-f97ac666.js";import"./p-c6a4faff.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e,h as t,F as i,g as r}from"./p-c6a4faff.js";function o(e,t){if(e){const i=document.createElement("style");i.innerHTML=t,e.appendChild(i)}}function s(e,t){const i=new URL(t);fetch(i.href).then((e=>e.text())).then((t=>{const i=document.createElement("style");i.innerHTML=t,e&&e.appendChild(i)})).catch((e=>{console.error("There was an error while trying to load client styling from URL",e)}))}const n={en:{popupMessage:"Please enter the security code received on your email address to perform the update.",minutes:"minutes",errorHeader:"Error",configError:"Unable to load OTP data. Please try again later.",otpHeading:"Enter OTP",resendOtp:"Resent OTP",submit:"Submit",close:"Close",invalidOtp:"The code you've sent is not valid. Please try again.",accountBlocked:"Too many attempts for OTP. Your account has been blocked for one hour.",submissionError:"Something went wrong. Please try again."},ro:{popupMessage:"Introduceți codul de securitate primit pe adresa dvs. de e-mail pentru a efectua actualizarea.",minutes:"minute",errorHeader:"Eroare",configError:"Nu s-a putut încărca datele OTP. Vă rugăm să încercați din nou mai târziu.",otpHeading:"Introduceți OTP",resendOtp:"Retrimitere OTP",submit:"Trimite",close:"Închide",invalidOtp:"Codul introdus nu este valid. Vă rugăm să încercați din nou.",accountBlocked:"Prea multe încercări de OTP. Contul dvs. a fost blocat timp de o oră.",submissionError:"Ceva a mers prost. Vă rugăm să încercați din nou."},fr:{popupMessage:"Veuillez entrer le code de sécurité reçu sur votre adresse e-mail pour effectuer la mise à jour.",minutes:"minutes",errorHeader:"Erreur",configError:"Impossible de charger les données OTP. Veuillez réessayer plus tard.",otpHeading:"Entrez OTP",resendOtp:"Renvoyer OTP",submit:"Soumettre",close:"Fermer",invalidOtp:"Le code que vous avez saisi n’est pas valide. Veuillez réessayer.",accountBlocked:"Trop de tentatives OTP. Votre compte a été bloqué pendant une heure.",submissionError:"Quelque chose s'est mal passé. Veuillez réessayer."},hu:{popupMessage:"Kérjük, adja meg az e-mail címére küldött biztonsági kódot a frissítés végrehajtásához.",minutes:"perc",errorHeader:"Hiba",configError:"Nem sikerült betölteni az OTP adatokat. Kérjük, próbálja újra később.",otpHeading:"OTP megadása",resendOtp:"Újraküldés",submit:"Beküldés",close:"Bezárás",invalidOtp:"A megadott kód érvénytelen. Kérjük, próbálja újra.",accountBlocked:"Túl sok OTP próbálkozás. A fiókja egy órára zárolva lett.",submissionError:"Valami hiba történt. Kérjük, próbálja újra."},tr:{popupMessage:"Güncellemeyi gerçekleştirmek için e-posta adresinize gelen güvenlik kodunu girin.",minutes:"dakika",errorHeader:"Hata",configError:"OTP verisi yüklenemedi. Lütfen daha sonra tekrar deneyin.",otpHeading:"OTP Girin",resendOtp:"OTP'yi Yeniden Gönder",submit:"Gönder",close:"Kapat",invalidOtp:"Gönderdiğiniz kod geçersiz. Lütfen tekrar deneyin.",accountBlocked:"Çok fazla OTP denemesi yapıldı. Hesabınız bir saat boyunca kilitlendi.",submissionError:"Bir şeyler yanlış gitti. Lütfen tekrar deneyin."},el:{popupMessage:"Παρακαλώ εισάγετε τον κωδικό ασφαλείας που λάβατε στο email σας για να ολοκληρώσετε την ενημέρωση.",minutes:"λεπτά",errorHeader:"Σφάλμα",configError:"Δεν ήταν δυνατή η φόρτωση των δεδομένων OTP. Παρακαλούμε προσπαθήστε ξανά αργότερα.",otpHeading:"Εισαγωγή OTP",resendOtp:"Αποστολή ξανά OTP",submit:"Υποβολή",close:"Κλείσιμο",invalidOtp:"Ο κωδικός που εισαγάγατε δεν είναι έγκυρος. Παρακαλώ προσπαθήστε ξανά.",accountBlocked:"Πάρα πολλές προσπάθειες OTP. Ο λογαριασμός σας έχει αποκλειστεί για μία ώρα.",submissionError:"Κάτι πήγε στραβά. Παρακαλώ προσπαθήστε ξανά."},es:{popupMessage:"Por favor, introduzca el código de seguridad recibido en su correo electrónico para realizar la actualización.",minutes:"minutos",errorHeader:"Error",configError:"No se pudo cargar los datos del OTP. Por favor, inténtelo de nuevo más tarde.",otpHeading:"Introducir OTP",resendOtp:"Reenviar OTP",submit:"Enviar",close:"Cerrar",invalidOtp:"El código que ingresaste no es válido. Por favor, inténtalo de nuevo.",accountBlocked:"Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.",submissionError:"Algo salió mal. Por favor, inténtelo de nuevo."},pt:{popupMessage:"Por favor, insira o código de segurança recebido no seu e-mail para realizar a atualização.",minutes:"minutos",errorHeader:"Erro",configError:"Não foi possível carregar os dados do OTP. Tente novamente mais tarde.",otpHeading:"Insira o OTP",resendOtp:"Reenviar OTP",submit:"Enviar",close:"Fechar",invalidOtp:"O código inserido não é válido. Por favor, tente novamente.",accountBlocked:"Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.",submissionError:"Algo deu errado. Por favor, tente novamente."},hr:{popupMessage:"Unesite sigurnosni kod primljen na vašu e-mail adresu kako biste izvršili ažuriranje.",minutes:"minute",errorHeader:"Greška",configError:"Nije moguće učitati OTP podatke. Pokušajte ponovno kasnije.",otpHeading:"Unesite OTP",resendOtp:"Ponovno pošalji OTP",submit:"Pošalji",close:"Zatvori",invalidOtp:"Uneseni kod nije valjan. Molimo pokušajte ponovo.",accountBlocked:"Previše pokušaja unosa OTP-a. Vaš račun je blokiran na jedan sat.",submissionError:"Nešto je pošlo po zlu. Molimo pokušajte ponovo."},de:{popupMessage:"Bitte geben Sie den Sicherheitscode ein, den Sie an Ihre E-Mail-Adresse erhalten haben, um das Update durchzuführen.",minutes:"Minuten",errorHeader:"Fehler",configError:"OTP-Daten konnten nicht geladen werden. Bitte versuchen Sie es später erneut.",otpHeading:"OTP eingeben",resendOtp:"OTP erneut senden",submit:"Absenden",close:"Schließen",invalidOtp:"Der eingegebene Code ist ungültig. Bitte versuchen Sie es erneut.",accountBlocked:"Zu viele OTP-Versuche. Ihr Konto wurde für eine Stunde gesperrt.",submissionError:"Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut."},"es-mx":{popupMessage:"Por favor, ingrese el código de seguridad recibido en su correo electrónico para realizar la actualización.",minutes:"minutos",errorHeader:"Error",configError:"No se pudieron cargar los datos del OTP. Inténtelo de nuevo más tarde.",otpHeading:"Ingrese OTP",resendOtp:"Reenviar OTP",submit:"Enviar",close:"Cerrar",invalidOtp:"El código que ingresó no es válido. Inténtelo de nuevo.",accountBlocked:"Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.",submissionError:"Algo salió mal. Por favor, inténtelo de nuevo."},"pt-br":{popupMessage:"Por favor, digite o código de segurança recebido no seu e-mail para realizar a atualização.",minutes:"minutos",errorHeader:"Erro",configError:"Não foi possível carregar os dados do OTP. Tente novamente mais tarde.",otpHeading:"Digite o OTP",resendOtp:"Reenviar OTP",submit:"Enviar",close:"Fechar",invalidOtp:"O código informado não é válido. Tente novamente.",accountBlocked:"Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.",submissionError:"Algo deu errado. Por favor, tente novamente."}},a=e=>new Promise((t=>{fetch(e).then((e=>e.json())).then((e=>{Object.keys(e).forEach((t=>{for(let i in e[t])n[t][i]=e[t][i]})),t(!0)}))})),d=(e,t)=>n[void 0!==t?t:"en"][e],l=class{handleNewTranslations(){a(this.translationUrl)}handleClientStylingChange(e,t){e!==t&&o(this.el,this.clientStyling)}handleClientStylingUrlChange(e,t){e!=t&&this.clientStylingUrl&&s(this.stylingContainer,this.clientStylingUrl)}async handleStepUpAuthEvent(e){var t;(null===(t=e.detail)||void 0===t?void 0:t["x-step-up-required"])&&(this.hasConfigErrors=!1,this.hasErrors=!1,this.errorMessage="",this.showPopup=!0,this.token=e.detail["x-step-up-token"],await this.getConfig())}constructor(t){e(this,t),this.otpInputs=[],this.countdownTimer=null,this.mbSource=void 0,this.clientStyling=void 0,this.clientStylingUrl=void 0,this.language="en",this.endpoint=void 0,this.userSession=void 0,this.translationUrl="",this.showPopup=!1,this.otp=void 0,this.isLoading=!0,this.config=null,this.timeLeft=0,this.expirationTime="",this.serverTime="",this.hasErrors=!1,this.hasConfigErrors=!1,this.errorMessage="",this.token="",this.showResendOtp=!1,this.closePopup=this.closePopup.bind(this),this.handleResendOtp=this.handleResendOtp.bind(this),this.submitOtp=this.submitOtp.bind(this),this.setOtpContainerRef=this.setOtpContainerRef.bind(this)}async getConfig(){if(this.endpoint)try{const e=new URL(`/api/v1/mfa/challenge/${this.token}/config`,this.endpoint);this.isLoading=!0;const t=await fetch(e.href);if(!t.ok)throw new Error(`HTTP error! Status: ${t.status}`);this.config=await t.json(),this.otp=new Array(this.config.inputLength).fill(""),this.isLoading=!1,this.showResendOtp=!1,this.expirationTime=this.config.expirationTime,this.serverTime=this.config.serverTime,this.calculateTimeLeft(),this.startCountdown()}catch(e){this.isLoading=!1,this.hasConfigErrors=!0,this.errorMessage=d("configError",this.language),console.error("Error loading 2FA config:",e)}}calculateTimeLeft(){const e=new Date(this.expirationTime),t=new Date(this.serverTime);this.currentTime||(this.currentTime=new Date);const i=t.getTime()-this.currentTime.getTime(),r=new Date(this.currentTime.getTime()+i);this.timeLeft=Math.floor((e.getTime()-r.getTime())/1e3)}startCountdown(){this.countdownTimer&&clearInterval(this.countdownTimer),this.countdownTimer=setInterval((()=>{this.timeLeft>0?this.timeLeft-=1:(clearInterval(this.countdownTimer),this.countdownTimer=null,this.showResendOtp=!0)}),1e3)}formatTime(e){const t=e%60;return`${Math.floor(e/60).toString().padStart(2,"0")}:${t.toString().padStart(2,"0")}`}setOtpContainerRef(e){e&&(this.otpContainer=e)}setOtpInputRef(e,t){e&&(this.otpInputs[t]=e)}handleOnPasteOtp(e){var t;e.preventDefault();const i=null===(t=e.clipboardData)||void 0===t?void 0:t.getData("text").trim();if(!i)return;const r=i.slice(0,this.config.inputLength).split("");this.otp=[...r,...new Array(this.config.inputLength-r.length).fill("")];const o=Array.from(this.otpContainer.children);if(o){r.forEach(((e,t)=>{o[t].value=e}));const e=o[r.length-1];null==e||e.focus(),r.length===this.config.inputLength&&this.submitOtp()}}handleOtpInput(e,t){const i=e.target;let r=i.value.replace(/[^0-9a-zA-Z]/gi,"").toUpperCase();if(i.value=r.charAt(0),!r)return;this.otp[t]=r[0];const o=this.otpInputs[t+1];null==o||o.focus()}handleKeyDown(e,t){if("Backspace"===e.key){this.otp[t]="",this.otpInputs[t].value="";const e=this.otpInputs[t-1];null==e||e.focus()}}handleResendOtp(){const e=new CustomEvent("otpResendRequested",{detail:{message:"User requested OTP resend"}});window.dispatchEvent(e)}async submitOtp(){if(this.otp.join("").length!==this.config.inputLength)return this.hasErrors=!0,void(this.errorMessage=d("invalidOtp",this.language));this.isLoading=!0,this.hasErrors=!1,this.errorMessage="";const e=this.otp.join(""),t=new URL(`/api/v1/mfa/challenge/${this.token}/validate`,this.endpoint);t.searchParams.append("input",e);try{const e=await fetch(t.href,{method:"POST"});if(200===e.status)return void this.handleSuccess();const i=await e.json();throw new Error(i.message)}catch(e){if("gm.multifactorauthentication.challenge"===e.message){if(this.config.numberOfValidateAttempts===this.config.maxValidationAttempts-1){const e=new Date(this.serverTime);e.setHours(e.getHours()+1);const t=e.toISOString().slice(0,16).replace("T"," ");return window.postMessage({type:"SetPlayerAccountTimeout",timeoutSelected:"CoolOffUntilSelectedDate",timeoutExpiryDate:t},window.location.href),window.postMessage({type:"WidgetNotification",data:{type:"error",message:d("accountBlocked",this.language)}},window.location.href),void this.closePopup()}return this.hasErrors=!0,this.errorMessage=d("invalidOtp",this.language),void this.getConfig()}console.error("OTP submission failed:",e),this.hasErrors=!0,this.errorMessage=d("submissionError",this.language)}finally{this.isLoading=!1}}handleSuccess(){window.dispatchEvent(new CustomEvent("otpSuccess",{detail:{message:"User successfully authenticated"}})),this.closePopup()}closePopup(){this.showPopup=!1,window.dispatchEvent(new CustomEvent("popupClosed",{detail:{message:"User closed the popup"}}))}disconnectedCallback(){var e;this.countdownTimer&&clearInterval(this.countdownTimer),null===(e=this.stylingSubscription)||void 0===e||e.unsubscribe()}async componentWillLoad(){this.translationUrl.length>2&&await a(this.translationUrl)}componentDidLoad(){this.stylingContainer&&(null!=window.emMessageBuss?function(e,t){if(window.emMessageBus){const i=document.createElement("style");window.emMessageBus.subscribe(t,(t=>{i.innerHTML=t,e&&e.appendChild(i)}))}}(this.stylingContainer,`${this.mbSource}.Style`):(this.clientStyling&&o(this.stylingContainer,this.clientStyling),this.clientStylingUrl&&s(this.stylingContainer,this.clientStylingUrl)))}render(){return t("div",{key:"2761de23ad41b4ead177d63931e7756584defd11"},this.showPopup&&t("div",{key:"1d01dd47770c5190a5c5c3e0c6e2c4af9e71ae15",class:"OtpPopupOverlay"},t("div",{key:"626dbc731ca03790bf9cae42e56919851928a36f",class:"OtpPopupContent"},this.isLoading?t("div",{class:"OtpLoaderContainer"},t("span",{class:"OtpLoader"})):this.hasConfigErrors?t("div",{class:"OtpError"},t("div",{class:"OtpErrorHeader"},t("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512"},t("path",{d:"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"})),t("h2",null,d("errorHeader",this.language))),t("p",null,this.errorMessage),t("button",{class:"OtpButton error",onClick:this.closePopup},d("close",this.language))):t(i,null,t("div",{class:"otp-description"},t("p",null,d("popupMessage",this.language)),this.hasErrors&&t("p",{class:"OtpErrorMessage"},this.errorMessage)),t("div",{class:"OtpFieldWrapper"},t("h2",null,d("otpHeading",this.language)),t("div",{class:"OtpField",ref:this.setOtpContainerRef},this.otp.map(((e,i)=>t("input",{key:i,ref:e=>this.setOtpInputRef(e,i),id:`otp-input-${i}`,type:"text",class:"otp-box "+(this.config.inputLength%2==0&&i===this.config.inputLength/2-1?"space":""),maxLength:1,value:e,onInput:e=>this.handleOtpInput(e,i),onKeyDown:e=>this.handleKeyDown(e,i),onPaste:e=>this.handleOnPasteOtp(e),disabled:this.timeLeft<=0})))),t("div",{class:"otp-timer"},this.formatTime(this.timeLeft)," ",d("minutes",this.language))),t("div",{class:"OtpActionButtons"},this.showResendOtp?t("button",{class:"OtpButton",onClick:this.handleResendOtp},d("resendOtp",this.language)):t("button",{class:"OtpButton",onClick:this.submitOtp,disabled:this.otp.join("").length!==this.config.inputLength},d("submit",this.language)),t("button",{class:"OtpButton",onClick:this.closePopup},d("close",this.language)))))))}get el(){return r(this)}static get watchers(){return{translationUrl:["handleNewTranslations"],clientStyling:["handleClientStylingChange"],clientStylingUrl:["handleClientStylingUrlChange"]}}};l.style=".OtpPopupOverlay{position:fixed;top:0;left:0;width:100%;height:100%;background:var(--emw--color-overlay, rgba(0, 0, 0, 0.5));display:flex;align-items:center;justify-content:center}.OtpButton{font-family:var(--emw--button-typography);border:var(--emw--button-border, none);border-radius:var(--emw--button-border-radius, 3px);border-color:var(--emw--button-border-color);background-color:var(--emw--button-background-color, var(--emw--color-primary, #007bff));color:var(--emw--button-typography, var(--emw--color-white, #fff));padding:10px 20px;cursor:pointer;font-size:16px}.OtpButton.error{background:var(--emw--color-error, #dd3434)}.OtpPopupContent{position:relative;background:var(--emw--color-white, #fff);padding:20px;border-radius:5px;text-align:center;min-width:25%;min-height:200px;display:flex;flex-direction:column;justify-content:center;gap:20px}.OtpPopupContent .OtpError{display:flex;flex-direction:column;gap:20px;align-items:center}.OtpPopupContent .OtpError .OtpErrorHeader{display:flex;justify-content:center;gap:5px}.OtpPopupContent .OtpError h2{margin:0}.OtpPopupContent .OtpError svg{width:25px;fill:var(--emw--color-error, #dd3434)}.OtpFieldWrapper{display:flex;flex-direction:column;gap:10px}.OtpFieldWrapper h2{margin:0}.OtpField{display:flex;justify-content:center}.OtpField input{width:24px;font-size:32px;padding:10px;text-align:center;border-radius:5px;margin:2px;border:2px solid var(--emw--otp-border-color, #55525c);font-weight:bold;outline:none;transition:all 0.1s}.OtpField input.space{margin-right:1rem !important}.OtpField input:focus{border:2px solid var(--emw--color-primary, #007bff);box-shadow:0 0 2px 2px var(--emw--color-primary, #007bff)}.OtpActionButtons{display:flex;justify-content:space-between}.OtpErrorMessage{color:var(--emw--color-error, #dd3434);font-weight:bold}.OtpLoaderContainer{width:100%;height:100%;display:flex;justify-content:center;align-items:center}.OtpLoader{width:48px;height:48px;border:5px solid var(--emw--color-secondary, #b3d8ff);border-bottom-color:var(--emw--color-primary, #007bff);border-radius:50%;display:inline-block;box-sizing:border-box;animation:rotation 1s linear infinite}@keyframes rotation{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}";export{l as P}
|