@everymatrix/player-step-up-auth 1.70.3 → 1.70.5

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const playerStepUpAuth = require('./player-step-up-auth-c7542709.js');
5
+ const playerStepUpAuth = require('./player-step-up-auth-80ad5fa5.js');
6
6
  require('./index-bf4d774c.js');
7
7
 
8
8
 
@@ -73,7 +73,8 @@ const TRANSLATIONS = {
73
73
  close: 'Close',
74
74
  invalidOtp: 'The code you\'ve sent is not valid. Please try again.',
75
75
  accountBlocked: 'Too many attempts for OTP. Your account has been blocked for one hour.',
76
- submissionError: 'Something went wrong. Please try again.'
76
+ submissionError: 'Something went wrong. Please try again.',
77
+ otpExpiredMessage: 'Validation code has expired, please request a new one to continue.'
77
78
  },
78
79
  ro: {
79
80
  popupMessage: 'Introduceți codul de securitate primit pe adresa dvs. de e-mail pentru a efectua actualizarea.',
@@ -87,7 +88,8 @@ const TRANSLATIONS = {
87
88
  close: 'Închide',
88
89
  invalidOtp: 'Codul introdus nu este valid. Vă rugăm să încercați din nou.',
89
90
  accountBlocked: 'Prea multe încercări de OTP. Contul dvs. a fost blocat timp de o oră.',
90
- submissionError: 'Ceva a mers prost. Vă rugăm să încercați din nou.'
91
+ submissionError: 'Ceva a mers prost. Vă rugăm să încercați din nou.',
92
+ otpExpiredMessage: 'Codul de validare a expirat, vă rugăm să solicitați unul nou pentru a continua.'
91
93
  },
92
94
  fr: {
93
95
  popupMessage: 'Veuillez entrer le code de sécurité reçu sur votre adresse e-mail pour effectuer la mise à jour.',
@@ -101,7 +103,8 @@ const TRANSLATIONS = {
101
103
  close: 'Fermer',
102
104
  invalidOtp: 'Le code que vous avez saisi n’est pas valide. Veuillez réessayer.',
103
105
  accountBlocked: 'Trop de tentatives OTP. Votre compte a été bloqué pendant une heure.',
104
- submissionError: 'Quelque chose s\'est mal passé. Veuillez réessayer.'
106
+ submissionError: 'Quelque chose s\'est mal passé. Veuillez réessayer.',
107
+ otpExpiredMessage: 'Le code de validation a expiré, veuillez en demander un nouveau pour continuer.'
105
108
  },
106
109
  hu: {
107
110
  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.',
@@ -115,7 +118,8 @@ const TRANSLATIONS = {
115
118
  close: 'Bezárás',
116
119
  invalidOtp: 'A megadott kód érvénytelen. Kérjük, próbálja újra.',
117
120
  accountBlocked: 'Túl sok OTP próbálkozás. A fiókja egy órára zárolva lett.',
118
- submissionError: 'Valami hiba történt. Kérjük, próbálja újra.'
121
+ submissionError: 'Valami hiba történt. Kérjük, próbálja újra.',
122
+ otpExpiredMessage: 'A megerősítő kód lejárt, kérjük, kérjen egy újat a folytatáshoz.'
119
123
  },
120
124
  tr: {
121
125
  popupMessage: 'Güncellemeyi gerçekleştirmek için e-posta adresinize gelen güvenlik kodunu girin.',
@@ -129,7 +133,8 @@ const TRANSLATIONS = {
129
133
  close: 'Kapat',
130
134
  invalidOtp: 'Gönderdiğiniz kod geçersiz. Lütfen tekrar deneyin.',
131
135
  accountBlocked: 'Çok fazla OTP denemesi yapıldı. Hesabınız bir saat boyunca kilitlendi.',
132
- submissionError: 'Bir şeyler yanlış gitti. Lütfen tekrar deneyin.'
136
+ submissionError: 'Bir şeyler yanlış gitti. Lütfen tekrar deneyin.',
137
+ otpExpiredMessage: 'Doğrulama kodunun süresi doldu, devam etmek için lütfen yeni bir tane isteyin.'
133
138
  },
134
139
  el: {
135
140
  popupMessage: 'Παρακαλώ εισάγετε τον κωδικό ασφαλείας που λάβατε στο email σας για να ολοκληρώσετε την ενημέρωση.',
@@ -143,7 +148,8 @@ const TRANSLATIONS = {
143
148
  close: 'Κλείσιμο',
144
149
  invalidOtp: 'Ο κωδικός που εισαγάγατε δεν είναι έγκυρος. Παρακαλώ προσπαθήστε ξανά.',
145
150
  accountBlocked: 'Πάρα πολλές προσπάθειες OTP. Ο λογαριασμός σας έχει αποκλειστεί για μία ώρα.',
146
- submissionError: 'Κάτι πήγε στραβά. Παρακαλώ προσπαθήστε ξανά.'
151
+ submissionError: 'Κάτι πήγε στραβά. Παρακαλώ προσπαθήστε ξανά.',
152
+ otpExpiredMessage: 'Ο κωδικός επαλήθευσης έχει λήξει, παρακαλώ ζητήστε έναν νέο για να συνεχίσετε.'
147
153
  },
148
154
  es: {
149
155
  popupMessage: 'Por favor, introduzca el código de seguridad recibido en su correo electrónico para realizar la actualización.',
@@ -157,7 +163,8 @@ const TRANSLATIONS = {
157
163
  close: 'Cerrar',
158
164
  invalidOtp: 'El código que ingresaste no es válido. Por favor, inténtalo de nuevo.',
159
165
  accountBlocked: 'Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.',
160
- submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.'
166
+ submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.',
167
+ otpExpiredMessage: 'El código de validación ha expirado, por favor solicite uno nuevo para continuar.'
161
168
  },
162
169
  pt: {
163
170
  popupMessage: 'Por favor, insira o código de segurança recebido no seu e-mail para realizar a atualização.',
@@ -171,7 +178,8 @@ const TRANSLATIONS = {
171
178
  close: 'Fechar',
172
179
  invalidOtp: 'O código inserido não é válido. Por favor, tente novamente.',
173
180
  accountBlocked: 'Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.',
174
- submissionError: 'Algo deu errado. Por favor, tente novamente.'
181
+ submissionError: 'Algo deu errado. Por favor, tente novamente.',
182
+ otpExpiredMessage: 'O código de validação expirou, por favor solicite um novo para continuar.'
175
183
  },
176
184
  hr: {
177
185
  popupMessage: 'Unesite sigurnosni kod primljen na vašu e-mail adresu kako biste izvršili ažuriranje.',
@@ -185,7 +193,8 @@ const TRANSLATIONS = {
185
193
  close: 'Zatvori',
186
194
  invalidOtp: 'Uneseni kod nije valjan. Molimo pokušajte ponovo.',
187
195
  accountBlocked: 'Previše pokušaja unosa OTP-a. Vaš račun je blokiran na jedan sat.',
188
- submissionError: 'Nešto je pošlo po zlu. Molimo pokušajte ponovo.'
196
+ submissionError: 'Nešto je pošlo po zlu. Molimo pokušajte ponovo.',
197
+ otpExpiredMessage: 'Kod za potvrdu je istekao, molimo zatražite novi kako biste nastavili.'
189
198
  },
190
199
  de: {
191
200
  popupMessage: 'Bitte geben Sie den Sicherheitscode ein, den Sie an Ihre E-Mail-Adresse erhalten haben, um das Update durchzuführen.',
@@ -199,7 +208,8 @@ const TRANSLATIONS = {
199
208
  close: 'Schließen',
200
209
  invalidOtp: 'Der eingegebene Code ist ungültig. Bitte versuchen Sie es erneut.',
201
210
  accountBlocked: 'Zu viele OTP-Versuche. Ihr Konto wurde für eine Stunde gesperrt.',
202
- submissionError: 'Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.'
211
+ submissionError: 'Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.',
212
+ otpExpiredMessage: 'Der Bestätigungscode ist abgelaufen, bitte fordern Sie einen neuen an, um fortzufahren.'
203
213
  },
204
214
  'es-mx': {
205
215
  popupMessage: 'Por favor, ingrese el código de seguridad recibido en su correo electrónico para realizar la actualización.',
@@ -213,7 +223,8 @@ const TRANSLATIONS = {
213
223
  close: 'Cerrar',
214
224
  invalidOtp: 'El código que ingresó no es válido. Inténtelo de nuevo.',
215
225
  accountBlocked: 'Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.',
216
- submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.'
226
+ submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.',
227
+ otpExpiredMessage: 'El código de validación ha expirado, por favor solicite uno nuevo para continuar.'
217
228
  },
218
229
  'pt-br': {
219
230
  popupMessage: 'Por favor, digite o código de segurança recebido no seu e-mail para realizar a atualização.',
@@ -227,7 +238,8 @@ const TRANSLATIONS = {
227
238
  close: 'Fechar',
228
239
  invalidOtp: 'O código informado não é válido. Tente novamente.',
229
240
  accountBlocked: 'Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.',
230
- submissionError: 'Algo deu errado. Por favor, tente novamente.'
241
+ submissionError: 'Algo deu errado. Por favor, tente novamente.',
242
+ otpExpiredMessage: 'O código de validação expirou, por favor solicite um novo para continuar.'
231
243
  },
232
244
  };
233
245
  const getTranslations = (url) => {
@@ -314,15 +326,18 @@ const PlayerStepUpAuth = class {
314
326
  }
315
327
  }
316
328
  /**
317
- * Listens for the 'closePopup' event dispatched on the window
318
- * and triggers popup closing logic. This allows other components
319
- * or scripts to close the popup via a custom event.
329
+ * Listens for the global 'closePopup' event to close the popup manually.
320
330
  */
321
331
  handleCloseWidget() {
332
+ if (this.countdownTimer) {
333
+ clearInterval(this.countdownTimer);
334
+ this.countdownTimer = null;
335
+ }
322
336
  this.hasErrors = false;
323
337
  this.hasConfigErrors = false;
324
338
  this.errorMessage = '';
325
339
  this.showPopup = false;
340
+ this.isLastWarning = false;
326
341
  }
327
342
  /**
328
343
  * Class constructor
@@ -331,6 +346,7 @@ const PlayerStepUpAuth = class {
331
346
  index.registerInstance(this, hostRef);
332
347
  this.otpInputs = [];
333
348
  this.countdownTimer = null;
349
+ this.expirationTimestamp = 0;
334
350
  this.mbSource = undefined;
335
351
  this.clientStyling = undefined;
336
352
  this.clientStylingUrl = undefined;
@@ -399,41 +415,37 @@ const PlayerStepUpAuth = class {
399
415
  }
400
416
  }
401
417
  /**
402
- * Starts the countdown timer for OTP expiration.
403
- * - Clears any existing timer to prevent duplicate intervals.
404
- * - Decreases `timeLeft` every second.
405
- * - Stops the countdown when time reaches 0.
406
- * - Shows the "Resend OTP" option when time runs out.
418
+ * Calculates the remaining time for OTP expiration.
419
+ * Adjusts client time based on server offset.
407
420
  */
408
421
  calculateTimeLeft() {
409
422
  const expirationDate = new Date(this.expirationTime);
410
- const serverTime = new Date(this.serverTime);
411
- if (!this.currentTime) {
412
- this.currentTime = new Date();
413
- }
414
- // Calculate the offset (difference between server time and local time)
415
- const offset = serverTime.getTime() - this.currentTime.getTime();
416
- // Adjust current time using the offset
417
- const adjustedCurrentDate = new Date(this.currentTime.getTime() + offset);
418
- // Calculate time left in seconds
419
- this.timeLeft = Math.floor((expirationDate.getTime() - adjustedCurrentDate.getTime()) / 1000);
423
+ const serverDate = new Date(this.serverTime);
424
+ const localDate = new Date();
425
+ const offset = serverDate.getTime() - localDate.getTime();
426
+ this.expirationTimestamp = expirationDate.getTime() - offset;
427
+ const now = Date.now();
428
+ const timeRemaining = Math.max(0, Math.floor((this.expirationTimestamp - now) / 1000));
429
+ this.timeLeft = timeRemaining;
420
430
  }
421
431
  /**
422
- * Starts a countdown timer for OTP expiration.
423
- * Decreases `timeLeft` every second and closes the popup when time runs out.
432
+ * Starts a 1-second interval countdown for OTP expiration.
433
+ * Updates `timeLeft` state. Enables "Resend OTP" when expired.
424
434
  */
425
435
  startCountdown() {
426
436
  if (this.countdownTimer) {
427
- clearInterval(this.countdownTimer); // Clear any existing timer
437
+ clearInterval(this.countdownTimer);
428
438
  }
429
439
  this.countdownTimer = setInterval(() => {
430
- if (this.timeLeft > 0) {
431
- this.timeLeft -= 1; // Update state correctly
432
- }
433
- else {
440
+ const now = Date.now();
441
+ const timeRemaining = Math.max(0, Math.floor((this.expirationTimestamp - now) / 1000));
442
+ this.timeLeft = timeRemaining;
443
+ if (timeRemaining <= 0) {
434
444
  clearInterval(this.countdownTimer);
435
445
  this.countdownTimer = null;
436
446
  this.showResendOtp = true;
447
+ this.hasErrors = false;
448
+ this.isLastWarning = false;
437
449
  }
438
450
  }, 1000);
439
451
  }
@@ -672,7 +684,7 @@ const PlayerStepUpAuth = class {
672
684
  * Displays the OTP popup, input fields, timer, and action buttons.
673
685
  */
674
686
  render() {
675
- return (index.h("div", { key: '15b15a9406ca14d5e09e2ed8018d096bc493493e', ref: el => this.stylingContainer = el }, this.showPopup && (index.h("div", { key: '27bb8fbc5d1a4e798852684e90996ce019d9fe97', class: "OtpPopupOverlay" }, index.h("div", { key: 'cc34a822937d9f9b553b59ff5b085ee6099326e3', 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.manualClosePopup }, translate('close', this.language)))) : (index.h(index.Fragment, null, index.h("div", { class: "otp-description" }, index.h("p", { class: this.isLastWarning ? 'LastWarningMessage' : '' }, translate(this.isLastWarning ? 'popupMessageLastWarning' : '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) => {
687
+ return (index.h("div", { key: '9afac9d2e248a06828ce17dcb8dc6902fe4ec8cf', ref: el => this.stylingContainer = el }, this.showPopup && (index.h("div", { key: '48bab2747dcba4c64cb97a973a5f9961856126b8', class: "OtpPopupOverlay" }, index.h("div", { key: '89c38b7dbeb7a151f3c172d6913ea2e6884f2c40', 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.manualClosePopup }, translate('close', this.language)))) : (index.h(index.Fragment, null, index.h("div", { class: "otp-description" }, this.showResendOtp ? (index.h("p", { class: "OtpNoticeMessage", role: "alert" }, translate('otpExpiredMessage', this.language))) : (index.h(index.Fragment, null, index.h("p", { class: this.isLastWarning ? 'LastWarningMessage' : '' }, translate(this.isLastWarning ? 'popupMessageLastWarning' : 'popupMessage', this.language)), this.hasErrors && (index.h("p", { class: "OtpErrorMessage", role: "alert" }, 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) => {
676
688
  const isHalfway = this.config.inputLength % 2 === 0 && index$1 === (this.config.inputLength / 2) - 1;
677
689
  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 }));
678
690
  })), 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.manualClosePopup }, translate('close', this.language)))))))))));
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const playerStepUpAuth = require('./player-step-up-auth-c7542709.js');
5
+ const playerStepUpAuth = require('./player-step-up-auth-80ad5fa5.js');
6
6
  require('./index-bf4d774c.js');
7
7
 
8
8
 
@@ -63,15 +63,18 @@ export class PlayerStepUpAuth {
63
63
  }
64
64
  }
65
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.
66
+ * Listens for the global 'closePopup' event to close the popup manually.
69
67
  */
70
68
  handleCloseWidget() {
69
+ if (this.countdownTimer) {
70
+ clearInterval(this.countdownTimer);
71
+ this.countdownTimer = null;
72
+ }
71
73
  this.hasErrors = false;
72
74
  this.hasConfigErrors = false;
73
75
  this.errorMessage = '';
74
76
  this.showPopup = false;
77
+ this.isLastWarning = false;
75
78
  }
76
79
  /**
77
80
  * Class constructor
@@ -79,6 +82,7 @@ export class PlayerStepUpAuth {
79
82
  constructor() {
80
83
  this.otpInputs = [];
81
84
  this.countdownTimer = null;
85
+ this.expirationTimestamp = 0;
82
86
  this.mbSource = undefined;
83
87
  this.clientStyling = undefined;
84
88
  this.clientStylingUrl = undefined;
@@ -147,41 +151,37 @@ export class PlayerStepUpAuth {
147
151
  }
148
152
  }
149
153
  /**
150
- * Starts the countdown timer for OTP expiration.
151
- * - Clears any existing timer to prevent duplicate intervals.
152
- * - Decreases `timeLeft` every second.
153
- * - Stops the countdown when time reaches 0.
154
- * - Shows the "Resend OTP" option when time runs out.
154
+ * Calculates the remaining time for OTP expiration.
155
+ * Adjusts client time based on server offset.
155
156
  */
156
157
  calculateTimeLeft() {
157
158
  const expirationDate = new Date(this.expirationTime);
158
- const serverTime = new Date(this.serverTime);
159
- if (!this.currentTime) {
160
- this.currentTime = new Date();
161
- }
162
- // Calculate the offset (difference between server time and local time)
163
- const offset = serverTime.getTime() - this.currentTime.getTime();
164
- // Adjust current time using the offset
165
- const adjustedCurrentDate = new Date(this.currentTime.getTime() + offset);
166
- // Calculate time left in seconds
167
- this.timeLeft = Math.floor((expirationDate.getTime() - adjustedCurrentDate.getTime()) / 1000);
159
+ const serverDate = new Date(this.serverTime);
160
+ const localDate = new Date();
161
+ const offset = serverDate.getTime() - localDate.getTime();
162
+ this.expirationTimestamp = expirationDate.getTime() - offset;
163
+ const now = Date.now();
164
+ const timeRemaining = Math.max(0, Math.floor((this.expirationTimestamp - now) / 1000));
165
+ this.timeLeft = timeRemaining;
168
166
  }
169
167
  /**
170
- * Starts a countdown timer for OTP expiration.
171
- * Decreases `timeLeft` every second and closes the popup when time runs out.
168
+ * Starts a 1-second interval countdown for OTP expiration.
169
+ * Updates `timeLeft` state. Enables "Resend OTP" when expired.
172
170
  */
173
171
  startCountdown() {
174
172
  if (this.countdownTimer) {
175
- clearInterval(this.countdownTimer); // Clear any existing timer
173
+ clearInterval(this.countdownTimer);
176
174
  }
177
175
  this.countdownTimer = setInterval(() => {
178
- if (this.timeLeft > 0) {
179
- this.timeLeft -= 1; // Update state correctly
180
- }
181
- else {
176
+ const now = Date.now();
177
+ const timeRemaining = Math.max(0, Math.floor((this.expirationTimestamp - now) / 1000));
178
+ this.timeLeft = timeRemaining;
179
+ if (timeRemaining <= 0) {
182
180
  clearInterval(this.countdownTimer);
183
181
  this.countdownTimer = null;
184
182
  this.showResendOtp = true;
183
+ this.hasErrors = false;
184
+ this.isLastWarning = false;
185
185
  }
186
186
  }, 1000);
187
187
  }
@@ -420,7 +420,7 @@ export class PlayerStepUpAuth {
420
420
  * Displays the OTP popup, input fields, timer, and action buttons.
421
421
  */
422
422
  render() {
423
- return (h("div", { key: '15b15a9406ca14d5e09e2ed8018d096bc493493e', ref: el => this.stylingContainer = el }, this.showPopup && (h("div", { key: '27bb8fbc5d1a4e798852684e90996ce019d9fe97', class: "OtpPopupOverlay" }, h("div", { key: 'cc34a822937d9f9b553b59ff5b085ee6099326e3', 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.manualClosePopup }, translate('close', this.language)))) : (h(Fragment, null, h("div", { class: "otp-description" }, h("p", { class: this.isLastWarning ? 'LastWarningMessage' : '' }, translate(this.isLastWarning ? 'popupMessageLastWarning' : '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) => {
423
+ return (h("div", { key: '9afac9d2e248a06828ce17dcb8dc6902fe4ec8cf', ref: el => this.stylingContainer = el }, this.showPopup && (h("div", { key: '48bab2747dcba4c64cb97a973a5f9961856126b8', class: "OtpPopupOverlay" }, h("div", { key: '89c38b7dbeb7a151f3c172d6913ea2e6884f2c40', 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.manualClosePopup }, translate('close', this.language)))) : (h(Fragment, null, h("div", { class: "otp-description" }, this.showResendOtp ? (h("p", { class: "OtpNoticeMessage", role: "alert" }, translate('otpExpiredMessage', this.language))) : (h(Fragment, null, h("p", { class: this.isLastWarning ? 'LastWarningMessage' : '' }, translate(this.isLastWarning ? 'popupMessageLastWarning' : 'popupMessage', this.language)), this.hasErrors && (h("p", { class: "OtpErrorMessage", role: "alert" }, 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) => {
424
424
  const isHalfway = this.config.inputLength % 2 === 0 && index === (this.config.inputLength / 2) - 1;
425
425
  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 }));
426
426
  })), 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.manualClosePopup }, translate('close', this.language)))))))))));
@@ -12,7 +12,8 @@ const TRANSLATIONS = {
12
12
  close: 'Close',
13
13
  invalidOtp: 'The code you\'ve sent is not valid. Please try again.',
14
14
  accountBlocked: 'Too many attempts for OTP. Your account has been blocked for one hour.',
15
- submissionError: 'Something went wrong. Please try again.'
15
+ submissionError: 'Something went wrong. Please try again.',
16
+ otpExpiredMessage: 'Validation code has expired, please request a new one to continue.'
16
17
  },
17
18
  ro: {
18
19
  popupMessage: 'Introduceți codul de securitate primit pe adresa dvs. de e-mail pentru a efectua actualizarea.',
@@ -26,7 +27,8 @@ const TRANSLATIONS = {
26
27
  close: 'Închide',
27
28
  invalidOtp: 'Codul introdus nu este valid. Vă rugăm să încercați din nou.',
28
29
  accountBlocked: 'Prea multe încercări de OTP. Contul dvs. a fost blocat timp de o oră.',
29
- submissionError: 'Ceva a mers prost. Vă rugăm să încercați din nou.'
30
+ submissionError: 'Ceva a mers prost. Vă rugăm să încercați din nou.',
31
+ otpExpiredMessage: 'Codul de validare a expirat, vă rugăm să solicitați unul nou pentru a continua.'
30
32
  },
31
33
  fr: {
32
34
  popupMessage: 'Veuillez entrer le code de sécurité reçu sur votre adresse e-mail pour effectuer la mise à jour.',
@@ -40,7 +42,8 @@ const TRANSLATIONS = {
40
42
  close: 'Fermer',
41
43
  invalidOtp: 'Le code que vous avez saisi n’est pas valide. Veuillez réessayer.',
42
44
  accountBlocked: 'Trop de tentatives OTP. Votre compte a été bloqué pendant une heure.',
43
- submissionError: 'Quelque chose s\'est mal passé. Veuillez réessayer.'
45
+ submissionError: 'Quelque chose s\'est mal passé. Veuillez réessayer.',
46
+ otpExpiredMessage: 'Le code de validation a expiré, veuillez en demander un nouveau pour continuer.'
44
47
  },
45
48
  hu: {
46
49
  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.',
@@ -54,7 +57,8 @@ const TRANSLATIONS = {
54
57
  close: 'Bezárás',
55
58
  invalidOtp: 'A megadott kód érvénytelen. Kérjük, próbálja újra.',
56
59
  accountBlocked: 'Túl sok OTP próbálkozás. A fiókja egy órára zárolva lett.',
57
- submissionError: 'Valami hiba történt. Kérjük, próbálja újra.'
60
+ submissionError: 'Valami hiba történt. Kérjük, próbálja újra.',
61
+ otpExpiredMessage: 'A megerősítő kód lejárt, kérjük, kérjen egy újat a folytatáshoz.'
58
62
  },
59
63
  tr: {
60
64
  popupMessage: 'Güncellemeyi gerçekleştirmek için e-posta adresinize gelen güvenlik kodunu girin.',
@@ -68,7 +72,8 @@ const TRANSLATIONS = {
68
72
  close: 'Kapat',
69
73
  invalidOtp: 'Gönderdiğiniz kod geçersiz. Lütfen tekrar deneyin.',
70
74
  accountBlocked: 'Çok fazla OTP denemesi yapıldı. Hesabınız bir saat boyunca kilitlendi.',
71
- submissionError: 'Bir şeyler yanlış gitti. Lütfen tekrar deneyin.'
75
+ submissionError: 'Bir şeyler yanlış gitti. Lütfen tekrar deneyin.',
76
+ otpExpiredMessage: 'Doğrulama kodunun süresi doldu, devam etmek için lütfen yeni bir tane isteyin.'
72
77
  },
73
78
  el: {
74
79
  popupMessage: 'Παρακαλώ εισάγετε τον κωδικό ασφαλείας που λάβατε στο email σας για να ολοκληρώσετε την ενημέρωση.',
@@ -82,7 +87,8 @@ const TRANSLATIONS = {
82
87
  close: 'Κλείσιμο',
83
88
  invalidOtp: 'Ο κωδικός που εισαγάγατε δεν είναι έγκυρος. Παρακαλώ προσπαθήστε ξανά.',
84
89
  accountBlocked: 'Πάρα πολλές προσπάθειες OTP. Ο λογαριασμός σας έχει αποκλειστεί για μία ώρα.',
85
- submissionError: 'Κάτι πήγε στραβά. Παρακαλώ προσπαθήστε ξανά.'
90
+ submissionError: 'Κάτι πήγε στραβά. Παρακαλώ προσπαθήστε ξανά.',
91
+ otpExpiredMessage: 'Ο κωδικός επαλήθευσης έχει λήξει, παρακαλώ ζητήστε έναν νέο για να συνεχίσετε.'
86
92
  },
87
93
  es: {
88
94
  popupMessage: 'Por favor, introduzca el código de seguridad recibido en su correo electrónico para realizar la actualización.',
@@ -96,7 +102,8 @@ const TRANSLATIONS = {
96
102
  close: 'Cerrar',
97
103
  invalidOtp: 'El código que ingresaste no es válido. Por favor, inténtalo de nuevo.',
98
104
  accountBlocked: 'Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.',
99
- submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.'
105
+ submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.',
106
+ otpExpiredMessage: 'El código de validación ha expirado, por favor solicite uno nuevo para continuar.'
100
107
  },
101
108
  pt: {
102
109
  popupMessage: 'Por favor, insira o código de segurança recebido no seu e-mail para realizar a atualização.',
@@ -110,7 +117,8 @@ const TRANSLATIONS = {
110
117
  close: 'Fechar',
111
118
  invalidOtp: 'O código inserido não é válido. Por favor, tente novamente.',
112
119
  accountBlocked: 'Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.',
113
- submissionError: 'Algo deu errado. Por favor, tente novamente.'
120
+ submissionError: 'Algo deu errado. Por favor, tente novamente.',
121
+ otpExpiredMessage: 'O código de validação expirou, por favor solicite um novo para continuar.'
114
122
  },
115
123
  hr: {
116
124
  popupMessage: 'Unesite sigurnosni kod primljen na vašu e-mail adresu kako biste izvršili ažuriranje.',
@@ -124,7 +132,8 @@ const TRANSLATIONS = {
124
132
  close: 'Zatvori',
125
133
  invalidOtp: 'Uneseni kod nije valjan. Molimo pokušajte ponovo.',
126
134
  accountBlocked: 'Previše pokušaja unosa OTP-a. Vaš račun je blokiran na jedan sat.',
127
- submissionError: 'Nešto je pošlo po zlu. Molimo pokušajte ponovo.'
135
+ submissionError: 'Nešto je pošlo po zlu. Molimo pokušajte ponovo.',
136
+ otpExpiredMessage: 'Kod za potvrdu je istekao, molimo zatražite novi kako biste nastavili.'
128
137
  },
129
138
  de: {
130
139
  popupMessage: 'Bitte geben Sie den Sicherheitscode ein, den Sie an Ihre E-Mail-Adresse erhalten haben, um das Update durchzuführen.',
@@ -138,7 +147,8 @@ const TRANSLATIONS = {
138
147
  close: 'Schließen',
139
148
  invalidOtp: 'Der eingegebene Code ist ungültig. Bitte versuchen Sie es erneut.',
140
149
  accountBlocked: 'Zu viele OTP-Versuche. Ihr Konto wurde für eine Stunde gesperrt.',
141
- submissionError: 'Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.'
150
+ submissionError: 'Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.',
151
+ otpExpiredMessage: 'Der Bestätigungscode ist abgelaufen, bitte fordern Sie einen neuen an, um fortzufahren.'
142
152
  },
143
153
  'es-mx': {
144
154
  popupMessage: 'Por favor, ingrese el código de seguridad recibido en su correo electrónico para realizar la actualización.',
@@ -152,7 +162,8 @@ const TRANSLATIONS = {
152
162
  close: 'Cerrar',
153
163
  invalidOtp: 'El código que ingresó no es válido. Inténtelo de nuevo.',
154
164
  accountBlocked: 'Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.',
155
- submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.'
165
+ submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.',
166
+ otpExpiredMessage: 'El código de validación ha expirado, por favor solicite uno nuevo para continuar.'
156
167
  },
157
168
  'pt-br': {
158
169
  popupMessage: 'Por favor, digite o código de segurança recebido no seu e-mail para realizar a atualização.',
@@ -166,7 +177,8 @@ const TRANSLATIONS = {
166
177
  close: 'Fechar',
167
178
  invalidOtp: 'O código informado não é válido. Tente novamente.',
168
179
  accountBlocked: 'Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.',
169
- submissionError: 'Algo deu errado. Por favor, tente novamente.'
180
+ submissionError: 'Algo deu errado. Por favor, tente novamente.',
181
+ otpExpiredMessage: 'O código de validação expirou, por favor solicite um novo para continuar.'
170
182
  },
171
183
  };
172
184
  export const getTranslations = (url) => {
package/dist/esm/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { P as PlayerStepUpAuth } from './player-step-up-auth-7691b0c5.js';
1
+ export { P as PlayerStepUpAuth } from './player-step-up-auth-045726cf.js';
2
2
  import './index-c6eee6d8.js';
@@ -71,7 +71,8 @@ const TRANSLATIONS = {
71
71
  close: 'Close',
72
72
  invalidOtp: 'The code you\'ve sent is not valid. Please try again.',
73
73
  accountBlocked: 'Too many attempts for OTP. Your account has been blocked for one hour.',
74
- submissionError: 'Something went wrong. Please try again.'
74
+ submissionError: 'Something went wrong. Please try again.',
75
+ otpExpiredMessage: 'Validation code has expired, please request a new one to continue.'
75
76
  },
76
77
  ro: {
77
78
  popupMessage: 'Introduceți codul de securitate primit pe adresa dvs. de e-mail pentru a efectua actualizarea.',
@@ -85,7 +86,8 @@ const TRANSLATIONS = {
85
86
  close: 'Închide',
86
87
  invalidOtp: 'Codul introdus nu este valid. Vă rugăm să încercați din nou.',
87
88
  accountBlocked: 'Prea multe încercări de OTP. Contul dvs. a fost blocat timp de o oră.',
88
- submissionError: 'Ceva a mers prost. Vă rugăm să încercați din nou.'
89
+ submissionError: 'Ceva a mers prost. Vă rugăm să încercați din nou.',
90
+ otpExpiredMessage: 'Codul de validare a expirat, vă rugăm să solicitați unul nou pentru a continua.'
89
91
  },
90
92
  fr: {
91
93
  popupMessage: 'Veuillez entrer le code de sécurité reçu sur votre adresse e-mail pour effectuer la mise à jour.',
@@ -99,7 +101,8 @@ const TRANSLATIONS = {
99
101
  close: 'Fermer',
100
102
  invalidOtp: 'Le code que vous avez saisi n’est pas valide. Veuillez réessayer.',
101
103
  accountBlocked: 'Trop de tentatives OTP. Votre compte a été bloqué pendant une heure.',
102
- submissionError: 'Quelque chose s\'est mal passé. Veuillez réessayer.'
104
+ submissionError: 'Quelque chose s\'est mal passé. Veuillez réessayer.',
105
+ otpExpiredMessage: 'Le code de validation a expiré, veuillez en demander un nouveau pour continuer.'
103
106
  },
104
107
  hu: {
105
108
  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.',
@@ -113,7 +116,8 @@ const TRANSLATIONS = {
113
116
  close: 'Bezárás',
114
117
  invalidOtp: 'A megadott kód érvénytelen. Kérjük, próbálja újra.',
115
118
  accountBlocked: 'Túl sok OTP próbálkozás. A fiókja egy órára zárolva lett.',
116
- submissionError: 'Valami hiba történt. Kérjük, próbálja újra.'
119
+ submissionError: 'Valami hiba történt. Kérjük, próbálja újra.',
120
+ otpExpiredMessage: 'A megerősítő kód lejárt, kérjük, kérjen egy újat a folytatáshoz.'
117
121
  },
118
122
  tr: {
119
123
  popupMessage: 'Güncellemeyi gerçekleştirmek için e-posta adresinize gelen güvenlik kodunu girin.',
@@ -127,7 +131,8 @@ const TRANSLATIONS = {
127
131
  close: 'Kapat',
128
132
  invalidOtp: 'Gönderdiğiniz kod geçersiz. Lütfen tekrar deneyin.',
129
133
  accountBlocked: 'Çok fazla OTP denemesi yapıldı. Hesabınız bir saat boyunca kilitlendi.',
130
- submissionError: 'Bir şeyler yanlış gitti. Lütfen tekrar deneyin.'
134
+ submissionError: 'Bir şeyler yanlış gitti. Lütfen tekrar deneyin.',
135
+ otpExpiredMessage: 'Doğrulama kodunun süresi doldu, devam etmek için lütfen yeni bir tane isteyin.'
131
136
  },
132
137
  el: {
133
138
  popupMessage: 'Παρακαλώ εισάγετε τον κωδικό ασφαλείας που λάβατε στο email σας για να ολοκληρώσετε την ενημέρωση.',
@@ -141,7 +146,8 @@ const TRANSLATIONS = {
141
146
  close: 'Κλείσιμο',
142
147
  invalidOtp: 'Ο κωδικός που εισαγάγατε δεν είναι έγκυρος. Παρακαλώ προσπαθήστε ξανά.',
143
148
  accountBlocked: 'Πάρα πολλές προσπάθειες OTP. Ο λογαριασμός σας έχει αποκλειστεί για μία ώρα.',
144
- submissionError: 'Κάτι πήγε στραβά. Παρακαλώ προσπαθήστε ξανά.'
149
+ submissionError: 'Κάτι πήγε στραβά. Παρακαλώ προσπαθήστε ξανά.',
150
+ otpExpiredMessage: 'Ο κωδικός επαλήθευσης έχει λήξει, παρακαλώ ζητήστε έναν νέο για να συνεχίσετε.'
145
151
  },
146
152
  es: {
147
153
  popupMessage: 'Por favor, introduzca el código de seguridad recibido en su correo electrónico para realizar la actualización.',
@@ -155,7 +161,8 @@ const TRANSLATIONS = {
155
161
  close: 'Cerrar',
156
162
  invalidOtp: 'El código que ingresaste no es válido. Por favor, inténtalo de nuevo.',
157
163
  accountBlocked: 'Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.',
158
- submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.'
164
+ submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.',
165
+ otpExpiredMessage: 'El código de validación ha expirado, por favor solicite uno nuevo para continuar.'
159
166
  },
160
167
  pt: {
161
168
  popupMessage: 'Por favor, insira o código de segurança recebido no seu e-mail para realizar a atualização.',
@@ -169,7 +176,8 @@ const TRANSLATIONS = {
169
176
  close: 'Fechar',
170
177
  invalidOtp: 'O código inserido não é válido. Por favor, tente novamente.',
171
178
  accountBlocked: 'Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.',
172
- submissionError: 'Algo deu errado. Por favor, tente novamente.'
179
+ submissionError: 'Algo deu errado. Por favor, tente novamente.',
180
+ otpExpiredMessage: 'O código de validação expirou, por favor solicite um novo para continuar.'
173
181
  },
174
182
  hr: {
175
183
  popupMessage: 'Unesite sigurnosni kod primljen na vašu e-mail adresu kako biste izvršili ažuriranje.',
@@ -183,7 +191,8 @@ const TRANSLATIONS = {
183
191
  close: 'Zatvori',
184
192
  invalidOtp: 'Uneseni kod nije valjan. Molimo pokušajte ponovo.',
185
193
  accountBlocked: 'Previše pokušaja unosa OTP-a. Vaš račun je blokiran na jedan sat.',
186
- submissionError: 'Nešto je pošlo po zlu. Molimo pokušajte ponovo.'
194
+ submissionError: 'Nešto je pošlo po zlu. Molimo pokušajte ponovo.',
195
+ otpExpiredMessage: 'Kod za potvrdu je istekao, molimo zatražite novi kako biste nastavili.'
187
196
  },
188
197
  de: {
189
198
  popupMessage: 'Bitte geben Sie den Sicherheitscode ein, den Sie an Ihre E-Mail-Adresse erhalten haben, um das Update durchzuführen.',
@@ -197,7 +206,8 @@ const TRANSLATIONS = {
197
206
  close: 'Schließen',
198
207
  invalidOtp: 'Der eingegebene Code ist ungültig. Bitte versuchen Sie es erneut.',
199
208
  accountBlocked: 'Zu viele OTP-Versuche. Ihr Konto wurde für eine Stunde gesperrt.',
200
- submissionError: 'Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.'
209
+ submissionError: 'Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.',
210
+ otpExpiredMessage: 'Der Bestätigungscode ist abgelaufen, bitte fordern Sie einen neuen an, um fortzufahren.'
201
211
  },
202
212
  'es-mx': {
203
213
  popupMessage: 'Por favor, ingrese el código de seguridad recibido en su correo electrónico para realizar la actualización.',
@@ -211,7 +221,8 @@ const TRANSLATIONS = {
211
221
  close: 'Cerrar',
212
222
  invalidOtp: 'El código que ingresó no es válido. Inténtelo de nuevo.',
213
223
  accountBlocked: 'Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.',
214
- submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.'
224
+ submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.',
225
+ otpExpiredMessage: 'El código de validación ha expirado, por favor solicite uno nuevo para continuar.'
215
226
  },
216
227
  'pt-br': {
217
228
  popupMessage: 'Por favor, digite o código de segurança recebido no seu e-mail para realizar a atualização.',
@@ -225,7 +236,8 @@ const TRANSLATIONS = {
225
236
  close: 'Fechar',
226
237
  invalidOtp: 'O código informado não é válido. Tente novamente.',
227
238
  accountBlocked: 'Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.',
228
- submissionError: 'Algo deu errado. Por favor, tente novamente.'
239
+ submissionError: 'Algo deu errado. Por favor, tente novamente.',
240
+ otpExpiredMessage: 'O código de validação expirou, por favor solicite um novo para continuar.'
229
241
  },
230
242
  };
231
243
  const getTranslations = (url) => {
@@ -312,15 +324,18 @@ const PlayerStepUpAuth = class {
312
324
  }
313
325
  }
314
326
  /**
315
- * Listens for the 'closePopup' event dispatched on the window
316
- * and triggers popup closing logic. This allows other components
317
- * or scripts to close the popup via a custom event.
327
+ * Listens for the global 'closePopup' event to close the popup manually.
318
328
  */
319
329
  handleCloseWidget() {
330
+ if (this.countdownTimer) {
331
+ clearInterval(this.countdownTimer);
332
+ this.countdownTimer = null;
333
+ }
320
334
  this.hasErrors = false;
321
335
  this.hasConfigErrors = false;
322
336
  this.errorMessage = '';
323
337
  this.showPopup = false;
338
+ this.isLastWarning = false;
324
339
  }
325
340
  /**
326
341
  * Class constructor
@@ -329,6 +344,7 @@ const PlayerStepUpAuth = class {
329
344
  registerInstance(this, hostRef);
330
345
  this.otpInputs = [];
331
346
  this.countdownTimer = null;
347
+ this.expirationTimestamp = 0;
332
348
  this.mbSource = undefined;
333
349
  this.clientStyling = undefined;
334
350
  this.clientStylingUrl = undefined;
@@ -397,41 +413,37 @@ const PlayerStepUpAuth = class {
397
413
  }
398
414
  }
399
415
  /**
400
- * Starts the countdown timer for OTP expiration.
401
- * - Clears any existing timer to prevent duplicate intervals.
402
- * - Decreases `timeLeft` every second.
403
- * - Stops the countdown when time reaches 0.
404
- * - Shows the "Resend OTP" option when time runs out.
416
+ * Calculates the remaining time for OTP expiration.
417
+ * Adjusts client time based on server offset.
405
418
  */
406
419
  calculateTimeLeft() {
407
420
  const expirationDate = new Date(this.expirationTime);
408
- const serverTime = new Date(this.serverTime);
409
- if (!this.currentTime) {
410
- this.currentTime = new Date();
411
- }
412
- // Calculate the offset (difference between server time and local time)
413
- const offset = serverTime.getTime() - this.currentTime.getTime();
414
- // Adjust current time using the offset
415
- const adjustedCurrentDate = new Date(this.currentTime.getTime() + offset);
416
- // Calculate time left in seconds
417
- this.timeLeft = Math.floor((expirationDate.getTime() - adjustedCurrentDate.getTime()) / 1000);
421
+ const serverDate = new Date(this.serverTime);
422
+ const localDate = new Date();
423
+ const offset = serverDate.getTime() - localDate.getTime();
424
+ this.expirationTimestamp = expirationDate.getTime() - offset;
425
+ const now = Date.now();
426
+ const timeRemaining = Math.max(0, Math.floor((this.expirationTimestamp - now) / 1000));
427
+ this.timeLeft = timeRemaining;
418
428
  }
419
429
  /**
420
- * Starts a countdown timer for OTP expiration.
421
- * Decreases `timeLeft` every second and closes the popup when time runs out.
430
+ * Starts a 1-second interval countdown for OTP expiration.
431
+ * Updates `timeLeft` state. Enables "Resend OTP" when expired.
422
432
  */
423
433
  startCountdown() {
424
434
  if (this.countdownTimer) {
425
- clearInterval(this.countdownTimer); // Clear any existing timer
435
+ clearInterval(this.countdownTimer);
426
436
  }
427
437
  this.countdownTimer = setInterval(() => {
428
- if (this.timeLeft > 0) {
429
- this.timeLeft -= 1; // Update state correctly
430
- }
431
- else {
438
+ const now = Date.now();
439
+ const timeRemaining = Math.max(0, Math.floor((this.expirationTimestamp - now) / 1000));
440
+ this.timeLeft = timeRemaining;
441
+ if (timeRemaining <= 0) {
432
442
  clearInterval(this.countdownTimer);
433
443
  this.countdownTimer = null;
434
444
  this.showResendOtp = true;
445
+ this.hasErrors = false;
446
+ this.isLastWarning = false;
435
447
  }
436
448
  }, 1000);
437
449
  }
@@ -670,7 +682,7 @@ const PlayerStepUpAuth = class {
670
682
  * Displays the OTP popup, input fields, timer, and action buttons.
671
683
  */
672
684
  render() {
673
- return (h("div", { key: '15b15a9406ca14d5e09e2ed8018d096bc493493e', ref: el => this.stylingContainer = el }, this.showPopup && (h("div", { key: '27bb8fbc5d1a4e798852684e90996ce019d9fe97', class: "OtpPopupOverlay" }, h("div", { key: 'cc34a822937d9f9b553b59ff5b085ee6099326e3', 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.manualClosePopup }, translate('close', this.language)))) : (h(Fragment, null, h("div", { class: "otp-description" }, h("p", { class: this.isLastWarning ? 'LastWarningMessage' : '' }, translate(this.isLastWarning ? 'popupMessageLastWarning' : '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) => {
685
+ return (h("div", { key: '9afac9d2e248a06828ce17dcb8dc6902fe4ec8cf', ref: el => this.stylingContainer = el }, this.showPopup && (h("div", { key: '48bab2747dcba4c64cb97a973a5f9961856126b8', class: "OtpPopupOverlay" }, h("div", { key: '89c38b7dbeb7a151f3c172d6913ea2e6884f2c40', 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.manualClosePopup }, translate('close', this.language)))) : (h(Fragment, null, h("div", { class: "otp-description" }, this.showResendOtp ? (h("p", { class: "OtpNoticeMessage", role: "alert" }, translate('otpExpiredMessage', this.language))) : (h(Fragment, null, h("p", { class: this.isLastWarning ? 'LastWarningMessage' : '' }, translate(this.isLastWarning ? 'popupMessageLastWarning' : 'popupMessage', this.language)), this.hasErrors && (h("p", { class: "OtpErrorMessage", role: "alert" }, 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) => {
674
686
  const isHalfway = this.config.inputLength % 2 === 0 && index === (this.config.inputLength / 2) - 1;
675
687
  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 }));
676
688
  })), 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.manualClosePopup }, translate('close', this.language)))))))))));
@@ -1,2 +1,2 @@
1
- export { P as player_step_up_auth } from './player-step-up-auth-7691b0c5.js';
1
+ export { P as player_step_up_auth } from './player-step-up-auth-045726cf.js';
2
2
  import './index-c6eee6d8.js';
@@ -1 +1 @@
1
- export{P as PlayerStepUpAuth}from"./player-step-up-auth-7691b0c5.js";import"./index-c6eee6d8.js";
1
+ export{P as PlayerStepUpAuth}from"./player-step-up-auth-045726cf.js";import"./index-c6eee6d8.js";
@@ -0,0 +1 @@
1
+ import{r as e,h as t,F as i,g as r}from"./index-c6eee6d8.js";function o(e,t){if(e){const i=document.createElement("style");i.innerHTML=t,e.appendChild(i)}}function a(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 s={en:{popupMessage:"Please enter the security code received on your email address to perform the update.",popupMessageLastWarning:"If the next validation attempt is failed, you will be logged out and blocked temporarily.",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.",otpExpiredMessage:"Validation code has expired, please request a new one to continue."},ro:{popupMessage:"Introduceți codul de securitate primit pe adresa dvs. de e-mail pentru a efectua actualizarea.",popupMessageLastWarning:"Dacă următoarea încercare de validare eșuează, veți fi delogat și blocat temporar.",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.",otpExpiredMessage:"Codul de validare a expirat, vă rugăm să solicitați unul nou pentru a continua."},fr:{popupMessage:"Veuillez entrer le code de sécurité reçu sur votre adresse e-mail pour effectuer la mise à jour.",popupMessageLastWarning:"Si la prochaine tentative de validation échoue, vous serez déconnecté et temporairement bloqué.",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.",otpExpiredMessage:"Le code de validation a expiré, veuillez en demander un nouveau pour continuer."},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.",popupMessageLastWarning:"Ha a következő érvényesítési kísérlet sikertelen, ki lesz jelentkeztetve és ideiglenesen letiltva.",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.",otpExpiredMessage:"A megerősítő kód lejárt, kérjük, kérjen egy újat a folytatáshoz."},tr:{popupMessage:"Güncellemeyi gerçekleştirmek için e-posta adresinize gelen güvenlik kodunu girin.",popupMessageLastWarning:"Bir sonraki doğrulama girişimi başarısız olursa, oturumunuz kapatılacak ve geçici olarak engelleneceksiniz.",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.",otpExpiredMessage:"Doğrulama kodunun süresi doldu, devam etmek için lütfen yeni bir tane isteyin."},el:{popupMessage:"Παρακαλώ εισάγετε τον κωδικό ασφαλείας που λάβατε στο email σας για να ολοκληρώσετε την ενημέρωση.",popupMessageLastWarning:"Αν η επόμενη προσπάθεια επικύρωσης αποτύχει, θα αποσυνδεθείτε και θα αποκλειστείτε προσωρινά.",minutes:"λεπτά",errorHeader:"Σφάλμα",configError:"Δεν ήταν δυνατή η φόρτωση των δεδομένων OTP. Παρακαλούμε προσπαθήστε ξανά αργότερα.",otpHeading:"Εισαγωγή OTP",resendOtp:"Αποστολή ξανά OTP",submit:"Υποβολή",close:"Κλείσιμο",invalidOtp:"Ο κωδικός που εισαγάγατε δεν είναι έγκυρος. Παρακαλώ προσπαθήστε ξανά.",accountBlocked:"Πάρα πολλές προσπάθειες OTP. Ο λογαριασμός σας έχει αποκλειστεί για μία ώρα.",submissionError:"Κάτι πήγε στραβά. Παρακαλώ προσπαθήστε ξανά.",otpExpiredMessage:"Ο κωδικός επαλήθευσης έχει λήξει, παρακαλώ ζητήστε έναν νέο για να συνεχίσετε."},es:{popupMessage:"Por favor, introduzca el código de seguridad recibido en su correo electrónico para realizar la actualización.",popupMessageLastWarning:"Si el siguiente intento de validación falla, se cerrará tu sesión y serás bloqueado temporalmente.",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.",otpExpiredMessage:"El código de validación ha expirado, por favor solicite uno nuevo para continuar."},pt:{popupMessage:"Por favor, insira o código de segurança recebido no seu e-mail para realizar a atualização.",popupMessageLastWarning:"Se a próxima tentativa de validação falhar, será desconectado e temporariamente bloqueado.",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.",otpExpiredMessage:"O código de validação expirou, por favor solicite um novo para continuar."},hr:{popupMessage:"Unesite sigurnosni kod primljen na vašu e-mail adresu kako biste izvršili ažuriranje.",popupMessageLastWarning:"Ako sljedeći pokušaj provjere ne uspije, bit ćete odjavljeni i privremeno blokirani.",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.",otpExpiredMessage:"Kod za potvrdu je istekao, molimo zatražite novi kako biste nastavili."},de:{popupMessage:"Bitte geben Sie den Sicherheitscode ein, den Sie an Ihre E-Mail-Adresse erhalten haben, um das Update durchzuführen.",popupMessageLastWarning:"Wenn der nächste Validierungsversuch fehlschlägt, werden Sie abgemeldet und vorübergehend gesperrt.",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.",otpExpiredMessage:"Der Bestätigungscode ist abgelaufen, bitte fordern Sie einen neuen an, um fortzufahren."},"es-mx":{popupMessage:"Por favor, ingrese el código de seguridad recibido en su correo electrónico para realizar la actualización.",popupMessageLastWarning:"Si el siguiente intento de validación falla, se cerrará tu sesión y serás bloqueado temporalmente.",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.",otpExpiredMessage:"El código de validación ha expirado, por favor solicite uno nuevo para continuar."},"pt-br":{popupMessage:"Por favor, digite o código de segurança recebido no seu e-mail para realizar a atualização.",popupMessageLastWarning:"Se a próxima tentativa de validação falhar, você será desconectado e bloqueado temporariamente.",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.",otpExpiredMessage:"O código de validação expirou, por favor solicite um novo para continuar."}},n=e=>new Promise((t=>{fetch(e).then((e=>e.json())).then((e=>{Object.keys(e).forEach((t=>{for(let i in e[t])s[t][i]=e[t][i]})),t(!0)}))})),l=(e,t)=>s[void 0!==t?t:"en"][e],d=class{handleNewTranslations(){n(this.translationUrl)}handleClientStylingChange(e,t){e!==t&&o(this.el,this.clientStyling)}handleClientStylingUrlChange(e,t){e!=t&&this.clientStylingUrl&&a(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.countdownTimer&&(clearInterval(this.countdownTimer),this.countdownTimer=null),this.hasErrors=!1,this.hasConfigErrors=!1,this.errorMessage="",this.showPopup=!1,this.isLastWarning=!1}constructor(t){e(this,t),this.otpInputs=[],this.countdownTimer=null,this.expirationTimestamp=0,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.isLastWarning=!1,this.handleResendOtp=this.handleResendOtp.bind(this),this.submitOtp=this.submitOtp.bind(this),this.setOtpContainerRef=this.setOtpContainerRef.bind(this),this.handleCloseWidget=this.handleCloseWidget.bind(this),this.manualClosePopup=this.manualClosePopup.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.config.numberOfValidateAttempts===this.config.maxValidationAttempts-1&&(this.isLastWarning=!0),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),i=new Date,r=t.getTime()-i.getTime();this.expirationTimestamp=e.getTime()-r;const o=Date.now(),a=Math.max(0,Math.floor((this.expirationTimestamp-o)/1e3));this.timeLeft=a}startCountdown(){this.countdownTimer&&clearInterval(this.countdownTimer),this.countdownTimer=setInterval((()=>{const e=Date.now(),t=Math.max(0,Math.floor((this.expirationTimestamp-e)/1e3));this.timeLeft=t,t<=0&&(clearInterval(this.countdownTimer),this.countdownTimer=null,this.showResendOtp=!0,this.hasErrors=!1,this.isLastWarning=!1)}),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,maxAttempts:this.config.maxValidationAttempts,validatedAttempts:this.config.numberOfValidateAttempts}}))}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)return this.config.numberOfValidateAttempts===this.config.maxValidationAttempts-1?(window.dispatchEvent(new CustomEvent("otpSetTimeout")),window.postMessage({type:"WidgetNotification",data:{type:"error",message:l("accountBlocked",this.language)}},window.location.href),void this.handleCloseWidget()):(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.handleCloseWidget()}manualClosePopup(){window.dispatchEvent(new CustomEvent("manualClosePopup")),this.handleCloseWidget()}disconnectedCallback(){var e;this.countdownTimer&&clearInterval(this.countdownTimer),null===(e=this.stylingSubscription)||void 0===e||e.unsubscribe()}async componentWillLoad(){this.translationUrl.length>2&&await n(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&&a(this.stylingContainer,this.clientStylingUrl)))}render(){return t("div",{key:"9afac9d2e248a06828ce17dcb8dc6902fe4ec8cf",ref:e=>this.stylingContainer=e},this.showPopup&&t("div",{key:"48bab2747dcba4c64cb97a973a5f9961856126b8",class:"OtpPopupOverlay"},t("div",{key:"89c38b7dbeb7a151f3c172d6913ea2e6884f2c40",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.manualClosePopup},l("close",this.language))):t(i,null,t("div",{class:"otp-description"},this.showResendOtp?t("p",{class:"OtpNoticeMessage",role:"alert"},l("otpExpiredMessage",this.language)):t(i,null,t("p",{class:this.isLastWarning?"LastWarningMessage":""},l(this.isLastWarning?"popupMessageLastWarning":"popupMessage",this.language)),this.hasErrors&&t("p",{class:"OtpErrorMessage",role:"alert"},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.manualClosePopup},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
- export{P as player_step_up_auth}from"./player-step-up-auth-7691b0c5.js";import"./index-c6eee6d8.js";
1
+ export{P as player_step_up_auth}from"./player-step-up-auth-045726cf.js";import"./index-c6eee6d8.js";
@@ -46,8 +46,8 @@ export declare class PlayerStepUpAuth {
46
46
  private stylingSubscription;
47
47
  private otpContainer;
48
48
  private otpInputs;
49
- private currentTime;
50
49
  private countdownTimer;
50
+ private expirationTimestamp;
51
51
  /**
52
52
  * Watch for changes in the translation URL and fetch new translations
53
53
  */
@@ -81,9 +81,7 @@ export declare class PlayerStepUpAuth {
81
81
  */
82
82
  handleStepUpAuthEvent(event: CustomEvent): Promise<void>;
83
83
  /**
84
- * Listens for the 'closePopup' event dispatched on the window
85
- * and triggers popup closing logic. This allows other components
86
- * or scripts to close the popup via a custom event.
84
+ * Listens for the global 'closePopup' event to close the popup manually.
87
85
  */
88
86
  handleCloseWidget(): void;
89
87
  /**
@@ -96,16 +94,13 @@ export declare class PlayerStepUpAuth {
96
94
  */
97
95
  getConfig(): Promise<void>;
98
96
  /**
99
- * Starts the countdown timer for OTP expiration.
100
- * - Clears any existing timer to prevent duplicate intervals.
101
- * - Decreases `timeLeft` every second.
102
- * - Stops the countdown when time reaches 0.
103
- * - Shows the "Resend OTP" option when time runs out.
97
+ * Calculates the remaining time for OTP expiration.
98
+ * Adjusts client time based on server offset.
104
99
  */
105
100
  calculateTimeLeft(): void;
106
101
  /**
107
- * Starts a countdown timer for OTP expiration.
108
- * Decreases `timeLeft` every second and closes the popup when time runs out.
102
+ * Starts a 1-second interval countdown for OTP expiration.
103
+ * Updates `timeLeft` state. Enables "Resend OTP" when expired.
109
104
  */
110
105
  startCountdown(): void;
111
106
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everymatrix/player-step-up-auth",
3
- "version": "1.70.3",
3
+ "version": "1.70.5",
4
4
  "main": "./dist/index.cjs.js",
5
5
  "module": "./dist/index.js",
6
6
  "es2015": "./dist/esm/index.mjs",
@@ -23,4 +23,4 @@
23
23
  "publishConfig": {
24
24
  "access": "public"
25
25
  }
26
- }
26
+ }
@@ -1 +0,0 @@
1
- import{r as e,h as t,F as i,g as r}from"./index-c6eee6d8.js";function s(e,t){if(e){const i=document.createElement("style");i.innerHTML=t,e.appendChild(i)}}function o(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 a={en:{popupMessage:"Please enter the security code received on your email address to perform the update.",popupMessageLastWarning:"If the next validation attempt is failed, you will be logged out and blocked temporarily.",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.",popupMessageLastWarning:"Dacă următoarea încercare de validare eșuează, veți fi delogat și blocat temporar.",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.",popupMessageLastWarning:"Si la prochaine tentative de validation échoue, vous serez déconnecté et temporairement bloqué.",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.",popupMessageLastWarning:"Ha a következő érvényesítési kísérlet sikertelen, ki lesz jelentkeztetve és ideiglenesen letiltva.",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.",popupMessageLastWarning:"Bir sonraki doğrulama girişimi başarısız olursa, oturumunuz kapatılacak ve geçici olarak engelleneceksiniz.",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 σας για να ολοκληρώσετε την ενημέρωση.",popupMessageLastWarning:"Αν η επόμενη προσπάθεια επικύρωσης αποτύχει, θα αποσυνδεθείτε και θα αποκλειστείτε προσωρινά.",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.",popupMessageLastWarning:"Si el siguiente intento de validación falla, se cerrará tu sesión y serás bloqueado temporalmente.",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.",popupMessageLastWarning:"Se a próxima tentativa de validação falhar, será desconectado e temporariamente bloqueado.",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.",popupMessageLastWarning:"Ako sljedeći pokušaj provjere ne uspije, bit ćete odjavljeni i privremeno blokirani.",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.",popupMessageLastWarning:"Wenn der nächste Validierungsversuch fehlschlägt, werden Sie abgemeldet und vorübergehend gesperrt.",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.",popupMessageLastWarning:"Si el siguiente intento de validación falla, se cerrará tu sesión y serás bloqueado temporalmente.",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.",popupMessageLastWarning:"Se a próxima tentativa de validação falhar, você será desconectado e bloqueado temporariamente.",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."}},n=e=>new Promise((t=>{fetch(e).then((e=>e.json())).then((e=>{Object.keys(e).forEach((t=>{for(let i in e[t])a[t][i]=e[t][i]})),t(!0)}))})),l=(e,t)=>a[void 0!==t?t:"en"][e],d=class{handleNewTranslations(){n(this.translationUrl)}handleClientStylingChange(e,t){e!==t&&s(this.el,this.clientStyling)}handleClientStylingUrlChange(e,t){e!=t&&this.clientStylingUrl&&o(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.hasErrors=!1,this.hasConfigErrors=!1,this.errorMessage="",this.showPopup=!1}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.isLastWarning=!1,this.handleResendOtp=this.handleResendOtp.bind(this),this.submitOtp=this.submitOtp.bind(this),this.setOtpContainerRef=this.setOtpContainerRef.bind(this),this.handleCloseWidget=this.handleCloseWidget.bind(this),this.manualClosePopup=this.manualClosePopup.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.config.numberOfValidateAttempts===this.config.maxValidationAttempts-1&&(this.isLastWarning=!0),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 s=Array.from(this.otpContainer.children);if(s){r.forEach(((e,t)=>{s[t].value=e}));const e=s[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 s=this.otpInputs[t+1];null==s||s.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,maxAttempts:this.config.maxValidationAttempts,validatedAttempts:this.config.numberOfValidateAttempts}}))}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)return this.config.numberOfValidateAttempts===this.config.maxValidationAttempts-1?(window.dispatchEvent(new CustomEvent("otpSetTimeout")),window.postMessage({type:"WidgetNotification",data:{type:"error",message:l("accountBlocked",this.language)}},window.location.href),void this.handleCloseWidget()):(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.handleCloseWidget()}manualClosePopup(){window.dispatchEvent(new CustomEvent("manualClosePopup")),this.handleCloseWidget()}disconnectedCallback(){var e;this.countdownTimer&&clearInterval(this.countdownTimer),null===(e=this.stylingSubscription)||void 0===e||e.unsubscribe()}async componentWillLoad(){this.translationUrl.length>2&&await n(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&&s(this.stylingContainer,this.clientStyling),this.clientStylingUrl&&o(this.stylingContainer,this.clientStylingUrl)))}render(){return t("div",{key:"15b15a9406ca14d5e09e2ed8018d096bc493493e",ref:e=>this.stylingContainer=e},this.showPopup&&t("div",{key:"27bb8fbc5d1a4e798852684e90996ce019d9fe97",class:"OtpPopupOverlay"},t("div",{key:"cc34a822937d9f9b553b59ff5b085ee6099326e3",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.manualClosePopup},l("close",this.language))):t(i,null,t("div",{class:"otp-description"},t("p",{class:this.isLastWarning?"LastWarningMessage":""},l(this.isLastWarning?"popupMessageLastWarning":"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.manualClosePopup},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}