@everymatrix/player-step-up-auth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/cjs/app-globals-3a1e7e63.js +5 -0
  2. package/dist/cjs/index-bf4d774c.js +1330 -0
  3. package/dist/cjs/index.cjs.js +10 -0
  4. package/dist/cjs/loader.cjs.js +15 -0
  5. package/dist/cjs/player-step-up-auth-2fac8df5.js +617 -0
  6. package/dist/cjs/player-step-up-auth.cjs.entry.js +10 -0
  7. package/dist/cjs/player-step-up-auth.cjs.js +25 -0
  8. package/dist/collection/collection-manifest.json +12 -0
  9. package/dist/collection/components/player-step-up-auth/index.js +1 -0
  10. package/dist/collection/components/player-step-up-auth/player-step-up-auth.css +131 -0
  11. package/dist/collection/components/player-step-up-auth/player-step-up-auth.js +543 -0
  12. package/dist/collection/index.js +1 -0
  13. package/dist/collection/utils/types.js +0 -0
  14. package/dist/collection/utils/utils.js +177 -0
  15. package/dist/esm/app-globals-0f993ce5.js +3 -0
  16. package/dist/esm/index-c6eee6d8.js +1302 -0
  17. package/dist/esm/index.js +2 -0
  18. package/dist/esm/loader.js +11 -0
  19. package/dist/esm/player-step-up-auth-009badea.js +615 -0
  20. package/dist/esm/player-step-up-auth.entry.js +2 -0
  21. package/dist/esm/player-step-up-auth.js +20 -0
  22. package/dist/index.cjs.js +1 -0
  23. package/dist/index.js +1 -0
  24. package/dist/player-step-up-auth/index.esm.js +1 -0
  25. package/dist/player-step-up-auth/p-3b187b6e.entry.js +1 -0
  26. package/dist/player-step-up-auth/p-c6a4faff.js +2 -0
  27. package/dist/player-step-up-auth/p-e1255160.js +1 -0
  28. package/dist/player-step-up-auth/p-f97ac666.js +1 -0
  29. package/dist/player-step-up-auth/player-step-up-auth.esm.js +1 -0
  30. package/dist/stencil.config.dev.js +19 -0
  31. package/dist/stencil.config.js +18 -0
  32. package/dist/storybook/main.js +43 -0
  33. package/dist/storybook/preview.js +9 -0
  34. package/dist/types/Users/adrian.pripon/Documents/Work/widgets-monorepo/packages/stencil/player-step-up-auth/.stencil/libs/common/src/storybook/storybook-utils.d.ts +39 -0
  35. package/dist/types/Users/adrian.pripon/Documents/Work/widgets-monorepo/packages/stencil/player-step-up-auth/.stencil/packages/stencil/player-step-up-auth/stencil.config.d.ts +2 -0
  36. package/dist/types/Users/adrian.pripon/Documents/Work/widgets-monorepo/packages/stencil/player-step-up-auth/.stencil/packages/stencil/player-step-up-auth/stencil.config.dev.d.ts +2 -0
  37. package/dist/types/Users/adrian.pripon/Documents/Work/widgets-monorepo/packages/stencil/player-step-up-auth/.stencil/packages/stencil/player-step-up-auth/storybook/main.d.ts +3 -0
  38. package/dist/types/Users/adrian.pripon/Documents/Work/widgets-monorepo/packages/stencil/player-step-up-auth/.stencil/packages/stencil/player-step-up-auth/storybook/preview.d.ts +70 -0
  39. package/dist/types/Users/adrian.pripon/Documents/Work/widgets-monorepo/packages/stencil/player-step-up-auth/.stencil/tools/plugins/index.d.ts +3 -0
  40. package/dist/types/Users/adrian.pripon/Documents/Work/widgets-monorepo/packages/stencil/player-step-up-auth/.stencil/tools/plugins/stencil-clean-deps-plugin.d.ts +5 -0
  41. package/dist/types/Users/adrian.pripon/Documents/Work/widgets-monorepo/packages/stencil/player-step-up-auth/.stencil/tools/plugins/vite-chunk-plugin.d.ts +6 -0
  42. package/dist/types/Users/adrian.pripon/Documents/Work/widgets-monorepo/packages/stencil/player-step-up-auth/.stencil/tools/plugins/vite-clean-deps-plugin.d.ts +4 -0
  43. package/dist/types/components/player-step-up-auth/index.d.ts +1 -0
  44. package/dist/types/components/player-step-up-auth/player-step-up-auth.d.ts +168 -0
  45. package/dist/types/components.d.ts +93 -0
  46. package/dist/types/index.d.ts +1 -0
  47. package/dist/types/stencil-public-runtime.d.ts +1674 -0
  48. package/dist/types/utils/types.d.ts +0 -0
  49. package/dist/types/utils/utils.d.ts +2 -0
  50. package/loader/cdn.js +1 -0
  51. package/loader/index.cjs.js +1 -0
  52. package/loader/index.d.ts +24 -0
  53. package/loader/index.es2017.js +1 -0
  54. package/loader/index.js +2 -0
  55. package/loader/package.json +11 -0
  56. package/package.json +27 -0
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const playerStepUpAuth = require('./player-step-up-auth-2fac8df5.js');
6
+ require('./index-bf4d774c.js');
7
+
8
+
9
+
10
+ exports.PlayerStepUpAuth = playerStepUpAuth.PlayerStepUpAuth;
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const index = require('./index-bf4d774c.js');
6
+ const appGlobals = require('./app-globals-3a1e7e63.js');
7
+
8
+ const defineCustomElements = async (win, options) => {
9
+ if (typeof window === 'undefined') return undefined;
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);
12
+ };
13
+
14
+ exports.setNonce = index.setNonce;
15
+ exports.defineCustomElements = defineCustomElements;
@@ -0,0 +1,617 @@
1
+ 'use strict';
2
+
3
+ const index = require('./index-bf4d774c.js');
4
+
5
+ /**
6
+ * @name setClientStyling
7
+ * @description Method used to create and append to the passed element of the widget a style element with the content received
8
+ * @param {HTMLElement} stylingContainer The reference element of the widget
9
+ * @param {string} clientStyling The style content
10
+ */
11
+ function setClientStyling(stylingContainer, clientStyling) {
12
+ if (stylingContainer) {
13
+ const sheet = document.createElement('style');
14
+ sheet.innerHTML = clientStyling;
15
+ stylingContainer.appendChild(sheet);
16
+ }
17
+ }
18
+
19
+ /**
20
+ * @name setClientStylingURL
21
+ * @description Method used to create and append to the passed element of the widget a style element with the content fetched from a given URL
22
+ * @param {HTMLElement} stylingContainer The reference element of the widget
23
+ * @param {string} clientStylingUrl The URL of the style content
24
+ */
25
+ function setClientStylingURL(stylingContainer, clientStylingUrl) {
26
+ const url = new URL(clientStylingUrl);
27
+
28
+ fetch(url.href)
29
+ .then((res) => res.text())
30
+ .then((data) => {
31
+ const cssFile = document.createElement('style');
32
+ cssFile.innerHTML = data;
33
+ if (stylingContainer) {
34
+ stylingContainer.appendChild(cssFile);
35
+ }
36
+ })
37
+ .catch((err) => {
38
+ console.error('There was an error while trying to load client styling from URL', err);
39
+ });
40
+ }
41
+
42
+ /**
43
+ * @name setStreamLibrary
44
+ * @description Method used to create and append to the passed element of the widget a style element with content fetched from the MessageBus
45
+ * @param {HTMLElement} stylingContainer The highest element of the widget
46
+ * @param {string} domain The domain from where the content should be fetched (e.g. 'Casino.Style', 'App.Style', 'casino-footer.style', etc.)
47
+ * @param {ref} subscription A reference to a variable where the subscription should be saved for unsubscribing when no longer needed
48
+ */
49
+ function setStreamStyling(stylingContainer, domain, subscription) {
50
+ if (window.emMessageBus) {
51
+ const sheet = document.createElement('style');
52
+
53
+ window.emMessageBus.subscribe(domain, (data) => {
54
+ sheet.innerHTML = data;
55
+ if (stylingContainer) {
56
+ stylingContainer.appendChild(sheet);
57
+ }
58
+ });
59
+ }
60
+ }
61
+
62
+ const DEFAULT_LANGUAGE = 'en';
63
+ const TRANSLATIONS = {
64
+ en: {
65
+ popupMessage: 'Please enter the security code received on your email address to perform the update.',
66
+ minutes: 'minutes',
67
+ errorHeader: 'Error',
68
+ configError: 'Unable to load OTP data. Please try again later.',
69
+ otpHeading: 'Enter OTP',
70
+ resendOtp: 'Resent OTP',
71
+ submit: 'Submit',
72
+ close: 'Close',
73
+ invalidOtp: 'The code you\'ve sent is not valid. Please try again.',
74
+ accountBlocked: 'Too many attempts for OTP. Your account has been blocked for one hour.',
75
+ submissionError: 'Something went wrong. Please try again.'
76
+ },
77
+ ro: {
78
+ popupMessage: 'Introduceți codul de securitate primit pe adresa dvs. de e-mail pentru a efectua actualizarea.',
79
+ minutes: 'minute',
80
+ errorHeader: 'Eroare',
81
+ configError: 'Nu s-a putut încărca datele OTP. Vă rugăm să încercați din nou mai târziu.',
82
+ otpHeading: 'Introduceți OTP',
83
+ resendOtp: 'Retrimitere OTP',
84
+ submit: 'Trimite',
85
+ close: 'Închide',
86
+ invalidOtp: 'Codul introdus nu este valid. Vă rugăm să încercați din nou.',
87
+ 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
+ },
90
+ fr: {
91
+ popupMessage: 'Veuillez entrer le code de sécurité reçu sur votre adresse e-mail pour effectuer la mise à jour.',
92
+ minutes: 'minutes',
93
+ errorHeader: 'Erreur',
94
+ configError: 'Impossible de charger les données OTP. Veuillez réessayer plus tard.',
95
+ otpHeading: 'Entrez OTP',
96
+ resendOtp: 'Renvoyer OTP',
97
+ submit: 'Soumettre',
98
+ close: 'Fermer',
99
+ invalidOtp: 'Le code que vous avez saisi n’est pas valide. Veuillez réessayer.',
100
+ accountBlocked: 'Trop de tentatives OTP. Votre compte a été bloqué pendant une heure.',
101
+ submissionError: 'Quelque chose s\'est mal passé. Veuillez réessayer.'
102
+ },
103
+ hu: {
104
+ 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.',
105
+ minutes: 'perc',
106
+ errorHeader: 'Hiba',
107
+ configError: 'Nem sikerült betölteni az OTP adatokat. Kérjük, próbálja újra később.',
108
+ otpHeading: 'OTP megadása',
109
+ resendOtp: 'Újraküldés',
110
+ submit: 'Beküldés',
111
+ close: 'Bezárás',
112
+ invalidOtp: 'A megadott kód érvénytelen. Kérjük, próbálja újra.',
113
+ accountBlocked: 'Túl sok OTP próbálkozás. A fiókja egy órára zárolva lett.',
114
+ submissionError: 'Valami hiba történt. Kérjük, próbálja újra.'
115
+ },
116
+ tr: {
117
+ popupMessage: 'Güncellemeyi gerçekleştirmek için e-posta adresinize gelen güvenlik kodunu girin.',
118
+ minutes: 'dakika',
119
+ errorHeader: 'Hata',
120
+ configError: 'OTP verisi yüklenemedi. Lütfen daha sonra tekrar deneyin.',
121
+ otpHeading: 'OTP Girin',
122
+ resendOtp: 'OTP\'yi Yeniden Gönder',
123
+ submit: 'Gönder',
124
+ close: 'Kapat',
125
+ invalidOtp: 'Gönderdiğiniz kod geçersiz. Lütfen tekrar deneyin.',
126
+ accountBlocked: 'Çok fazla OTP denemesi yapıldı. Hesabınız bir saat boyunca kilitlendi.',
127
+ submissionError: 'Bir şeyler yanlış gitti. Lütfen tekrar deneyin.'
128
+ },
129
+ el: {
130
+ popupMessage: 'Παρακαλώ εισάγετε τον κωδικό ασφαλείας που λάβατε στο email σας για να ολοκληρώσετε την ενημέρωση.',
131
+ minutes: 'λεπτά',
132
+ errorHeader: 'Σφάλμα',
133
+ configError: 'Δεν ήταν δυνατή η φόρτωση των δεδομένων OTP. Παρακαλούμε προσπαθήστε ξανά αργότερα.',
134
+ otpHeading: 'Εισαγωγή OTP',
135
+ resendOtp: 'Αποστολή ξανά OTP',
136
+ submit: 'Υποβολή',
137
+ close: 'Κλείσιμο',
138
+ invalidOtp: 'Ο κωδικός που εισαγάγατε δεν είναι έγκυρος. Παρακαλώ προσπαθήστε ξανά.',
139
+ accountBlocked: 'Πάρα πολλές προσπάθειες OTP. Ο λογαριασμός σας έχει αποκλειστεί για μία ώρα.',
140
+ submissionError: 'Κάτι πήγε στραβά. Παρακαλώ προσπαθήστε ξανά.'
141
+ },
142
+ es: {
143
+ popupMessage: 'Por favor, introduzca el código de seguridad recibido en su correo electrónico para realizar la actualización.',
144
+ minutes: 'minutos',
145
+ errorHeader: 'Error',
146
+ configError: 'No se pudo cargar los datos del OTP. Por favor, inténtelo de nuevo más tarde.',
147
+ otpHeading: 'Introducir OTP',
148
+ resendOtp: 'Reenviar OTP',
149
+ submit: 'Enviar',
150
+ close: 'Cerrar',
151
+ invalidOtp: 'El código que ingresaste no es válido. Por favor, inténtalo de nuevo.',
152
+ accountBlocked: 'Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.',
153
+ submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.'
154
+ },
155
+ pt: {
156
+ popupMessage: 'Por favor, insira o código de segurança recebido no seu e-mail para realizar a atualização.',
157
+ minutes: 'minutos',
158
+ errorHeader: 'Erro',
159
+ configError: 'Não foi possível carregar os dados do OTP. Tente novamente mais tarde.',
160
+ otpHeading: 'Insira o OTP',
161
+ resendOtp: 'Reenviar OTP',
162
+ submit: 'Enviar',
163
+ close: 'Fechar',
164
+ invalidOtp: 'O código inserido não é válido. Por favor, tente novamente.',
165
+ accountBlocked: 'Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.',
166
+ submissionError: 'Algo deu errado. Por favor, tente novamente.'
167
+ },
168
+ hr: {
169
+ popupMessage: 'Unesite sigurnosni kod primljen na vašu e-mail adresu kako biste izvršili ažuriranje.',
170
+ minutes: 'minute',
171
+ errorHeader: 'Greška',
172
+ configError: 'Nije moguće učitati OTP podatke. Pokušajte ponovno kasnije.',
173
+ otpHeading: 'Unesite OTP',
174
+ resendOtp: 'Ponovno pošalji OTP',
175
+ submit: 'Pošalji',
176
+ close: 'Zatvori',
177
+ invalidOtp: 'Uneseni kod nije valjan. Molimo pokušajte ponovo.',
178
+ accountBlocked: 'Previše pokušaja unosa OTP-a. Vaš račun je blokiran na jedan sat.',
179
+ submissionError: 'Nešto je pošlo po zlu. Molimo pokušajte ponovo.'
180
+ },
181
+ de: {
182
+ popupMessage: 'Bitte geben Sie den Sicherheitscode ein, den Sie an Ihre E-Mail-Adresse erhalten haben, um das Update durchzuführen.',
183
+ minutes: 'Minuten',
184
+ errorHeader: 'Fehler',
185
+ configError: 'OTP-Daten konnten nicht geladen werden. Bitte versuchen Sie es später erneut.',
186
+ otpHeading: 'OTP eingeben',
187
+ resendOtp: 'OTP erneut senden',
188
+ submit: 'Absenden',
189
+ close: 'Schließen',
190
+ invalidOtp: 'Der eingegebene Code ist ungültig. Bitte versuchen Sie es erneut.',
191
+ accountBlocked: 'Zu viele OTP-Versuche. Ihr Konto wurde für eine Stunde gesperrt.',
192
+ submissionError: 'Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.'
193
+ },
194
+ 'es-mx': {
195
+ popupMessage: 'Por favor, ingrese el código de seguridad recibido en su correo electrónico para realizar la actualización.',
196
+ minutes: 'minutos',
197
+ errorHeader: 'Error',
198
+ configError: 'No se pudieron cargar los datos del OTP. Inténtelo de nuevo más tarde.',
199
+ otpHeading: 'Ingrese OTP',
200
+ resendOtp: 'Reenviar OTP',
201
+ submit: 'Enviar',
202
+ close: 'Cerrar',
203
+ invalidOtp: 'El código que ingresó no es válido. Inténtelo de nuevo.',
204
+ accountBlocked: 'Demasiados intentos de OTP. Su cuenta ha sido bloqueada por una hora.',
205
+ submissionError: 'Algo salió mal. Por favor, inténtelo de nuevo.'
206
+ },
207
+ 'pt-br': {
208
+ popupMessage: 'Por favor, digite o código de segurança recebido no seu e-mail para realizar a atualização.',
209
+ minutes: 'minutos',
210
+ errorHeader: 'Erro',
211
+ configError: 'Não foi possível carregar os dados do OTP. Tente novamente mais tarde.',
212
+ otpHeading: 'Digite o OTP',
213
+ resendOtp: 'Reenviar OTP',
214
+ submit: 'Enviar',
215
+ close: 'Fechar',
216
+ invalidOtp: 'O código informado não é válido. Tente novamente.',
217
+ accountBlocked: 'Muitas tentativas de OTP. Sua conta foi bloqueada por uma hora.',
218
+ submissionError: 'Algo deu errado. Por favor, tente novamente.'
219
+ },
220
+ };
221
+ const getTranslations = (url) => {
222
+ return new Promise((resolve) => {
223
+ fetch(url)
224
+ .then((res) => res.json())
225
+ .then((data) => {
226
+ Object.keys(data).forEach((item) => {
227
+ for (let key in data[item]) {
228
+ TRANSLATIONS[item][key] = data[item][key];
229
+ }
230
+ });
231
+ resolve(true);
232
+ });
233
+ });
234
+ };
235
+ const translate = (key, customLang) => {
236
+ const lang = customLang;
237
+ return TRANSLATIONS[lang !== undefined ? lang : DEFAULT_LANGUAGE][key];
238
+ };
239
+
240
+ const playerStepUpAuthCss = ".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)}}";
241
+ const PlayerStepUpAuthStyle0 = playerStepUpAuthCss;
242
+
243
+ const PlayerStepUpAuth = class {
244
+ /**
245
+ * Watch for changes in the translation URL and fetch new translations
246
+ */
247
+ handleNewTranslations() {
248
+ getTranslations(this.translationUrl);
249
+ }
250
+ /**
251
+ * Watch for changes in the client styling and apply the new styling
252
+ *
253
+ * @param newValue - new client styling
254
+ * @param oldValue - previous client styling
255
+ */
256
+ handleClientStylingChange(newValue, oldValue) {
257
+ if (newValue !== oldValue) {
258
+ setClientStyling(this.el, this.clientStyling);
259
+ }
260
+ }
261
+ /**
262
+ * Watch for changes in the client styling URL and fetch the new CSS
263
+ *
264
+ * @param newValue - new client styling URL
265
+ * @param oldValue - previous client styling URL
266
+ */
267
+ handleClientStylingUrlChange(newValue, oldValue) {
268
+ if (newValue != oldValue) {
269
+ if (this.clientStylingUrl)
270
+ setClientStylingURL(this.stylingContainer, this.clientStylingUrl);
271
+ }
272
+ }
273
+ async handleStepUpAuthEvent(event) {
274
+ var _a;
275
+ if ((_a = event.detail) === null || _a === void 0 ? void 0 : _a['x-step-up-required']) {
276
+ this.hasConfigErrors = false;
277
+ this.hasErrors = false;
278
+ this.errorMessage = '';
279
+ this.showPopup = true;
280
+ this.token = event.detail['x-step-up-token'];
281
+ await this.getConfig();
282
+ }
283
+ }
284
+ /**
285
+ * Class constructor
286
+ */
287
+ constructor(hostRef) {
288
+ index.registerInstance(this, hostRef);
289
+ this.otpInputs = [];
290
+ this.countdownTimer = null;
291
+ this.mbSource = undefined;
292
+ this.clientStyling = undefined;
293
+ this.clientStylingUrl = undefined;
294
+ this.language = 'en';
295
+ this.endpoint = undefined;
296
+ this.userSession = undefined;
297
+ this.translationUrl = '';
298
+ this.showPopup = false;
299
+ this.otp = undefined;
300
+ this.isLoading = true;
301
+ this.config = null;
302
+ this.timeLeft = 0;
303
+ this.expirationTime = '';
304
+ this.serverTime = '';
305
+ this.hasErrors = false;
306
+ this.hasConfigErrors = false;
307
+ this.errorMessage = '';
308
+ this.token = '';
309
+ this.showResendOtp = false;
310
+ this.closePopup = this.closePopup.bind(this);
311
+ this.handleResendOtp = this.handleResendOtp.bind(this);
312
+ this.submitOtp = this.submitOtp.bind(this);
313
+ this.setOtpContainerRef = this.setOtpContainerRef.bind(this);
314
+ }
315
+ /**
316
+ * Fetches OTP configuration from the endpoint.
317
+ * Updates the OTP state, expiration time, and starts the countdown timer.
318
+ */
319
+ async getConfig() {
320
+ if (!this.endpoint)
321
+ return;
322
+ try {
323
+ const url = new URL(`/api/v1/mfa/challenge/${this.token}/config`, this.endpoint);
324
+ this.isLoading = true;
325
+ const response = await fetch(url.href);
326
+ if (!response.ok)
327
+ throw new Error(`HTTP error! Status: ${response.status}`);
328
+ this.config = await response.json();
329
+ this.otp = new Array(this.config.inputLength).fill('');
330
+ this.isLoading = false;
331
+ this.showResendOtp = false;
332
+ this.expirationTime = this.config.expirationTime;
333
+ this.serverTime = this.config.serverTime;
334
+ this.calculateTimeLeft();
335
+ this.startCountdown();
336
+ }
337
+ catch (error) {
338
+ this.isLoading = false;
339
+ this.hasConfigErrors = true;
340
+ this.errorMessage = translate('configError', this.language);
341
+ console.error('Error loading 2FA config:', error);
342
+ }
343
+ }
344
+ /**
345
+ * Starts the countdown timer for OTP expiration.
346
+ * - Clears any existing timer to prevent duplicate intervals.
347
+ * - Decreases `timeLeft` every second.
348
+ * - Stops the countdown when time reaches 0.
349
+ * - Shows the "Resend OTP" option when time runs out.
350
+ */
351
+ calculateTimeLeft() {
352
+ const expirationDate = new Date(this.expirationTime);
353
+ const serverTime = new Date(this.serverTime);
354
+ if (!this.currentTime) {
355
+ this.currentTime = new Date();
356
+ }
357
+ // Calculate the offset (difference between server time and local time)
358
+ const offset = serverTime.getTime() - this.currentTime.getTime();
359
+ // Adjust current time using the offset
360
+ const adjustedCurrentDate = new Date(this.currentTime.getTime() + offset);
361
+ // Calculate time left in seconds
362
+ this.timeLeft = Math.floor((expirationDate.getTime() - adjustedCurrentDate.getTime()) / 1000);
363
+ }
364
+ /**
365
+ * Starts a countdown timer for OTP expiration.
366
+ * Decreases `timeLeft` every second and closes the popup when time runs out.
367
+ */
368
+ startCountdown() {
369
+ if (this.countdownTimer) {
370
+ clearInterval(this.countdownTimer); // Clear any existing timer
371
+ }
372
+ this.countdownTimer = setInterval(() => {
373
+ if (this.timeLeft > 0) {
374
+ this.timeLeft -= 1; // Update state correctly
375
+ }
376
+ else {
377
+ clearInterval(this.countdownTimer);
378
+ this.countdownTimer = null;
379
+ this.showResendOtp = true;
380
+ }
381
+ }, 1000);
382
+ }
383
+ /**
384
+ * Formats time from seconds to MM:SS format.
385
+ *
386
+ * @param seconds - The time in seconds.
387
+ * @returns A formatted string representing minutes and seconds.
388
+ */
389
+ formatTime(seconds) {
390
+ const minutes = Math.floor(seconds / 60);
391
+ const remainingSeconds = seconds % 60;
392
+ return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
393
+ }
394
+ /**
395
+ * Sets a reference to the OTP input container.
396
+ *
397
+ * @param el - The OTP input container element.
398
+ */
399
+ setOtpContainerRef(el) {
400
+ if (el)
401
+ this.otpContainer = el;
402
+ }
403
+ /**
404
+ * Sets a reference to the OTP inputs.
405
+ *
406
+ * @param el - The OTP input container element.
407
+ */
408
+ setOtpInputRef(el, index) {
409
+ if (el) {
410
+ this.otpInputs[index] = el;
411
+ }
412
+ }
413
+ /**
414
+ * Handles pasting an OTP directly into the input fields.
415
+ * Extracts characters from the clipboard and populates the OTP fields.
416
+ *
417
+ * @param e - The clipboard event containing pasted data.
418
+ */
419
+ handleOnPasteOtp(e) {
420
+ var _a;
421
+ e.preventDefault();
422
+ const data = (_a = e.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text').trim();
423
+ if (!data)
424
+ return;
425
+ const value = data.slice(0, this.config.inputLength).split(""); // Limit to OTP length
426
+ this.otp = [...value, ...new Array(this.config.inputLength - value.length).fill('')];
427
+ const inputs = Array.from(this.otpContainer.children);
428
+ if (inputs) {
429
+ value.forEach((char, index) => {
430
+ inputs[index].value = char;
431
+ });
432
+ // Move focus to the last input or trigger submit
433
+ const lastInput = inputs[value.length - 1];
434
+ lastInput === null || lastInput === void 0 ? void 0 : lastInput.focus();
435
+ if (value.length === this.config.inputLength) {
436
+ this.submitOtp();
437
+ }
438
+ }
439
+ }
440
+ /**
441
+ * Handles OTP input changes.
442
+ * Allows only alphanumeric characters and moves focus to the next input field.
443
+ *
444
+ * @param e - The input event.
445
+ * @param index - The index of the input field being updated.
446
+ */
447
+ handleOtpInput(e, index) {
448
+ const input = e.target;
449
+ let value = input.value.replace(/[^0-9a-zA-Z]/gi, '').toUpperCase();
450
+ input.value = value.charAt(0);
451
+ if (!value)
452
+ return;
453
+ this.otp[index] = value[0];
454
+ // Move focus using stored refs
455
+ const nextInput = this.otpInputs[index + 1];
456
+ nextInput === null || nextInput === void 0 ? void 0 : nextInput.focus();
457
+ }
458
+ /**
459
+ * Handles key press events for OTP inputs.
460
+ * Supports backspace for deleting characters and moving focus to the previous input field.
461
+ *
462
+ * @param e - The keyboard event.
463
+ * @param index - The index of the input field.
464
+ */
465
+ handleKeyDown(e, index) {
466
+ if (e.key === "Backspace") {
467
+ this.otp[index] = '';
468
+ this.otpInputs[index].value = ''; // Clear input field
469
+ const prevInput = this.otpInputs[index - 1];
470
+ prevInput === null || prevInput === void 0 ? void 0 : prevInput.focus();
471
+ }
472
+ }
473
+ /**
474
+ * Handles resending the OTP when time expires.
475
+ */
476
+ handleResendOtp() {
477
+ // 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
+ });
481
+ window.dispatchEvent(event);
482
+ }
483
+ /**
484
+ * Submits the entered OTP for validation.
485
+ * Sends a request to the endpoint with the OTP and handles the response.
486
+ */
487
+ async submitOtp() {
488
+ if (this.otp.join('').length !== this.config.inputLength) {
489
+ this.hasErrors = true;
490
+ this.errorMessage = translate('invalidOtp', this.language);
491
+ return;
492
+ }
493
+ this.isLoading = true; // Set loading state
494
+ this.hasErrors = false;
495
+ this.errorMessage = '';
496
+ const otpValue = this.otp.join('');
497
+ const url = new URL(`/api/v1/mfa/challenge/${this.token}/validate`, this.endpoint);
498
+ url.searchParams.append('input', otpValue);
499
+ try {
500
+ const response = await fetch(url.href, { method: 'POST' });
501
+ if (response.status === 200) {
502
+ this.handleSuccess();
503
+ return;
504
+ }
505
+ const result = await response.json();
506
+ throw new Error(result.message);
507
+ }
508
+ catch (error) {
509
+ if (error.message === 'gm.multifactorauthentication.challenge') {
510
+ if (this.config.numberOfValidateAttempts === (this.config.maxValidationAttempts - 1)) {
511
+ //Set timeout for 1h
512
+ const serverTime = new Date(this.serverTime);
513
+ serverTime.setHours(serverTime.getHours() + 1);
514
+ const timeoutExpiryDate = serverTime.toISOString().slice(0, 16).replace('T', ' ');
515
+ window.postMessage({
516
+ type: 'SetPlayerAccountTimeout',
517
+ timeoutSelected: 'CoolOffUntilSelectedDate',
518
+ timeoutExpiryDate
519
+ }, window.location.href);
520
+ //Trigger notification
521
+ window.postMessage({
522
+ type: 'WidgetNotification',
523
+ data: {
524
+ type: 'error',
525
+ message: translate('accountBlocked', this.language)
526
+ }
527
+ }, window.location.href);
528
+ this.closePopup();
529
+ return;
530
+ }
531
+ this.hasErrors = true;
532
+ this.errorMessage = translate('invalidOtp', this.language);
533
+ this.getConfig();
534
+ return;
535
+ }
536
+ console.error('OTP submission failed:', error);
537
+ this.hasErrors = true;
538
+ this.errorMessage = translate('submissionError', this.language);
539
+ }
540
+ finally {
541
+ this.isLoading = false;
542
+ }
543
+ }
544
+ /**
545
+ * Handles successful OTP validation.
546
+ * Closes the popup upon successful authentication.
547
+ */
548
+ handleSuccess() {
549
+ window.dispatchEvent(new CustomEvent('otpSuccess', {
550
+ detail: { message: 'User successfully authenticated' }
551
+ }));
552
+ this.closePopup();
553
+ }
554
+ /**
555
+ * Closes the OTP popup.
556
+ * Resets the authentication UI state.
557
+ */
558
+ closePopup() {
559
+ this.showPopup = false;
560
+ window.dispatchEvent(new CustomEvent('popupClosed', {
561
+ detail: { message: 'User closed the popup' }
562
+ }));
563
+ }
564
+ /**
565
+ * Lifecycle method: Clean up event listeners when the component is removed
566
+ */
567
+ disconnectedCallback() {
568
+ var _a;
569
+ if (this.countdownTimer) {
570
+ clearInterval(this.countdownTimer);
571
+ }
572
+ (_a = this.stylingSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
573
+ }
574
+ /**
575
+ * Lifecycle method: Fetch translations on component load
576
+ */
577
+ async componentWillLoad() {
578
+ if (this.translationUrl.length > 2) {
579
+ await getTranslations(this.translationUrl);
580
+ }
581
+ }
582
+ /**
583
+ * Lifecycle method: Set up event listeners after the component is rendered
584
+ */
585
+ componentDidLoad() {
586
+ if (this.stylingContainer) {
587
+ if (window.emMessageBuss != undefined) {
588
+ setStreamStyling(this.stylingContainer, `${this.mbSource}.Style`);
589
+ }
590
+ else {
591
+ if (this.clientStyling)
592
+ setClientStyling(this.stylingContainer, this.clientStyling);
593
+ if (this.clientStylingUrl)
594
+ setClientStylingURL(this.stylingContainer, this.clientStylingUrl);
595
+ }
596
+ }
597
+ }
598
+ /**
599
+ * Renders the OTP authentication component.
600
+ * Displays the OTP popup, input fields, timer, and action buttons.
601
+ */
602
+ render() {
603
+ return (index.h("div", { key: '2761de23ad41b4ead177d63931e7756584defd11' }, this.showPopup && (index.h("div", { key: '1d01dd47770c5190a5c5c3e0c6e2c4af9e71ae15', class: "OtpPopupOverlay" }, index.h("div", { key: '626dbc731ca03790bf9cae42e56919851928a36f', 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
+ const isHalfway = this.config.inputLength % 2 === 0 && index$1 === (this.config.inputLength / 2) - 1;
605
+ 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
+ })), 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)))))))))));
607
+ }
608
+ get el() { return index.getElement(this); }
609
+ static get watchers() { return {
610
+ "translationUrl": ["handleNewTranslations"],
611
+ "clientStyling": ["handleClientStylingChange"],
612
+ "clientStylingUrl": ["handleClientStylingUrlChange"]
613
+ }; }
614
+ };
615
+ PlayerStepUpAuth.style = PlayerStepUpAuthStyle0;
616
+
617
+ exports.PlayerStepUpAuth = PlayerStepUpAuth;
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const playerStepUpAuth = require('./player-step-up-auth-2fac8df5.js');
6
+ require('./index-bf4d774c.js');
7
+
8
+
9
+
10
+ exports.player_step_up_auth = playerStepUpAuth.PlayerStepUpAuth;