@sambath999/localize-token 19.0.3 → 19.0.4

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,28 +1,25 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, NgModule, Component, ViewEncapsulation, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
3
- import { BehaviorSubject } from 'rxjs';
4
- import * as jwt_decode from 'jwt-decode';
5
- import * as i1 from '@angular/common/http';
6
- import { HttpHeaders } from '@angular/common/http';
7
- import * as i1$1 from 'primeng/api';
2
+ import { Injectable, Component, ViewEncapsulation, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
3
+ import * as i1 from 'primeng/api';
8
4
  import { MessageService } from 'primeng/api';
9
5
  import * as i2 from 'primeng/dynamicdialog';
10
- import { DialogService, DynamicDialogModule } from 'primeng/dynamicdialog';
11
- import * as i5 from '@angular/common';
6
+ import { DialogService } from 'primeng/dynamicdialog';
7
+ import { BehaviorSubject, takeUntil, catchError, throwError, Subject } from 'rxjs';
8
+ import * as jwt_decode from 'jwt-decode';
9
+ import * as i4 from '@angular/common/http';
10
+ import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
11
+ import * as i5 from '@angular/platform-browser';
12
+ import { BrowserModule } from '@angular/platform-browser';
13
+ import * as i6 from '@angular/common';
12
14
  import { CommonModule } from '@angular/common';
13
- import * as i6 from 'primeng/toast';
15
+ import * as i7 from 'primeng/toast';
14
16
  import { ToastModule } from 'primeng/toast';
15
- import * as i7 from 'primeng/inputtext';
17
+ import * as i8 from 'primeng/inputtext';
16
18
  import { InputTextModule } from 'primeng/inputtext';
17
- import * as i8 from '@angular/forms';
19
+ import * as i9 from '@angular/forms';
18
20
  import { FormsModule } from '@angular/forms';
19
- import * as i9 from 'primeng/button';
21
+ import * as i10 from 'primeng/button';
20
22
  import { ButtonModule } from 'primeng/button';
21
- import * as i10 from 'primeng/inputgroup';
22
- import { InputGroupModule } from 'primeng/inputgroup';
23
- import * as i11 from 'primeng/inputgroupaddon';
24
- import { InputGroupAddonModule } from 'primeng/inputgroupaddon';
25
- import { BrowserModule } from '@angular/platform-browser';
26
23
 
27
24
  /**
28
25
  * Assembly of @package ng2-cookies @see https://www.npmjs.com/package/ng2-cookies
@@ -132,18 +129,6 @@ class LocalizeTokenStorage {
132
129
  }
133
130
 
134
131
  class LocalizeToken {
135
- static init(config) {
136
- LocalizeToken.config = { ...LocalizeToken.config, ...config };
137
- }
138
- static config = {
139
- mainDomain: extractMainDomain(),
140
- authTokenName: 'auth-token',
141
- tenantTokenName: '_lze_tnt_01',
142
- refreshTokenName: '_lze_rftkp_',
143
- needTenant: false,
144
- isProduction: false,
145
- revokeTokenUrl: ''
146
- };
147
132
  static storage = new LocalizeTokenStorage();
148
133
  static httpHeaders = {
149
134
  AUTHORIZATION: 'Authorization',
@@ -187,41 +172,52 @@ function extractMainDomain(subdomain) {
187
172
  }
188
173
 
189
174
  class LocalizeTokenService {
175
+ configSubject = new BehaviorSubject({});
190
176
  isRevokingTokenSubject = new BehaviorSubject(false);
191
- config;
192
- constructor() {
193
- if (!LocalizeToken.config.authTokenName || !LocalizeToken.config.refreshTokenName || !LocalizeToken.config.tenantTokenName) {
194
- throw new Error('authTokenName, refreshTokenName, and tenantTokenName must be defined in LocalizeToken.config');
195
- }
196
- this.config = LocalizeToken.config;
177
+ defaultConfig = {
178
+ mainDomain: extractMainDomain(),
179
+ authToken: {
180
+ name: 'auth-token',
181
+ },
182
+ refreshToken: {
183
+ name: 'refresh-token',
184
+ requestUrl: '/api/token/revoke'
185
+ },
186
+ };
187
+ get config() {
188
+ this.throwIfNotInitialized();
189
+ return this.configSubject.value;
190
+ }
191
+ isInitialized = false;
192
+ init(config) {
193
+ console.log('LocalizeTokenService is initialized.');
194
+ this.configSubject.next({ ...this.defaultConfig, ...config });
195
+ this.isInitialized = true;
196
+ }
197
+ ngOnDestroy() {
198
+ // this.configSubject.complete();
199
+ // this.isRevokingTokenSubject.complete();
197
200
  }
198
201
  get authToken() { return this.storageGet(); }
199
202
  set authToken(value) {
200
203
  value
201
204
  ? this.storageSet(value)
202
- : LocalizeToken.storage.delete(this.config.authTokenName);
205
+ : LocalizeToken.storage.delete(this.config.authToken?.name);
203
206
  }
204
- get refreshToken() { return LocalizeToken.storage.get(this.config.refreshTokenName); }
207
+ get tenantToken() { return LocalizeToken.storage.get(this.config.tenantToken?.name || ''); }
208
+ get refreshToken() { return LocalizeToken.storage.get(this.config.refreshToken?.name || ''); }
205
209
  get accessToken() { return this.authToken?.token; }
206
210
  set accessToken(value) {
207
- if (value) {
208
- this.authToken = { token: value, revoke: false };
209
- }
211
+ value && (this.authToken = { token: value, revoke: false });
210
212
  }
211
213
  get isRevokingToken() { return this.isRevokingTokenSubject.value; /* this.authToken?.revoke ?? false */ }
212
214
  set isRevokingToken(value) {
213
215
  this.isRevokingTokenSubject.next(value);
214
- if (this.authToken) {
215
- this.authToken = { ...this.authToken, revoke: value };
216
- }
217
- }
218
- // get tenantToken() { return LocalizeToken.storage.get(this.config.tenantTokenName!) }
219
- tenantToken(name) {
220
- return LocalizeToken.storage.get(name ?? this.config.tenantTokenName);
216
+ this.authToken && (this.authToken = { ...this.authToken, revoke: value });
221
217
  }
222
218
  storageGet() {
223
219
  try {
224
- const encoded = LocalizeToken.storage.get(this.config.authTokenName);
220
+ const encoded = LocalizeToken.storage.get(this.config.authToken?.name || '');
225
221
  const decoded = atob(encoded || '');
226
222
  return JSON.parse(decoded);
227
223
  }
@@ -231,17 +227,21 @@ class LocalizeTokenService {
231
227
  }
232
228
  storageSet(value) {
233
229
  const base64 = btoa(JSON.stringify(value));
234
- LocalizeToken.storage.set(this.config.authTokenName, base64);
230
+ LocalizeToken.storage.set(this.config.authToken?.name || '', base64);
235
231
  }
236
232
  tokensValid() {
237
- return this.refreshToken?.length && (!this.config.needTenant || this.tenantToken()?.length);
233
+ return !!this.refreshToken?.length
234
+ && (!this.config.tenantToken || !!this.tenantToken?.length);
238
235
  }
239
236
  decodeToken = (token) => jwt_decode.jwtDecode(token);
240
237
  get decodeRefreshToken() {
241
- const token = LocalizeToken.storage.get(this.config.refreshTokenName);
242
- if (!token)
243
- return null;
244
- return this.decodeToken(token);
238
+ const token = this.refreshToken;
239
+ return !token ? null : this.decodeToken(token);
240
+ }
241
+ throwIfNotInitialized() {
242
+ if (!this.isInitialized) {
243
+ throw new Error('LocalizeTokenService is not initialized. Call init() method before using it.');
244
+ }
245
245
  }
246
246
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
247
247
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenService, providedIn: 'root' });
@@ -249,161 +249,6 @@ class LocalizeTokenService {
249
249
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenService, decorators: [{
250
250
  type: Injectable,
251
251
  args: [{ providedIn: 'root' }]
252
- }], ctorParameters: () => [] });
253
-
254
- /**
255
- * Http method options
256
- */
257
- var EMethod;
258
- (function (EMethod) {
259
- EMethod[EMethod["POST"] = 1] = "POST";
260
- EMethod[EMethod["GET"] = 2] = "GET";
261
- EMethod[EMethod["PUT"] = 3] = "PUT";
262
- EMethod[EMethod["DELETE"] = 4] = "DELETE";
263
- EMethod[EMethod["PATCH"] = 5] = "PATCH";
264
- })(EMethod || (EMethod = {}));
265
- class LocalizeApiService {
266
- httpClient;
267
- localizeTokenService;
268
- isRequestingSubject = new BehaviorSubject(false);
269
- isResolvedStartupSubject = new BehaviorSubject(false);
270
- get isRequesting() { return this.isRequestingSubject.value; }
271
- get isResolvedStartup() { return this.isResolvedStartupSubject.value; }
272
- apiConfigs = {};
273
- isInitialized = false;
274
- constructor(httpClient, localizeTokenService) {
275
- this.httpClient = httpClient;
276
- this.localizeTokenService = localizeTokenService;
277
- }
278
- /**
279
- * Initialize the API service.
280
- * @param apiConfigs - The API configurations.
281
- */
282
- init(apiConfigs) {
283
- if (this.isInitialized)
284
- return;
285
- this.isInitialized = true;
286
- this.apiConfigs = apiConfigs;
287
- }
288
- /**
289
- * A higher-order function that returns a curried function for making API requests.
290
- *
291
- * @param baseUrl - The base URL of the API.
292
- * @returns A curried function that can be used to make API requests.
293
- */
294
- func = (baseUrl) => (path, method = EMethod.GET, value = null, isFormData = false, headers) => this.base(baseUrl, path, method, value, isFormData, headers);
295
- async base(baseUrl, path, method = EMethod.GET, value = null, isFormData = false, headers) {
296
- await this.ifPromise(this.apiConfigs.onPrepareRequest);
297
- const url = `${baseUrl.trim().replace(/\/?$/, '/')}${path.trim().replace(/^\//, '')}`;
298
- const httpMethod = EMethod[method].toLowerCase();
299
- const request = () => { return { body: value, headers: this.options(isFormData, headers) }; };
300
- // Wait for previous request to complete
301
- await this.toWaitForPreviousRequest();
302
- // Process request
303
- try {
304
- return await this.processRequest(httpMethod, url, request());
305
- }
306
- // Handle unauthorized error if any
307
- catch (error) {
308
- if (error.status !== 401) {
309
- throw error;
310
- }
311
- return await this.onUnauthorizedError(httpMethod, url, request);
312
- }
313
- }
314
- async onUnauthorizedError(httpMethod, url, request) {
315
- await this.revokeToken();
316
- if (!this.isResolvedStartup) {
317
- return await this.processRequest(httpMethod, url, request());
318
- }
319
- }
320
- async toWaitForPreviousRequest() {
321
- if (this.localizeTokenService.isRevokingToken) {
322
- await waitUntil(() => !this.localizeTokenService.isRevokingToken);
323
- }
324
- // to wait for each request in 50ms, even if the request is not completed
325
- if (this.apiConfigs.waitEachRequest?.milliseconds) {
326
- await waitFor(this.apiConfigs.waitEachRequest.milliseconds, this.isRequesting);
327
- }
328
- }
329
- async processRequest(method, url, options) {
330
- this.isRequestingSubject.next(true);
331
- const result = await new Promise((resolve, reject) => this.httpClient.request(method, url, options).subscribe({ next: resolve, error: reject }));
332
- this.isRequestingSubject.next(false);
333
- return result;
334
- }
335
- async revokeToken() {
336
- if (this.localizeTokenService.isRevokingToken) {
337
- await waitUntil(() => !this.localizeTokenService.isRevokingToken);
338
- return;
339
- }
340
- try {
341
- this.localizeTokenService.isRevokingToken = true;
342
- const reqUrl = LocalizeToken.config.revokeTokenUrl;
343
- const reqHeaders = this.options().append(LocalizeToken.httpHeaders.X_REFRESH_TOKEN, `${this.localizeTokenService.refreshToken}`);
344
- const revokeToken = await new Promise((resolve, reject) => this.httpClient.get(reqUrl, { headers: reqHeaders }).subscribe({ next: resolve, error: reject }));
345
- if (revokeToken?.status) {
346
- this.localizeTokenService.accessToken = revokeToken.message;
347
- }
348
- else if (!this.localizeTokenService.refreshToken) {
349
- await this.ifPromise(this.apiConfigs.onAutoLogout);
350
- }
351
- else {
352
- if (this.apiConfigs.onRevokeUnauthorized) {
353
- await this.ifPromise(this.apiConfigs.onRevokeUnauthorized);
354
- // await this.revokeToken();
355
- }
356
- }
357
- }
358
- finally {
359
- this.localizeTokenService.isRevokingToken = false;
360
- }
361
- }
362
- /** default http request options */
363
- options(isFormData = false, headers = {}) {
364
- const defaultHeaders = { [LocalizeToken.httpHeaders.AUTHORIZATION]: `Bearer ${this.localizeTokenService.accessToken}`, };
365
- if (LocalizeToken.config.needTenant) {
366
- defaultHeaders[LocalizeToken.httpHeaders.X_TENANT] = `${this.localizeTokenService.tenantToken(this.apiConfigs.tenantTokenName)}`;
367
- }
368
- if (!isFormData) {
369
- defaultHeaders[LocalizeToken.httpHeaders.CONTENT_TYPE] = 'application/json';
370
- }
371
- const filteredHeaders = Object.keys(defaultHeaders).filter(key => !Object.keys(headers).includes(key))
372
- .reduce((acc, key) => ({ ...acc, [key]: defaultHeaders[key] }), {});
373
- const mergedHeaders = { ...filteredHeaders, ...headers };
374
- return new HttpHeaders(mergedHeaders);
375
- }
376
- async ifPromise(fn) {
377
- if (!fn)
378
- return;
379
- return fn instanceof Promise ? await fn() : fn();
380
- }
381
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiService, deps: [{ token: i1.HttpClient }, { token: LocalizeTokenService }], target: i0.ɵɵFactoryTarget.Injectable });
382
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiService, providedIn: 'root' });
383
- } //class
384
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiService, decorators: [{
385
- type: Injectable,
386
- args: [{
387
- providedIn: 'root'
388
- }]
389
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: LocalizeTokenService }] });
390
-
391
- class LocalizeTokenModule {
392
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
393
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule });
394
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule, providers: [
395
- LocalizeTokenService,
396
- LocalizeApiService
397
- ] });
398
- }
399
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule, decorators: [{
400
- type: NgModule,
401
- args: [{
402
- providers: [
403
- LocalizeTokenService,
404
- LocalizeApiService
405
- ],
406
- }]
407
252
  }] });
408
253
 
409
254
  class LocalizeLogindlgComponent {
@@ -413,24 +258,28 @@ class LocalizeLogindlgComponent {
413
258
  dlgConfig;
414
259
  tokenService;
415
260
  httpClient;
261
+ sanitizer;
416
262
  messageKey = "$login-dlg";
417
263
  password;
418
264
  decodeToken;
419
265
  loading = false;
420
266
  success = false;
421
- config = LocalizeToken.config;
267
+ get config() { return this.tokenService.config; }
422
268
  loginConfig;
423
269
  logout;
424
270
  loginUrl;
425
- constructor(messageService, cdt, dlgRef, dlgConfig, tokenService, httpClient) {
271
+ properties;
272
+ constructor(messageService, cdt, dlgRef, dlgConfig, tokenService, httpClient, sanitizer) {
426
273
  this.messageService = messageService;
427
274
  this.cdt = cdt;
428
275
  this.dlgRef = dlgRef;
429
276
  this.dlgConfig = dlgConfig;
430
277
  this.tokenService = tokenService;
431
278
  this.httpClient = httpClient;
279
+ this.sanitizer = sanitizer;
432
280
  this.decodeToken = this.tokenService.decodeRefreshToken;
433
281
  this.loginConfig = this.dlgConfig.data.loginConfig;
282
+ this.properties = this.loginConfig.properties;
434
283
  }
435
284
  ngOnInit() {
436
285
  this.dlgConfig.closable = false;
@@ -446,29 +295,34 @@ class LocalizeLogindlgComponent {
446
295
  }
447
296
  async clickLogin() {
448
297
  if (!this.isValidPassword) {
449
- this.showMessage("error", "Password is required and must be at least 6 characters");
450
- return;
298
+ return this.showMessage("error", "Password is required and must be at least 6 characters");
451
299
  }
452
300
  this.loading = true;
453
301
  const loginRes = await this.login();
454
302
  if (!loginRes?.status) {
455
- this.showMessage("error", loginRes.message ?? "An error occurred");
456
- return;
303
+ return this.showMessage("error", loginRes.message ?? "An error occurred");
457
304
  }
458
305
  this.tokenService.accessToken = loginRes.tokens.accessToken;
459
- const cookieOptions = { expires: this.loginConfig.expire ?? 5 };
460
- LocalizeToken.storage.set(this.config.refreshTokenName, loginRes.tokens.refreshToken, cookieOptions);
306
+ const cookieOptions = { expires: this.loginConfig.expire ?? 365 };
307
+ LocalizeToken.storage.set(this.config.refreshToken?.name || '', loginRes.tokens.refreshToken, cookieOptions);
461
308
  this.success = true;
462
- setTimeout(() => this.dlgRef.close(true), 2000);
309
+ setTimeout(() => {
310
+ this.dlgConfig.dismissableMask = true;
311
+ this.dlgConfig.modal = false;
312
+ this.dlgRef.close(true);
313
+ }, 2000);
463
314
  }
464
315
  async login() {
465
- if (!this.loginUrl || !this.loginUrl.trim().length) {
316
+ if (!this.loginUrl?.trim().length) {
466
317
  this.showMessage("error", "Login url is required");
467
318
  throw new Error("Login url is required");
468
319
  }
469
320
  try {
470
- return await new Promise((resolve, reject) => this.httpClient.post(this.loginUrl, { password: this.password.trim() }, { headers: this.getHeaders() })
471
- .subscribe({ next: resolve, error: reject }));
321
+ if (this.loginConfig.loginFunction) {
322
+ console.log("Using custom login function");
323
+ return await this.loginConfig.loginFunction(this.decodeToken?.email ?? '', this.password.trim(), this.getHeaders());
324
+ }
325
+ return await new Promise((resolve, reject) => this.httpClient.post(this.loginUrl, { password: this.password.trim() }, { headers: this.getHeaders() }).subscribe({ next: resolve, error: reject }));
472
326
  }
473
327
  catch (e) {
474
328
  this.showMessage("error", e.message);
@@ -477,26 +331,31 @@ class LocalizeLogindlgComponent {
477
331
  }
478
332
  getHeaders() {
479
333
  return {
480
- [LocalizeToken.httpHeaders.X_REFRESH_TOKEN]: LocalizeToken.storage.get(this.config.refreshTokenName) ?? "",
481
- [LocalizeToken.httpHeaders.X_TENANT]: LocalizeToken.storage.get(this.config.tenantTokenName) ?? "",
334
+ [LocalizeToken.httpHeaders.X_REFRESH_TOKEN]: this.tokenService.refreshToken ?? "",
335
+ [LocalizeToken.httpHeaders.X_TENANT]: this.tokenService.tenantToken ?? "",
482
336
  };
483
337
  }
484
338
  get isValidPassword() {
485
339
  this.loading = false;
486
- return this.password && this.password.trim().length >= 6 && this.password.trim().length <= 50;
340
+ return this.properties.passwordValidator
341
+ ? this.properties.passwordValidator(this.password)
342
+ : this.password && this.password.trim().length >= 6 && this.password.trim().length <= 50;
487
343
  }
488
344
  clickLogout = () => this.logout?.();
489
345
  showMessage(severity, summary) {
490
346
  this.messageService.add({ key: this.messageKey, severity, summary });
491
347
  this.loading = false;
492
348
  }
493
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgComponent, deps: [{ token: i1$1.MessageService }, { token: i0.ChangeDetectorRef }, { token: i2.DynamicDialogRef }, { token: i2.DynamicDialogConfig }, { token: LocalizeTokenService }, { token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
349
+ get sanitizedTitle() {
350
+ return this.sanitizer.bypassSecurityTrustHtml(this.properties.title ?? '');
351
+ }
352
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgComponent, deps: [{ token: i1.MessageService }, { token: i0.ChangeDetectorRef }, { token: i2.DynamicDialogRef }, { token: i2.DynamicDialogConfig }, { token: LocalizeTokenService }, { token: i4.HttpClient }, { token: i5.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
494
353
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: LocalizeLogindlgComponent, isStandalone: false, selector: "app-localize-logindlg", providers: [MessageService], ngImport: i0, template: `<p-toast key="$login-dlg" position="top-center"></p-toast>
495
354
  <div id="login-dlg-wrap">
496
355
  <div id="login-dlg-header">
497
- <div id="login-logo" class="p-mb-2"></div>
498
- <h3 *ngIf="!success">Your session is expired! <br> Please login again to continue.</h3>
499
- <h3 *ngIf="success" style="color:green !important;">You haved successfully logged in.</h3>
356
+ <div id="login-logo" class="p-mb-2" style="background: url('{{properties.logoImage}}') no-repeat"></div>
357
+ <h3 *ngIf="!success" [innerHTML]="sanitizedTitle"></h3>
358
+ <h3 *ngIf="success" style="color:green !important;">{{properties.loginSuccessMessage}}</h3>
500
359
  </div>
501
360
  <div id="login-dlg-content">
502
361
  <ng-container *ngIf="!success">
@@ -504,35 +363,33 @@ class LocalizeLogindlgComponent {
504
363
  <div class="login-dlg-loader"></div>
505
364
  </div>
506
365
  <div class="login-dlg-elm">
507
- <p-inputgroup>
508
- <p-inputgroup-addon [style]="{background:'var(--p-inputtext-disabled-background)'}">
509
- <span class="p-inputgroup-addon">
510
- <i class="material-icons-round" style="color: var(--p-inputtext-disabled-color);">person</i>
511
- </span>
512
- </p-inputgroup-addon>
513
- <input disabled pInputText type="text" placeholder="Username" [value]="decodeToken?.email" />
514
- </p-inputgroup>
366
+ <div class="p-inputgroup">
367
+ <span class="p-inputgroup-addon">
368
+ <i class="material-icons-round">person</i>
369
+ </span>
370
+ <input disabled pInputText type="text" placeholder="{{properties.username?.placeHolder}}" [value]="decodeToken?.email" />
371
+ </div>
515
372
  </div>
516
373
 
517
374
  <div class="login-dlg-elm">
518
- <p-inputgroup>
519
- <p-inputgroup-addon>
520
- <span class="p-inputgroup-addon">
521
- <i class="material-icons-round">lock</i>
522
- </span>
523
- </p-inputgroup-addon>
524
- <input [disabled]="loading" (keydown.enter)="clickLogin()" pInputText type="password" placeholder="Password" [(ngModel)]="password"
375
+ <div class="p-inputgroup">
376
+ <span class="p-inputgroup-addon">
377
+ <i class="material-icons-round">lock</i>
378
+ </span>
379
+ <input [disabled]="loading" (keydown.enter)="clickLogin()" pInputText type="password"
380
+ placeholder="{{properties.password?.placeHolder}}" [(ngModel)]="password"
525
381
  autofocus />
526
- </p-inputgroup>
382
+ </div>
527
383
  </div>
528
384
  <div class="login-dlg-elm">
529
- <button style="width: 100%;" pButton type="button" label="Login" (click)="clickLogin()"
385
+ <button style="width: 100%;" pButton type="button" label="{{properties.loginButton?.placeHolder}}" (click)="clickLogin()"
530
386
  [disabled]="!password || loading"></button>
531
387
  </div>
532
388
 
533
- <div class="login-dlg-elm" style="display:flex;align-items: center;user-select: none;">
534
- <span>No, I want to login with another user.</span>
535
- <button class="p-button-text" pButton type="button" label="Logout" (click)="clickLogout()"></button>
389
+ <div class="login-dlg-elm login-dlg-suggest" style="display:flex;align-items: center;user-select: none;">
390
+ <span>{{properties.logoutButton?.message}}</span>
391
+ <button class="p-button-text" pButton type="button" label="{{properties.logoutButton?.placeHolder}}"
392
+ (click)="clickLogout()"></button>
536
393
  </div>
537
394
  </ng-container>
538
395
 
@@ -552,16 +409,16 @@ class LocalizeLogindlgComponent {
552
409
  </div>
553
410
  </ng-container>
554
411
  </div>
555
- </div>`, isInline: true, styles: ["#login-dlg-wrap{width:100%;max-width:400px;margin:0 auto;padding:30px}.login-dlg-elm{margin-top:1rem}#login-dlg-header{display:flex;flex-direction:column;align-items:center;justify-content:center}#login-dlg-header h3{font-weight:700;font-size:.9rem;color:orange;text-align:center}#login-logo{height:40px;width:40px;background:url(/assets/images/logo-300px.png) no-repeat;background-size:contain}#login-dlg-content .p-inputgroup{height:45px}#login-dlg-content .p-inputgroup .p-inputgroup-addon *{font-size:1rem}#login-dlg-content .p-inputgroup input{height:45px;border-radius:0 15px 15px 0}#login-dlg-content button{height:45px;border-radius:15px}.check-animation-wrap{top:0;left:0;position:absolute;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:calc(100% - 200px);min-height:400px}.check-main-container{width:100%;height:100vh;display:flex;flex-flow:column;justify-content:center;align-items:center}.check-container{width:6.25rem;height:7.5rem;display:flex;flex-flow:column;align-items:center;justify-content:space-between}.check-container .check-background{width:100%;height:calc(100% - 1.25rem);background:linear-gradient(to bottom right,#5de593,#41d67c);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset;transform:scale(.84);border-radius:50%;animation:animateContainer .75s ease-out forwards .75s;display:flex;align-items:center;justify-content:center;opacity:0}.check-container .check-background svg{width:65%;transform:translateY(.25rem);stroke-dasharray:80;stroke-dashoffset:80;animation:animateCheck .35s forwards 1.25s ease-out;min-width:auto!important}.check-container .check-shadow{bottom:calc(-15% - 5px);left:0;border-radius:50%;background:radial-gradient(closest-side,rgba(73,218,131,1),transparent);animation:animateShadow .75s ease-out forwards .75s}@keyframes animateContainer{0%{opacity:0;transform:scale(0);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset}25%{opacity:1;transform:scale(.9);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset}43.75%{transform:scale(1.15);box-shadow:0 0 0 43.334px #ffffff40 inset,0 0 0 65px #ffffff40 inset}62.5%{transform:scale(1);box-shadow:0 0 #ffffff40 inset,0 0 0 21.667px #ffffff40 inset}81.25%{box-shadow:0 0 #ffffff40 inset,0 0 #ffffff40 inset}to{opacity:1;box-shadow:0 0 #ffffff40 inset,0 0 #ffffff40 inset}}@keyframes animateCheck{0%{stroke-dashoffset:80}to{stroke-dashoffset:0}}@keyframes animateShadow{0%{opacity:0;width:100%;height:15%}25%{opacity:.25}43.75%{width:40%;height:7%;opacity:.35}to{width:85%;height:15%;opacity:.25}}#login-dlg-wrap .loader-wrap{display:flex;justify-content:center;align-items:center;height:100%;width:100%;position:absolute;top:0;left:0;z-index:100;background:#ffffff42;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px)}#login-dlg-wrap .login-dlg-loader{border:15px solid #e7e7e7;border-top:15px solid #52dba1;border-radius:50%;width:100px;height:100px;animation:spinloader 2s linear infinite}#login-dlg-wrap .loader-wrap:before{content:\"\";position:absolute;width:70px;height:70px;transform:translate(-50%,-50%);z-index:1;border:15px solid #e7e7e700;border-top:15px solid #52dba1c9;border-radius:50%;animation:spinloader .75s linear infinite}@keyframes spinloader{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "directive", type: i7.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "directive", type: i8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i9.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i10.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["style", "styleClass"] }, { kind: "component", type: i11.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }], encapsulation: i0.ViewEncapsulation.None });
412
+ </div>`, isInline: true, styles: ["#login-dlg-wrap{width:100%;max-width:400px;margin:0 auto;padding:30px;height:100%}.login-dlg-elm{margin-top:1rem}.login-dlg-elm.login-dlg-suggest{display:flex;align-items:center;-webkit-user-select:none;user-select:none;border-bottom:solid 1px #ddd;border-radius:5px;padding:5px 10px;background:#f9f9f9;box-shadow:1px 5px 10px -12px #000}#login-dlg-header{display:flex;flex-direction:column;align-items:center;justify-content:center}#login-dlg-header h3{font-weight:700;font-size:.9rem;color:orange;text-align:center}#login-logo{height:55px;width:55px;background-size:contain!important}#login-dlg-content .p-inputgroup{height:45px}#login-dlg-content .p-inputgroup .p-inputgroup-addon{height:45px;border-radius:15px 0 0 15px;width:50px}#login-dlg-content *{font-size:.9rem}#login-dlg-content .p-inputgroup .p-inputgroup-addon *{font-size:1rem}#login-dlg-content .p-inputgroup input{height:45px;border-radius:0 15px 15px 0}#login-dlg-content button{height:45px;border-radius:15px}.check-animation-wrap{top:0;left:0;position:absolute;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:calc(100% - 200px);min-height:400px}.check-main-container{width:100%;height:100vh;display:flex;flex-flow:column;justify-content:center;align-items:center}.check-container{width:6.25rem;height:7.5rem;display:flex;flex-flow:column;align-items:center;justify-content:space-between}.check-container .check-background{width:100%;height:calc(100% - 1.25rem);background:linear-gradient(to bottom right,#5de593,#41d67c);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset;transform:scale(.84);border-radius:50%;animation:animateContainer .75s ease-out forwards .75s;display:flex;align-items:center;justify-content:center;opacity:0}.check-container .check-background svg{width:65%;transform:translateY(.25rem);stroke-dasharray:80;stroke-dashoffset:80;animation:animateCheck .35s forwards 1.25s ease-out;min-width:auto!important}.check-container .check-shadow{bottom:calc(-15% - 5px);left:0;border-radius:50%;background:radial-gradient(closest-side,rgba(73,218,131,1),transparent);animation:animateShadow .75s ease-out forwards .75s}@keyframes animateContainer{0%{opacity:0;transform:scale(0);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset}25%{opacity:1;transform:scale(.9);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset}43.75%{transform:scale(1.15);box-shadow:0 0 0 43.334px #ffffff40 inset,0 0 0 65px #ffffff40 inset}62.5%{transform:scale(1);box-shadow:0 0 #ffffff40 inset,0 0 0 21.667px #ffffff40 inset}81.25%{box-shadow:0 0 #ffffff40 inset,0 0 #ffffff40 inset}to{opacity:1;box-shadow:0 0 #ffffff40 inset,0 0 #ffffff40 inset}}@keyframes animateCheck{0%{stroke-dashoffset:80}to{stroke-dashoffset:0}}@keyframes animateShadow{0%{opacity:0;width:100%;height:15%}25%{opacity:.25}43.75%{width:40%;height:7%;opacity:.35}to{width:85%;height:15%;opacity:.25}}#login-dlg-wrap .loader-wrap{display:flex;justify-content:center;align-items:center;height:100%;width:100%;position:absolute;top:0;left:0;z-index:100;background:#ffffff42;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px)}#login-dlg-wrap .login-dlg-loader{border:15px solid #e7e7e7;border-top:15px solid #52dba1;border-radius:50%;width:100px;height:100px;animation:spinloader 2s linear infinite}#login-dlg-wrap .loader-wrap:before{content:\"\";position:absolute;width:70px;height:70px;transform:translate(-50%,-50%);z-index:1;border:15px solid #e7e7e700;border-top:15px solid #52dba1c9;border-radius:50%;animation:spinloader .75s linear infinite}@keyframes spinloader{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i7.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "directive", type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i10.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }], encapsulation: i0.ViewEncapsulation.None });
556
413
  }
557
414
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgComponent, decorators: [{
558
415
  type: Component,
559
416
  args: [{ standalone: false, template: `<p-toast key="$login-dlg" position="top-center"></p-toast>
560
417
  <div id="login-dlg-wrap">
561
418
  <div id="login-dlg-header">
562
- <div id="login-logo" class="p-mb-2"></div>
563
- <h3 *ngIf="!success">Your session is expired! <br> Please login again to continue.</h3>
564
- <h3 *ngIf="success" style="color:green !important;">You haved successfully logged in.</h3>
419
+ <div id="login-logo" class="p-mb-2" style="background: url('{{properties.logoImage}}') no-repeat"></div>
420
+ <h3 *ngIf="!success" [innerHTML]="sanitizedTitle"></h3>
421
+ <h3 *ngIf="success" style="color:green !important;">{{properties.loginSuccessMessage}}</h3>
565
422
  </div>
566
423
  <div id="login-dlg-content">
567
424
  <ng-container *ngIf="!success">
@@ -569,35 +426,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
569
426
  <div class="login-dlg-loader"></div>
570
427
  </div>
571
428
  <div class="login-dlg-elm">
572
- <p-inputgroup>
573
- <p-inputgroup-addon [style]="{background:'var(--p-inputtext-disabled-background)'}">
574
- <span class="p-inputgroup-addon">
575
- <i class="material-icons-round" style="color: var(--p-inputtext-disabled-color);">person</i>
576
- </span>
577
- </p-inputgroup-addon>
578
- <input disabled pInputText type="text" placeholder="Username" [value]="decodeToken?.email" />
579
- </p-inputgroup>
429
+ <div class="p-inputgroup">
430
+ <span class="p-inputgroup-addon">
431
+ <i class="material-icons-round">person</i>
432
+ </span>
433
+ <input disabled pInputText type="text" placeholder="{{properties.username?.placeHolder}}" [value]="decodeToken?.email" />
434
+ </div>
580
435
  </div>
581
436
 
582
437
  <div class="login-dlg-elm">
583
- <p-inputgroup>
584
- <p-inputgroup-addon>
585
- <span class="p-inputgroup-addon">
586
- <i class="material-icons-round">lock</i>
587
- </span>
588
- </p-inputgroup-addon>
589
- <input [disabled]="loading" (keydown.enter)="clickLogin()" pInputText type="password" placeholder="Password" [(ngModel)]="password"
438
+ <div class="p-inputgroup">
439
+ <span class="p-inputgroup-addon">
440
+ <i class="material-icons-round">lock</i>
441
+ </span>
442
+ <input [disabled]="loading" (keydown.enter)="clickLogin()" pInputText type="password"
443
+ placeholder="{{properties.password?.placeHolder}}" [(ngModel)]="password"
590
444
  autofocus />
591
- </p-inputgroup>
445
+ </div>
592
446
  </div>
593
447
  <div class="login-dlg-elm">
594
- <button style="width: 100%;" pButton type="button" label="Login" (click)="clickLogin()"
448
+ <button style="width: 100%;" pButton type="button" label="{{properties.loginButton?.placeHolder}}" (click)="clickLogin()"
595
449
  [disabled]="!password || loading"></button>
596
450
  </div>
597
451
 
598
- <div class="login-dlg-elm" style="display:flex;align-items: center;user-select: none;">
599
- <span>No, I want to login with another user.</span>
600
- <button class="p-button-text" pButton type="button" label="Logout" (click)="clickLogout()"></button>
452
+ <div class="login-dlg-elm login-dlg-suggest" style="display:flex;align-items: center;user-select: none;">
453
+ <span>{{properties.logoutButton?.message}}</span>
454
+ <button class="p-button-text" pButton type="button" label="{{properties.logoutButton?.placeHolder}}"
455
+ (click)="clickLogout()"></button>
601
456
  </div>
602
457
  </ng-container>
603
458
 
@@ -617,8 +472,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
617
472
  </div>
618
473
  </ng-container>
619
474
  </div>
620
- </div>`, selector: "app-localize-logindlg", providers: [MessageService], encapsulation: ViewEncapsulation.None, styles: ["#login-dlg-wrap{width:100%;max-width:400px;margin:0 auto;padding:30px}.login-dlg-elm{margin-top:1rem}#login-dlg-header{display:flex;flex-direction:column;align-items:center;justify-content:center}#login-dlg-header h3{font-weight:700;font-size:.9rem;color:orange;text-align:center}#login-logo{height:40px;width:40px;background:url(/assets/images/logo-300px.png) no-repeat;background-size:contain}#login-dlg-content .p-inputgroup{height:45px}#login-dlg-content .p-inputgroup .p-inputgroup-addon *{font-size:1rem}#login-dlg-content .p-inputgroup input{height:45px;border-radius:0 15px 15px 0}#login-dlg-content button{height:45px;border-radius:15px}.check-animation-wrap{top:0;left:0;position:absolute;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:calc(100% - 200px);min-height:400px}.check-main-container{width:100%;height:100vh;display:flex;flex-flow:column;justify-content:center;align-items:center}.check-container{width:6.25rem;height:7.5rem;display:flex;flex-flow:column;align-items:center;justify-content:space-between}.check-container .check-background{width:100%;height:calc(100% - 1.25rem);background:linear-gradient(to bottom right,#5de593,#41d67c);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset;transform:scale(.84);border-radius:50%;animation:animateContainer .75s ease-out forwards .75s;display:flex;align-items:center;justify-content:center;opacity:0}.check-container .check-background svg{width:65%;transform:translateY(.25rem);stroke-dasharray:80;stroke-dashoffset:80;animation:animateCheck .35s forwards 1.25s ease-out;min-width:auto!important}.check-container .check-shadow{bottom:calc(-15% - 5px);left:0;border-radius:50%;background:radial-gradient(closest-side,rgba(73,218,131,1),transparent);animation:animateShadow .75s ease-out forwards .75s}@keyframes animateContainer{0%{opacity:0;transform:scale(0);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset}25%{opacity:1;transform:scale(.9);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset}43.75%{transform:scale(1.15);box-shadow:0 0 0 43.334px #ffffff40 inset,0 0 0 65px #ffffff40 inset}62.5%{transform:scale(1);box-shadow:0 0 #ffffff40 inset,0 0 0 21.667px #ffffff40 inset}81.25%{box-shadow:0 0 #ffffff40 inset,0 0 #ffffff40 inset}to{opacity:1;box-shadow:0 0 #ffffff40 inset,0 0 #ffffff40 inset}}@keyframes animateCheck{0%{stroke-dashoffset:80}to{stroke-dashoffset:0}}@keyframes animateShadow{0%{opacity:0;width:100%;height:15%}25%{opacity:.25}43.75%{width:40%;height:7%;opacity:.35}to{width:85%;height:15%;opacity:.25}}#login-dlg-wrap .loader-wrap{display:flex;justify-content:center;align-items:center;height:100%;width:100%;position:absolute;top:0;left:0;z-index:100;background:#ffffff42;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px)}#login-dlg-wrap .login-dlg-loader{border:15px solid #e7e7e7;border-top:15px solid #52dba1;border-radius:50%;width:100px;height:100px;animation:spinloader 2s linear infinite}#login-dlg-wrap .loader-wrap:before{content:\"\";position:absolute;width:70px;height:70px;transform:translate(-50%,-50%);z-index:1;border:15px solid #e7e7e700;border-top:15px solid #52dba1c9;border-radius:50%;animation:spinloader .75s linear infinite}@keyframes spinloader{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
621
- }], ctorParameters: () => [{ type: i1$1.MessageService }, { type: i0.ChangeDetectorRef }, { type: i2.DynamicDialogRef }, { type: i2.DynamicDialogConfig }, { type: LocalizeTokenService }, { type: i1.HttpClient }] });
475
+ </div>`, selector: "app-localize-logindlg", providers: [MessageService], encapsulation: ViewEncapsulation.None, styles: ["#login-dlg-wrap{width:100%;max-width:400px;margin:0 auto;padding:30px;height:100%}.login-dlg-elm{margin-top:1rem}.login-dlg-elm.login-dlg-suggest{display:flex;align-items:center;-webkit-user-select:none;user-select:none;border-bottom:solid 1px #ddd;border-radius:5px;padding:5px 10px;background:#f9f9f9;box-shadow:1px 5px 10px -12px #000}#login-dlg-header{display:flex;flex-direction:column;align-items:center;justify-content:center}#login-dlg-header h3{font-weight:700;font-size:.9rem;color:orange;text-align:center}#login-logo{height:55px;width:55px;background-size:contain!important}#login-dlg-content .p-inputgroup{height:45px}#login-dlg-content .p-inputgroup .p-inputgroup-addon{height:45px;border-radius:15px 0 0 15px;width:50px}#login-dlg-content *{font-size:.9rem}#login-dlg-content .p-inputgroup .p-inputgroup-addon *{font-size:1rem}#login-dlg-content .p-inputgroup input{height:45px;border-radius:0 15px 15px 0}#login-dlg-content button{height:45px;border-radius:15px}.check-animation-wrap{top:0;left:0;position:absolute;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:calc(100% - 200px);min-height:400px}.check-main-container{width:100%;height:100vh;display:flex;flex-flow:column;justify-content:center;align-items:center}.check-container{width:6.25rem;height:7.5rem;display:flex;flex-flow:column;align-items:center;justify-content:space-between}.check-container .check-background{width:100%;height:calc(100% - 1.25rem);background:linear-gradient(to bottom right,#5de593,#41d67c);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset;transform:scale(.84);border-radius:50%;animation:animateContainer .75s ease-out forwards .75s;display:flex;align-items:center;justify-content:center;opacity:0}.check-container .check-background svg{width:65%;transform:translateY(.25rem);stroke-dasharray:80;stroke-dashoffset:80;animation:animateCheck .35s forwards 1.25s ease-out;min-width:auto!important}.check-container .check-shadow{bottom:calc(-15% - 5px);left:0;border-radius:50%;background:radial-gradient(closest-side,rgba(73,218,131,1),transparent);animation:animateShadow .75s ease-out forwards .75s}@keyframes animateContainer{0%{opacity:0;transform:scale(0);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset}25%{opacity:1;transform:scale(.9);box-shadow:0 0 0 65px #ffffff40 inset,0 0 0 65px #ffffff40 inset}43.75%{transform:scale(1.15);box-shadow:0 0 0 43.334px #ffffff40 inset,0 0 0 65px #ffffff40 inset}62.5%{transform:scale(1);box-shadow:0 0 #ffffff40 inset,0 0 0 21.667px #ffffff40 inset}81.25%{box-shadow:0 0 #ffffff40 inset,0 0 #ffffff40 inset}to{opacity:1;box-shadow:0 0 #ffffff40 inset,0 0 #ffffff40 inset}}@keyframes animateCheck{0%{stroke-dashoffset:80}to{stroke-dashoffset:0}}@keyframes animateShadow{0%{opacity:0;width:100%;height:15%}25%{opacity:.25}43.75%{width:40%;height:7%;opacity:.35}to{width:85%;height:15%;opacity:.25}}#login-dlg-wrap .loader-wrap{display:flex;justify-content:center;align-items:center;height:100%;width:100%;position:absolute;top:0;left:0;z-index:100;background:#ffffff42;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px)}#login-dlg-wrap .login-dlg-loader{border:15px solid #e7e7e7;border-top:15px solid #52dba1;border-radius:50%;width:100px;height:100px;animation:spinloader 2s linear infinite}#login-dlg-wrap .loader-wrap:before{content:\"\";position:absolute;width:70px;height:70px;transform:translate(-50%,-50%);z-index:1;border:15px solid #e7e7e700;border-top:15px solid #52dba1c9;border-radius:50%;animation:spinloader .75s linear infinite}@keyframes spinloader{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
476
+ }], ctorParameters: () => [{ type: i1.MessageService }, { type: i0.ChangeDetectorRef }, { type: i2.DynamicDialogRef }, { type: i2.DynamicDialogConfig }, { type: LocalizeTokenService }, { type: i4.HttpClient }, { type: i5.DomSanitizer }] });
622
477
 
623
478
  class LocalizeLogindlgService {
624
479
  injector;
@@ -626,12 +481,9 @@ class LocalizeLogindlgService {
626
481
  this.injector = injector;
627
482
  }
628
483
  async openLoginDialog(loginConfig, config) {
629
- config ??= {
630
- header: 'Login',
631
- height: '650px',
632
- style: { 'max-width': '400px', width: '100%', 'height': '650px' },
633
- };
634
- config.data = { ...config.data || {}, ...{ loginConfig } };
484
+ config = this.intercepDialogConfig(config);
485
+ this.initConfig(loginConfig);
486
+ config.data = { ...(config.data || {}), ...{ loginConfig } };
635
487
  const dialogService = this.injector.get(DialogService);
636
488
  const dialog = dialogService.open(LocalizeLogindlgComponent, config);
637
489
  await new Promise((resolve) => dialog.onClose.subscribe(res => {
@@ -640,6 +492,37 @@ class LocalizeLogindlgService {
640
492
  }
641
493
  }));
642
494
  }
495
+ intercepDialogConfig(config) {
496
+ config ??= {
497
+ header: 'Login',
498
+ style: { 'max-width': '400px', width: '100%', 'height': '650px' },
499
+ modal: true,
500
+ closable: false,
501
+ showHeader: false,
502
+ };
503
+ config = {
504
+ ...config, ...{
505
+ contentStyle: { 'height': '100%', 'border-radius': '20px' }
506
+ }
507
+ };
508
+ config.style = { ...config.style, ...{ 'border-radius': '20px' } };
509
+ return config;
510
+ }
511
+ initConfig(loginConfig) {
512
+ loginConfig ??= {};
513
+ loginConfig.properties ??= {
514
+ title: 'Your session is expired!<br/> Please login again to continue.',
515
+ loginSuccessMessage: 'You have successfully logged in.',
516
+ logoImage: '/assets/images/logo-300px.png',
517
+ username: { placeHolder: 'Username' },
518
+ password: { placeHolder: 'Password' },
519
+ loginButton: { placeHolder: 'Login' },
520
+ logoutButton: {
521
+ message: 'No, I want to login with another user.',
522
+ placeHolder: 'Logout'
523
+ }
524
+ };
525
+ }
643
526
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
644
527
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgService, providedIn: 'root' });
645
528
  }
@@ -657,19 +540,13 @@ class LocalizeLogindlgModule {
657
540
  InputTextModule,
658
541
  BrowserModule,
659
542
  FormsModule,
660
- ButtonModule,
661
- DynamicDialogModule,
662
- InputGroupModule,
663
- InputGroupAddonModule], exports: [LocalizeLogindlgComponent] });
543
+ ButtonModule], exports: [LocalizeLogindlgComponent] });
664
544
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgModule, providers: [LocalizeLogindlgService], imports: [CommonModule,
665
545
  ToastModule,
666
546
  InputTextModule,
667
547
  BrowserModule,
668
548
  FormsModule,
669
- ButtonModule,
670
- DynamicDialogModule,
671
- InputGroupModule,
672
- InputGroupAddonModule] });
549
+ ButtonModule] });
673
550
  }
674
551
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgModule, decorators: [{
675
552
  type: NgModule,
@@ -683,18 +560,558 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
683
560
  BrowserModule,
684
561
  FormsModule,
685
562
  ButtonModule,
686
- DynamicDialogModule,
687
- InputGroupModule,
688
- InputGroupAddonModule
689
563
  ],
690
564
  providers: [LocalizeLogindlgService],
691
565
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
692
566
  }]
693
567
  }] });
694
568
 
569
+ const LOCALIZE_API_ASSETS = {
570
+ network: {
571
+ noConnection: `<?xml version="1.0" encoding="UTF-8"?>
572
+ <svg id="lze-no-connection" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 77.29 70.98">
573
+ <defs>
574
+ <style> .cls-1 { fill: #fff; } .cls-2, .cls-3 { fill: #e30613; } .cls-3 { stroke: #e30613; stroke-miterlimit: 10; stroke-width: .25px; } </style>
575
+ </defs>
576
+ <g id="Layer_3" data-name="Layer 3">
577
+ <g>
578
+ <path class="cls-1" d="m73.29,35c-1.2,0-2.33-.53-3.09-1.46-.48-.57-11.23-13.2-31.55-13.2s-31.11,12.66-31.56,13.2c-1.4,1.71-3.92,1.95-5.63.55-1.71-1.4-1.95-3.92-.55-5.63.54-.66,13.47-16.12,37.74-16.12s37.2,15.46,37.74,16.12c1.4,1.71,1.15,4.23-.56,5.62-.71.58-1.61.9-2.53.9Z"/>
579
+ <path class="cls-1" d="m63.96,45.66c-1.19,0-2.32-.53-3.08-1.44-5.79-6.05-13.86-9.39-22.24-9.21-8.38-.18-16.45,3.16-22.24,9.22-1.46,1.65-3.99,1.81-5.64.35-1.57-1.39-1.8-3.77-.52-5.43,7.32-7.89,17.64-12.29,28.4-12.12,10.76-.17,21.08,4.24,28.4,12.12,1.4,1.71,1.15,4.23-.56,5.62-.71.58-1.6.9-2.53.9Z"/>
580
+ <path class="cls-1" d="m53.3,56.32c-1.24,0-2.41-.57-3.16-1.55-5.73-6.35-15.52-6.85-21.87-1.13-.4.36-.77.73-1.13,1.13-1.36,1.73-3.88,2.03-5.61.67-1.71-1.34-2.03-3.8-.73-5.54,8.39-9.85,23.18-11.04,33.03-2.65.95.81,1.84,1.69,2.65,2.65,1.34,1.75,1,4.26-.75,5.6-.7.53-1.55.82-2.43.82Z"/>
581
+ </g>
582
+ <path class="cls-2" d="m47.21,9.45l-4.06,41.36c-.64,5.42-8.39,5.39-9.01,0,0,0-4.06-41.36-4.06-41.36-.46-4.73,2.99-8.94,7.72-9.4,5.33-.58,9.97,4.09,9.4,9.4h0Z"/>
583
+ <circle class="cls-3" cx="38.64" cy="64.79" r="6.07"/>
584
+ </g>
585
+ </svg>`
586
+ }
587
+ };
588
+
589
+ /**
590
+ * Http method options
591
+ */
592
+ var EMethod;
593
+ (function (EMethod) {
594
+ EMethod["POST"] = "post";
595
+ EMethod["GET"] = "get";
596
+ EMethod["PUT"] = "put";
597
+ EMethod["DELETE"] = "delete";
598
+ EMethod["PATCH"] = "patch";
599
+ })(EMethod || (EMethod = {}));
600
+
601
+ class LocalizeApiHelper {
602
+ defaultRetryOptions = {
603
+ connectionError: {
604
+ message: 'Connection error occurred. Please wait',
605
+ blockScreen: true,
606
+ blockScreenZIndex: 10000
607
+ }
608
+ };
609
+ async performRetry(options) {
610
+ let attempts = 0;
611
+ let lastError;
612
+ let consoleCount = 0;
613
+ // Merge default retry options with provided options
614
+ options = { ...this.defaultRetryOptions, ...options };
615
+ let styleElement;
616
+ while (attempts < options.maxRetries()) {
617
+ try {
618
+ const result = await options.callback();
619
+ this.removeBlocker(styleElement);
620
+ return result;
621
+ }
622
+ catch (error) {
623
+ lastError = error;
624
+ if (consoleCount >= 7) {
625
+ console.clear();
626
+ consoleCount = 0;
627
+ }
628
+ if (options.retryUnless && !options.retryUnless(error))
629
+ throw error; // If the error should not be retried, rethrow it
630
+ // Handle connection error
631
+ styleElement = await this.onConnectionError(options, error);
632
+ if (options.onError)
633
+ await this.invokeHook(options.onError.bind(this, error));
634
+ if (attempts >= options.maxRetries() - 1)
635
+ throw error;
636
+ attempts++;
637
+ consoleCount++;
638
+ console.warn(`Attempt ${attempts} failed. Retrying...`, error);
639
+ await waitFor(options.delay);
640
+ }
641
+ }
642
+ console.warn(`Failed after ${options.maxRetries} attempts`);
643
+ throw lastError;
644
+ }
645
+ async performRequestWithRetry(options, config, performRequest) {
646
+ const retryUnless = config.retryOptions?.retryFunction
647
+ || this.isConnectionError;
648
+ return await this.performRetry({
649
+ connectionError: config.retryOptions?.onConnectionError,
650
+ maxRetries: () => config.retryOptions?.maxRetries ?? 1000,
651
+ delay: config.retryOptions?.delay ?? 500,
652
+ callback: () => performRequest(options),
653
+ retryUnless: retryUnless,
654
+ });
655
+ }
656
+ buildUrl(baseUrl, path) {
657
+ const normalizedUrl = `${baseUrl.trim().replace(/\/?$/, '/')}${path.trim().replace(/^\//, '')}`;
658
+ return normalizedUrl.endsWith('/')
659
+ ? normalizedUrl.slice(0, -1)
660
+ : normalizedUrl;
661
+ }
662
+ normalizeError(error) {
663
+ return {
664
+ code: error.error?.code || `HTTP_${error.status}`,
665
+ message: error.error?.message || error.message,
666
+ details: error.error?.details,
667
+ status: error.status
668
+ };
669
+ }
670
+ async invokeHook(callback) {
671
+ if (!callback)
672
+ return;
673
+ const result = callback();
674
+ if (result instanceof Promise) {
675
+ await result;
676
+ }
677
+ }
678
+ createRequest(instance, method, url, body, options) {
679
+ const request$ = instance.client.request(method, url, {
680
+ ...options,
681
+ body,
682
+ observe: 'response',
683
+ }).pipe(takeUntil(instance.destroy$()), catchError((error) => {
684
+ // Convert to a non-observable error to handle in the promise
685
+ return throwError(() => this.normalizeError(error));
686
+ }));
687
+ return request$;
688
+ }
689
+ defaultRetryFunction(error) {
690
+ // Don't retry for other errors (like 400, 401, 403, etc.)
691
+ if (!this.isConnectionError(error))
692
+ throw error;
693
+ return true;
694
+ }
695
+ isConnectionError(error) {
696
+ const isNetworkError = error.status === 0;
697
+ const isServerError = error.status >= 1000 && error.status < 600;
698
+ return isNetworkError || isServerError;
699
+ }
700
+ async onConnectionError(options, error) {
701
+ if (!options.connectionError)
702
+ return;
703
+ let styleElement;
704
+ if (this.isConnectionError(error)) {
705
+ styleElement = this.screenBlocker(options, error, true);
706
+ await this.invokeHook(options.connectionError.callback?.bind(this, error));
707
+ return styleElement;
708
+ }
709
+ else {
710
+ this.screenBlocker(options, error, false);
711
+ styleElement?.remove();
712
+ }
713
+ }
714
+ screenBlocker(optons, error, add = true) {
715
+ if (!optons.connectionError?.blockScreen)
716
+ return;
717
+ if (error instanceof HttpErrorResponse)
718
+ error = this.normalizeError(error);
719
+ const message = optons.connectionError?.message
720
+ || 'Connection error occurred. Please wait';
721
+ const errorMessage = error?.message || 'An error occurred';
722
+ const suggestinMessage = optons.connectionError?.suggestionMessage
723
+ || 'Please check your internet connection or the server status.';
724
+ const zIndex = optons.connectionError?.blockScreenZIndex || 10000;
725
+ const body = document.body;
726
+ const blcokerHtml = `
727
+ <div class="lze-blocker">
728
+ ${LOCALIZE_API_ASSETS.network.noConnection}
729
+ <div class="lze-blocker__message">
730
+ ${message}
731
+ <span class="lze-blocker__dotting">
732
+ <span class="lze-blocker__dot"></span>
733
+ <span class="lze-blocker__dot"></span>
734
+ <span class="lze-blocker__dot"></span>
735
+ </span>
736
+ </div>
737
+ <div class="lze-blocker__error">${errorMessage}</div>
738
+ <div class="lze-blocker__error_suggestion">${suggestinMessage}</div>
739
+ </div>
740
+ `;
741
+ const style = `
742
+ div.lze-blocker {
743
+ position: fixed;
744
+ top: 0;
745
+ left: 0;
746
+ width: 100%;
747
+ height: 100%;
748
+ background: rgba(0, 0, 0, 0.85) !important;
749
+ z-index: ${zIndex};
750
+ display: flex;
751
+ align-items: center;
752
+ justify-content: center;
753
+ flex-direction: column;
754
+ color: #fff !important;
755
+ font-family: Arial, sans-serif;
756
+ text-align: center;
757
+ padding: 20px;
758
+ box-sizing: border-box;
759
+ overflow: hidden;
760
+ user-select: none;
761
+ }
762
+
763
+ svg#lze-no-connection {
764
+ width: 75px;
765
+ height: 75px;
766
+ margin-bottom: 20px;
767
+ }
768
+
769
+ div.lze-blocker__message {
770
+ color: #fff !important;
771
+ font-size: 18px !important;
772
+ margin-bottom: 10px;
773
+ }
774
+
775
+ .lze-blocker__dotting {
776
+ display: inline-block;
777
+ vertical-align: middle;
778
+ }
779
+ span.lze-blocker__dot {
780
+ display: inline-block;
781
+ width: 7px;
782
+ height: 7px;
783
+ background-color: #ffffff !important;
784
+ border-radius: 50%;
785
+ margin-left: 3px;
786
+ opacity: 0.3;
787
+ animation: dotting 1s infinite;
788
+ }
789
+ .lze-blocker__dot:nth-child(1) {
790
+ animation-delay: 0s;
791
+ opacity: 1;
792
+ }
793
+ .lze-blocker__dot:nth-child(2) {
794
+ animation-delay: 0.2s;
795
+ }
796
+ .lze-blocker__dot:nth-child(3) {
797
+ animation-delay: 0.4s;
798
+ }
799
+
800
+ @keyframes dotting {
801
+ 0%, 80%, 100% { opacity: 0.3; }
802
+ 40% { opacity: 1; }
803
+ }
804
+
805
+ div.lze-blocker__error {
806
+ color: #f00;
807
+ font-size: 14px !important;
808
+ margin-bottom: 10px;
809
+ text-shadow: 0 0 1px #ff5f5f !important;
810
+ }
811
+
812
+ div.lze-blocker__error_suggestion {
813
+ color: #ccc !important;
814
+ font-size: 14px !important;
815
+ margin-top: 10px;
816
+ }
817
+
818
+ @keyframes spin {
819
+ 0% { transform: rotate(0deg); }
820
+ 100% { transform: rotate(360deg); }
821
+ }
822
+ `;
823
+ const styleElement = document.createElement('style');
824
+ if (add) {
825
+ if (!document.querySelector('.lze-blocker')) {
826
+ styleElement.innerHTML = style;
827
+ document.head.appendChild(styleElement);
828
+ body.insertAdjacentHTML('beforeend', blcokerHtml);
829
+ }
830
+ }
831
+ else {
832
+ this.removeBlocker(styleElement);
833
+ }
834
+ return styleElement;
835
+ }
836
+ removeBlocker(styleElement) {
837
+ const blocker = document.querySelector('.lze-blocker');
838
+ blocker?.remove();
839
+ styleElement?.remove();
840
+ }
841
+ }
842
+ const ApiHelper = new LocalizeApiHelper();
843
+
844
+ const SCHEMES = LocalizeToken.httpHeaders;
845
+ class LocalizeApiService {
846
+ httpClient;
847
+ localizeTokenService;
848
+ destroy$ = new Subject();
849
+ configSubject = new BehaviorSubject({});
850
+ isRequestingSubject = new BehaviorSubject(false);
851
+ isResolvingStartupSubject = new BehaviorSubject(false);
852
+ get isResolvingStartup() { return this.isResolvingStartupSubject.value; }
853
+ get needTenant() { return this.localizeTokenService.config.tenantToken !== undefined; }
854
+ get isRequesting() { return this.isRequestingSubject.value; }
855
+ get isRevokingToken() { return this.localizeTokenService.isRevokingToken; }
856
+ set isRevokingToken(value) { this.localizeTokenService.isRevokingToken = value; }
857
+ get accessToken() { return this.localizeTokenService.accessToken; }
858
+ set accessToken(value) { this.localizeTokenService.accessToken = value; }
859
+ get refreshToken() { return this.localizeTokenService.refreshToken; }
860
+ get tenantToken() { return this.localizeTokenService.tenantToken; }
861
+ defaultConfig = {
862
+ waitEachRequest: { milliseconds: 0 },
863
+ enableRequestCancellation: true,
864
+ retryOptions: {
865
+ maxRetries: 1000,
866
+ delay: 1000,
867
+ retryFunction: ApiHelper.defaultRetryFunction.bind(this),
868
+ },
869
+ };
870
+ get config() {
871
+ this.validateConfig();
872
+ return this.configSubject.value;
873
+ }
874
+ apiOptions = {
875
+ method: EMethod.GET,
876
+ requestBody: null,
877
+ };
878
+ constructor(httpClient, localizeTokenService) {
879
+ this.httpClient = httpClient;
880
+ this.localizeTokenService = localizeTokenService;
881
+ }
882
+ /**
883
+ * Initialize the API service.
884
+ * @param apiConfigs - The API configurations.
885
+ */
886
+ init(apiConfigs) {
887
+ console.log('LocalizeApiService is initialized.');
888
+ this.configSubject.next({ ...this.defaultConfig, ...apiConfigs });
889
+ }
890
+ cancelPendingRequests() {
891
+ this.config.enableRequestCancellation
892
+ && this.destroy$.next();
893
+ }
894
+ ngOnDestroy() {
895
+ this.destroy$.next();
896
+ this.destroy$.complete();
897
+ // this.isResolvingStartupSubject.complete();
898
+ // this.isRequestingSubject.complete();
899
+ // this.configSubject.complete();
900
+ }
901
+ /**
902
+ * A higher-order function that returns a curried function for making API requests.
903
+ *
904
+ * @param baseUrl - The base URL of the API.
905
+ * @returns A curried function that can be used to make API requests.
906
+ */
907
+ func = (baseUrl) => (path, method = EMethod.GET, reqBody = null, reqHeaders) => this.request(baseUrl, path, method, reqBody, reqHeaders);
908
+ async request(baseUrl, path, method = EMethod.GET, reqBody = null, reqHeaders) {
909
+ await waitUntil(() => !this.isResolvingStartup, 500);
910
+ await ApiHelper.invokeHook(this.config.onPrepareRequest);
911
+ const apiOptions = this.buildApiOptions(baseUrl, path, method, reqBody, reqHeaders);
912
+ try {
913
+ await this.toWaitForPreviousRequest();
914
+ return await ApiHelper.performRequestWithRetry(apiOptions, this.config, this.performRequest.bind(this));
915
+ }
916
+ catch (error) {
917
+ return await this.handleOnRequestError(error, apiOptions);
918
+ }
919
+ }
920
+ async handleOnRequestError(error, options) {
921
+ if (error.status !== 401)
922
+ throw error;
923
+ await waitUntil(() => !this.isResolvingStartup, 500);
924
+ return await ApiHelper.performRetry({
925
+ maxRetries: () => 1000,
926
+ delay: 500,
927
+ retryUnless: (error) => error.status === 401 || ApiHelper.isConnectionError(error),
928
+ callback: async () => {
929
+ // Only handle 401 Unauthorized errors
930
+ await this.revokeToken();
931
+ // Retry the request with the new access token
932
+ return await this.performRequest(options);
933
+ }
934
+ });
935
+ }
936
+ async performRequest(options) {
937
+ // Build the request options
938
+ const buildOptions = { headers: this.buildHeaderOptions(options) };
939
+ // Create the request observable
940
+ const request$ = ApiHelper.createRequest({
941
+ client: this.httpClient,
942
+ destroy$: () => this.destroy$
943
+ }, options.method, options.requestUrl, options.requestBody, buildOptions);
944
+ // Set the isRequesting state to true before making the request
945
+ this.isRequestingSubject.next(true);
946
+ const response = await new Promise((resolve, reject) => request$.subscribe({ next: (res) => resolve(res.body), error: reject }));
947
+ // Reset the isRequesting state after the request completes
948
+ this.isRequestingSubject.next(false);
949
+ return response;
950
+ }
951
+ async revokeToken() {
952
+ try {
953
+ if (await this.interceptRevokeToken())
954
+ return;
955
+ this.isRevokingToken = true;
956
+ const apiOptions = {
957
+ ...this.buildApiOptions(this.localizeTokenService.config.refreshToken?.requestUrl || ''),
958
+ refreshToken: true,
959
+ };
960
+ // const revokeToken = await this.performRequest(apiOptions);
961
+ const revokeToken = await ApiHelper.performRequestWithRetry(apiOptions, this.config, this.performRequest.bind(this));
962
+ await this.handleOnTokenRevoked(revokeToken);
963
+ }
964
+ catch (error) {
965
+ // Handle the error, log it
966
+ await ApiHelper.invokeHook(this.config.onAutoLogout);
967
+ }
968
+ finally {
969
+ // Reset the revoking token state
970
+ this.isRevokingToken = false;
971
+ }
972
+ }
973
+ /** default http request options */
974
+ buildHeaderOptions(options) {
975
+ const headers = {
976
+ ...(options.refreshToken && { [SCHEMES.X_REFRESH_TOKEN]: `${this.refreshToken}` }),
977
+ ...(!options.isFormData && { [SCHEMES.CONTENT_TYPE]: 'application/json' }),
978
+ [SCHEMES.AUTHORIZATION]: `Bearer ${this.accessToken}`,
979
+ ...(this.needTenant && { [SCHEMES.X_TENANT]: `${this.tenantToken}` })
980
+ };
981
+ return new HttpHeaders({ ...headers, ...options.headers });
982
+ }
983
+ buildApiOptions(baseUrl, path = '', method = EMethod.GET, requestBody = null, headers) {
984
+ const requestUrl = ApiHelper.buildUrl(baseUrl, path);
985
+ const isFormData = requestBody && requestBody instanceof FormData;
986
+ return {
987
+ ...this.apiOptions,
988
+ ...{ headers, method, requestUrl, requestBody, isFormData }
989
+ };
990
+ }
991
+ async toWaitForPreviousRequest() {
992
+ this.isRevokingToken &&
993
+ (await waitUntil(() => !this.isRevokingToken));
994
+ // to wait for each request in 50ms, even if the request is not completed
995
+ this.config.waitEachRequest?.milliseconds &&
996
+ (await waitFor(this.config.waitEachRequest.milliseconds, this.isRequesting));
997
+ }
998
+ async handleOnTokenRevoked(response) {
999
+ if (response?.status) {
1000
+ // If the response is successful, update the access token
1001
+ this.accessToken = response.message;
1002
+ }
1003
+ else {
1004
+ // If the response indicates an error, invoke the onRevokeUnauthorized hook
1005
+ console.warn('Token revocation failed, refresh token is expired.', response.message);
1006
+ await ApiHelper.invokeHook(this.config.onRevokeUnauthorized);
1007
+ }
1008
+ }
1009
+ async interceptRevokeToken() {
1010
+ if (this.isRevokingToken) {
1011
+ console.warn('Token is already being revoked. Waiting for the current operation to complete...');
1012
+ await waitUntil(() => !this.isRevokingToken);
1013
+ return true;
1014
+ }
1015
+ if (!this.refreshToken) {
1016
+ // await ApiHelper.invokeHook(this.apiConfigs.onAutoLogout);
1017
+ throw new Error('Refresh token is missing. Please login again.');
1018
+ }
1019
+ return false;
1020
+ }
1021
+ validateConfig() {
1022
+ if (this.localizeTokenService.config.tenantToken
1023
+ && !this.localizeTokenService.config.tenantToken?.name?.trim().length) {
1024
+ throw Error('Tenant token is required but tenantTokenName is not configured');
1025
+ }
1026
+ if (!this.localizeTokenService.config.refreshToken?.requestUrl?.trim().length) {
1027
+ throw Error('Revoke token URL is not configured - token refresh will not work');
1028
+ }
1029
+ }
1030
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiService, deps: [{ token: i4.HttpClient }, { token: LocalizeTokenService }], target: i0.ɵɵFactoryTarget.Injectable });
1031
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiService, providedIn: 'root' });
1032
+ }
1033
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiService, decorators: [{
1034
+ type: Injectable,
1035
+ args: [{
1036
+ providedIn: 'root'
1037
+ }]
1038
+ }], ctorParameters: () => [{ type: i4.HttpClient }, { type: LocalizeTokenService }] });
1039
+
1040
+ class LocalizeTokenModule {
1041
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1042
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule });
1043
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule, providers: [
1044
+ LocalizeTokenService,
1045
+ LocalizeApiService
1046
+ ] });
1047
+ }
1048
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule, decorators: [{
1049
+ type: NgModule,
1050
+ args: [{
1051
+ providers: [
1052
+ LocalizeTokenService,
1053
+ LocalizeApiService
1054
+ ]
1055
+ }]
1056
+ }] });
1057
+
1058
+ class LocalizeApiTokenService {
1059
+ api;
1060
+ token;
1061
+ loginDialog;
1062
+ constructor(tokenService, apiService, loginDialogService) {
1063
+ this.api = apiService;
1064
+ this.token = tokenService;
1065
+ this.loginDialog = loginDialogService;
1066
+ }
1067
+ initialize(tokenConfig, apiConfig) {
1068
+ // Initialize the LocalizeTokenService with the provided token configuration
1069
+ this.token.init(tokenConfig);
1070
+ // Initialize the LocalizeApiService with the provided API configuration
1071
+ this.api.init(apiConfig);
1072
+ console.log('LocalizeApiTokenService initialized with token and API configurations.');
1073
+ }
1074
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiTokenService, deps: [{ token: LocalizeTokenService }, { token: LocalizeApiService }, { token: LocalizeLogindlgService }], target: i0.ɵɵFactoryTarget.Injectable });
1075
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiTokenService, providedIn: 'root' });
1076
+ }
1077
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiTokenService, decorators: [{
1078
+ type: Injectable,
1079
+ args: [{
1080
+ providedIn: 'root'
1081
+ }]
1082
+ }], ctorParameters: () => [{ type: LocalizeTokenService }, { type: LocalizeApiService }, { type: LocalizeLogindlgService }] });
1083
+
1084
+ class LocalizeApiTokenModule {
1085
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiTokenModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1086
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiTokenModule, imports: [CommonModule,
1087
+ LocalizeTokenModule,
1088
+ LocalizeLogindlgModule] });
1089
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiTokenModule, providers: [
1090
+ LocalizeApiTokenService
1091
+ ], imports: [CommonModule,
1092
+ LocalizeTokenModule,
1093
+ LocalizeLogindlgModule] });
1094
+ }
1095
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiTokenModule, decorators: [{
1096
+ type: NgModule,
1097
+ args: [{
1098
+ declarations: [],
1099
+ imports: [
1100
+ CommonModule,
1101
+ LocalizeTokenModule,
1102
+ LocalizeLogindlgModule
1103
+ ],
1104
+ providers: [
1105
+ LocalizeApiTokenService
1106
+ ]
1107
+ }]
1108
+ }] });
1109
+
1110
+ //#region login dialog
1111
+
695
1112
  /**
696
1113
  * Generated bundle index. Do not edit.
697
1114
  */
698
1115
 
699
- export { EMethod, LocalizeApiService, LocalizeLogindlgComponent, LocalizeLogindlgModule, LocalizeLogindlgService, LocalizeToken, LocalizeTokenModule, LocalizeTokenService, LocalizeTokenStorage, extractMainDomain, waitFor, waitUntil };
1116
+ export { ApiHelper, EMethod, LOCALIZE_API_ASSETS, LocalizeApiService, LocalizeApiTokenModule, LocalizeApiTokenService, LocalizeLogindlgComponent, LocalizeLogindlgModule, LocalizeLogindlgService, LocalizeToken, LocalizeTokenModule, LocalizeTokenService, LocalizeTokenStorage, extractMainDomain, waitFor, waitUntil };
700
1117
  //# sourceMappingURL=sambath999-localize-token.mjs.map