@everymatrix/user-login 1.46.1 → 1.47.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.
@@ -1,13 +1,20 @@
1
1
  import { h } from "@stencil/core";
2
2
  import { getTranslations, translate } from "../../utils/locale.utils";
3
+ import "@vaadin/combo-box";
3
4
  export class UserLogin {
4
5
  constructor() {
5
6
  this.errorCode = '';
7
+ /**
8
+ * Apply inline client styling
9
+ */
6
10
  this.setClientStyling = () => {
7
11
  let sheet = document.createElement('style');
8
12
  sheet.innerHTML = this.clientStyling;
9
13
  this.stylingContainer.appendChild(sheet);
10
14
  };
15
+ /**
16
+ * Fetch and apply CSS from a provided URL
17
+ */
11
18
  this.setClientStylingURL = () => {
12
19
  let url = new URL(this.clientStylingUrl);
13
20
  let cssFile = document.createElement('style');
@@ -18,28 +25,128 @@ export class UserLogin {
18
25
  setTimeout(() => { this.stylingContainer.appendChild(cssFile); }, 1);
19
26
  });
20
27
  };
28
+ /**
29
+ * Fetch phone prefixes from the API
30
+ */
31
+ this.getPhonePrefixes = () => {
32
+ const url = new URL('v1/player/validPhoneCodes', this.endpoint);
33
+ return new Promise((resolve) => {
34
+ fetch(url.href)
35
+ .then((res) => res.json())
36
+ .then((res) => {
37
+ this.userPrefixOptions = res.phoneCodes.map(code => {
38
+ return { label: code.Prefix, value: code.Prefix };
39
+ });
40
+ resolve();
41
+ });
42
+ });
43
+ };
44
+ /**
45
+ * Handle autofilling of credentials from a dispatched event
46
+ */
21
47
  this.autofillCredentialsHandler = (e) => {
22
48
  this.userNameEmail = e.detail.userNameEmail;
23
49
  this.userPassword = e.detail.userPassword;
24
50
  this.handleLogin();
25
51
  };
26
- this.userLogin = async ({ username, password }) => {
52
+ /**
53
+ * Login API call for Gm 1.7
54
+ */
55
+ this.userLoginGm17 = async () => {
27
56
  let headers = {
28
57
  'Content-Type': 'application/json'
29
58
  };
30
- let bodyData = {
31
- username,
32
- password
59
+ const bodyData = {
60
+ contact: this.userNameEmail,
61
+ password: this.userPassword
62
+ };
63
+ const options = {
64
+ method: 'POST',
65
+ headers,
66
+ body: JSON.stringify(bodyData),
67
+ };
68
+ try {
69
+ const res = await fetch(`${this.endpoint}/api/v1/players/password-management/auth/password/verify`, options);
70
+ const data = await res.json();
71
+ const { token } = data;
72
+ if (token) {
73
+ // Perform the second API call
74
+ await this.sendLegislationLogin(token);
75
+ }
76
+ else {
77
+ throw new Error('Token not received from the API call.');
78
+ }
79
+ }
80
+ catch (err) {
81
+ // Handle unexpected errors
82
+ console.error(err);
83
+ this.hasError = true;
84
+ this.errorMessage = translate('genericError', this.lang);
85
+ this.sendErrorNotification(this.errorMessage);
86
+ }
87
+ };
88
+ /**
89
+ * Function to send legislation login request
90
+ */
91
+ this.sendLegislationLogin = async (token) => {
92
+ const headers = {
93
+ 'Content-Type': 'application/json'
94
+ };
95
+ const bodyData = {
96
+ token,
97
+ method: 'login'
33
98
  };
34
- let options = {
99
+ const options = {
35
100
  method: 'POST',
36
101
  headers,
37
102
  body: JSON.stringify(bodyData),
38
103
  };
39
- fetch(`${this.endpoint}/v1/player/legislation/login`, options)
40
- .then((res) => {
41
- return res.json();
42
- }).then((data) => {
104
+ try {
105
+ const res = await fetch(`${this.endpoint}/api/v2/gm/legislation/login`, options);
106
+ const responseBody = await res.json();
107
+ if (res.ok) {
108
+ const { sessionId, playerId } = responseBody;
109
+ if (sessionId) {
110
+ window.postMessage({ type: 'UserSessionID', session: sessionId, userid: playerId }, window.location.href);
111
+ window.postMessage({ type: 'WidgetNotification', data: {
112
+ type: 'success',
113
+ message: translate('successMessage', this.lang)
114
+ } }, window.location.href);
115
+ this.hasError = false;
116
+ }
117
+ }
118
+ else {
119
+ const { message, errors } = responseBody;
120
+ console.error(`Legislation login failed: ${message}`, errors);
121
+ throw new Error('Legislation login request failed.');
122
+ }
123
+ }
124
+ catch (err) {
125
+ console.error(err);
126
+ this.hasError = true;
127
+ this.errorMessage = translate('genericError', this.lang);
128
+ this.sendErrorNotification(this.errorMessage);
129
+ }
130
+ };
131
+ /**
132
+ * Login API call
133
+ */
134
+ this.userLogin = async () => {
135
+ const url = new URL('/v1/player/legislation/login', this.endpoint);
136
+ const headers = new Headers();
137
+ headers.append('Content-Type', 'application/json');
138
+ const body = JSON.stringify({
139
+ username: this.loginByPhoneNumber === 'true' ? `${this.userPrefix} ${this.userPhone}` : this.userNameEmail,
140
+ password: this.userPassword
141
+ });
142
+ const params = {
143
+ method: 'POST',
144
+ headers: headers,
145
+ body: body
146
+ };
147
+ fetch(url.href, params)
148
+ .then((res) => res.json())
149
+ .then((data) => {
43
150
  var _a, _b, _c;
44
151
  if ((_a = data.sessionBlockers) === null || _a === void 0 ? void 0 : _a.includes('has-to-set-consents')) {
45
152
  window.postMessage({ type: 'PlayerActions', gmversion: 'gm16' }, window.location.href);
@@ -73,37 +180,80 @@ export class UserLogin {
73
180
  this.sendErrorNotification(this.errorMessage);
74
181
  });
75
182
  };
76
- this.debouncedUserLogin = this.debounce(this.userLogin, 850);
183
+ /**
184
+ * Trigger login process
185
+ */
77
186
  this.handleLogin = () => {
78
- this.debouncedUserLogin({
79
- username: this.userNameEmail,
80
- password: this.userPassword
81
- });
187
+ const DEBOUNCE_DELAY = 850;
188
+ const loginActions = {
189
+ gm16: this.userLogin,
190
+ gm17: this.userLoginGm17,
191
+ };
192
+ const loginAction = loginActions[this.version] || this.userLogin;
193
+ // Apply debounce with the selected function
194
+ const debouncedLogin = this.debounce(loginAction, DEBOUNCE_DELAY);
195
+ debouncedLogin();
82
196
  this.dispatchUpdateLoginCredentialsEvent();
83
197
  };
198
+ /**
199
+ * Handle input changes for username/email and password
200
+ *
201
+ * @param event - input event
202
+ * @param location - 'user' | 'phone' | 'password'
203
+ */
84
204
  this.handleInputChange = (event, location) => {
85
205
  this.hasError = false;
86
206
  const inputValue = event.target.value;
87
- if (location === 'user') {
88
- this.userNameEmail = inputValue;
89
- this.isValidUserEmail = this.userEmailValidation(this.userNameEmail);
207
+ switch (location) {
208
+ case 'user':
209
+ this.userNameEmail = inputValue;
210
+ this.isValidUserEmail = this.validate('user', this.userNameEmail);
211
+ break;
212
+ case 'phone':
213
+ this.userPhone = inputValue;
214
+ this.isValidUserPhone = this.validate('phone', this.userPhone);
215
+ break;
216
+ case 'prefix':
217
+ this.userPrefix = inputValue;
218
+ this.isValidUserPhone = this.validate('phone', this.userPhone);
219
+ break;
220
+ case 'password':
221
+ this.userPassword = inputValue;
222
+ this.isValidPassword = this.validate('password', inputValue);
223
+ break;
90
224
  }
91
- else {
92
- this.userPassword = inputValue;
93
- this.isValidPassword = this.passwordValidation(inputValue);
94
- }
95
- };
96
- this.userEmailValidation = (input) => {
97
- const regex = new RegExp(this.userEmailRegex, this.userEmailRegexOptions);
98
- return regex.test(input);
99
225
  };
100
- this.passwordValidation = (input) => {
101
- const regex = new RegExp(this.passwordRegex, this.passwordRegexOptions);
102
- return regex.test(input);
226
+ // this partially applies the location to avoid constructing an anonymous function in jsx, i.e. (e)=>handleInputChange(e,location), which would be needed for 2 args
227
+ this.handleInputChangePartial = (location) => (e) => this.handleInputChange(e, location);
228
+ /**
229
+ * Validate input based on the specific regex
230
+ *
231
+ * @param useRuleFor - 'user' | 'phone' | 'password'
232
+ * @param input - input value to validate
233
+ */
234
+ this.validate = (useRuleFor, input) => {
235
+ let regex;
236
+ switch (useRuleFor) {
237
+ case 'user':
238
+ regex = new RegExp(this.userEmailRegex, this.userEmailRegexOptions);
239
+ return regex.test(input);
240
+ case 'phone':
241
+ regex = new RegExp(this.userPhoneRegex, this.userPhoneRegexOptions);
242
+ return regex.test(input) && !!this.userPrefix;
243
+ case 'password':
244
+ regex = new RegExp(this.passwordRegex, this.passwordRegexOptions);
245
+ return regex.test(input);
246
+ }
103
247
  };
248
+ /**
249
+ * Toggle password
250
+ */
104
251
  this.togglePassword = () => {
105
252
  this.isPasswordVisible = !this.isPasswordVisible;
106
253
  };
254
+ /**
255
+ * Reset password
256
+ */
107
257
  this.resetPassword = () => {
108
258
  window.postMessage({ type: "NavForgotPassword" }, window.location.href);
109
259
  };
@@ -115,31 +265,73 @@ export class UserLogin {
115
265
  this.passwordReset = 'false';
116
266
  this.userEmailRegex = undefined;
117
267
  this.userEmailRegexOptions = 'i';
268
+ this.userPhoneRegex = undefined;
269
+ this.userPhoneRegexOptions = '';
118
270
  this.passwordRegex = undefined;
119
271
  this.passwordRegexOptions = '';
272
+ this.version = 'gm16';
273
+ this.loginByPhoneNumber = 'false';
120
274
  this.userNameEmail = '';
121
275
  this.userPassword = '';
122
276
  this.isValidUserEmail = true;
277
+ this.userPhone = '';
278
+ this.userPrefix = '';
123
279
  this.isValidPassword = true;
280
+ this.isValidUserPhone = true;
124
281
  this.isPasswordVisible = false;
125
282
  this.limitStylingAppends = false;
126
283
  this.errorMessage = '';
127
284
  this.hasError = false;
285
+ this.userPrefixOptions = undefined;
128
286
  }
287
+ /**
288
+ * Watch for changes in the translation URL and fetch new translations
289
+ */
129
290
  handleNewTranslations() {
130
291
  getTranslations(this.translationUrl);
131
292
  }
293
+ /**
294
+ * Watch for changes in the client styling and apply the new styling
295
+ *
296
+ * @param newValue - new client styling
297
+ * @param oldValue - previous client styling
298
+ */
299
+ handleStylingChange(newValue, oldValue) {
300
+ if (newValue !== oldValue)
301
+ this.setClientStyling();
302
+ }
303
+ /**
304
+ * Watch for changes in the client styling URL and fetch the new CSS
305
+ *
306
+ * @param newValue - new client styling URL
307
+ * @param oldValue - previous client styling URL
308
+ */
309
+ handleStylingUrlChange(newValue, oldValue) {
310
+ if (newValue !== oldValue)
311
+ this.setClientStylingURL();
312
+ }
313
+ /**
314
+ * Lifecycle method: Fetch translations on component load
315
+ */
132
316
  async componentWillLoad() {
317
+ if (this.loginByPhoneNumber === 'true') {
318
+ await this.getPhonePrefixes();
319
+ }
133
320
  if (this.translationUrl.length > 2) {
134
321
  await getTranslations(this.translationUrl);
135
322
  }
136
323
  }
324
+ /**
325
+ * Lifecycle method: Set up event listeners after the component is rendered
326
+ */
137
327
  componentDidLoad() {
138
328
  window.addEventListener('LoginCredentials', this.autofillCredentialsHandler);
139
329
  window.postMessage({ type: 'UserLoginDidLoad' });
140
330
  }
331
+ /**
332
+ * Lifecycle method: Apply client styling after the component renders
333
+ */
141
334
  componentDidRender() {
142
- // start custom styling area
143
335
  if (!this.limitStylingAppends && this.stylingContainer) {
144
336
  if (this.clientStyling)
145
337
  this.setClientStyling();
@@ -147,11 +339,16 @@ export class UserLogin {
147
339
  this.setClientStylingURL();
148
340
  this.limitStylingAppends = true;
149
341
  }
150
- // end custom styling area
151
342
  }
343
+ /**
344
+ * Lifecycle method: Clean up event listeners when the component is removed
345
+ */
152
346
  disconnectedCallback() {
153
347
  window.removeEventListener('LoginCredentials', this.autofillCredentialsHandler);
154
348
  }
349
+ /**
350
+ * Send error notification as a post message
351
+ */
155
352
  sendErrorNotification(errorMessage) {
156
353
  window.postMessage({ type: "HasError", error: errorMessage }, window.location.href);
157
354
  window.postMessage({ type: 'WidgetNotification', data: {
@@ -159,6 +356,9 @@ export class UserLogin {
159
356
  message: errorMessage
160
357
  } }, window.location.href);
161
358
  }
359
+ /**
360
+ * Debounce function to limit API calls
361
+ */
162
362
  debounce(func, delay) {
163
363
  let timer;
164
364
  return function (...args) {
@@ -168,6 +368,9 @@ export class UserLogin {
168
368
  }, delay);
169
369
  };
170
370
  }
371
+ /**
372
+ * Dispatch event to notify about login credential updates
373
+ */
171
374
  dispatchUpdateLoginCredentialsEvent() {
172
375
  if (!this.hasError) {
173
376
  this.updateLoginCredentialsEvent = new CustomEvent("UpdateLoginCredentials", {
@@ -181,16 +384,24 @@ export class UserLogin {
181
384
  }
182
385
  }
183
386
  ;
387
+ /**
388
+ * Render function
389
+ */
184
390
  render() {
185
- let visibilityIcon = h("span", { key: '4ccb9d4b1c8209e22320c3667101b9e435d1b604', class: "InputIcon" }, this.isPasswordVisible &&
186
- h("svg", { key: 'fd168b4ec7ed18213aef15d5c7bcb89183b5626d', onClick: () => this.togglePassword(), class: "TogglePasswordVisibility", part: "TogglePasswordVisibility", xmlns: "http://www.w3.org/2000/svg", width: "18.844", height: "12.887", viewBox: "0 0 18.844 12.887" }, h("g", { key: '3ab8953db8743082bb19d4f97ae6191724145a0e', transform: "translate(-110.856 -23.242)" }, h("circle", { key: '716eb0de02150f4d5791cb7cf1cf7e904de4e8b9', class: "PasswordVisibilityIcon", cx: "0.05", cy: "0.05", r: "0.05", transform: "translate(121.017 31.148)" }), h("g", { key: '4ca623e6f31b09dbf6495fe657e9f6b67bfddbd8', transform: "translate(117.499 27.37)" }, h("path", { key: '0377c51b5536b07d0cefb77ed82d714fc82b5d9e', class: "PasswordVisibilityIcon", d: "M147.413,43.174a2.774,2.774,0,0,0-3.229-3.943Z", transform: "translate(-142.164 -39.123)" }), h("path", { key: '3ee2f6849511a3ce18ccfcaea0b503f1b9e57329', class: "PasswordVisibilityIcon", d: "M137.031,43.1a2.778,2.778,0,0,0,3.447,4.209Z", transform: "translate(-136.413 -42.068)" })), h("g", { key: '24fab8dc6f6ef08ef1a36227156b768925a2a7ba', transform: "translate(110.856 24.899)" }, h("path", { key: 'b41b45065b8f55772bbdfbced34ef4d7736c133a', class: "PasswordVisibilityIcon", d: "M122.538,42.061a7.043,7.043,0,0,1-2.325.53,10.373,10.373,0,0,1-4.393-1.482,36.509,36.509,0,0,1-3.873-2.391.13.13,0,0,1,0-.208,44.141,44.141,0,0,1,3.873-2.651c.394-.233.768-.437,1.13-.622l-.686-.838c-.322.167-.651.347-.99.55a37.989,37.989,0,0,0-3.977,2.729,1.21,1.21,0,0,0-.442.962,1.1,1.1,0,0,0,.494.936,34.416,34.416,0,0,0,3.977,2.469,11.468,11.468,0,0,0,4.886,1.611,8.427,8.427,0,0,0,3.039-.725Z", transform: "translate(-110.856 -33.157)" }), h("path", { key: '39f77d5f4028baf654fdc07a2f03525b994d508f', class: "PasswordVisibilityIcon", d: "M149.119,34.14a45.875,45.875,0,0,0-4.055-2.729,20.541,20.541,0,0,0-2.547-1.248,5.6,5.6,0,0,0-4.79-.017l.7.856a5.254,5.254,0,0,1,1.672-.346,10.072,10.072,0,0,1,4.445,1.663,34.132,34.132,0,0,1,3.925,2.651.13.13,0,0,1,0,.208,40.2,40.2,0,0,1-3.925,2.391c-.179.092-.352.176-.525.26l.684.835c.1-.054.2-.1.309-.159a36.356,36.356,0,0,0,4.055-2.469,1.067,1.067,0,0,0,.52-.936A1.159,1.159,0,0,0,149.119,34.14Z", transform: "translate(-130.743 -29.617)" })), h("rect", { key: '74bdc0477190de8bd67e30e0799ed1d4c255fff0', class: "PasswordVisibilityIcon", width: "0.972", height: "15.861", rx: "0.486", transform: "translate(114.827 23.858) rotate(-39.315)" }))), !this.isPasswordVisible &&
187
- h("svg", { key: '89e71e7d5fc2af237c7a0af69838a60f997dc0ee', onClick: () => this.togglePassword(), class: "TogglePasswordVisibility PasswordVisible", part: "TogglePasswordVisibility", xmlns: "http://www.w3.org/2000/svg", width: "18.843", height: "10.5", viewBox: "0 0 18.843 10.5" }, h("g", { key: '97447b59b0e079f3b2a154681aef2cef572e445b', transform: "translate(-14.185 -27.832)" }, h("path", { key: 'c35b80be71460f5fc0c469ee807e3f83f5ab1cb9', class: "PasswordVisibilityIcon", d: "M23.541,38.332a11.467,11.467,0,0,1-4.886-1.611,34.413,34.413,0,0,1-3.976-2.469,1.1,1.1,0,0,1-.494-.936,1.21,1.21,0,0,1,.442-.962A37.986,37.986,0,0,1,18.6,29.625a16.06,16.06,0,0,1,2.521-1.248,6.862,6.862,0,0,1,2.417-.546,6.862,6.862,0,0,1,2.417.546,20.541,20.541,0,0,1,2.547,1.248,45.872,45.872,0,0,1,4.054,2.729,1.159,1.159,0,0,1,.468.962,1.067,1.067,0,0,1-.52.936,36.353,36.353,0,0,1-4.054,2.469A11.2,11.2,0,0,1,23.541,38.332Zm0-9.46a9.813,9.813,0,0,0-4.392,1.663,44.138,44.138,0,0,0-3.873,2.651.13.13,0,0,0,0,.208,36.5,36.5,0,0,0,3.873,2.391,10.372,10.372,0,0,0,4.392,1.481,11.051,11.051,0,0,0,4.444-1.481,40.2,40.2,0,0,0,3.925-2.391.13.13,0,0,0,0-.208h0a34.132,34.132,0,0,0-3.925-2.651A10.072,10.072,0,0,0,23.541,28.872Z", transform: "translate(0)" }), h("circle", { key: '3a6bfc9d02b7c66ecd0e07481e1963a6bcab3fb0', class: "PasswordVisibilityIcon", cx: "2.779", cy: "2.779", r: "2.779", transform: "translate(20.827 30.303)" }))));
188
- let userIdentification = h("div", { key: '5b43adf706d46ce330b81e0bc5e8bbd1bfc2b883', class: "FormBox" }, h("div", { key: '0c53a0428fbcb10876e16d0505cf895c5bffa3bd', class: "FormValue" }, h("div", { key: '8aeda926da67db1e58595287f15d815e7887dc45', class: (!this.isValidUserEmail || this.hasError) ? 'InputBox InputInvalidBox' : 'InputBox' }, h("input", { key: 'bf82f8b419fe217143d3928262b9b256e43a9f79', type: "text", placeholder: '', value: this.userNameEmail, onFocus: (event) => this.handleInputChange(event, 'user'), onInput: (event) => this.handleInputChange(event, 'user'), autocapitalize: "none", required: true }), h("label", { key: '7a0f71f2c013c8d00d0d7c66452e09badfd17bb3', class: (this.userNameEmail ? 'FieldFilledIn' : '') + ' ' + (!this.isValidUserEmail || this.hasError ? 'FieldInvalid' : '') }, translate('userEmail', this.lang)), !this.isValidUserEmail &&
189
- h("p", { key: 'ed3453e628b9d60f8df2c3c1e04024706c532bfd', class: "InvalidField" }, translate('invalidField', this.lang))), h("div", { key: 'c778082662a1f29bdb6b19799c702ce3b4773a0a', class: (!this.isValidPassword || this.hasError) ? 'InputBox InputInvalidBox' : 'InputBox' }, visibilityIcon, h("input", { key: '7cbdd79f39f986efc4cfadf0577782c86af8eec9', type: this.isPasswordVisible ? "text" : "password", placeholder: '', value: this.userPassword, onFocus: (event) => this.handleInputChange(event, 'password'), onInput: (event) => this.handleInputChange(event, 'password'), autocapitalize: "none", required: true }), h("label", { key: '94d576059031cb459757f417245a241a768137fe', class: (this.userPassword ? 'FieldFilledIn' : '') + ' ' + (!this.isValidPassword || this.hasError ? 'FieldInvalid' : '') }, translate('password', this.lang)), !this.isValidPassword &&
190
- h("p", { key: '9c961763ac1a5c3af53d63b4b4423f22d341f2a4', class: "InvalidField" }, translate('invalidField', this.lang))), this.passwordReset == 'true' &&
191
- h("div", { key: '9f0730d9d3000def2d5b0edb2fcef7c2b77633cf', class: "ForgotPassword" }, h("button", { key: '3bd5379cf60cba95c1338968c451366264bec081', onClick: () => this.resetPassword() }, translate('forgotPassword', this.lang))), h("button", { key: '7a5ac0291a075d7c4f1a1f235dc6be2ccfa2239e', disabled: (!this.isValidUserEmail || !this.isValidPassword || !this.userNameEmail || !this.userPassword), class: "SubmitCredentials", onClick: () => this.handleLogin() }, translate('login', this.lang)), this.hasError &&
192
- h("p", { key: 'f40b7b875d615bb6af19dac753910763638409a8', class: "CredentialsError" }, this.errorMessage)));
193
- return h("section", { key: '6c0b3e43c5fdd9993a02f11b9bfa817b2a5069f2', ref: el => this.stylingContainer = el }, userIdentification);
391
+ let visibilityIcon = h("span", { key: '7e2a13b86952a81d92e46aadc7ce5029a481bcc0', class: "InputIcon" }, this.isPasswordVisible &&
392
+ h("svg", { key: 'f745357aebd4ba59b18a268e1159545ab9227b6d', onClick: () => this.togglePassword(), class: "TogglePasswordVisibility", part: "TogglePasswordVisibility", xmlns: "http://www.w3.org/2000/svg", width: "18.844", height: "12.887", viewBox: "0 0 18.844 12.887" }, h("g", { key: '6a34839a4c1a9bcc227ce71ac1f55809b05e5b46', transform: "translate(-110.856 -23.242)" }, h("circle", { key: '77448e74d7ebc1f89c11793f1de0cafd1c26e0b3', class: "PasswordVisibilityIcon", cx: "0.05", cy: "0.05", r: "0.05", transform: "translate(121.017 31.148)" }), h("g", { key: 'e627dcd5784c782862ac444a570369b9f718934d', transform: "translate(117.499 27.37)" }, h("path", { key: 'f2238aee9409d92971971850266ac84587bd7d13', class: "PasswordVisibilityIcon", d: "M147.413,43.174a2.774,2.774,0,0,0-3.229-3.943Z", transform: "translate(-142.164 -39.123)" }), h("path", { key: '26c81b19ba3275bd40eb4395507f0e9f8d5f9d40', class: "PasswordVisibilityIcon", d: "M137.031,43.1a2.778,2.778,0,0,0,3.447,4.209Z", transform: "translate(-136.413 -42.068)" })), h("g", { key: '35f83887aa01cc7c6412b462a581bf6954046dc5', transform: "translate(110.856 24.899)" }, h("path", { key: 'da30b190df442cbf7a89c9dd0790a65cf8bae574', class: "PasswordVisibilityIcon", d: "M122.538,42.061a7.043,7.043,0,0,1-2.325.53,10.373,10.373,0,0,1-4.393-1.482,36.509,36.509,0,0,1-3.873-2.391.13.13,0,0,1,0-.208,44.141,44.141,0,0,1,3.873-2.651c.394-.233.768-.437,1.13-.622l-.686-.838c-.322.167-.651.347-.99.55a37.989,37.989,0,0,0-3.977,2.729,1.21,1.21,0,0,0-.442.962,1.1,1.1,0,0,0,.494.936,34.416,34.416,0,0,0,3.977,2.469,11.468,11.468,0,0,0,4.886,1.611,8.427,8.427,0,0,0,3.039-.725Z", transform: "translate(-110.856 -33.157)" }), h("path", { key: 'febf8ee47512ae58e178eeeb4d4024c74d04fb96', class: "PasswordVisibilityIcon", d: "M149.119,34.14a45.875,45.875,0,0,0-4.055-2.729,20.541,20.541,0,0,0-2.547-1.248,5.6,5.6,0,0,0-4.79-.017l.7.856a5.254,5.254,0,0,1,1.672-.346,10.072,10.072,0,0,1,4.445,1.663,34.132,34.132,0,0,1,3.925,2.651.13.13,0,0,1,0,.208,40.2,40.2,0,0,1-3.925,2.391c-.179.092-.352.176-.525.26l.684.835c.1-.054.2-.1.309-.159a36.356,36.356,0,0,0,4.055-2.469,1.067,1.067,0,0,0,.52-.936A1.159,1.159,0,0,0,149.119,34.14Z", transform: "translate(-130.743 -29.617)" })), h("rect", { key: '053ec6df6b3a49e17df73ce8a32c393d8630140a', class: "PasswordVisibilityIcon", width: "0.972", height: "15.861", rx: "0.486", transform: "translate(114.827 23.858) rotate(-39.315)" }))), !this.isPasswordVisible &&
393
+ h("svg", { key: 'ac96ad3c2e6cd9653e8bd8d17ea4b0cc43896319', onClick: () => this.togglePassword(), class: "TogglePasswordVisibility PasswordVisible", part: "TogglePasswordVisibility", xmlns: "http://www.w3.org/2000/svg", width: "18.843", height: "10.5", viewBox: "0 0 18.843 10.5" }, h("g", { key: 'f0431fab2dea65be11afa02d4c50af4940cf76bd', transform: "translate(-14.185 -27.832)" }, h("path", { key: 'fdc015794619daca5d45f90f931708775ecd8db3', class: "PasswordVisibilityIcon", d: "M23.541,38.332a11.467,11.467,0,0,1-4.886-1.611,34.413,34.413,0,0,1-3.976-2.469,1.1,1.1,0,0,1-.494-.936,1.21,1.21,0,0,1,.442-.962A37.986,37.986,0,0,1,18.6,29.625a16.06,16.06,0,0,1,2.521-1.248,6.862,6.862,0,0,1,2.417-.546,6.862,6.862,0,0,1,2.417.546,20.541,20.541,0,0,1,2.547,1.248,45.872,45.872,0,0,1,4.054,2.729,1.159,1.159,0,0,1,.468.962,1.067,1.067,0,0,1-.52.936,36.353,36.353,0,0,1-4.054,2.469A11.2,11.2,0,0,1,23.541,38.332Zm0-9.46a9.813,9.813,0,0,0-4.392,1.663,44.138,44.138,0,0,0-3.873,2.651.13.13,0,0,0,0,.208,36.5,36.5,0,0,0,3.873,2.391,10.372,10.372,0,0,0,4.392,1.481,11.051,11.051,0,0,0,4.444-1.481,40.2,40.2,0,0,0,3.925-2.391.13.13,0,0,0,0-.208h0a34.132,34.132,0,0,0-3.925-2.651A10.072,10.072,0,0,0,23.541,28.872Z", transform: "translate(0)" }), h("circle", { key: '24dbfed823b18d05f65b448b322c415fd9f61d2e', class: "PasswordVisibilityIcon", cx: "2.779", cy: "2.779", r: "2.779", transform: "translate(20.827 30.303)" }))));
394
+ let userIdentification = h("div", { key: 'ee9856d867a413208cb3d75945106804178afd08', class: "FormBox" }, h("div", { key: 'a2749547b6b7eac8183ef4dd79d3e24549d0cdde', class: "FormValue" }, this.loginByPhoneNumber === 'true'
395
+ ? h("div", { class: (!this.isValidUserPhone || this.hasError) ? 'InputBox InputInvalidBox' : 'InputBox ' }, h("div", { class: "PhoneInputBox" }, h("div", { class: "PrefixBox" }, h("vaadin-combo-box", { items: this.userPrefixOptions, value: this.userPrefix, onChange: this.handleInputChangePartial('prefix') }), h("label", { class: (this.userPrefix ? 'FieldFilledIn' : '') + ' ' + (!this.isValidUserPhone || this.hasError ? 'FieldInvalid' : '') }, translate('userPrefix', this.lang))), h("div", { class: "PhoneBox" }, h("input", { type: "text", placeholder: '', value: this.userPhone, onFocus: this.handleInputChangePartial('phone'), onInput: this.handleInputChangePartial('phone'), autocapitalize: "none", required: true }), h("label", { class: (this.userPhone ? 'FieldFilledIn' : '') + ' ' + (!this.isValidUserPhone || this.hasError ? 'FieldInvalid' : '') }, translate('userPhone', this.lang)))), !this.isValidUserPhone &&
396
+ h("p", { class: "InvalidField" }, translate('invalidField', this.lang)))
397
+ : h("div", { class: (!this.isValidUserEmail || this.hasError) ? 'InputBox InputInvalidBox' : 'InputBox' }, h("input", { type: "text", placeholder: '', value: this.userNameEmail, onFocus: this.handleInputChangePartial('user'), onInput: this.handleInputChangePartial('user'), autocapitalize: "none", required: true }), h("label", { class: (this.userNameEmail ? 'FieldFilledIn' : '') + ' ' + (!this.isValidUserEmail || this.hasError ? 'FieldInvalid' : '') }, translate('userEmail', this.lang)), !this.isValidUserEmail &&
398
+ h("p", { class: "InvalidField" }, translate('invalidField', this.lang))), h("div", { key: '9e5a38927b2355764882b86ec41b3c905ba28a74', class: (!this.isValidPassword || this.hasError) ? 'InputBox InputInvalidBox' : 'InputBox' }, visibilityIcon, h("input", { key: '171eaa238653e8875898397e4c5c5875e2a4e8b9', type: this.isPasswordVisible ? "text" : "password", placeholder: '', value: this.userPassword, onFocus: this.handleInputChangePartial('password'), onInput: this.handleInputChangePartial('password'), autocapitalize: "none", required: true }), h("label", { key: '691a65151e6011c7acf94ff489d3f931b7b6f2b9', class: (this.userPassword ? 'FieldFilledIn' : '') + ' ' + (!this.isValidPassword || this.hasError ? 'FieldInvalid' : '') }, translate('password', this.lang)), !this.isValidPassword &&
399
+ h("p", { key: '880a618f35b645250420ddff462a07d4c6a15e21', class: "InvalidField" }, translate('invalidField', this.lang))), this.passwordReset == 'true' &&
400
+ h("div", { key: '67d0dda3a8c3b7dc16add392d28111760e3c8941', class: "ForgotPassword" }, h("button", { key: '2f15ce7031f0536252c38ba71eab46a99035bb10', onClick: this.resetPassword }, translate('forgotPassword', this.lang))), h("button", { key: 'f719e61f203d5ad26927c03852fe0813f90c9382', disabled: ((this.loginByPhoneNumber !== 'true' && (!this.isValidUserEmail || !this.userNameEmail)) ||
401
+ (this.loginByPhoneNumber === 'true' && (!this.isValidUserPhone || !this.userPhone || !this.userPrefix)) ||
402
+ !this.userPassword || !this.isValidPassword), class: "SubmitCredentials", onClick: this.handleLogin }, translate('login', this.lang)), this.hasError &&
403
+ h("p", { key: 'd7ef26b85544e6491a52a0bad48faa505c85e848', class: "CredentialsError" }, this.errorMessage)));
404
+ return h("section", { key: 'b5d37deebd2f1911594b7845c7eb0d65cbda6e75', ref: el => this.stylingContainer = el }, userIdentification);
194
405
  }
195
406
  static get is() { return "user-login"; }
196
407
  static get encapsulation() { return "shadow"; }
@@ -218,7 +429,7 @@ export class UserLogin {
218
429
  "optional": false,
219
430
  "docs": {
220
431
  "tags": [],
221
- "text": "Endpoint"
432
+ "text": "API endpoint URL for login requests"
222
433
  },
223
434
  "attribute": "endpoint",
224
435
  "reflect": true,
@@ -236,7 +447,7 @@ export class UserLogin {
236
447
  "optional": false,
237
448
  "docs": {
238
449
  "tags": [],
239
- "text": "Language"
450
+ "text": "Language code for translations (default is 'en')"
240
451
  },
241
452
  "attribute": "lang",
242
453
  "reflect": true,
@@ -254,7 +465,7 @@ export class UserLogin {
254
465
  "optional": false,
255
466
  "docs": {
256
467
  "tags": [],
257
- "text": "Client styling"
468
+ "text": "Inline CSS styling provided by the client"
258
469
  },
259
470
  "attribute": "client-styling",
260
471
  "reflect": true,
@@ -272,7 +483,7 @@ export class UserLogin {
272
483
  "optional": false,
273
484
  "docs": {
274
485
  "tags": [],
275
- "text": "Client styling by url"
486
+ "text": "URL to load additional CSS styling"
276
487
  },
277
488
  "attribute": "client-styling-url",
278
489
  "reflect": true,
@@ -290,7 +501,7 @@ export class UserLogin {
290
501
  "optional": false,
291
502
  "docs": {
292
503
  "tags": [],
293
- "text": "Translation url"
504
+ "text": "URL for fetching translations"
294
505
  },
295
506
  "attribute": "translation-url",
296
507
  "reflect": true,
@@ -308,7 +519,7 @@ export class UserLogin {
308
519
  "optional": false,
309
520
  "docs": {
310
521
  "tags": [],
311
- "text": "Password reset"
522
+ "text": "Flag indicating whether the password reset feature is enabled"
312
523
  },
313
524
  "attribute": "password-reset",
314
525
  "reflect": true,
@@ -326,7 +537,7 @@ export class UserLogin {
326
537
  "optional": false,
327
538
  "docs": {
328
539
  "tags": [],
329
- "text": "User email regex"
540
+ "text": "Regular expression for validating the user email"
330
541
  },
331
542
  "attribute": "user-email-regex",
332
543
  "reflect": true
@@ -343,12 +554,47 @@ export class UserLogin {
343
554
  "optional": false,
344
555
  "docs": {
345
556
  "tags": [],
346
- "text": "User email regex options"
557
+ "text": "Regex options for user email validation"
347
558
  },
348
559
  "attribute": "user-email-regex-options",
349
560
  "reflect": true,
350
561
  "defaultValue": "'i'"
351
562
  },
563
+ "userPhoneRegex": {
564
+ "type": "string",
565
+ "mutable": false,
566
+ "complexType": {
567
+ "original": "string",
568
+ "resolved": "string",
569
+ "references": {}
570
+ },
571
+ "required": false,
572
+ "optional": false,
573
+ "docs": {
574
+ "tags": [],
575
+ "text": "User phone regex"
576
+ },
577
+ "attribute": "user-phone-regex",
578
+ "reflect": true
579
+ },
580
+ "userPhoneRegexOptions": {
581
+ "type": "string",
582
+ "mutable": false,
583
+ "complexType": {
584
+ "original": "string",
585
+ "resolved": "string",
586
+ "references": {}
587
+ },
588
+ "required": false,
589
+ "optional": false,
590
+ "docs": {
591
+ "tags": [],
592
+ "text": "User phone regex options"
593
+ },
594
+ "attribute": "user-phone-regex-options",
595
+ "reflect": true,
596
+ "defaultValue": "''"
597
+ },
352
598
  "passwordRegex": {
353
599
  "type": "string",
354
600
  "mutable": false,
@@ -361,7 +607,7 @@ export class UserLogin {
361
607
  "optional": false,
362
608
  "docs": {
363
609
  "tags": [],
364
- "text": "Password regex"
610
+ "text": "Regular expression for validating the password"
365
611
  },
366
612
  "attribute": "password-regex",
367
613
  "reflect": true
@@ -378,11 +624,47 @@ export class UserLogin {
378
624
  "optional": false,
379
625
  "docs": {
380
626
  "tags": [],
381
- "text": "Password regex options"
627
+ "text": "Regex options for password validation"
382
628
  },
383
629
  "attribute": "password-regex-options",
384
630
  "reflect": true,
385
631
  "defaultValue": "''"
632
+ },
633
+ "version": {
634
+ "type": "string",
635
+ "mutable": false,
636
+ "complexType": {
637
+ "original": "string",
638
+ "resolved": "string",
639
+ "references": {}
640
+ },
641
+ "required": false,
642
+ "optional": false,
643
+ "docs": {
644
+ "tags": [],
645
+ "text": "Flag to determine if the component uses version 2 of the API"
646
+ },
647
+ "attribute": "version",
648
+ "reflect": true,
649
+ "defaultValue": "'gm16'"
650
+ },
651
+ "loginByPhoneNumber": {
652
+ "type": "string",
653
+ "mutable": false,
654
+ "complexType": {
655
+ "original": "string",
656
+ "resolved": "string",
657
+ "references": {}
658
+ },
659
+ "required": false,
660
+ "optional": false,
661
+ "docs": {
662
+ "tags": [],
663
+ "text": "If set to true, login will be done by phone number, else by username/email"
664
+ },
665
+ "attribute": "login-by-phone-number",
666
+ "reflect": true,
667
+ "defaultValue": "'false'"
386
668
  }
387
669
  };
388
670
  }
@@ -391,17 +673,27 @@ export class UserLogin {
391
673
  "userNameEmail": {},
392
674
  "userPassword": {},
393
675
  "isValidUserEmail": {},
676
+ "userPhone": {},
677
+ "userPrefix": {},
394
678
  "isValidPassword": {},
679
+ "isValidUserPhone": {},
395
680
  "isPasswordVisible": {},
396
681
  "limitStylingAppends": {},
397
682
  "errorMessage": {},
398
- "hasError": {}
683
+ "hasError": {},
684
+ "userPrefixOptions": {}
399
685
  };
400
686
  }
401
687
  static get watchers() {
402
688
  return [{
403
689
  "propName": "translationUrl",
404
690
  "methodName": "handleNewTranslations"
691
+ }, {
692
+ "propName": "clientStyling",
693
+ "methodName": "handleStylingChange"
694
+ }, {
695
+ "propName": "clientStylingUrl",
696
+ "methodName": "handleStylingUrlChange"
405
697
  }];
406
698
  }
407
699
  }