@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.
- package/dist/cjs/app-globals-3a1e7e63.js +5 -0
- package/dist/cjs/index-bf4d774c.js +1330 -0
- package/dist/cjs/index.cjs.js +10 -0
- package/dist/cjs/loader.cjs.js +15 -0
- package/dist/cjs/player-step-up-auth-2fac8df5.js +617 -0
- package/dist/cjs/player-step-up-auth.cjs.entry.js +10 -0
- package/dist/cjs/player-step-up-auth.cjs.js +25 -0
- package/dist/collection/collection-manifest.json +12 -0
- package/dist/collection/components/player-step-up-auth/index.js +1 -0
- package/dist/collection/components/player-step-up-auth/player-step-up-auth.css +131 -0
- package/dist/collection/components/player-step-up-auth/player-step-up-auth.js +543 -0
- package/dist/collection/index.js +1 -0
- package/dist/collection/utils/types.js +0 -0
- package/dist/collection/utils/utils.js +177 -0
- package/dist/esm/app-globals-0f993ce5.js +3 -0
- package/dist/esm/index-c6eee6d8.js +1302 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/loader.js +11 -0
- package/dist/esm/player-step-up-auth-009badea.js +615 -0
- package/dist/esm/player-step-up-auth.entry.js +2 -0
- package/dist/esm/player-step-up-auth.js +20 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/player-step-up-auth/index.esm.js +1 -0
- package/dist/player-step-up-auth/p-3b187b6e.entry.js +1 -0
- package/dist/player-step-up-auth/p-c6a4faff.js +2 -0
- package/dist/player-step-up-auth/p-e1255160.js +1 -0
- package/dist/player-step-up-auth/p-f97ac666.js +1 -0
- package/dist/player-step-up-auth/player-step-up-auth.esm.js +1 -0
- package/dist/stencil.config.dev.js +19 -0
- package/dist/stencil.config.js +18 -0
- package/dist/storybook/main.js +43 -0
- package/dist/storybook/preview.js +9 -0
- 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
- 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
- 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
- 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
- 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
- package/dist/types/Users/adrian.pripon/Documents/Work/widgets-monorepo/packages/stencil/player-step-up-auth/.stencil/tools/plugins/index.d.ts +3 -0
- 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
- 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
- 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
- package/dist/types/components/player-step-up-auth/index.d.ts +1 -0
- package/dist/types/components/player-step-up-auth/player-step-up-auth.d.ts +168 -0
- package/dist/types/components.d.ts +93 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/stencil-public-runtime.d.ts +1674 -0
- package/dist/types/utils/types.d.ts +0 -0
- package/dist/types/utils/utils.d.ts +2 -0
- package/loader/cdn.js +1 -0
- package/loader/index.cjs.js +1 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +1 -0
- package/loader/index.js +2 -0
- package/loader/package.json +11 -0
- package/package.json +27 -0
|
@@ -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;
|