@sambath999/localize-token 12.4.1 → 12.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/bundles/sambath999-localize-token.umd.js +283 -233
  2. package/bundles/sambath999-localize-token.umd.js.map +1 -1
  3. package/esm2015/localize-api-token/localize-api-token.module.js +21 -0
  4. package/esm2015/localize-api-token/localize-api-token.service.js +34 -0
  5. package/esm2015/localize-logindlg/localize-logindlg.component.js +1 -1
  6. package/esm2015/localize-logindlg/localize-logindlg.module.js +1 -1
  7. package/esm2015/localize-logindlg/localize-logindlg.service.js +1 -1
  8. package/esm2015/localize-token/helpers/interfaces.js +1 -1
  9. package/esm2015/localize-token/helpers/localize.api.assets.js +1 -1
  10. package/esm2015/localize-token/helpers/loccalize.api.helper.js +1 -1
  11. package/esm2015/localize-token/localize.api.service.js +2 -2
  12. package/esm2015/localize-token/localize.token.js +1 -1
  13. package/esm2015/localize-token/localize.token.module.js +1 -1
  14. package/esm2015/localize-token/localize.token.service.js +1 -1
  15. package/esm2015/localize-token/localize.token.storage.js +1 -1
  16. package/esm2015/public-api.js +17 -3
  17. package/esm2015/sambath999-localize-token.js +1 -1
  18. package/fesm2015/sambath999-localize-token.js +944 -900
  19. package/fesm2015/sambath999-localize-token.js.map +1 -1
  20. package/localize-api-token/localize-api-token.module.d.ts +2 -0
  21. package/localize-api-token/localize-api-token.service.d.ts +12 -0
  22. package/package.json +1 -1
  23. package/public-api.d.ts +13 -2
  24. package/sambath999-localize-token.metadata.json +1 -1
  25. package/esm2015/localize-logindlg/public-api.js +0 -4
  26. package/esm2015/localize-token/public-api.js +0 -9
  27. package/localize-logindlg/public-api.d.ts +0 -3
  28. package/localize-token/public-api.d.ts +0 -8
@@ -1,12 +1,12 @@
1
- import * as i0 from '@angular/core';
2
- import { Injectable, NgModule, Component, ViewEncapsulation, ChangeDetectorRef, Injector, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
3
1
  import { __awaiter } from 'tslib';
4
- import { BehaviorSubject, takeUntil, catchError, throwError, Subject } from 'rxjs';
5
- import * as jwt_decode from 'jwt-decode';
6
2
  import * as i1 from '@angular/common/http';
7
- import { HttpErrorResponse, HttpHeaders, HttpClient } from '@angular/common/http';
3
+ import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
4
+ import * as i0 from '@angular/core';
5
+ import { Injectable, Component, ViewEncapsulation, ChangeDetectorRef, Injector, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
8
6
  import { MessageService } from 'primeng/api';
9
7
  import { DynamicDialogRef, DynamicDialogConfig, DialogService } from 'primeng/dynamicdialog';
8
+ import { BehaviorSubject, takeUntil, catchError, throwError, Subject } from 'rxjs';
9
+ import * as jwt_decode from 'jwt-decode';
10
10
  import { DomSanitizer, BrowserModule } from '@angular/platform-browser';
11
11
  import { CommonModule } from '@angular/common';
12
12
  import { ToastModule } from 'primeng/toast';
@@ -14,26 +14,6 @@ import { InputTextModule } from 'primeng/inputtext';
14
14
  import { ButtonModule } from 'primeng/button';
15
15
  import { FormsModule } from '@angular/forms';
16
16
 
17
- const LOCALIZE_API_ASSETS = {
18
- network: {
19
- noConnection: `<?xml version="1.0" encoding="UTF-8"?>
20
- <svg id="lze-no-connection" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 77.29 70.98">
21
- <defs>
22
- <style> .cls-1 { fill: #fff; } .cls-2, .cls-3 { fill: #e30613; } .cls-3 { stroke: #e30613; stroke-miterlimit: 10; stroke-width: .25px; } </style>
23
- </defs>
24
- <g id="Layer_3" data-name="Layer 3">
25
- <g>
26
- <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"/>
27
- <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"/>
28
- <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"/>
29
- </g>
30
- <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"/>
31
- <circle class="cls-3" cx="38.64" cy="64.79" r="6.07"/>
32
- </g>
33
- </svg>`
34
- }
35
- };
36
-
37
17
  /**
38
18
  * Assembly of @package ng2-cookies @see https://www.npmjs.com/package/ng2-cookies
39
19
  *
@@ -271,980 +251,1044 @@ LocalizeTokenService.decorators = [
271
251
  { type: Injectable, args: [{ providedIn: 'root' },] }
272
252
  ];
273
253
 
274
- /**
275
- * Http method options
276
- */
277
- var EMethod;
278
- (function (EMethod) {
279
- EMethod["POST"] = "post";
280
- EMethod["GET"] = "get";
281
- EMethod["PUT"] = "put";
282
- EMethod["DELETE"] = "delete";
283
- EMethod["PATCH"] = "patch";
284
- })(EMethod || (EMethod = {}));
285
-
286
- class LocalizeApiHelper {
287
- constructor() {
288
- this.defaultRetryOptions = {
289
- connectionError: {
290
- message: 'Connection error occurred. Please wait',
291
- blockScreen: true,
292
- blockScreenZIndex: 10000
293
- }
294
- };
254
+ class LocalizeLogindlgComponent {
255
+ constructor(messageService, cdt, dlgRef, dlgConfig, tokenService, httpClient, sanitizer) {
256
+ this.messageService = messageService;
257
+ this.cdt = cdt;
258
+ this.dlgRef = dlgRef;
259
+ this.dlgConfig = dlgConfig;
260
+ this.tokenService = tokenService;
261
+ this.httpClient = httpClient;
262
+ this.sanitizer = sanitizer;
263
+ this.messageKey = "$login-dlg";
264
+ this.loading = false;
265
+ this.success = false;
266
+ this.clickLogout = () => { var _a; return (_a = this.logout) === null || _a === void 0 ? void 0 : _a.call(this); };
267
+ this.decodeToken = this.tokenService.decodeRefreshToken;
268
+ this.loginConfig = this.dlgConfig.data.loginConfig;
269
+ this.properties = this.loginConfig.properties;
295
270
  }
296
- performRetry(options) {
297
- return __awaiter(this, void 0, void 0, function* () {
298
- let attempts = 0;
299
- let lastError;
300
- let consoleCount = 0;
301
- // Merge default retry options with provided options
302
- options = Object.assign(Object.assign({}, this.defaultRetryOptions), options);
303
- let styleElement;
304
- while (attempts < options.maxRetries()) {
305
- try {
306
- const result = yield options.callback();
307
- this.removeBlocker(styleElement);
308
- return result;
309
- }
310
- catch (error) {
311
- lastError = error;
312
- if (consoleCount >= 7) {
313
- console.clear();
314
- consoleCount = 0;
315
- }
316
- if (options.retryUnless && !options.retryUnless(error))
317
- throw error; // If the error should not be retried, rethrow it
318
- // Handle connection error
319
- styleElement = yield this.onConnectionError(options, error);
320
- if (options.onError)
321
- yield this.invokeHook(options.onError.bind(this, error));
322
- if (attempts >= options.maxRetries() - 1)
323
- throw error;
324
- attempts++;
325
- consoleCount++;
326
- console.warn(`Attempt ${attempts} failed. Retrying...`, error);
327
- yield waitFor(options.delay);
328
- }
329
- }
330
- console.warn(`Failed after ${options.maxRetries} attempts`);
331
- throw lastError;
332
- });
271
+ get config() { return this.tokenService.config; }
272
+ ngOnInit() {
273
+ this.dlgConfig.closable = false;
274
+ this.logout = this.loginConfig.logoutFunc;
275
+ this.loginUrl = this.loginConfig.loginUrl;
276
+ if (!this.decodeToken) {
277
+ this.showMessage("error", "Token is invalid");
278
+ setTimeout(() => { var _a; return (_a = this.logout) === null || _a === void 0 ? void 0 : _a.call(this); }, 2000);
279
+ }
333
280
  }
334
- performRequestWithRetry(options, config, performRequest) {
335
- var _a, _b, _c, _d;
281
+ ngAfterViewInit() {
282
+ this.cdt.detectChanges();
283
+ }
284
+ clickLogin() {
285
+ var _a, _b, _c;
336
286
  return __awaiter(this, void 0, void 0, function* () {
337
- const retryUnless = ((_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.retryFunction)
338
- || this.isConnectionError;
339
- return yield this.performRetry({
340
- connectionError: (_b = config.retryOptions) === null || _b === void 0 ? void 0 : _b.onConnectionError,
341
- maxRetries: () => { var _a, _b; return (_b = (_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.maxRetries) !== null && _b !== void 0 ? _b : 1000; },
342
- delay: (_d = (_c = config.retryOptions) === null || _c === void 0 ? void 0 : _c.delay) !== null && _d !== void 0 ? _d : 500,
343
- callback: () => performRequest(options),
344
- retryUnless: retryUnless,
345
- });
287
+ if (!this.isValidPassword) {
288
+ return this.showMessage("error", "Password is required and must be at least 6 characters");
289
+ }
290
+ this.loading = true;
291
+ const loginRes = yield this.login();
292
+ if (!(loginRes === null || loginRes === void 0 ? void 0 : loginRes.status)) {
293
+ return this.showMessage("error", (_a = loginRes.message) !== null && _a !== void 0 ? _a : "An error occurred");
294
+ }
295
+ this.tokenService.accessToken = loginRes.tokens.accessToken;
296
+ const cookieOptions = { expires: (_b = this.loginConfig.expire) !== null && _b !== void 0 ? _b : 365 };
297
+ LocalizeToken.storage.set(((_c = this.config.refreshToken) === null || _c === void 0 ? void 0 : _c.name) || '', loginRes.tokens.refreshToken, cookieOptions);
298
+ this.success = true;
299
+ setTimeout(() => {
300
+ this.dlgConfig.dismissableMask = true;
301
+ this.dlgConfig.modal = false;
302
+ this.dlgRef.close(true);
303
+ }, 2000);
346
304
  });
347
305
  }
348
- buildUrl(baseUrl, path) {
349
- const normalizedUrl = `${baseUrl.trim().replace(/\/?$/, '/')}${path.trim().replace(/^\//, '')}`;
350
- return normalizedUrl.endsWith('/')
351
- ? normalizedUrl.slice(0, -1)
352
- : normalizedUrl;
353
- }
354
- normalizeError(error) {
306
+ login() {
355
307
  var _a, _b, _c;
356
- return {
357
- code: ((_a = error.error) === null || _a === void 0 ? void 0 : _a.code) || `HTTP_${error.status}`,
358
- message: ((_b = error.error) === null || _b === void 0 ? void 0 : _b.message) || error.message,
359
- details: (_c = error.error) === null || _c === void 0 ? void 0 : _c.details,
360
- status: error.status
361
- };
362
- }
363
- invokeHook(callback) {
364
308
  return __awaiter(this, void 0, void 0, function* () {
365
- if (!callback)
366
- return;
367
- const result = callback();
368
- if (result instanceof Promise) {
369
- yield result;
309
+ if (!((_a = this.loginUrl) === null || _a === void 0 ? void 0 : _a.trim().length)) {
310
+ this.showMessage("error", "Login url is required");
311
+ throw new Error("Login url is required");
312
+ }
313
+ try {
314
+ if (this.loginConfig.loginFunction) {
315
+ console.log("Using custom login function");
316
+ return yield this.loginConfig.loginFunction((_c = (_b = this.decodeToken) === null || _b === void 0 ? void 0 : _b.email) !== null && _c !== void 0 ? _c : '', this.password.trim(), this.getHeaders());
317
+ }
318
+ return yield new Promise((resolve, reject) => this.httpClient.post(this.loginUrl, { password: this.password.trim() }, { headers: this.getHeaders() }).subscribe({ next: resolve, error: reject }));
319
+ }
320
+ catch (e) {
321
+ this.showMessage("error", e.message);
322
+ return null;
370
323
  }
371
324
  });
372
325
  }
373
- createRequest(instance, method, url, body, options) {
374
- const request$ = instance.client.request(method, url, Object.assign(Object.assign({}, options), { body, observe: 'response' })).pipe(takeUntil(instance.destroy$()), catchError((error) => {
375
- // Convert to a non-observable error to handle in the promise
376
- return throwError(() => this.normalizeError(error));
377
- }));
378
- return request$;
326
+ getHeaders() {
327
+ var _a, _b;
328
+ return {
329
+ [LocalizeToken.httpHeaders.X_REFRESH_TOKEN]: (_a = this.tokenService.refreshToken) !== null && _a !== void 0 ? _a : "",
330
+ [LocalizeToken.httpHeaders.X_TENANT]: (_b = this.tokenService.tenantToken) !== null && _b !== void 0 ? _b : "",
331
+ };
379
332
  }
380
- defaultRetryFunction(error) {
381
- // Don't retry for other errors (like 400, 401, 403, etc.)
382
- if (!this.isConnectionError(error))
383
- throw error;
384
- return true;
333
+ get isValidPassword() {
334
+ this.loading = false;
335
+ return this.properties.passwordValidator
336
+ ? this.properties.passwordValidator(this.password)
337
+ : this.password && this.password.trim().length >= 6 && this.password.trim().length <= 50;
385
338
  }
386
- isConnectionError(error) {
387
- const isNetworkError = error.status === 0;
388
- const isServerError = error.status >= 1000 && error.status < 600;
389
- return isNetworkError || isServerError;
339
+ showMessage(severity, summary) {
340
+ this.messageService.add({ key: this.messageKey, severity, summary });
341
+ this.loading = false;
390
342
  }
391
- onConnectionError(options, error) {
343
+ get sanitizedTitle() {
392
344
  var _a;
393
- return __awaiter(this, void 0, void 0, function* () {
394
- if (!options.connectionError)
395
- return;
396
- let styleElement;
397
- if (this.isConnectionError(error)) {
398
- styleElement = this.screenBlocker(options, error, true);
399
- yield this.invokeHook((_a = options.connectionError.callback) === null || _a === void 0 ? void 0 : _a.bind(this, error));
400
- return styleElement;
401
- }
402
- else {
403
- this.screenBlocker(options, error, false);
404
- styleElement === null || styleElement === void 0 ? void 0 : styleElement.remove();
405
- }
406
- });
345
+ return this.sanitizer.bypassSecurityTrustHtml((_a = this.properties.title) !== null && _a !== void 0 ? _a : '');
407
346
  }
408
- screenBlocker(optons, error, add = true) {
409
- var _a, _b, _c, _d;
410
- if (!((_a = optons.connectionError) === null || _a === void 0 ? void 0 : _a.blockScreen))
411
- return;
412
- if (error instanceof HttpErrorResponse)
413
- error = this.normalizeError(error);
414
- const message = ((_b = optons.connectionError) === null || _b === void 0 ? void 0 : _b.message)
415
- || 'Connection error occurred. Please wait';
416
- const errorMessage = (error === null || error === void 0 ? void 0 : error.message) || 'An error occurred';
417
- const suggestinMessage = ((_c = optons.connectionError) === null || _c === void 0 ? void 0 : _c.suggestionMessage)
418
- || 'Please check your internet connection or the server status.';
419
- const zIndex = ((_d = optons.connectionError) === null || _d === void 0 ? void 0 : _d.blockScreenZIndex) || 10000;
420
- const body = document.body;
421
- const blcokerHtml = `
422
- <div class="lze-blocker">
423
- ${LOCALIZE_API_ASSETS.network.noConnection}
424
- <div class="lze-blocker__message">
425
- ${message}
426
- <span class="lze-blocker__dotting">
427
- <span class="lze-blocker__dot"></span>
428
- <span class="lze-blocker__dot"></span>
429
- <span class="lze-blocker__dot"></span>
430
- </span>
431
- </div>
432
- <div class="lze-blocker__error">${errorMessage}</div>
433
- <div class="lze-blocker__error_suggestion">${suggestinMessage}</div>
434
- </div>
435
- `;
436
- const style = `
437
- div.lze-blocker {
438
- position: fixed;
439
- top: 0;
440
- left: 0;
441
- width: 100%;
442
- height: 100%;
443
- background: rgba(0, 0, 0, 0.85) !important;
444
- z-index: ${zIndex};
445
- display: flex;
446
- align-items: center;
447
- justify-content: center;
448
- flex-direction: column;
449
- color: #fff !important;
450
- font-family: Arial, sans-serif;
451
- text-align: center;
452
- padding: 20px;
453
- box-sizing: border-box;
454
- overflow: hidden;
455
- user-select: none;
456
- }
457
-
458
- svg#lze-no-connection {
459
- width: 75px;
460
- height: 75px;
461
- margin-bottom: 20px;
462
- }
463
-
464
- div.lze-blocker__message {
465
- color: #fff !important;
466
- font-size: 18px !important;
467
- margin-bottom: 10px;
468
- }
469
-
470
- .lze-blocker__dotting {
471
- display: inline-block;
472
- vertical-align: middle;
473
- }
474
- span.lze-blocker__dot {
475
- display: inline-block;
476
- width: 7px;
477
- height: 7px;
478
- background-color: #ffffff !important;
479
- border-radius: 50%;
480
- margin-left: 3px;
481
- opacity: 0.3;
482
- animation: dotting 1s infinite;
483
- }
484
- .lze-blocker__dot:nth-child(1) {
485
- animation-delay: 0s;
486
- opacity: 1;
487
- }
488
- .lze-blocker__dot:nth-child(2) {
489
- animation-delay: 0.2s;
490
- }
491
- .lze-blocker__dot:nth-child(3) {
492
- animation-delay: 0.4s;
493
- }
494
-
495
- @keyframes dotting {
496
- 0%, 80%, 100% { opacity: 0.3; }
497
- 40% { opacity: 1; }
498
- }
499
-
500
- div.lze-blocker__error {
501
- color: #f00;
502
- font-size: 14px !important;
503
- margin-bottom: 10px;
504
- text-shadow: 0 0 1px #ff5f5f !important;
505
- }
347
+ }
348
+ LocalizeLogindlgComponent.decorators = [
349
+ { type: Component, args: [{
350
+ template: `<p-toast key="$login-dlg" position="top-center"></p-toast>
351
+ <div id="login-dlg-wrap">
352
+ <div id="login-dlg-header">
353
+ <div id="login-logo" class="p-mb-2" style="background: url('{{properties.logoImage}}') no-repeat"></div>
354
+ <h3 *ngIf="!success" [innerHTML]="sanitizedTitle"></h3>
355
+ <h3 *ngIf="success" style="color:green !important;">{{properties.loginSuccessMessage}}</h3>
356
+ </div>
357
+ <div id="login-dlg-content">
358
+ <ng-container *ngIf="!success">
359
+ <div *ngIf="loading" class="loader-wrap">
360
+ <div class="login-dlg-loader"></div>
361
+ </div>
362
+ <div class="login-dlg-elm">
363
+ <div class="p-inputgroup">
364
+ <span class="p-inputgroup-addon">
365
+ <i class="material-icons-round">person</i>
366
+ </span>
367
+ <input disabled pInputText type="text" placeholder="{{properties.username?.placeHolder}}" [value]="decodeToken?.email" />
368
+ </div>
369
+ </div>
370
+
371
+ <div class="login-dlg-elm">
372
+ <div class="p-inputgroup">
373
+ <span class="p-inputgroup-addon">
374
+ <i class="material-icons-round">lock</i>
375
+ </span>
376
+ <input [disabled]="loading" (keydown.enter)="clickLogin()" pInputText type="password"
377
+ placeholder="{{properties.password?.placeHolder}}" [(ngModel)]="password"
378
+ autofocus />
379
+ </div>
380
+ </div>
381
+ <div class="login-dlg-elm">
382
+ <button style="width: 100%;" pButton type="button" label="{{properties.loginButton?.placeHolder}}" (click)="clickLogin()"
383
+ [disabled]="!password || loading"></button>
384
+ </div>
385
+
386
+ <div class="login-dlg-elm login-dlg-suggest" style="display:flex;align-items: center;user-select: none;">
387
+ <span>{{properties.logoutButton?.message}}</span>
388
+ <button class="p-button-text" pButton type="button" label="{{properties.logoutButton?.placeHolder}}"
389
+ (click)="clickLogout()"></button>
390
+ </div>
391
+ </ng-container>
392
+
393
+ <ng-container *ngIf="success">
394
+ <div style="margin-top:35px;"></div>
395
+ <div class="check-animation-wrap">
396
+ <div class="check-main-container">
397
+ <div class="check-container">
398
+ <div class="check-background">
399
+ <svg viewBox="0 0 65 51" fill="none" xmlns="http://www.w3.org/2000/svg">
400
+ <path d="M7 25L27.3077 44L58.5 7" stroke="white" stroke-width="13" stroke-linecap="round"
401
+ stroke-linejoin="round"></path>
402
+ </svg>
403
+ </div>
404
+ </div>
405
+ </div>
406
+ </div>
407
+ </ng-container>
408
+ </div>
409
+ </div>`,
410
+ selector: "app-localize-logindlg",
411
+ providers: [MessageService],
412
+ encapsulation: ViewEncapsulation.None,
413
+ styles: [`
414
+ #login-dlg-wrap {
415
+ width: 100%;
416
+ max-width: 400px;
417
+ margin: 0 auto;
418
+ padding: 30px;
419
+ height: 100%;
420
+ }
421
+
422
+ .login-dlg-elm {
423
+ margin-top: 1rem;
424
+ }
506
425
 
507
- div.lze-blocker__error_suggestion {
508
- color: #ccc !important;
509
- font-size: 14px !important;
510
- margin-top: 10px;
511
- }
512
-
513
- @keyframes spin {
514
- 0% { transform: rotate(0deg); }
515
- 100% { transform: rotate(360deg); }
516
- }
517
- `;
518
- const styleElement = document.createElement('style');
519
- if (add) {
520
- if (!document.querySelector('.lze-blocker')) {
521
- styleElement.innerHTML = style;
522
- document.head.appendChild(styleElement);
523
- body.insertAdjacentHTML('beforeend', blcokerHtml);
524
- }
525
- }
526
- else {
527
- this.removeBlocker(styleElement);
528
- }
529
- return styleElement;
426
+ .login-dlg-elm.login-dlg-suggest {
427
+ display: flex ;
428
+ align-items: center;
429
+ user-select: none;
430
+ border-bottom: solid 1px #ddd;
431
+ border-radius: 5px;
432
+ padding: 5px 10px;
433
+ background: #f9f9f9;
434
+ box-shadow: 1px 5px 10px -12px #000;
435
+ }
436
+
437
+ #login-dlg-header {
438
+ display: flex;
439
+ flex-direction: column;
440
+ align-items: center;
441
+ justify-content: center;
442
+ }
443
+
444
+ #login-dlg-header h3 {
445
+ font-weight: bold;
446
+ font-size: 0.9rem;
447
+ color: orange;
448
+ text-align: center;
449
+ }
450
+
451
+ #login-logo {
452
+ height: 55px;
453
+ width: 55px;
454
+ /* background: url("/assets/images/logo-300px.png") no-repeat; */
455
+ background-size: contain !important;
456
+ }
457
+
458
+ #login-dlg-content .p-inputgroup {
459
+ height: 45px;
460
+ }
461
+
462
+ #login-dlg-content .p-inputgroup .p-inputgroup-addon {
463
+ height: 45px;
464
+ border-radius: 15px 0 0 15px;
465
+ width: 50px;
466
+ }
467
+ #login-dlg-content *{
468
+ font-size: .9rem;
469
+ /* font-family: 'Lexend', 'Roboto', sans-serif, 'material-icons-round'; */
470
+ }
471
+
472
+ #login-dlg-content .p-inputgroup .p-inputgroup-addon * {
473
+ font-size: 1rem;
474
+ }
475
+
476
+ #login-dlg-content .p-inputgroup input {
477
+ height: 45px;
478
+ border-radius: 0 15px 15px 0;
479
+ }
480
+
481
+ #login-dlg-content button {
482
+ height: 45px;
483
+ border-radius: 15px;
484
+ }
485
+
486
+ /*check animation block*/
487
+
488
+ .check-animation-wrap {
489
+ top: 0;
490
+ left: 0;
491
+ position: absolute;
492
+ display: flex;
493
+ flex-direction: column;
494
+ align-items: center;
495
+ justify-content: center;
496
+ width: 100%;
497
+ height: calc(100% - 200px);
498
+ min-height: 400px;
499
+ }
500
+
501
+ .check-main-container {
502
+ width: 100%;
503
+ height: 100vh;
504
+ display: flex;
505
+ flex-flow: column;
506
+ justify-content: center;
507
+ align-items: center;
508
+ }
509
+
510
+ .check-container {
511
+ width: 6.25rem;
512
+ height: 7.5rem;
513
+ display: flex;
514
+ flex-flow: column;
515
+ align-items: center;
516
+ justify-content: space-between;
517
+ }
518
+
519
+ .check-container .check-background {
520
+ width: 100%;
521
+ height: calc(100% - 1.25rem);
522
+ background: linear-gradient(to bottom right, #5de593, #41d67c);
523
+ box-shadow: 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset;
524
+ transform: scale(0.84);
525
+ border-radius: 50%;
526
+ animation: animateContainer 0.75s ease-out forwards 0.75s;
527
+ display: flex;
528
+ align-items: center;
529
+ justify-content: center;
530
+ opacity: 0;
531
+ }
532
+
533
+ .check-container .check-background svg {
534
+ width: 65%;
535
+ transform: translateY(0.25rem);
536
+ stroke-dasharray: 80;
537
+ stroke-dashoffset: 80;
538
+ animation: animateCheck 0.35s forwards 1.25s ease-out;
539
+ min-width: auto !important;
540
+ }
541
+
542
+ .check-container .check-shadow {
543
+ bottom: calc(-15% - 5px);
544
+ left: 0;
545
+ border-radius: 50%;
546
+ background: radial-gradient(closest-side, rgba(73, 218, 131, 1), transparent);
547
+ animation: animateShadow 0.75s ease-out forwards 0.75s;
548
+ }
549
+
550
+ @keyframes animateContainer {
551
+ 0% {
552
+ opacity: 0;
553
+ transform: scale(0);
554
+ box-shadow: 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset;
530
555
  }
531
- removeBlocker(styleElement) {
532
- const blocker = document.querySelector('.lze-blocker');
533
- blocker === null || blocker === void 0 ? void 0 : blocker.remove();
534
- styleElement === null || styleElement === void 0 ? void 0 : styleElement.remove();
556
+
557
+ 25% {
558
+ opacity: 1;
559
+ transform: scale(0.9);
560
+ box-shadow: 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset;
535
561
  }
536
- }
537
- const ApiHelper = new LocalizeApiHelper();
538
-
539
- const SCHEMES = LocalizeToken.httpHeaders;
540
- class LocalizeApiService {
541
- constructor(httpClient, localizeTokenService) {
542
- this.httpClient = httpClient;
543
- this.localizeTokenService = localizeTokenService;
544
- this.destroy$ = new Subject();
545
- this.configSubject = new BehaviorSubject({});
546
- this.isRequestingSubject = new BehaviorSubject(false);
547
- this.isResolvingStartupSubject = new BehaviorSubject(false);
548
- this.defaultConfig = {
549
- waitEachRequest: { milliseconds: 0 },
550
- enableRequestCancellation: true,
551
- retryOptions: {
552
- maxRetries: 1000,
553
- delay: 1000,
554
- retryFunction: ApiHelper.defaultRetryFunction.bind(this),
555
- },
556
- };
557
- this.apiOptions = {
558
- method: EMethod.GET,
559
- requestBody: null,
560
- };
561
- /**
562
- * A higher-order function that returns a curried function for making API requests.
563
- *
564
- * @param baseUrl - The base URL of the API.
565
- * @returns A curried function that can be used to make API requests.
566
- */
567
- this.func = (baseUrl) => (path, method = EMethod.GET, reqBody = null, reqHeaders) => this.request(baseUrl, path, method, reqBody, reqHeaders);
562
+
563
+ 43.75% {
564
+ transform: scale(1.15);
565
+ box-shadow: 0px 0px 0px 43.334px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset;
568
566
  }
569
- get isResolvingStartup() { return this.isResolvingStartupSubject.value; }
570
- get needTenant() { return this.localizeTokenService.config.tenantToken !== undefined; }
571
- get isRequesting() { return this.isRequestingSubject.value; }
572
- get isRevokingToken() { return this.localizeTokenService.isRevokingToken; }
573
- set isRevokingToken(value) { this.localizeTokenService.isRevokingToken = value; }
574
- get accessToken() { return this.localizeTokenService.accessToken; }
575
- set accessToken(value) { this.localizeTokenService.accessToken = value; }
576
- get refreshToken() { return this.localizeTokenService.refreshToken; }
577
- get tenantToken() { return this.localizeTokenService.tenantToken; }
578
- get config() {
579
- this.validateConfig();
580
- return this.configSubject.value;
567
+
568
+ 62.5% {
569
+ transform: scale(1);
570
+ box-shadow: 0px 0px 0px 0px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 21.667px rgba(255, 255, 255, 0.25) inset;
581
571
  }
582
- /**
583
- * Initialize the API service.
584
- * @param apiConfigs - The API configurations.
585
- */
586
- init(apiConfigs) {
587
- console.log('LocalizeApiService is initialized.');
588
- this.configSubject.next(Object.assign(Object.assign({}, this.defaultConfig), apiConfigs));
572
+
573
+ 81.25% {
574
+ box-shadow: 0px 0px 0px 0px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 0px rgba(255, 255, 255, 0.25) inset;
589
575
  }
590
- cancelPendingRequests() {
591
- this.config.enableRequestCancellation
592
- && this.destroy$.next();
576
+
577
+ 100% {
578
+ opacity: 1;
579
+ box-shadow: 0px 0px 0px 0px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 0px rgba(255, 255, 255, 0.25) inset;
593
580
  }
594
- ngOnDestroy() {
595
- this.destroy$.next();
596
- this.destroy$.complete();
597
- // this.isResolvingStartupSubject.complete();
598
- // this.isRequestingSubject.complete();
599
- // this.configSubject.complete();
581
+ }
582
+
583
+ @keyframes animateCheck {
584
+ from {
585
+ stroke-dashoffset: 80;
600
586
  }
601
- request(baseUrl, path, method = EMethod.GET, reqBody = null, reqHeaders) {
602
- return __awaiter(this, void 0, void 0, function* () {
603
- yield waitUntil(() => !this.isResolvingStartup, 500);
604
- yield ApiHelper.invokeHook(this.config.onPrepareRequest);
605
- const apiOptions = this.buildApiOptions(baseUrl, path, method, reqBody, reqHeaders);
606
- try {
607
- yield this.toWaitForPreviousRequest();
608
- return yield ApiHelper.performRequestWithRetry(apiOptions, this.config, this.performRequest.bind(this));
609
- }
610
- catch (error) {
611
- return yield this.handleOnRequestError(error, apiOptions);
612
- }
613
- });
587
+
588
+ to {
589
+ stroke-dashoffset: 0;
614
590
  }
615
- handleOnRequestError(error, options) {
616
- return __awaiter(this, void 0, void 0, function* () {
617
- if (error.status !== 401)
618
- throw error;
619
- yield waitUntil(() => !this.isResolvingStartup, 500);
620
- return yield ApiHelper.performRetry({
621
- maxRetries: () => 1000,
622
- delay: 500,
623
- retryUnless: (error) => error.status === 401 || ApiHelper.isConnectionError(error),
624
- callback: () => __awaiter(this, void 0, void 0, function* () {
625
- // Only handle 401 Unauthorized errors
626
- yield this.revokeToken();
627
- // Retry the request with the new access token
628
- return yield this.performRequest(options);
629
- })
630
- });
631
- });
591
+ }
592
+
593
+ @keyframes animateShadow {
594
+ 0% {
595
+ opacity: 0;
596
+ width: 100%;
597
+ height: 15%;
632
598
  }
633
- performRequest(options) {
634
- return __awaiter(this, void 0, void 0, function* () {
635
- // Build the request options
636
- const buildOptions = { headers: this.buildHeaderOptions(options) };
637
- // Create the request observable
638
- const request$ = ApiHelper.createRequest({
639
- client: this.httpClient,
640
- destroy$: () => this.destroy$
641
- }, options.method, options.requestUrl, options.requestBody, buildOptions);
642
- // Set the isRequesting state to true before making the request
643
- this.isRequestingSubject.next(true);
644
- const response = yield new Promise((resolve, reject) => request$.subscribe({ next: (res) => resolve(res.body), error: reject }));
645
- // Reset the isRequesting state after the request completes
646
- this.isRequestingSubject.next(false);
647
- return response;
648
- });
599
+
600
+ 25% {
601
+ opacity: 0.25;
649
602
  }
650
- revokeToken() {
651
- var _a;
652
- return __awaiter(this, void 0, void 0, function* () {
653
- try {
654
- if (yield this.interceptRevokeToken())
655
- return;
656
- this.isRevokingToken = true;
657
- const apiOptions = Object.assign(Object.assign({}, this.buildApiOptions(((_a = this.localizeTokenService.config.refreshToken) === null || _a === void 0 ? void 0 : _a.requestUrl) || '')), { refreshToken: true });
658
- // const revokeToken = await this.performRequest(apiOptions);
659
- const revokeToken = yield ApiHelper.performRequestWithRetry(apiOptions, this.config, this.performRequest.bind(this));
660
- yield this.handleOnTokenRevoked(revokeToken);
661
- }
662
- catch (error) {
663
- // Handle the error, log it
664
- yield ApiHelper.invokeHook(this.config.onAutoLogout);
665
- }
666
- finally {
667
- // Reset the revoking token state
668
- this.isRevokingToken = false;
669
- }
670
- });
603
+
604
+ 43.75% {
605
+ width: 40%;
606
+ height: 7%;
607
+ opacity: 0.35;
671
608
  }
672
- /** default http request options */
673
- buildHeaderOptions(options) {
674
- const headers = Object.assign(Object.assign(Object.assign(Object.assign({}, (options.refreshToken && { [SCHEMES.X_REFRESH_TOKEN]: `${this.refreshToken}` })), (!options.isFormData && { [SCHEMES.CONTENT_TYPE]: 'application/json' })), { [SCHEMES.AUTHORIZATION]: `Bearer ${this.accessToken}` }), (this.needTenant && { [SCHEMES.X_TENANT]: `${this.tenantToken}` }));
675
- return new HttpHeaders(Object.assign(Object.assign({}, headers), options.headers));
609
+
610
+ 100% {
611
+ width: 85%;
612
+ height: 15%;
613
+ opacity: 0.25;
676
614
  }
677
- buildApiOptions(baseUrl, path = '', method = EMethod.GET, requestBody = null, headers) {
678
- const requestUrl = ApiHelper.buildUrl(baseUrl, path);
679
- const isFormData = requestBody && requestBody instanceof FormData;
680
- return Object.assign(Object.assign({}, this.apiOptions), { headers, method, requestUrl, requestBody, isFormData });
615
+ }
616
+ #login-dlg-wrap .loader-wrap {
617
+ display: flex;
618
+ justify-content: center;
619
+ align-items: center;
620
+ height:100%;
621
+ width:100%;
622
+ position: absolute;
623
+ top: 0;
624
+ left: 0;
625
+ z-index: 100;
626
+ background: #ffffff42;
627
+ backdrop-filter: blur(1px);
628
+ }
629
+
630
+ #login-dlg-wrap .login-dlg-loader {
631
+ border: 15px solid #e7e7e7;
632
+ border-top: 15px solid #52dba1;
633
+ border-radius: 50%;
634
+ width: 100px;
635
+ height: 100px;
636
+ animation: spinloader 2s linear infinite;
637
+ }
638
+
639
+ #login-dlg-wrap .loader-wrap::before {
640
+ content: "";
641
+ position: absolute;
642
+ width: 70px;
643
+ height: 70px;
644
+ transform: translate(-50%, -50%);
645
+ z-index: 1;
646
+ border: 15px solid #e7e7e700;
647
+ border-top: 15px solid #52dba1c9;
648
+ border-radius: 50%;
649
+ animation: spinloader .75s linear infinite;
650
+ }
651
+
652
+ @keyframes spinloader {
653
+ 0% { transform: rotate(0deg); }
654
+ 100% { transform: rotate(360deg); }
655
+ }
656
+ `]
657
+ },] }
658
+ ];
659
+ LocalizeLogindlgComponent.ctorParameters = () => [
660
+ { type: MessageService },
661
+ { type: ChangeDetectorRef },
662
+ { type: DynamicDialogRef },
663
+ { type: DynamicDialogConfig },
664
+ { type: LocalizeTokenService },
665
+ { type: HttpClient },
666
+ { type: DomSanitizer }
667
+ ];
668
+
669
+ class LocalizeLogindlgService {
670
+ constructor(injector) {
671
+ this.injector = injector;
681
672
  }
682
- toWaitForPreviousRequest() {
683
- var _a;
673
+ openLoginDialog(loginConfig, config) {
684
674
  return __awaiter(this, void 0, void 0, function* () {
685
- this.isRevokingToken &&
686
- (yield waitUntil(() => !this.isRevokingToken));
687
- // to wait for each request in 50ms, even if the request is not completed
688
- ((_a = this.config.waitEachRequest) === null || _a === void 0 ? void 0 : _a.milliseconds) &&
689
- (yield waitFor(this.config.waitEachRequest.milliseconds, this.isRequesting));
675
+ config = this.intercepDialogConfig(config);
676
+ this.initConfig(loginConfig);
677
+ config.data = Object.assign(Object.assign({}, (config.data || {})), { loginConfig });
678
+ const dialogService = this.injector.get(DialogService);
679
+ const dialog = dialogService.open(LocalizeLogindlgComponent, config);
680
+ yield new Promise((resolve) => dialog.onClose.subscribe(res => {
681
+ if (res) {
682
+ resolve();
683
+ }
684
+ }));
690
685
  });
691
686
  }
692
- handleOnTokenRevoked(response) {
693
- return __awaiter(this, void 0, void 0, function* () {
694
- if (response === null || response === void 0 ? void 0 : response.status) {
695
- // If the response is successful, update the access token
696
- this.accessToken = response.message;
697
- }
698
- else {
699
- // If the response indicates an error, invoke the onRevokeUnauthorized hook
700
- console.warn('Token revocation failed, refresh token is expired.', response.message);
701
- yield ApiHelper.invokeHook(this.config.onRevokeUnauthorized);
702
- }
687
+ intercepDialogConfig(config) {
688
+ config !== null && config !== void 0 ? config : (config = {
689
+ header: 'Login',
690
+ style: { 'max-width': '400px', width: '100%', 'height': '650px' },
691
+ modal: true,
692
+ closable: false,
693
+ showHeader: false,
694
+ });
695
+ config = Object.assign(Object.assign({}, config), {
696
+ contentStyle: { 'height': '100%', 'border-radius': '20px' }
703
697
  });
698
+ config.style = Object.assign(Object.assign({}, config.style), { 'border-radius': '20px' });
699
+ return config;
704
700
  }
705
- interceptRevokeToken() {
706
- return __awaiter(this, void 0, void 0, function* () {
707
- if (this.isRevokingToken) {
708
- console.warn('Token is already being revoked. Waiting for the current operation to complete...');
709
- yield waitUntil(() => !this.isRevokingToken);
710
- return true;
711
- }
712
- if (!this.refreshToken) {
713
- // await ApiHelper.invokeHook(this.apiConfigs.onAutoLogout);
714
- throw new Error('Refresh token is missing. Please login again.');
701
+ initConfig(loginConfig) {
702
+ var _a;
703
+ loginConfig !== null && loginConfig !== void 0 ? loginConfig : (loginConfig = {});
704
+ (_a = loginConfig.properties) !== null && _a !== void 0 ? _a : (loginConfig.properties = {
705
+ title: 'Your session is expired!<br/> Please login again to continue.',
706
+ loginSuccessMessage: 'You have successfully logged in.',
707
+ logoImage: '/assets/images/logo-300px.png',
708
+ username: { placeHolder: 'Username' },
709
+ password: { placeHolder: 'Password' },
710
+ loginButton: { placeHolder: 'Login' },
711
+ logoutButton: {
712
+ message: 'No, I want to login with another user.',
713
+ placeHolder: 'Logout'
715
714
  }
716
- return false;
717
715
  });
718
716
  }
719
- validateConfig() {
720
- var _a, _b, _c, _d;
721
- if (this.localizeTokenService.config.tenantToken
722
- && !((_b = (_a = this.localizeTokenService.config.tenantToken) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.trim().length)) {
723
- throw Error('Tenant token is required but tenantTokenName is not configured');
724
- }
725
- if (!((_d = (_c = this.localizeTokenService.config.refreshToken) === null || _c === void 0 ? void 0 : _c.requestUrl) === null || _d === void 0 ? void 0 : _d.trim().length)) {
726
- throw Error('Revoke token URL is not configured - token refresh will not work');
727
- }
728
- }
729
717
  }
730
- LocalizeApiService.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalizeApiService_Factory() { return new LocalizeApiService(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(LocalizeTokenService)); }, token: LocalizeApiService, providedIn: "root" });
731
- LocalizeApiService.decorators = [
718
+ LocalizeLogindlgService.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalizeLogindlgService_Factory() { return new LocalizeLogindlgService(i0.ɵɵinject(i0.INJECTOR)); }, token: LocalizeLogindlgService, providedIn: "root" });
719
+ LocalizeLogindlgService.decorators = [
732
720
  { type: Injectable, args: [{
733
721
  providedIn: 'root'
734
722
  },] }
735
723
  ];
736
- LocalizeApiService.ctorParameters = () => [
737
- { type: HttpClient },
738
- { type: LocalizeTokenService }
724
+ LocalizeLogindlgService.ctorParameters = () => [
725
+ { type: Injector }
739
726
  ];
740
727
 
741
- class LocalizeTokenModule {
728
+ class LocalizeLogindlgModule {
742
729
  }
743
- LocalizeTokenModule.decorators = [
730
+ LocalizeLogindlgModule.decorators = [
744
731
  { type: NgModule, args: [{
745
- providers: [
746
- LocalizeTokenService,
747
- LocalizeApiService
748
- ]
732
+ declarations: [LocalizeLogindlgComponent],
733
+ exports: [LocalizeLogindlgComponent],
734
+ imports: [
735
+ CommonModule,
736
+ ToastModule,
737
+ InputTextModule,
738
+ BrowserModule,
739
+ FormsModule,
740
+ ButtonModule,
741
+ ],
742
+ providers: [LocalizeLogindlgService],
743
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
749
744
  },] }
750
745
  ];
751
746
 
752
- class LocalizeLogindlgComponent {
753
- constructor(messageService, cdt, dlgRef, dlgConfig, tokenService, httpClient, sanitizer) {
754
- this.messageService = messageService;
755
- this.cdt = cdt;
756
- this.dlgRef = dlgRef;
757
- this.dlgConfig = dlgConfig;
758
- this.tokenService = tokenService;
759
- this.httpClient = httpClient;
760
- this.sanitizer = sanitizer;
761
- this.messageKey = "$login-dlg";
762
- this.loading = false;
763
- this.success = false;
764
- this.clickLogout = () => { var _a; return (_a = this.logout) === null || _a === void 0 ? void 0 : _a.call(this); };
765
- this.decodeToken = this.tokenService.decodeRefreshToken;
766
- this.loginConfig = this.dlgConfig.data.loginConfig;
767
- this.properties = this.loginConfig.properties;
768
- }
769
- get config() { return this.tokenService.config; }
770
- ngOnInit() {
771
- this.dlgConfig.closable = false;
772
- this.logout = this.loginConfig.logoutFunc;
773
- this.loginUrl = this.loginConfig.loginUrl;
774
- if (!this.decodeToken) {
775
- this.showMessage("error", "Token is invalid");
776
- setTimeout(() => { var _a; return (_a = this.logout) === null || _a === void 0 ? void 0 : _a.call(this); }, 2000);
777
- }
747
+ const LOCALIZE_API_ASSETS = {
748
+ network: {
749
+ noConnection: `<?xml version="1.0" encoding="UTF-8"?>
750
+ <svg id="lze-no-connection" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 77.29 70.98">
751
+ <defs>
752
+ <style> .cls-1 { fill: #fff; } .cls-2, .cls-3 { fill: #e30613; } .cls-3 { stroke: #e30613; stroke-miterlimit: 10; stroke-width: .25px; } </style>
753
+ </defs>
754
+ <g id="Layer_3" data-name="Layer 3">
755
+ <g>
756
+ <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"/>
757
+ <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"/>
758
+ <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"/>
759
+ </g>
760
+ <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"/>
761
+ <circle class="cls-3" cx="38.64" cy="64.79" r="6.07"/>
762
+ </g>
763
+ </svg>`
778
764
  }
779
- ngAfterViewInit() {
780
- this.cdt.detectChanges();
765
+ };
766
+
767
+ /**
768
+ * Http method options
769
+ */
770
+ var EMethod;
771
+ (function (EMethod) {
772
+ EMethod["POST"] = "post";
773
+ EMethod["GET"] = "get";
774
+ EMethod["PUT"] = "put";
775
+ EMethod["DELETE"] = "delete";
776
+ EMethod["PATCH"] = "patch";
777
+ })(EMethod || (EMethod = {}));
778
+
779
+ class LocalizeApiHelper {
780
+ constructor() {
781
+ this.defaultRetryOptions = {
782
+ connectionError: {
783
+ message: 'Connection error occurred. Please wait',
784
+ blockScreen: true,
785
+ blockScreenZIndex: 10000
786
+ }
787
+ };
781
788
  }
782
- clickLogin() {
783
- var _a, _b, _c;
789
+ performRetry(options) {
784
790
  return __awaiter(this, void 0, void 0, function* () {
785
- if (!this.isValidPassword) {
786
- return this.showMessage("error", "Password is required and must be at least 6 characters");
787
- }
788
- this.loading = true;
789
- const loginRes = yield this.login();
790
- if (!(loginRes === null || loginRes === void 0 ? void 0 : loginRes.status)) {
791
- return this.showMessage("error", (_a = loginRes.message) !== null && _a !== void 0 ? _a : "An error occurred");
791
+ let attempts = 0;
792
+ let lastError;
793
+ let consoleCount = 0;
794
+ // Merge default retry options with provided options
795
+ options = Object.assign(Object.assign({}, this.defaultRetryOptions), options);
796
+ let styleElement;
797
+ while (attempts < options.maxRetries()) {
798
+ try {
799
+ const result = yield options.callback();
800
+ this.removeBlocker(styleElement);
801
+ return result;
802
+ }
803
+ catch (error) {
804
+ lastError = error;
805
+ if (consoleCount >= 7) {
806
+ console.clear();
807
+ consoleCount = 0;
808
+ }
809
+ if (options.retryUnless && !options.retryUnless(error))
810
+ throw error; // If the error should not be retried, rethrow it
811
+ // Handle connection error
812
+ styleElement = yield this.onConnectionError(options, error);
813
+ if (options.onError)
814
+ yield this.invokeHook(options.onError.bind(this, error));
815
+ if (attempts >= options.maxRetries() - 1)
816
+ throw error;
817
+ attempts++;
818
+ consoleCount++;
819
+ console.warn(`Attempt ${attempts} failed. Retrying...`, error);
820
+ yield waitFor(options.delay);
821
+ }
792
822
  }
793
- this.tokenService.accessToken = loginRes.tokens.accessToken;
794
- const cookieOptions = { expires: (_b = this.loginConfig.expire) !== null && _b !== void 0 ? _b : 365 };
795
- LocalizeToken.storage.set(((_c = this.config.refreshToken) === null || _c === void 0 ? void 0 : _c.name) || '', loginRes.tokens.refreshToken, cookieOptions);
796
- this.success = true;
797
- setTimeout(() => {
798
- this.dlgConfig.dismissableMask = true;
799
- this.dlgConfig.modal = false;
800
- this.dlgRef.close(true);
801
- }, 2000);
823
+ console.warn(`Failed after ${options.maxRetries} attempts`);
824
+ throw lastError;
802
825
  });
803
826
  }
804
- login() {
805
- var _a, _b, _c;
827
+ performRequestWithRetry(options, config, performRequest) {
828
+ var _a, _b, _c, _d;
806
829
  return __awaiter(this, void 0, void 0, function* () {
807
- if (!((_a = this.loginUrl) === null || _a === void 0 ? void 0 : _a.trim().length)) {
808
- this.showMessage("error", "Login url is required");
809
- throw new Error("Login url is required");
810
- }
811
- try {
812
- if (this.loginConfig.loginFunction) {
813
- console.log("Using custom login function");
814
- return yield this.loginConfig.loginFunction((_c = (_b = this.decodeToken) === null || _b === void 0 ? void 0 : _b.email) !== null && _c !== void 0 ? _c : '', this.password.trim(), this.getHeaders());
815
- }
816
- return yield new Promise((resolve, reject) => this.httpClient.post(this.loginUrl, { password: this.password.trim() }, { headers: this.getHeaders() }).subscribe({ next: resolve, error: reject }));
817
- }
818
- catch (e) {
819
- this.showMessage("error", e.message);
820
- return null;
821
- }
830
+ const retryUnless = ((_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.retryFunction)
831
+ || this.isConnectionError;
832
+ return yield this.performRetry({
833
+ connectionError: (_b = config.retryOptions) === null || _b === void 0 ? void 0 : _b.onConnectionError,
834
+ maxRetries: () => { var _a, _b; return (_b = (_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.maxRetries) !== null && _b !== void 0 ? _b : 1000; },
835
+ delay: (_d = (_c = config.retryOptions) === null || _c === void 0 ? void 0 : _c.delay) !== null && _d !== void 0 ? _d : 500,
836
+ callback: () => performRequest(options),
837
+ retryUnless: retryUnless,
838
+ });
822
839
  });
823
840
  }
824
- getHeaders() {
825
- var _a, _b;
841
+ buildUrl(baseUrl, path) {
842
+ const normalizedUrl = `${baseUrl.trim().replace(/\/?$/, '/')}${path.trim().replace(/^\//, '')}`;
843
+ return normalizedUrl.endsWith('/')
844
+ ? normalizedUrl.slice(0, -1)
845
+ : normalizedUrl;
846
+ }
847
+ normalizeError(error) {
848
+ var _a, _b, _c;
826
849
  return {
827
- [LocalizeToken.httpHeaders.X_REFRESH_TOKEN]: (_a = this.tokenService.refreshToken) !== null && _a !== void 0 ? _a : "",
828
- [LocalizeToken.httpHeaders.X_TENANT]: (_b = this.tokenService.tenantToken) !== null && _b !== void 0 ? _b : "",
850
+ code: ((_a = error.error) === null || _a === void 0 ? void 0 : _a.code) || `HTTP_${error.status}`,
851
+ message: ((_b = error.error) === null || _b === void 0 ? void 0 : _b.message) || error.message,
852
+ details: (_c = error.error) === null || _c === void 0 ? void 0 : _c.details,
853
+ status: error.status
829
854
  };
830
855
  }
831
- get isValidPassword() {
832
- this.loading = false;
833
- return this.properties.passwordValidator
834
- ? this.properties.passwordValidator(this.password)
835
- : this.password && this.password.trim().length >= 6 && this.password.trim().length <= 50;
856
+ invokeHook(callback) {
857
+ return __awaiter(this, void 0, void 0, function* () {
858
+ if (!callback)
859
+ return;
860
+ const result = callback();
861
+ if (result instanceof Promise) {
862
+ yield result;
863
+ }
864
+ });
836
865
  }
837
- showMessage(severity, summary) {
838
- this.messageService.add({ key: this.messageKey, severity, summary });
839
- this.loading = false;
866
+ createRequest(instance, method, url, body, options) {
867
+ const request$ = instance.client.request(method, url, Object.assign(Object.assign({}, options), { body, observe: 'response' })).pipe(takeUntil(instance.destroy$()), catchError((error) => {
868
+ // Convert to a non-observable error to handle in the promise
869
+ return throwError(() => this.normalizeError(error));
870
+ }));
871
+ return request$;
840
872
  }
841
- get sanitizedTitle() {
842
- var _a;
843
- return this.sanitizer.bypassSecurityTrustHtml((_a = this.properties.title) !== null && _a !== void 0 ? _a : '');
873
+ defaultRetryFunction(error) {
874
+ // Don't retry for other errors (like 400, 401, 403, etc.)
875
+ if (!this.isConnectionError(error))
876
+ throw error;
877
+ return true;
844
878
  }
845
- }
846
- LocalizeLogindlgComponent.decorators = [
847
- { type: Component, args: [{
848
- template: `<p-toast key="$login-dlg" position="top-center"></p-toast>
849
- <div id="login-dlg-wrap">
850
- <div id="login-dlg-header">
851
- <div id="login-logo" class="p-mb-2" style="background: url('{{properties.logoImage}}') no-repeat"></div>
852
- <h3 *ngIf="!success" [innerHTML]="sanitizedTitle"></h3>
853
- <h3 *ngIf="success" style="color:green !important;">{{properties.loginSuccessMessage}}</h3>
854
- </div>
855
- <div id="login-dlg-content">
856
- <ng-container *ngIf="!success">
857
- <div *ngIf="loading" class="loader-wrap">
858
- <div class="login-dlg-loader"></div>
859
- </div>
860
- <div class="login-dlg-elm">
861
- <div class="p-inputgroup">
862
- <span class="p-inputgroup-addon">
863
- <i class="material-icons-round">person</i>
864
- </span>
865
- <input disabled pInputText type="text" placeholder="{{properties.username?.placeHolder}}" [value]="decodeToken?.email" />
866
- </div>
867
- </div>
868
-
869
- <div class="login-dlg-elm">
870
- <div class="p-inputgroup">
871
- <span class="p-inputgroup-addon">
872
- <i class="material-icons-round">lock</i>
873
- </span>
874
- <input [disabled]="loading" (keydown.enter)="clickLogin()" pInputText type="password"
875
- placeholder="{{properties.password?.placeHolder}}" [(ngModel)]="password"
876
- autofocus />
877
- </div>
878
- </div>
879
- <div class="login-dlg-elm">
880
- <button style="width: 100%;" pButton type="button" label="{{properties.loginButton?.placeHolder}}" (click)="clickLogin()"
881
- [disabled]="!password || loading"></button>
882
- </div>
883
-
884
- <div class="login-dlg-elm login-dlg-suggest" style="display:flex;align-items: center;user-select: none;">
885
- <span>{{properties.logoutButton?.message}}</span>
886
- <button class="p-button-text" pButton type="button" label="{{properties.logoutButton?.placeHolder}}"
887
- (click)="clickLogout()"></button>
888
- </div>
889
- </ng-container>
890
-
891
- <ng-container *ngIf="success">
892
- <div style="margin-top:35px;"></div>
893
- <div class="check-animation-wrap">
894
- <div class="check-main-container">
895
- <div class="check-container">
896
- <div class="check-background">
897
- <svg viewBox="0 0 65 51" fill="none" xmlns="http://www.w3.org/2000/svg">
898
- <path d="M7 25L27.3077 44L58.5 7" stroke="white" stroke-width="13" stroke-linecap="round"
899
- stroke-linejoin="round"></path>
900
- </svg>
901
- </div>
902
- </div>
903
- </div>
904
- </div>
905
- </ng-container>
906
- </div>
907
- </div>`,
908
- selector: "app-localize-logindlg",
909
- providers: [MessageService],
910
- encapsulation: ViewEncapsulation.None,
911
- styles: [`
912
- #login-dlg-wrap {
913
- width: 100%;
914
- max-width: 400px;
915
- margin: 0 auto;
916
- padding: 30px;
917
- height: 100%;
918
- }
919
-
920
- .login-dlg-elm {
921
- margin-top: 1rem;
922
- }
923
-
924
- .login-dlg-elm.login-dlg-suggest {
925
- display: flex ;
926
- align-items: center;
927
- user-select: none;
928
- border-bottom: solid 1px #ddd;
929
- border-radius: 5px;
930
- padding: 5px 10px;
931
- background: #f9f9f9;
932
- box-shadow: 1px 5px 10px -12px #000;
933
- }
934
-
935
- #login-dlg-header {
936
- display: flex;
937
- flex-direction: column;
938
- align-items: center;
939
- justify-content: center;
940
- }
941
-
942
- #login-dlg-header h3 {
943
- font-weight: bold;
944
- font-size: 0.9rem;
945
- color: orange;
946
- text-align: center;
947
- }
948
-
949
- #login-logo {
950
- height: 55px;
951
- width: 55px;
952
- /* background: url("/assets/images/logo-300px.png") no-repeat; */
953
- background-size: contain !important;
954
- }
955
-
956
- #login-dlg-content .p-inputgroup {
957
- height: 45px;
958
- }
959
-
960
- #login-dlg-content .p-inputgroup .p-inputgroup-addon {
961
- height: 45px;
962
- border-radius: 15px 0 0 15px;
963
- width: 50px;
964
- }
965
- #login-dlg-content *{
966
- font-size: .9rem;
967
- /* font-family: 'Lexend', 'Roboto', sans-serif, 'material-icons-round'; */
968
- }
969
-
970
- #login-dlg-content .p-inputgroup .p-inputgroup-addon * {
971
- font-size: 1rem;
972
- }
973
-
974
- #login-dlg-content .p-inputgroup input {
975
- height: 45px;
976
- border-radius: 0 15px 15px 0;
977
- }
978
-
979
- #login-dlg-content button {
980
- height: 45px;
981
- border-radius: 15px;
982
- }
983
-
984
- /*check animation block*/
985
-
986
- .check-animation-wrap {
987
- top: 0;
988
- left: 0;
989
- position: absolute;
990
- display: flex;
991
- flex-direction: column;
992
- align-items: center;
993
- justify-content: center;
994
- width: 100%;
995
- height: calc(100% - 200px);
996
- min-height: 400px;
997
- }
998
-
999
- .check-main-container {
1000
- width: 100%;
1001
- height: 100vh;
1002
- display: flex;
1003
- flex-flow: column;
1004
- justify-content: center;
1005
- align-items: center;
1006
- }
1007
-
1008
- .check-container {
1009
- width: 6.25rem;
1010
- height: 7.5rem;
1011
- display: flex;
1012
- flex-flow: column;
1013
- align-items: center;
1014
- justify-content: space-between;
1015
- }
1016
-
1017
- .check-container .check-background {
1018
- width: 100%;
1019
- height: calc(100% - 1.25rem);
1020
- background: linear-gradient(to bottom right, #5de593, #41d67c);
1021
- box-shadow: 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset;
1022
- transform: scale(0.84);
1023
- border-radius: 50%;
1024
- animation: animateContainer 0.75s ease-out forwards 0.75s;
1025
- display: flex;
1026
- align-items: center;
1027
- justify-content: center;
1028
- opacity: 0;
1029
- }
1030
-
1031
- .check-container .check-background svg {
1032
- width: 65%;
1033
- transform: translateY(0.25rem);
1034
- stroke-dasharray: 80;
1035
- stroke-dashoffset: 80;
1036
- animation: animateCheck 0.35s forwards 1.25s ease-out;
1037
- min-width: auto !important;
1038
- }
1039
-
1040
- .check-container .check-shadow {
1041
- bottom: calc(-15% - 5px);
1042
- left: 0;
1043
- border-radius: 50%;
1044
- background: radial-gradient(closest-side, rgba(73, 218, 131, 1), transparent);
1045
- animation: animateShadow 0.75s ease-out forwards 0.75s;
1046
- }
1047
-
1048
- @keyframes animateContainer {
1049
- 0% {
1050
- opacity: 0;
1051
- transform: scale(0);
1052
- box-shadow: 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset;
879
+ isConnectionError(error) {
880
+ const isNetworkError = error.status === 0;
881
+ const isServerError = error.status >= 1000 && error.status < 600;
882
+ return isNetworkError || isServerError;
1053
883
  }
1054
-
1055
- 25% {
1056
- opacity: 1;
1057
- transform: scale(0.9);
1058
- box-shadow: 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset;
884
+ onConnectionError(options, error) {
885
+ var _a;
886
+ return __awaiter(this, void 0, void 0, function* () {
887
+ if (!options.connectionError)
888
+ return;
889
+ let styleElement;
890
+ if (this.isConnectionError(error)) {
891
+ styleElement = this.screenBlocker(options, error, true);
892
+ yield this.invokeHook((_a = options.connectionError.callback) === null || _a === void 0 ? void 0 : _a.bind(this, error));
893
+ return styleElement;
894
+ }
895
+ else {
896
+ this.screenBlocker(options, error, false);
897
+ styleElement === null || styleElement === void 0 ? void 0 : styleElement.remove();
898
+ }
899
+ });
1059
900
  }
1060
-
1061
- 43.75% {
1062
- transform: scale(1.15);
1063
- box-shadow: 0px 0px 0px 43.334px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 65px rgba(255, 255, 255, 0.25) inset;
901
+ screenBlocker(optons, error, add = true) {
902
+ var _a, _b, _c, _d;
903
+ if (!((_a = optons.connectionError) === null || _a === void 0 ? void 0 : _a.blockScreen))
904
+ return;
905
+ if (error instanceof HttpErrorResponse)
906
+ error = this.normalizeError(error);
907
+ const message = ((_b = optons.connectionError) === null || _b === void 0 ? void 0 : _b.message)
908
+ || 'Connection error occurred. Please wait';
909
+ const errorMessage = (error === null || error === void 0 ? void 0 : error.message) || 'An error occurred';
910
+ const suggestinMessage = ((_c = optons.connectionError) === null || _c === void 0 ? void 0 : _c.suggestionMessage)
911
+ || 'Please check your internet connection or the server status.';
912
+ const zIndex = ((_d = optons.connectionError) === null || _d === void 0 ? void 0 : _d.blockScreenZIndex) || 10000;
913
+ const body = document.body;
914
+ const blcokerHtml = `
915
+ <div class="lze-blocker">
916
+ ${LOCALIZE_API_ASSETS.network.noConnection}
917
+ <div class="lze-blocker__message">
918
+ ${message}
919
+ <span class="lze-blocker__dotting">
920
+ <span class="lze-blocker__dot"></span>
921
+ <span class="lze-blocker__dot"></span>
922
+ <span class="lze-blocker__dot"></span>
923
+ </span>
924
+ </div>
925
+ <div class="lze-blocker__error">${errorMessage}</div>
926
+ <div class="lze-blocker__error_suggestion">${suggestinMessage}</div>
927
+ </div>
928
+ `;
929
+ const style = `
930
+ div.lze-blocker {
931
+ position: fixed;
932
+ top: 0;
933
+ left: 0;
934
+ width: 100%;
935
+ height: 100%;
936
+ background: rgba(0, 0, 0, 0.85) !important;
937
+ z-index: ${zIndex};
938
+ display: flex;
939
+ align-items: center;
940
+ justify-content: center;
941
+ flex-direction: column;
942
+ color: #fff !important;
943
+ font-family: Arial, sans-serif;
944
+ text-align: center;
945
+ padding: 20px;
946
+ box-sizing: border-box;
947
+ overflow: hidden;
948
+ user-select: none;
949
+ }
950
+
951
+ svg#lze-no-connection {
952
+ width: 75px;
953
+ height: 75px;
954
+ margin-bottom: 20px;
955
+ }
956
+
957
+ div.lze-blocker__message {
958
+ color: #fff !important;
959
+ font-size: 18px !important;
960
+ margin-bottom: 10px;
961
+ }
962
+
963
+ .lze-blocker__dotting {
964
+ display: inline-block;
965
+ vertical-align: middle;
966
+ }
967
+ span.lze-blocker__dot {
968
+ display: inline-block;
969
+ width: 7px;
970
+ height: 7px;
971
+ background-color: #ffffff !important;
972
+ border-radius: 50%;
973
+ margin-left: 3px;
974
+ opacity: 0.3;
975
+ animation: dotting 1s infinite;
976
+ }
977
+ .lze-blocker__dot:nth-child(1) {
978
+ animation-delay: 0s;
979
+ opacity: 1;
980
+ }
981
+ .lze-blocker__dot:nth-child(2) {
982
+ animation-delay: 0.2s;
983
+ }
984
+ .lze-blocker__dot:nth-child(3) {
985
+ animation-delay: 0.4s;
986
+ }
987
+
988
+ @keyframes dotting {
989
+ 0%, 80%, 100% { opacity: 0.3; }
990
+ 40% { opacity: 1; }
991
+ }
992
+
993
+ div.lze-blocker__error {
994
+ color: #f00;
995
+ font-size: 14px !important;
996
+ margin-bottom: 10px;
997
+ text-shadow: 0 0 1px #ff5f5f !important;
998
+ }
999
+
1000
+ div.lze-blocker__error_suggestion {
1001
+ color: #ccc !important;
1002
+ font-size: 14px !important;
1003
+ margin-top: 10px;
1004
+ }
1005
+
1006
+ @keyframes spin {
1007
+ 0% { transform: rotate(0deg); }
1008
+ 100% { transform: rotate(360deg); }
1009
+ }
1010
+ `;
1011
+ const styleElement = document.createElement('style');
1012
+ if (add) {
1013
+ if (!document.querySelector('.lze-blocker')) {
1014
+ styleElement.innerHTML = style;
1015
+ document.head.appendChild(styleElement);
1016
+ body.insertAdjacentHTML('beforeend', blcokerHtml);
1017
+ }
1018
+ }
1019
+ else {
1020
+ this.removeBlocker(styleElement);
1021
+ }
1022
+ return styleElement;
1064
1023
  }
1065
-
1066
- 62.5% {
1067
- transform: scale(1);
1068
- box-shadow: 0px 0px 0px 0px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 21.667px rgba(255, 255, 255, 0.25) inset;
1024
+ removeBlocker(styleElement) {
1025
+ const blocker = document.querySelector('.lze-blocker');
1026
+ blocker === null || blocker === void 0 ? void 0 : blocker.remove();
1027
+ styleElement === null || styleElement === void 0 ? void 0 : styleElement.remove();
1028
+ }
1029
+ }
1030
+ const ApiHelper = new LocalizeApiHelper();
1031
+
1032
+ const SCHEMES = LocalizeToken.httpHeaders;
1033
+ class LocalizeApiService {
1034
+ constructor(httpClient, localizeTokenService) {
1035
+ this.httpClient = httpClient;
1036
+ this.localizeTokenService = localizeTokenService;
1037
+ this.destroy$ = new Subject();
1038
+ this.configSubject = new BehaviorSubject({});
1039
+ this.isRequestingSubject = new BehaviorSubject(false);
1040
+ this.isResolvingStartupSubject = new BehaviorSubject(false);
1041
+ this.defaultConfig = {
1042
+ waitEachRequest: { milliseconds: 0 },
1043
+ enableRequestCancellation: true,
1044
+ retryOptions: {
1045
+ maxRetries: 1000,
1046
+ delay: 1000,
1047
+ retryFunction: ApiHelper.defaultRetryFunction.bind(this),
1048
+ },
1049
+ };
1050
+ this.apiOptions = {
1051
+ method: EMethod.GET,
1052
+ requestBody: null,
1053
+ };
1054
+ /**
1055
+ * A higher-order function that returns a curried function for making API requests.
1056
+ *
1057
+ * @param baseUrl - The base URL of the API.
1058
+ * @returns A curried function that can be used to make API requests.
1059
+ */
1060
+ this.func = (baseUrl) => (path, method = EMethod.GET, reqBody = null, reqHeaders) => this.request(baseUrl, path, method, reqBody, reqHeaders);
1061
+ }
1062
+ get isResolvingStartup() { return this.isResolvingStartupSubject.value; }
1063
+ get needTenant() { return this.localizeTokenService.config.tenantToken !== undefined; }
1064
+ get isRequesting() { return this.isRequestingSubject.value; }
1065
+ get isRevokingToken() { return this.localizeTokenService.isRevokingToken; }
1066
+ set isRevokingToken(value) { this.localizeTokenService.isRevokingToken = value; }
1067
+ get accessToken() { return this.localizeTokenService.accessToken; }
1068
+ set accessToken(value) { this.localizeTokenService.accessToken = value; }
1069
+ get refreshToken() { return this.localizeTokenService.refreshToken; }
1070
+ get tenantToken() { return this.localizeTokenService.tenantToken; }
1071
+ get config() {
1072
+ this.validateConfig();
1073
+ return this.configSubject.value;
1074
+ }
1075
+ /**
1076
+ * Initialize the API service.
1077
+ * @param apiConfigs - The API configurations.
1078
+ */
1079
+ init(apiConfigs) {
1080
+ console.log('LocalizeApiService is initialized.');
1081
+ this.configSubject.next(Object.assign(Object.assign({}, this.defaultConfig), apiConfigs));
1082
+ }
1083
+ cancelPendingRequests() {
1084
+ this.config.enableRequestCancellation
1085
+ && this.destroy$.next();
1086
+ }
1087
+ ngOnDestroy() {
1088
+ this.destroy$.next();
1089
+ this.destroy$.complete();
1090
+ // this.isResolvingStartupSubject.complete();
1091
+ // this.isRequestingSubject.complete();
1092
+ // this.configSubject.complete();
1093
+ }
1094
+ request(baseUrl, path, method = EMethod.GET, reqBody = null, reqHeaders) {
1095
+ return __awaiter(this, void 0, void 0, function* () {
1096
+ yield waitUntil(() => !this.isResolvingStartup, 500);
1097
+ yield ApiHelper.invokeHook(this.config.onPrepareRequest);
1098
+ const apiOptions = this.buildApiOptions(baseUrl, path, method, reqBody, reqHeaders);
1099
+ try {
1100
+ yield this.toWaitForPreviousRequest();
1101
+ return yield ApiHelper.performRequestWithRetry(apiOptions, this.config, this.performRequest.bind(this));
1102
+ }
1103
+ catch (error) {
1104
+ return yield this.handleOnRequestError(error, apiOptions);
1105
+ }
1106
+ });
1107
+ }
1108
+ handleOnRequestError(error, options) {
1109
+ return __awaiter(this, void 0, void 0, function* () {
1110
+ if (error.status !== 401)
1111
+ throw error;
1112
+ yield waitUntil(() => !this.isResolvingStartup, 500);
1113
+ return yield ApiHelper.performRetry({
1114
+ maxRetries: () => 1000,
1115
+ delay: 500,
1116
+ retryUnless: (error) => error.status === 401 || ApiHelper.isConnectionError(error),
1117
+ callback: () => __awaiter(this, void 0, void 0, function* () {
1118
+ // Only handle 401 Unauthorized errors
1119
+ yield this.revokeToken();
1120
+ // Retry the request with the new access token
1121
+ return yield this.performRequest(options);
1122
+ })
1123
+ });
1124
+ });
1069
1125
  }
1070
-
1071
- 81.25% {
1072
- box-shadow: 0px 0px 0px 0px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 0px rgba(255, 255, 255, 0.25) inset;
1126
+ performRequest(options) {
1127
+ return __awaiter(this, void 0, void 0, function* () {
1128
+ // Build the request options
1129
+ const buildOptions = { headers: this.buildHeaderOptions(options) };
1130
+ // Create the request observable
1131
+ const request$ = ApiHelper.createRequest({
1132
+ client: this.httpClient,
1133
+ destroy$: () => this.destroy$
1134
+ }, options.method, options.requestUrl, options.requestBody, buildOptions);
1135
+ // Set the isRequesting state to true before making the request
1136
+ this.isRequestingSubject.next(true);
1137
+ const response = yield new Promise((resolve, reject) => request$.subscribe({ next: (res) => resolve(res.body), error: reject }));
1138
+ // Reset the isRequesting state after the request completes
1139
+ this.isRequestingSubject.next(false);
1140
+ return response;
1141
+ });
1073
1142
  }
1074
-
1075
- 100% {
1076
- opacity: 1;
1077
- box-shadow: 0px 0px 0px 0px rgba(255, 255, 255, 0.25) inset, 0px 0px 0px 0px rgba(255, 255, 255, 0.25) inset;
1143
+ revokeToken() {
1144
+ var _a;
1145
+ return __awaiter(this, void 0, void 0, function* () {
1146
+ try {
1147
+ if (yield this.interceptRevokeToken())
1148
+ return;
1149
+ this.isRevokingToken = true;
1150
+ const apiOptions = Object.assign(Object.assign({}, this.buildApiOptions(((_a = this.localizeTokenService.config.refreshToken) === null || _a === void 0 ? void 0 : _a.requestUrl) || '')), { refreshToken: true });
1151
+ // const revokeToken = await this.performRequest(apiOptions);
1152
+ const revokeToken = yield ApiHelper.performRequestWithRetry(apiOptions, this.config, this.performRequest.bind(this));
1153
+ yield this.handleOnTokenRevoked(revokeToken);
1154
+ }
1155
+ catch (error) {
1156
+ // Handle the error, log it
1157
+ yield ApiHelper.invokeHook(this.config.onAutoLogout);
1158
+ }
1159
+ finally {
1160
+ // Reset the revoking token state
1161
+ this.isRevokingToken = false;
1162
+ }
1163
+ });
1078
1164
  }
1079
- }
1080
-
1081
- @keyframes animateCheck {
1082
- from {
1083
- stroke-dashoffset: 80;
1165
+ /** default http request options */
1166
+ buildHeaderOptions(options) {
1167
+ const headers = Object.assign(Object.assign(Object.assign(Object.assign({}, (options.refreshToken && { [SCHEMES.X_REFRESH_TOKEN]: `${this.refreshToken}` })), (!options.isFormData && { [SCHEMES.CONTENT_TYPE]: 'application/json' })), { [SCHEMES.AUTHORIZATION]: `Bearer ${this.accessToken}` }), (this.needTenant && { [SCHEMES.X_TENANT]: `${this.tenantToken}` }));
1168
+ return new HttpHeaders(Object.assign(Object.assign({}, headers), options.headers));
1084
1169
  }
1085
-
1086
- to {
1087
- stroke-dashoffset: 0;
1170
+ buildApiOptions(baseUrl, path = '', method = EMethod.GET, requestBody = null, headers) {
1171
+ const requestUrl = ApiHelper.buildUrl(baseUrl, path);
1172
+ const isFormData = requestBody && requestBody instanceof FormData;
1173
+ return Object.assign(Object.assign({}, this.apiOptions), { headers, method, requestUrl, requestBody, isFormData });
1088
1174
  }
1089
- }
1090
-
1091
- @keyframes animateShadow {
1092
- 0% {
1093
- opacity: 0;
1094
- width: 100%;
1095
- height: 15%;
1175
+ toWaitForPreviousRequest() {
1176
+ var _a;
1177
+ return __awaiter(this, void 0, void 0, function* () {
1178
+ this.isRevokingToken &&
1179
+ (yield waitUntil(() => !this.isRevokingToken));
1180
+ // to wait for each request in 50ms, even if the request is not completed
1181
+ ((_a = this.config.waitEachRequest) === null || _a === void 0 ? void 0 : _a.milliseconds) &&
1182
+ (yield waitFor(this.config.waitEachRequest.milliseconds, this.isRequesting));
1183
+ });
1096
1184
  }
1097
-
1098
- 25% {
1099
- opacity: 0.25;
1185
+ handleOnTokenRevoked(response) {
1186
+ return __awaiter(this, void 0, void 0, function* () {
1187
+ if (response === null || response === void 0 ? void 0 : response.status) {
1188
+ // If the response is successful, update the access token
1189
+ this.accessToken = response.message;
1190
+ }
1191
+ else {
1192
+ // If the response indicates an error, invoke the onRevokeUnauthorized hook
1193
+ console.warn('Token revocation failed, refresh token is expired.', response.message);
1194
+ yield ApiHelper.invokeHook(this.config.onRevokeUnauthorized);
1195
+ }
1196
+ });
1100
1197
  }
1101
-
1102
- 43.75% {
1103
- width: 40%;
1104
- height: 7%;
1105
- opacity: 0.35;
1198
+ interceptRevokeToken() {
1199
+ return __awaiter(this, void 0, void 0, function* () {
1200
+ if (this.isRevokingToken) {
1201
+ console.warn('Token is already being revoked. Waiting for the current operation to complete...');
1202
+ yield waitUntil(() => !this.isRevokingToken);
1203
+ return true;
1204
+ }
1205
+ if (!this.refreshToken) {
1206
+ // await ApiHelper.invokeHook(this.apiConfigs.onAutoLogout);
1207
+ throw new Error('Refresh token is missing. Please login again.');
1208
+ }
1209
+ return false;
1210
+ });
1106
1211
  }
1107
-
1108
- 100% {
1109
- width: 85%;
1110
- height: 15%;
1111
- opacity: 0.25;
1212
+ validateConfig() {
1213
+ var _a, _b, _c, _d;
1214
+ if (this.localizeTokenService.config.tenantToken
1215
+ && !((_b = (_a = this.localizeTokenService.config.tenantToken) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.trim().length)) {
1216
+ throw Error('Tenant token is required but tenantTokenName is not configured');
1217
+ }
1218
+ if (!((_d = (_c = this.localizeTokenService.config.refreshToken) === null || _c === void 0 ? void 0 : _c.requestUrl) === null || _d === void 0 ? void 0 : _d.trim().length)) {
1219
+ throw Error('Revoke token URL is not configured - token refresh will not work');
1220
+ }
1112
1221
  }
1113
- }
1114
- #login-dlg-wrap .loader-wrap {
1115
- display: flex;
1116
- justify-content: center;
1117
- align-items: center;
1118
- height:100%;
1119
- width:100%;
1120
- position: absolute;
1121
- top: 0;
1122
- left: 0;
1123
- z-index: 100;
1124
- background: #ffffff42;
1125
- backdrop-filter: blur(1px);
1126
- }
1127
-
1128
- #login-dlg-wrap .login-dlg-loader {
1129
- border: 15px solid #e7e7e7;
1130
- border-top: 15px solid #52dba1;
1131
- border-radius: 50%;
1132
- width: 100px;
1133
- height: 100px;
1134
- animation: spinloader 2s linear infinite;
1135
- }
1136
-
1137
- #login-dlg-wrap .loader-wrap::before {
1138
- content: "";
1139
- position: absolute;
1140
- width: 70px;
1141
- height: 70px;
1142
- transform: translate(-50%, -50%);
1143
- z-index: 1;
1144
- border: 15px solid #e7e7e700;
1145
- border-top: 15px solid #52dba1c9;
1146
- border-radius: 50%;
1147
- animation: spinloader .75s linear infinite;
1148
- }
1149
-
1150
- @keyframes spinloader {
1151
- 0% { transform: rotate(0deg); }
1152
- 100% { transform: rotate(360deg); }
1153
- }
1154
- `]
1222
+ }
1223
+ LocalizeApiService.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalizeApiService_Factory() { return new LocalizeApiService(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(LocalizeTokenService)); }, token: LocalizeApiService, providedIn: "root" });
1224
+ LocalizeApiService.decorators = [
1225
+ { type: Injectable, args: [{
1226
+ providedIn: 'root'
1155
1227
  },] }
1156
1228
  ];
1157
- LocalizeLogindlgComponent.ctorParameters = () => [
1158
- { type: MessageService },
1159
- { type: ChangeDetectorRef },
1160
- { type: DynamicDialogRef },
1161
- { type: DynamicDialogConfig },
1162
- { type: LocalizeTokenService },
1229
+ LocalizeApiService.ctorParameters = () => [
1163
1230
  { type: HttpClient },
1164
- { type: DomSanitizer }
1231
+ { type: LocalizeTokenService }
1165
1232
  ];
1166
1233
 
1167
- class LocalizeLogindlgService {
1168
- constructor(injector) {
1169
- this.injector = injector;
1170
- }
1171
- openLoginDialog(loginConfig, config) {
1172
- return __awaiter(this, void 0, void 0, function* () {
1173
- config = this.intercepDialogConfig(config);
1174
- this.initConfig(loginConfig);
1175
- config.data = Object.assign(Object.assign({}, (config.data || {})), { loginConfig });
1176
- const dialogService = this.injector.get(DialogService);
1177
- const dialog = dialogService.open(LocalizeLogindlgComponent, config);
1178
- yield new Promise((resolve) => dialog.onClose.subscribe(res => {
1179
- if (res) {
1180
- resolve();
1181
- }
1182
- }));
1183
- });
1184
- }
1185
- intercepDialogConfig(config) {
1186
- config !== null && config !== void 0 ? config : (config = {
1187
- header: 'Login',
1188
- style: { 'max-width': '400px', width: '100%', 'height': '650px' },
1189
- modal: true,
1190
- closable: false,
1191
- showHeader: false,
1192
- });
1193
- config = Object.assign(Object.assign({}, config), {
1194
- contentStyle: { 'height': '100%', 'border-radius': '20px' }
1195
- });
1196
- config.style = Object.assign(Object.assign({}, config.style), { 'border-radius': '20px' });
1197
- return config;
1198
- }
1199
- initConfig(loginConfig) {
1200
- var _a;
1201
- loginConfig !== null && loginConfig !== void 0 ? loginConfig : (loginConfig = {});
1202
- (_a = loginConfig.properties) !== null && _a !== void 0 ? _a : (loginConfig.properties = {
1203
- title: 'Your session is expired!<br/> Please login again to continue.',
1204
- loginSuccessMessage: 'You have successfully logged in.',
1205
- logoImage: '/assets/images/logo-300px.png',
1206
- username: { placeHolder: 'Username' },
1207
- password: { placeHolder: 'Password' },
1208
- loginButton: { placeHolder: 'Login' },
1209
- logoutButton: {
1210
- message: 'No, I want to login with another user.',
1211
- placeHolder: 'Logout'
1212
- }
1213
- });
1234
+ class LocalizeTokenModule {
1235
+ }
1236
+ LocalizeTokenModule.decorators = [
1237
+ { type: NgModule, args: [{
1238
+ providers: [
1239
+ LocalizeTokenService,
1240
+ LocalizeApiService
1241
+ ]
1242
+ },] }
1243
+ ];
1244
+
1245
+ class LocalizeApiTokenService {
1246
+ constructor(tokenService, apiService, loginDialogService) {
1247
+ this.api = apiService;
1248
+ this.token = tokenService;
1249
+ this.loginDialog = loginDialogService;
1250
+ }
1251
+ initialize(tokenConfig, apiConfig) {
1252
+ // Initialize the LocalizeTokenService with the provided token configuration
1253
+ this.token.init(tokenConfig);
1254
+ // Initialize the LocalizeApiService with the provided API configuration
1255
+ this.api.init(apiConfig);
1256
+ console.log('LocalizeApiTokenService initialized with token and API configurations.');
1214
1257
  }
1215
1258
  }
1216
- LocalizeLogindlgService.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalizeLogindlgService_Factory() { return new LocalizeLogindlgService(i0.ɵɵinject(i0.INJECTOR)); }, token: LocalizeLogindlgService, providedIn: "root" });
1217
- LocalizeLogindlgService.decorators = [
1259
+ LocalizeApiTokenService.ɵprov = i0.ɵɵdefineInjectable({ factory: function LocalizeApiTokenService_Factory() { return new LocalizeApiTokenService(i0.ɵɵinject(LocalizeTokenService), i0.ɵɵinject(LocalizeApiService), i0.ɵɵinject(LocalizeLogindlgService)); }, token: LocalizeApiTokenService, providedIn: "root" });
1260
+ LocalizeApiTokenService.decorators = [
1218
1261
  { type: Injectable, args: [{
1219
1262
  providedIn: 'root'
1220
1263
  },] }
1221
1264
  ];
1222
- LocalizeLogindlgService.ctorParameters = () => [
1223
- { type: Injector }
1265
+ LocalizeApiTokenService.ctorParameters = () => [
1266
+ { type: LocalizeTokenService },
1267
+ { type: LocalizeApiService },
1268
+ { type: LocalizeLogindlgService }
1224
1269
  ];
1225
1270
 
1226
- class LocalizeLogindlgModule {
1271
+ class LocalizeApiTokenModule {
1227
1272
  }
1228
- LocalizeLogindlgModule.decorators = [
1273
+ LocalizeApiTokenModule.decorators = [
1229
1274
  { type: NgModule, args: [{
1230
- declarations: [LocalizeLogindlgComponent],
1231
- exports: [LocalizeLogindlgComponent],
1275
+ declarations: [],
1232
1276
  imports: [
1233
1277
  CommonModule,
1234
- ToastModule,
1235
- InputTextModule,
1236
- BrowserModule,
1237
- FormsModule,
1238
- ButtonModule,
1278
+ LocalizeTokenModule,
1279
+ LocalizeLogindlgModule
1239
1280
  ],
1240
- providers: [LocalizeLogindlgService],
1241
- schemas: [CUSTOM_ELEMENTS_SCHEMA],
1281
+ providers: [
1282
+ LocalizeApiTokenService
1283
+ ]
1242
1284
  },] }
1243
1285
  ];
1244
1286
 
1287
+ //#region login dialog
1288
+
1245
1289
  /**
1246
1290
  * Generated bundle index. Do not edit.
1247
1291
  */
1248
1292
 
1249
- export { ApiHelper, EMethod, LOCALIZE_API_ASSETS, LocalizeApiService, LocalizeLogindlgComponent, LocalizeLogindlgModule, LocalizeLogindlgService, LocalizeToken, LocalizeTokenModule, LocalizeTokenService, LocalizeTokenStorage, extractMainDomain, waitFor, waitUntil };
1293
+ export { ApiHelper, EMethod, LOCALIZE_API_ASSETS, LocalizeApiService, LocalizeApiTokenModule, LocalizeApiTokenService, LocalizeLogindlgComponent, LocalizeLogindlgModule, LocalizeLogindlgService, LocalizeToken, LocalizeTokenModule, LocalizeTokenService, LocalizeTokenStorage, extractMainDomain, waitFor, waitUntil };
1250
1294
  //# sourceMappingURL=sambath999-localize-token.js.map