@sambath999/localize-token 19.0.2 → 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,38 +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
- }
216
+ this.authToken && (this.authToken = { ...this.authToken, revoke: value });
217
217
  }
218
- get tenantToken() { return LocalizeToken.storage.get(this.config.tenantTokenName); }
219
218
  storageGet() {
220
219
  try {
221
- const encoded = LocalizeToken.storage.get(this.config.authTokenName);
220
+ const encoded = LocalizeToken.storage.get(this.config.authToken?.name || '');
222
221
  const decoded = atob(encoded || '');
223
222
  return JSON.parse(decoded);
224
223
  }
@@ -228,17 +227,21 @@ class LocalizeTokenService {
228
227
  }
229
228
  storageSet(value) {
230
229
  const base64 = btoa(JSON.stringify(value));
231
- LocalizeToken.storage.set(this.config.authTokenName, base64);
230
+ LocalizeToken.storage.set(this.config.authToken?.name || '', base64);
232
231
  }
233
232
  tokensValid() {
234
- return this.refreshToken?.length && (!this.config.needTenant || this.tenantToken?.length);
233
+ return !!this.refreshToken?.length
234
+ && (!this.config.tenantToken || !!this.tenantToken?.length);
235
235
  }
236
236
  decodeToken = (token) => jwt_decode.jwtDecode(token);
237
237
  get decodeRefreshToken() {
238
- const token = LocalizeToken.storage.get(this.config.refreshTokenName);
239
- if (!token)
240
- return null;
241
- 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
+ }
242
245
  }
243
246
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
244
247
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenService, providedIn: 'root' });
@@ -246,161 +249,6 @@ class LocalizeTokenService {
246
249
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenService, decorators: [{
247
250
  type: Injectable,
248
251
  args: [{ providedIn: 'root' }]
249
- }], ctorParameters: () => [] });
250
-
251
- /**
252
- * Http method options
253
- */
254
- var EMethod;
255
- (function (EMethod) {
256
- EMethod[EMethod["POST"] = 1] = "POST";
257
- EMethod[EMethod["GET"] = 2] = "GET";
258
- EMethod[EMethod["PUT"] = 3] = "PUT";
259
- EMethod[EMethod["DELETE"] = 4] = "DELETE";
260
- EMethod[EMethod["PATCH"] = 5] = "PATCH";
261
- })(EMethod || (EMethod = {}));
262
- class LocalizeApiService {
263
- httpClient;
264
- localizeTokenService;
265
- isRequestingSubject = new BehaviorSubject(false);
266
- isResolvedStartupSubject = new BehaviorSubject(false);
267
- get isRequesting() { return this.isRequestingSubject.value; }
268
- get isResolvedStartup() { return this.isResolvedStartupSubject.value; }
269
- apiConfigs = {};
270
- isInitialized = false;
271
- constructor(httpClient, localizeTokenService) {
272
- this.httpClient = httpClient;
273
- this.localizeTokenService = localizeTokenService;
274
- }
275
- /**
276
- * Initialize the API service.
277
- * @param apiConfigs - The API configurations.
278
- */
279
- init(apiConfigs) {
280
- if (this.isInitialized)
281
- return;
282
- this.isInitialized = true;
283
- this.apiConfigs = apiConfigs;
284
- }
285
- /**
286
- * A higher-order function that returns a curried function for making API requests.
287
- *
288
- * @param baseUrl - The base URL of the API.
289
- * @returns A curried function that can be used to make API requests.
290
- */
291
- func = (baseUrl) => (path, method = EMethod.GET, value = null, isFormData = false, headers) => this.base(baseUrl, path, method, value, isFormData, headers);
292
- async base(baseUrl, path, method = EMethod.GET, value = null, isFormData = false, headers) {
293
- await this.ifPromise(this.apiConfigs.onPrepareRequest);
294
- const url = `${baseUrl.trim().replace(/\/?$/, '/')}${path.trim().replace(/^\//, '')}`;
295
- const httpMethod = EMethod[method].toLowerCase();
296
- const request = () => { return { body: value, headers: this.options(isFormData, headers) }; };
297
- // Wait for previous request to complete
298
- await this.toWaitForPreviousRequest();
299
- // Process request
300
- try {
301
- return await this.processRequest(httpMethod, url, request());
302
- }
303
- // Handle unauthorized error if any
304
- catch (error) {
305
- if (error.status !== 401) {
306
- throw error;
307
- }
308
- return await this.onUnauthorizedError(httpMethod, url, request);
309
- }
310
- }
311
- async onUnauthorizedError(httpMethod, url, request) {
312
- await this.revokeToken();
313
- if (!this.isResolvedStartup) {
314
- return await this.processRequest(httpMethod, url, request());
315
- }
316
- }
317
- async toWaitForPreviousRequest() {
318
- if (this.localizeTokenService.isRevokingToken) {
319
- await waitUntil(() => !this.localizeTokenService.isRevokingToken);
320
- }
321
- // to wait for each request in 50ms, even if the request is not completed
322
- if (this.apiConfigs.waitEachRequest?.milliseconds) {
323
- await waitFor(this.apiConfigs.waitEachRequest.milliseconds, this.isRequesting);
324
- }
325
- }
326
- async processRequest(method, url, options) {
327
- this.isRequestingSubject.next(true);
328
- const result = await new Promise((resolve, reject) => this.httpClient.request(method, url, options).subscribe({ next: resolve, error: reject }));
329
- this.isRequestingSubject.next(false);
330
- return result;
331
- }
332
- async revokeToken() {
333
- if (this.localizeTokenService.isRevokingToken) {
334
- await waitUntil(() => !this.localizeTokenService.isRevokingToken);
335
- return;
336
- }
337
- try {
338
- this.localizeTokenService.isRevokingToken = true;
339
- const reqUrl = LocalizeToken.config.revokeTokenUrl;
340
- const reqHeaders = this.options().append(LocalizeToken.httpHeaders.X_REFRESH_TOKEN, `${this.localizeTokenService.refreshToken}`);
341
- const revokeToken = await new Promise((resolve, reject) => this.httpClient.get(reqUrl, { headers: reqHeaders }).subscribe({ next: resolve, error: reject }));
342
- if (revokeToken?.status) {
343
- this.localizeTokenService.accessToken = revokeToken.message;
344
- }
345
- else if (!this.localizeTokenService.refreshToken) {
346
- await this.ifPromise(this.apiConfigs.onAutoLogout);
347
- }
348
- else {
349
- if (this.apiConfigs.onRevokeUnauthorized) {
350
- await this.ifPromise(this.apiConfigs.onRevokeUnauthorized);
351
- // await this.revokeToken();
352
- }
353
- }
354
- }
355
- finally {
356
- this.localizeTokenService.isRevokingToken = false;
357
- }
358
- }
359
- /** default http request options */
360
- options(isFormData = false, headers = {}) {
361
- const defaultHeaders = { [LocalizeToken.httpHeaders.AUTHORIZATION]: `Bearer ${this.localizeTokenService.accessToken}`, };
362
- if (LocalizeToken.config.needTenant) {
363
- defaultHeaders[LocalizeToken.httpHeaders.X_TENANT] = `${this.localizeTokenService.tenantToken}`;
364
- }
365
- if (!isFormData) {
366
- defaultHeaders[LocalizeToken.httpHeaders.CONTENT_TYPE] = 'application/json';
367
- }
368
- const filteredHeaders = Object.keys(defaultHeaders).filter(key => !Object.keys(headers).includes(key))
369
- .reduce((acc, key) => ({ ...acc, [key]: defaultHeaders[key] }), {});
370
- const mergedHeaders = { ...filteredHeaders, ...headers };
371
- return new HttpHeaders(mergedHeaders);
372
- }
373
- async ifPromise(fn) {
374
- if (!fn)
375
- return;
376
- return fn instanceof Promise ? await fn() : fn();
377
- }
378
- 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 });
379
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiService, providedIn: 'root' });
380
- } //class
381
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeApiService, decorators: [{
382
- type: Injectable,
383
- args: [{
384
- providedIn: 'root'
385
- }]
386
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: LocalizeTokenService }] });
387
-
388
- class LocalizeTokenModule {
389
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
390
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule });
391
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule, providers: [
392
- LocalizeTokenService,
393
- LocalizeApiService
394
- ] });
395
- }
396
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeTokenModule, decorators: [{
397
- type: NgModule,
398
- args: [{
399
- providers: [
400
- LocalizeTokenService,
401
- LocalizeApiService
402
- ],
403
- }]
404
252
  }] });
405
253
 
406
254
  class LocalizeLogindlgComponent {
@@ -410,24 +258,28 @@ class LocalizeLogindlgComponent {
410
258
  dlgConfig;
411
259
  tokenService;
412
260
  httpClient;
261
+ sanitizer;
413
262
  messageKey = "$login-dlg";
414
263
  password;
415
264
  decodeToken;
416
265
  loading = false;
417
266
  success = false;
418
- config = LocalizeToken.config;
267
+ get config() { return this.tokenService.config; }
419
268
  loginConfig;
420
269
  logout;
421
270
  loginUrl;
422
- constructor(messageService, cdt, dlgRef, dlgConfig, tokenService, httpClient) {
271
+ properties;
272
+ constructor(messageService, cdt, dlgRef, dlgConfig, tokenService, httpClient, sanitizer) {
423
273
  this.messageService = messageService;
424
274
  this.cdt = cdt;
425
275
  this.dlgRef = dlgRef;
426
276
  this.dlgConfig = dlgConfig;
427
277
  this.tokenService = tokenService;
428
278
  this.httpClient = httpClient;
279
+ this.sanitizer = sanitizer;
429
280
  this.decodeToken = this.tokenService.decodeRefreshToken;
430
281
  this.loginConfig = this.dlgConfig.data.loginConfig;
282
+ this.properties = this.loginConfig.properties;
431
283
  }
432
284
  ngOnInit() {
433
285
  this.dlgConfig.closable = false;
@@ -443,29 +295,34 @@ class LocalizeLogindlgComponent {
443
295
  }
444
296
  async clickLogin() {
445
297
  if (!this.isValidPassword) {
446
- this.showMessage("error", "Password is required and must be at least 6 characters");
447
- return;
298
+ return this.showMessage("error", "Password is required and must be at least 6 characters");
448
299
  }
449
300
  this.loading = true;
450
301
  const loginRes = await this.login();
451
302
  if (!loginRes?.status) {
452
- this.showMessage("error", loginRes.message ?? "An error occurred");
453
- return;
303
+ return this.showMessage("error", loginRes.message ?? "An error occurred");
454
304
  }
455
305
  this.tokenService.accessToken = loginRes.tokens.accessToken;
456
- const cookieOptions = { expires: this.loginConfig.expire ?? 5 };
457
- 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);
458
308
  this.success = true;
459
- 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);
460
314
  }
461
315
  async login() {
462
- if (!this.loginUrl || !this.loginUrl.trim().length) {
316
+ if (!this.loginUrl?.trim().length) {
463
317
  this.showMessage("error", "Login url is required");
464
318
  throw new Error("Login url is required");
465
319
  }
466
320
  try {
467
- return await new Promise((resolve, reject) => this.httpClient.post(this.loginUrl, { password: this.password.trim() }, { headers: this.getHeaders() })
468
- .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 }));
469
326
  }
470
327
  catch (e) {
471
328
  this.showMessage("error", e.message);
@@ -474,26 +331,31 @@ class LocalizeLogindlgComponent {
474
331
  }
475
332
  getHeaders() {
476
333
  return {
477
- [LocalizeToken.httpHeaders.X_REFRESH_TOKEN]: LocalizeToken.storage.get(this.config.refreshTokenName) ?? "",
478
- [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 ?? "",
479
336
  };
480
337
  }
481
338
  get isValidPassword() {
482
339
  this.loading = false;
483
- return this.password && this.password.trim().length >= 6 && this.password.trim().length <= 16;
340
+ return this.properties.passwordValidator
341
+ ? this.properties.passwordValidator(this.password)
342
+ : this.password && this.password.trim().length >= 6 && this.password.trim().length <= 50;
484
343
  }
485
344
  clickLogout = () => this.logout?.();
486
345
  showMessage(severity, summary) {
487
346
  this.messageService.add({ key: this.messageKey, severity, summary });
488
347
  this.loading = false;
489
348
  }
490
- 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 });
491
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>
492
354
  <div id="login-dlg-wrap">
493
355
  <div id="login-dlg-header">
494
- <div id="login-logo" class="p-mb-2"></div>
495
- <h3 *ngIf="!success">Your session is expired! <br> Please login again to continue.</h3>
496
- <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>
497
359
  </div>
498
360
  <div id="login-dlg-content">
499
361
  <ng-container *ngIf="!success">
@@ -501,35 +363,33 @@ class LocalizeLogindlgComponent {
501
363
  <div class="login-dlg-loader"></div>
502
364
  </div>
503
365
  <div class="login-dlg-elm">
504
- <p-inputgroup>
505
- <p-inputgroup-addon [style]="{background:'var(--p-inputtext-disabled-background)'}">
506
- <span class="p-inputgroup-addon">
507
- <i class="material-icons-round" style="color: var(--p-inputtext-disabled-color);">person</i>
508
- </span>
509
- </p-inputgroup-addon>
510
- <input disabled pInputText type="text" placeholder="Username" [value]="decodeToken?.email" />
511
- </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>
512
372
  </div>
513
373
 
514
374
  <div class="login-dlg-elm">
515
- <p-inputgroup>
516
- <p-inputgroup-addon>
517
- <span class="p-inputgroup-addon">
518
- <i class="material-icons-round">lock</i>
519
- </span>
520
- </p-inputgroup-addon>
521
- <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"
522
381
  autofocus />
523
- </p-inputgroup>
382
+ </div>
524
383
  </div>
525
384
  <div class="login-dlg-elm">
526
- <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()"
527
386
  [disabled]="!password || loading"></button>
528
387
  </div>
529
388
 
530
- <div class="login-dlg-elm" style="display:flex;align-items: center;user-select: none;">
531
- <span>No, I want to login with another user.</span>
532
- <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>
533
393
  </div>
534
394
  </ng-container>
535
395
 
@@ -549,16 +409,16 @@ class LocalizeLogindlgComponent {
549
409
  </div>
550
410
  </ng-container>
551
411
  </div>
552
- </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 });
553
413
  }
554
414
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgComponent, decorators: [{
555
415
  type: Component,
556
416
  args: [{ standalone: false, template: `<p-toast key="$login-dlg" position="top-center"></p-toast>
557
417
  <div id="login-dlg-wrap">
558
418
  <div id="login-dlg-header">
559
- <div id="login-logo" class="p-mb-2"></div>
560
- <h3 *ngIf="!success">Your session is expired! <br> Please login again to continue.</h3>
561
- <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>
562
422
  </div>
563
423
  <div id="login-dlg-content">
564
424
  <ng-container *ngIf="!success">
@@ -566,35 +426,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
566
426
  <div class="login-dlg-loader"></div>
567
427
  </div>
568
428
  <div class="login-dlg-elm">
569
- <p-inputgroup>
570
- <p-inputgroup-addon [style]="{background:'var(--p-inputtext-disabled-background)'}">
571
- <span class="p-inputgroup-addon">
572
- <i class="material-icons-round" style="color: var(--p-inputtext-disabled-color);">person</i>
573
- </span>
574
- </p-inputgroup-addon>
575
- <input disabled pInputText type="text" placeholder="Username" [value]="decodeToken?.email" />
576
- </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>
577
435
  </div>
578
436
 
579
437
  <div class="login-dlg-elm">
580
- <p-inputgroup>
581
- <p-inputgroup-addon>
582
- <span class="p-inputgroup-addon">
583
- <i class="material-icons-round">lock</i>
584
- </span>
585
- </p-inputgroup-addon>
586
- <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"
587
444
  autofocus />
588
- </p-inputgroup>
445
+ </div>
589
446
  </div>
590
447
  <div class="login-dlg-elm">
591
- <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()"
592
449
  [disabled]="!password || loading"></button>
593
450
  </div>
594
451
 
595
- <div class="login-dlg-elm" style="display:flex;align-items: center;user-select: none;">
596
- <span>No, I want to login with another user.</span>
597
- <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>
598
456
  </div>
599
457
  </ng-container>
600
458
 
@@ -614,8 +472,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
614
472
  </div>
615
473
  </ng-container>
616
474
  </div>
617
- </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"] }]
618
- }], 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 }] });
619
477
 
620
478
  class LocalizeLogindlgService {
621
479
  injector;
@@ -623,12 +481,9 @@ class LocalizeLogindlgService {
623
481
  this.injector = injector;
624
482
  }
625
483
  async openLoginDialog(loginConfig, config) {
626
- config ??= {
627
- header: 'Login',
628
- height: '650px',
629
- style: { 'max-width': '400px', width: '100%', 'height': '650px' },
630
- };
631
- config.data = { ...config.data || {}, ...{ loginConfig } };
484
+ config = this.intercepDialogConfig(config);
485
+ this.initConfig(loginConfig);
486
+ config.data = { ...(config.data || {}), ...{ loginConfig } };
632
487
  const dialogService = this.injector.get(DialogService);
633
488
  const dialog = dialogService.open(LocalizeLogindlgComponent, config);
634
489
  await new Promise((resolve) => dialog.onClose.subscribe(res => {
@@ -637,6 +492,37 @@ class LocalizeLogindlgService {
637
492
  }
638
493
  }));
639
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
+ }
640
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 });
641
527
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgService, providedIn: 'root' });
642
528
  }
@@ -654,19 +540,13 @@ class LocalizeLogindlgModule {
654
540
  InputTextModule,
655
541
  BrowserModule,
656
542
  FormsModule,
657
- ButtonModule,
658
- DynamicDialogModule,
659
- InputGroupModule,
660
- InputGroupAddonModule], exports: [LocalizeLogindlgComponent] });
543
+ ButtonModule], exports: [LocalizeLogindlgComponent] });
661
544
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgModule, providers: [LocalizeLogindlgService], imports: [CommonModule,
662
545
  ToastModule,
663
546
  InputTextModule,
664
547
  BrowserModule,
665
548
  FormsModule,
666
- ButtonModule,
667
- DynamicDialogModule,
668
- InputGroupModule,
669
- InputGroupAddonModule] });
549
+ ButtonModule] });
670
550
  }
671
551
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: LocalizeLogindlgModule, decorators: [{
672
552
  type: NgModule,
@@ -680,18 +560,558 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
680
560
  BrowserModule,
681
561
  FormsModule,
682
562
  ButtonModule,
683
- DynamicDialogModule,
684
- InputGroupModule,
685
- InputGroupAddonModule
686
563
  ],
687
564
  providers: [LocalizeLogindlgService],
688
565
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
689
566
  }]
690
567
  }] });
691
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
+
692
1112
  /**
693
1113
  * Generated bundle index. Do not edit.
694
1114
  */
695
1115
 
696
- 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 };
697
1117
  //# sourceMappingURL=sambath999-localize-token.mjs.map