@acorex/connectivity 20.1.0 → 20.2.0-next.1

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,19 +1,19 @@
1
- import { AXP_ROOT_CONFIG_TOKEN, AXPFilterOperatorMiddlewareService, AXPRegionalService, AXPFileStorageService, AXPFileStorageStatus } from '@acorex/platform/common';
1
+ import { AXP_ROOT_CONFIG_TOKEN, AXPFilterOperatorMiddlewareService, AXPFileStorageService, AXPFileStorageStatus, AXPRegionalService } from '@acorex/platform/common';
2
2
  import { AXPEntityResolver, AXPEntityStorageService } from '@acorex/platform/layout/entity';
3
3
  import * as i1 from '@angular/common/http';
4
4
  import { HttpParams, HttpClient, HttpHeaders } from '@angular/common/http';
5
5
  import * as i0 from '@angular/core';
6
6
  import { inject, Injectable, NgModule } from '@angular/core';
7
7
  import { kebabCase } from 'lodash-es';
8
- import { firstValueFrom, catchError, of, map, BehaviorSubject, tap, filter, take, switchMap, delay } from 'rxjs';
8
+ import { firstValueFrom, map, BehaviorSubject, tap, filter, take, of, switchMap, delay, catchError } from 'rxjs';
9
9
  import * as i2 from '@acorex/platform/auth';
10
- import { AXPAuthStrategy, AXPSessionService, AXPAuthModule, AXP_TENANT_LOADER, AXP_APPLICATION_LOADER, AXP_PERMISSION_LOADER, AXP_FEATURE_LOADER } from '@acorex/platform/auth';
10
+ import { AXPSessionService, AXPAuthModule, AXP_APPLICATION_LOADER, AXP_PERMISSION_LOADER, AXP_FEATURE_LOADER } from '@acorex/platform/auth';
11
11
  import { STRATEGY_CONFIG_TOKEN } from '@acorex/platform/widgets';
12
12
  import * as i1$1 from 'angular-oauth2-oidc';
13
13
  import { OAuthService, OAuthModule } from 'angular-oauth2-oidc';
14
+ import { AXM_AUTH_CONFIG_TOKEN } from '@acorex/modules/auth';
14
15
  import { AXUSLocaleProfile, AXIRLocaleProfile } from '@acorex/core/locale';
15
16
  import { AXTranslationService } from '@acorex/core/translation';
16
- import { AXM_AUTH_CONFIG_TOKEN } from '@acorex/modules/auth';
17
17
 
18
18
  class AXCApiEntityStorageService {
19
19
  constructor(http) {
@@ -138,252 +138,386 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
138
138
  type: Injectable
139
139
  }], ctorParameters: () => [{ type: i1.HttpClient }] });
140
140
 
141
- class AXCRegionalApiService extends AXPRegionalService {
141
+ class AXMOidcApplicationLoader {
142
+ constructor(http) {
143
+ this.http = http;
144
+ this.configs = inject(AXP_ROOT_CONFIG_TOKEN);
145
+ this.apiGetApps = `${this.configs.baseUrl}/applications/applications-for-current-tenant`;
146
+ this.apiSetApp = `${this.configs.baseUrl}/SetApplication`;
147
+ }
148
+ getList() {
149
+ return this.http.get(this.apiGetApps).pipe(map((response) => {
150
+ return response.items.map((item) => this.mapToAXPApplication(item));
151
+ }));
152
+ }
153
+ set(application) {
154
+ return Promise.resolve();
155
+ }
156
+ // //TODO: shoud be removed
157
+ // set(application: AXPApplication): Observable<AXPRefreshTokenResult> {
158
+ // return this.http.post<any>(this.apiSetApp, { applicationId: application.id }).pipe(
159
+ // map((response) => {
160
+ // return {
161
+ // succeed: true,
162
+ // data: {
163
+ // accessToken: response.token,
164
+ // refreshToken: response.token,
165
+ // }
166
+ // };
167
+ // })
168
+ // );
169
+ // }
170
+ mapToAXPApplication(item) {
171
+ return {
172
+ id: item.id,
173
+ name: item.name || 'defaultName',
174
+ title: item.title || 'defaultTitle',
175
+ version: item.version || '1.0.0',
176
+ description: item.description,
177
+ logo: item.logo, // Assuming logo is of type AXPLogoConfig or undefined
178
+ editionName: item.editionName,
179
+ // features: item.features || [],
180
+ };
181
+ }
182
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcApplicationLoader, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
183
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcApplicationLoader }); }
184
+ }
185
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcApplicationLoader, decorators: [{
186
+ type: Injectable
187
+ }], ctorParameters: () => [{ type: i1.HttpClient }] });
188
+
189
+ class AXMConfigurationService {
190
+ constructor(http) {
191
+ this.http = http;
192
+ this.configs = inject(AXP_ROOT_CONFIG_TOKEN);
193
+ this.applicationConfig = null;
194
+ this.apiGetConfig = `${this.configs.baseUrl}/abp/application-configuration`;
195
+ this.fetchInProgress = false;
196
+ this.configSubject = new BehaviorSubject(null);
197
+ this.init().subscribe(); // Automatically trigger configuration load on service instantiation
198
+ }
199
+ init() {
200
+ if (!this.fetchInProgress) {
201
+ this.fetchInProgress = true;
202
+ return this.http.get(this.apiGetConfig).pipe(tap((response) => {
203
+ this.applicationConfig = response;
204
+ this.configSubject.next(this.applicationConfig);
205
+ this.fetchInProgress = false;
206
+ }));
207
+ }
208
+ else {
209
+ // Adjusted approach to handle TypeScript's type safety requirements
210
+ return this.configSubject.asObservable().pipe(filter((config) => config !== null), take(1) // Ensures it completes after emitting the first non-null value
211
+ );
212
+ }
213
+ }
214
+ getConfig() {
215
+ if (this.applicationConfig) {
216
+ // If the config is already loaded, return it immediately
217
+ return of(this.applicationConfig);
218
+ }
219
+ else {
220
+ // If the config is not loaded, initiate loading
221
+ return this.configSubject.asObservable().pipe(filter((config) => config !== null), take(1), // Ensure it only emits the first non-null value and completes
222
+ switchMap(() => of(this.applicationConfig)));
223
+ }
224
+ }
225
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMConfigurationService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
226
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMConfigurationService, providedIn: 'root' }); }
227
+ }
228
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMConfigurationService, decorators: [{
229
+ type: Injectable,
230
+ args: [{
231
+ providedIn: 'root',
232
+ }]
233
+ }], ctorParameters: () => [{ type: i1.HttpClient }] });
234
+
235
+ class AXMOidcFeatureLoader {
142
236
  constructor() {
143
- super(...arguments);
144
- this.http = inject(HttpClient);
145
- this.languageService = inject(AXTranslationService);
146
- //#region ---- API Endpoints ----
147
- this.baseUrl = '/api/regional';
148
- //#endregion
149
- //#region ---- Fallback Data ----
150
- this.fallbackCountries = [
151
- {
152
- code: 'US',
153
- title: 'United States',
154
- native: 'United States',
155
- regional: 'en',
156
- timezone: 'America/New_York'
157
- },
158
- {
159
- code: 'CA',
160
- title: 'Canada',
161
- native: 'Canada',
162
- regional: 'en',
163
- timezone: 'America/Toronto'
164
- },
165
- {
166
- code: 'GB',
167
- title: 'United Kingdom',
168
- native: 'United Kingdom',
169
- regional: 'en',
170
- timezone: 'Europe/London'
171
- }
172
- ];
173
- this.fallbackProvinces = [
174
- {
175
- code: 'CA',
176
- title: 'California',
177
- native: 'California',
178
- timezone: 'America/Los_Angeles'
179
- },
180
- {
181
- code: 'NY',
182
- title: 'New York',
183
- native: 'New York',
184
- timezone: 'America/New_York'
185
- },
186
- {
187
- code: 'ON',
188
- title: 'Ontario',
189
- native: 'Ontario',
190
- timezone: 'America/Toronto'
191
- }
192
- ];
193
- this.fallbackCities = [
194
- {
195
- code: 'NYC',
196
- title: 'New York City',
197
- native: 'New York City',
198
- timezone: 'America/New_York'
199
- },
237
+ this.list = [
200
238
  {
201
- code: 'LA',
202
- title: 'Los Angeles',
203
- native: 'Los Angeles',
204
- timezone: 'America/Los_Angeles'
239
+ name: 'axp-entity-list-custom-view',
240
+ title: 'Custom View',
241
+ value: false
205
242
  },
206
243
  {
207
- code: 'TOR',
208
- title: 'Toronto',
209
- native: 'Toronto',
210
- timezone: 'America/Toronto'
244
+ name: 'axp-entity-list-quick-search',
245
+ title: 'Custom View',
246
+ value: false
211
247
  }
212
248
  ];
213
- this.fallbackCurrencies = [
214
- {
215
- code: 'USD',
216
- title: 'United States Dollar',
217
- symbol: '$',
218
- format: '${amount}'
219
- },
220
- {
221
- code: 'CAD',
222
- title: 'Canadian Dollar',
223
- symbol: 'CA$',
224
- format: 'CA${amount}'
225
- },
226
- {
227
- code: 'GBP',
228
- title: 'British Pound',
229
- symbol: '£',
230
- format: '£{amount}'
249
+ }
250
+ getList() {
251
+ return of(this.list).pipe(delay(0));
252
+ }
253
+ }
254
+
255
+ class AXMOidcStrategy {
256
+ constructor() {
257
+ this.aXMAuthConfigs = inject(AXM_AUTH_CONFIG_TOKEN);
258
+ this.oauthService = inject(OAuthService);
259
+ this.http = inject(HttpClient);
260
+ }
261
+ async configureOAuth() {
262
+ if (this.openidConfigurationInfo)
263
+ return;
264
+ if (!this.authConfig) {
265
+ if (!this.aXMAuthConfigs.authConfig) {
266
+ throw new Error('authConfig is missing');
231
267
  }
232
- ];
233
- this.fallbackLocaleProfiles = [
234
- {
235
- ...AXUSLocaleProfile,
236
- code: 'en-US',
237
- title: 'English (United States)',
238
- nativeTitle: 'English (United States)',
239
- },
240
- {
241
- ...AXIRLocaleProfile,
242
- code: 'fa-IR',
243
- title: 'Persian (Iran)',
244
- nativeTitle: 'فارسی (ایران)',
268
+ this.authConfig = this.aXMAuthConfigs.authConfig;
269
+ }
270
+ this.oauthService.configure(this.authConfig);
271
+ this.oauthService.setStorage(localStorage);
272
+ this.openidConfigurationInfo = await this.oauthService.loadDiscoveryDocument();
273
+ if (!this.openidConfigurationInfo) {
274
+ throw new Error('openidConfigurationInfo is missing');
275
+ }
276
+ this.oauthService.events.subscribe(async (event) => {
277
+ // console.log('event', event);
278
+ // if (event.type === 'token_received') {
279
+ // console.log('Token has been refreshed');
280
+ // }
281
+ // if (event.type === 'token_expires') {
282
+ // console.log('Token is about to expire. Triggering silent refresh...');
283
+ // }
284
+ });
285
+ const oidcJson = localStorage.getItem(AXPSessionService.SESSION_KEY);
286
+ if (oidcJson) {
287
+ const authData = JSON.parse(oidcJson);
288
+ if (authData) {
289
+ this.setServiceProps(authData);
290
+ if (authData.expiresIn && new Date(authData.expiresIn) < new Date()) {
291
+ if (authData.expiresIn) {
292
+ // this.refresh();
293
+ }
294
+ else {
295
+ this.logout();
296
+ }
297
+ }
245
298
  }
246
- ];
247
- this.fallbackLanguages = [
248
- {
249
- code: 'en',
250
- title: 'English'
251
- },
252
- {
253
- code: 'fa',
254
- title: 'Persian'
255
- },
256
- {
257
- code: 'es',
258
- title: 'Spanish'
259
- }
260
- ];
261
- this.fallbackTimeZones = [
262
- {
263
- code: 'America/New_York',
264
- title: 'Eastern Time (US & Canada)',
265
- offset: '-05:00',
266
- iana: 'America/New_York',
267
- abbr: 'EST'
268
- },
269
- {
270
- code: 'America/Los_Angeles',
271
- title: 'Pacific Time (US & Canada)',
272
- offset: '-08:00',
273
- iana: 'America/Los_Angeles',
274
- abbr: 'PST'
275
- },
276
- {
277
- code: 'Europe/London',
278
- title: 'Greenwich Mean Time',
279
- offset: '+00:00',
280
- iana: 'Europe/London',
281
- abbr: 'GMT'
282
- }
283
- ];
299
+ }
284
300
  }
285
- //#endregion
286
- async getCountries() {
287
- const lang = await firstValueFrom(this.languageService.langChanges$);
301
+ async signin(credentials) {
302
+ await this.configureOAuth();
288
303
  try {
289
- const countries = await firstValueFrom(this.http.get(`${this.baseUrl}/countries`).pipe(catchError(() => of(this.fallbackCountries))));
290
- return countries.map((country) => {
291
- if (lang == country.regional) {
292
- return {
293
- ...country,
294
- title: country.native,
295
- };
296
- }
297
- else {
298
- return country;
299
- }
304
+ const body = new HttpParams()
305
+ .set('grant_type', 'password')
306
+ .set('client_id', this.authConfig.clientId)
307
+ .set('client_secret', this.authConfig.dummyClientSecret)
308
+ .set('username', credentials.username)
309
+ .set('password', credentials.password)
310
+ .set('scope', this.authConfig.scope);
311
+ const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
312
+ const response = await firstValueFrom(this.http.post(this.openidConfigurationInfo.info.discoveryDocument.token_endpoint, body.toString(), { headers }));
313
+ // const authData = new AuthenticationData(response);
314
+ this.setServiceProps({
315
+ accessToken: response.access_token,
316
+ refreshToken: response.refresh_token,
317
+ idToken: response.id_token,
318
+ expiresIn: this.calculateExpireInDate(response.expires_in ?? 0),
300
319
  });
320
+ return {
321
+ succeed: true,
322
+ data: {
323
+ accessToken: response.access_token,
324
+ expiresIn: this.calculateExpireInDate(response.expires_in ?? 0),
325
+ idToken: response.id_token,
326
+ refreshToken: response.refresh_token,
327
+ user: {
328
+ id: response.sub,
329
+ title: response.fullname,
330
+ name: response.sub,
331
+ avatar: response.picture,
332
+ },
333
+ tenant: {
334
+ id: response.tenantid,
335
+ name: response.tenantname,
336
+ title: response.tenanttitle,
337
+ },
338
+ application: {
339
+ id: response.applicationid,
340
+ name: response.applicationname,
341
+ title: response.applicationtitle,
342
+ },
343
+ },
344
+ };
301
345
  }
302
- catch {
303
- return this.fallbackCountries.map((country) => {
304
- if (lang == country.regional) {
305
- return {
306
- ...country,
307
- title: country.native,
308
- };
309
- }
310
- else {
311
- return country;
312
- }
313
- });
346
+ catch (error) {
347
+ this.handleError(error);
314
348
  }
315
349
  }
316
- async getProvinces(countryId) {
317
- let params = new HttpParams();
318
- if (countryId) {
319
- params = params.set('countryId', countryId);
320
- }
321
- try {
322
- return await firstValueFrom(this.http.get(`${this.baseUrl}/provinces`, { params }).pipe(catchError(() => of(this.fallbackProvinces))));
323
- }
324
- catch {
325
- return this.fallbackProvinces;
326
- }
350
+ async signout() {
351
+ //this.logout();
327
352
  }
328
- async getCities(filter) {
329
- let params = new HttpParams();
330
- if (filter?.countryId) {
331
- params = params.set('countryId', filter.countryId);
332
- }
333
- if (filter?.provinceId) {
334
- params = params.set('provinceId', filter.provinceId);
335
- }
353
+ async refreshToken(context) {
336
354
  try {
337
- return await firstValueFrom(this.http.get(`${this.baseUrl}/cities`, { params }).pipe(catchError(() => of(this.fallbackCities))));
355
+ await this.configureOAuth();
356
+ const refreshResult = await this.refresh(context.tenant?.id, context.application?.id);
357
+ if (refreshResult) {
358
+ return {
359
+ succeed: true,
360
+ data: {
361
+ accessToken: this.oauthService.getAccessToken(),
362
+ refreshToken: this.oauthService.getRefreshToken(),
363
+ },
364
+ };
365
+ }
366
+ else {
367
+ return { succeed: false };
368
+ }
338
369
  }
339
- catch {
340
- return this.fallbackCities;
370
+ catch (error) {
371
+ console.error('Error refreshing token', error);
372
+ return { succeed: false };
341
373
  }
342
374
  }
343
- async getCurrencies() {
375
+ async refresh(tenantId, applicationId) {
376
+ await this.configureOAuth();
377
+ const authData = this.loadAuthData();
378
+ if (!authData)
379
+ return false;
380
+ const refreshToken = this.oauthService.getRefreshToken();
381
+ if (!refreshToken)
382
+ return false;
383
+ const body = new HttpParams()
384
+ .set('grant_type', 'refresh_token')
385
+ .set('client_id', this.authConfig.clientId)
386
+ .set('client_secret', this.authConfig.dummyClientSecret)
387
+ .set('refresh_token', refreshToken)
388
+ .set('tenantId', tenantId ?? '')
389
+ .set('applicationId', applicationId ?? '');
390
+ const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
344
391
  try {
345
- return await firstValueFrom(this.http.get(`${this.baseUrl}/currencies`).pipe(catchError(() => of(this.fallbackCurrencies))));
392
+ const response = await firstValueFrom(this.http.post(this.openidConfigurationInfo.info.discoveryDocument.token_endpoint, body.toString(), { headers }));
393
+ this.setServiceProps({
394
+ accessToken: response.access_token,
395
+ refreshToken: response.refresh_token,
396
+ idToken: response.id_token,
397
+ expiresIn: this.calculateExpireInDate(response.expires_in ?? 0),
398
+ });
399
+ return true;
346
400
  }
347
- catch {
348
- return this.fallbackCurrencies;
401
+ catch (error) {
402
+ console.error('Token refresh error', error);
403
+ return false;
349
404
  }
350
405
  }
351
- async getLocaleProfiles() {
352
- try {
353
- return await firstValueFrom(this.http.get(`${this.baseUrl}/locale-profiles`).pipe(catchError(() => of(this.fallbackLocaleProfiles))));
354
- }
355
- catch {
356
- return this.fallbackLocaleProfiles;
406
+ expires_in_milisecound(expires_in_date) {
407
+ const now = new Date();
408
+ const expire = new Date(expires_in_date);
409
+ return expire.getTime() - now.getTime();
410
+ }
411
+ setServiceProps(authData) {
412
+ this.oauthService.getAccessToken = () => authData.accessToken;
413
+ this.oauthService.getIdToken = () => authData.idToken ?? '';
414
+ this.oauthService.getRefreshToken = () => authData.refreshToken;
415
+ if (authData.expiresIn) {
416
+ const refreshTime = this.expires_in_milisecound(authData.expiresIn);
417
+ this.oauthService.getAccessTokenExpiration = () => refreshTime;
418
+ // if (refreshTime < 0) {
419
+ // this.refresh();
420
+ // }else{
421
+ // }
357
422
  }
358
423
  }
359
- async getLanguages() {
360
- try {
361
- return await firstValueFrom(this.http.get(`${this.baseUrl}/languages`).pipe(catchError(() => of(this.fallbackLanguages))));
362
- }
363
- catch {
364
- return this.fallbackLanguages;
365
- }
424
+ loadAuthData() {
425
+ const authDataJson = localStorage.getItem(AXPSessionService.SESSION_KEY);
426
+ if (!authDataJson)
427
+ return undefined;
428
+ const authData = JSON.parse(authDataJson);
429
+ // return authData ? new AuthenticationData(authData) : undefined;
430
+ return authData;
366
431
  }
367
- async getAvailableLanguages() {
368
- try {
369
- return await firstValueFrom(this.http.get(`${this.baseUrl}/available-languages`).pipe(catchError(() => of(this.fallbackLanguages))));
370
- }
371
- catch {
372
- return this.fallbackLanguages;
373
- }
432
+ async loadUserInfo() {
433
+ return this.oauthService.loadUserProfile();
374
434
  }
375
- async getBrowserTimeZoneCode() {
376
- return Intl.DateTimeFormat().resolvedOptions().timeZone;
435
+ calculateExpireInDate(expireInMilisecound) {
436
+ return new Date(Date.now() + expireInMilisecound * 1000).toISOString();
377
437
  }
378
- async getTimeZones() {
379
- try {
380
- return await firstValueFrom(this.http.get(`${this.baseUrl}/timezones`).pipe(catchError(() => of(this.fallbackTimeZones))));
438
+ logout() {
439
+ this.oauthService.logOut({
440
+ noRedirectToLogoutUrl: true,
441
+ });
442
+ }
443
+ handleError(error) {
444
+ if (error?.reason) {
445
+ throw new Error(JSON.stringify(error.reason));
381
446
  }
382
- catch {
383
- return this.fallbackTimeZones;
447
+ else if (error?.message) {
448
+ throw new Error(error.message);
449
+ }
450
+ else {
451
+ throw new Error('Network or server error occurred');
384
452
  }
385
453
  }
454
+ //#region getter
455
+ get name() {
456
+ return 'user-pass';
457
+ }
458
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
459
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcStrategy }); }
460
+ }
461
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcStrategy, decorators: [{
462
+ type: Injectable
463
+ }] });
464
+
465
+ class AXMOidcPermissionLoader {
466
+ constructor(http) {
467
+ this.http = http;
468
+ this.configs = inject(AXP_ROOT_CONFIG_TOKEN);
469
+ this.apiGetConfig = `${this.configs.baseUrl}/abp/application-configuration`;
470
+ }
471
+ getList(context) {
472
+ return this.http.get(this.apiGetConfig).pipe(map((response) => this.mapTo(response)));
473
+ // if (context.user == null)
474
+ // return of([]);
475
+ // else if (context.user.name.toLowerCase() == 'admin')
476
+ // return of(['axp.admin.console', 'asc.admin.message', 'asc.admin.settings', 'asc.admin.gliding', 'asc.user.gliding']);
477
+ // else
478
+ // return of(['asc.user.gliding']);
479
+ // return of(['axp.admin.console', 'asc.admin.message', 'asc.admin.settings', 'asc.admin.gliding', 'asc.user.gliding']);
480
+ }
481
+ mapTo(jsonObj) {
482
+ const policies = jsonObj.auth.grantedPolicies;
483
+ const truePolicies = Object.keys(policies).filter((key) => policies[key] === true);
484
+ return truePolicies;
485
+ }
486
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcPermissionLoader, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
487
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcPermissionLoader }); }
488
+ }
489
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcPermissionLoader, decorators: [{
490
+ type: Injectable
491
+ }], ctorParameters: () => [{ type: i1.HttpClient }] });
492
+
493
+ class AXMOidcTenantLoader {
494
+ constructor(http) {
495
+ this.http = http;
496
+ this.configs = inject(AXP_ROOT_CONFIG_TOKEN);
497
+ this.apiGetTenants = `${this.configs.baseUrl}/tenants/available-for-user`;
498
+ }
499
+ getList() {
500
+ return this.http.get(this.apiGetTenants).pipe(map((response) => response.items.map((item) => {
501
+ return this.mapToAXPTenant(item);
502
+ })));
503
+ }
504
+ async set(tenant) {
505
+ return Promise.resolve();
506
+ }
507
+ mapToAXPTenant(item) {
508
+ return {
509
+ id: item.id,
510
+ name: item.name || 'defaultName',
511
+ title: item.title || 'defaultTitle',
512
+ // Add other fields and defaults as needed, and handle the logo if applicable
513
+ };
514
+ }
515
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcTenantLoader, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
516
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcTenantLoader }); }
386
517
  }
518
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcTenantLoader, decorators: [{
519
+ type: Injectable
520
+ }], ctorParameters: () => [{ type: i1.HttpClient }] });
387
521
 
388
522
  class AXCFileStorageApiService extends AXPFileStorageService {
389
523
  constructor() {
@@ -524,691 +658,252 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
524
658
  type: Injectable
525
659
  }] });
526
660
 
527
- class AXMOidcApplicationLoader {
528
- constructor(http) {
529
- this.http = http;
530
- this.configs = inject(AXP_ROOT_CONFIG_TOKEN);
531
- this.apiGetApps = `${this.configs.baseUrl}/applications/applications-for-current-tenant`;
532
- this.apiSetApp = `${this.configs.baseUrl}/SetApplication`;
533
- }
534
- getList() {
535
- return this.http.get(this.apiGetApps).pipe(map((response) => {
536
- return response.items.map((item) => this.mapToAXPApplication(item));
537
- }));
538
- }
539
- set(application) {
540
- return Promise.resolve();
541
- }
542
- // //TODO: shoud be removed
543
- // set(application: AXPApplication): Observable<AXPRefreshTokenResult> {
544
- // return this.http.post<any>(this.apiSetApp, { applicationId: application.id }).pipe(
545
- // map((response) => {
546
- // return {
547
- // succeed: true,
548
- // data: {
549
- // accessToken: response.token,
550
- // refreshToken: response.token,
551
- // }
552
- // };
553
- // })
554
- // );
555
- // }
556
- mapToAXPApplication(item) {
557
- return {
558
- id: item.id,
559
- name: item.name || 'defaultName',
560
- title: item.title || 'defaultTitle',
561
- version: item.version || '1.0.0',
562
- description: item.description,
563
- logo: item.logo, // Assuming logo is of type AXPLogoConfig or undefined
564
- editionName: item.editionName,
565
- // features: item.features || [],
566
- };
567
- }
568
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcApplicationLoader, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
569
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcApplicationLoader }); }
570
- }
571
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcApplicationLoader, decorators: [{
572
- type: Injectable
573
- }], ctorParameters: () => [{ type: i1.HttpClient }] });
574
-
575
- class AXMConfigurationService {
576
- constructor(http) {
577
- this.http = http;
578
- this.configs = inject(AXP_ROOT_CONFIG_TOKEN);
579
- this.applicationConfig = null;
580
- this.apiGetConfig = `${this.configs.baseUrl}/abp/application-configuration`;
581
- this.fetchInProgress = false;
582
- this.configSubject = new BehaviorSubject(null);
583
- this.init().subscribe(); // Automatically trigger configuration load on service instantiation
584
- }
585
- init() {
586
- if (!this.fetchInProgress) {
587
- this.fetchInProgress = true;
588
- return this.http.get(this.apiGetConfig).pipe(tap((response) => {
589
- this.applicationConfig = response;
590
- this.configSubject.next(this.applicationConfig);
591
- this.fetchInProgress = false;
592
- }));
593
- }
594
- else {
595
- // Adjusted approach to handle TypeScript's type safety requirements
596
- return this.configSubject.asObservable().pipe(filter((config) => config !== null), take(1) // Ensures it completes after emitting the first non-null value
597
- );
598
- }
599
- }
600
- getConfig() {
601
- if (this.applicationConfig) {
602
- // If the config is already loaded, return it immediately
603
- return of(this.applicationConfig);
604
- }
605
- else {
606
- // If the config is not loaded, initiate loading
607
- return this.configSubject.asObservable().pipe(filter((config) => config !== null), take(1), // Ensure it only emits the first non-null value and completes
608
- switchMap(() => of(this.applicationConfig)));
609
- }
610
- }
611
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMConfigurationService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
612
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMConfigurationService, providedIn: 'root' }); }
613
- }
614
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMConfigurationService, decorators: [{
615
- type: Injectable,
616
- args: [{
617
- providedIn: 'root',
618
- }]
619
- }], ctorParameters: () => [{ type: i1.HttpClient }] });
620
-
621
- class AXMOidcFeatureLoader {
661
+ class AXCRegionalApiService extends AXPRegionalService {
622
662
  constructor() {
623
- this.list = [
663
+ super(...arguments);
664
+ this.http = inject(HttpClient);
665
+ this.languageService = inject(AXTranslationService);
666
+ //#region ---- API Endpoints ----
667
+ this.baseUrl = '/api/regional';
668
+ //#endregion
669
+ //#region ---- Fallback Data ----
670
+ this.fallbackCountries = [
624
671
  {
625
- name: 'axp-entity-list-custom-view',
626
- title: 'Custom View',
627
- value: false
672
+ code: 'US',
673
+ title: 'United States',
674
+ native: 'United States',
675
+ regional: 'en',
676
+ timezone: 'America/New_York'
628
677
  },
629
678
  {
630
- name: 'axp-entity-list-quick-search',
631
- title: 'Custom View',
632
- value: false
679
+ code: 'CA',
680
+ title: 'Canada',
681
+ native: 'Canada',
682
+ regional: 'en',
683
+ timezone: 'America/Toronto'
684
+ },
685
+ {
686
+ code: 'GB',
687
+ title: 'United Kingdom',
688
+ native: 'United Kingdom',
689
+ regional: 'en',
690
+ timezone: 'Europe/London'
633
691
  }
634
692
  ];
635
- }
636
- getList() {
637
- return of(this.list).pipe(delay(0));
638
- }
639
- }
640
-
641
- class AXCAPIOidcStrategy extends AXPAuthStrategy {
642
- constructor() {
643
- super(...arguments);
644
- this.aXMAuthConfigs = inject(AXM_AUTH_CONFIG_TOKEN);
645
- this.oauthService = inject(OAuthService);
646
- this.http = inject(HttpClient);
647
- this.sessionService = inject(AXPSessionService);
648
- }
649
- async configureOAuth() {
650
- if (this.openidConfigurationInfo)
651
- return;
652
- if (!this.authConfig) {
653
- if (!this.aXMAuthConfigs.authConfig) {
654
- throw new Error('authConfig is missing');
693
+ this.fallbackProvinces = [
694
+ {
695
+ code: 'CA',
696
+ title: 'California',
697
+ native: 'California',
698
+ timezone: 'America/Los_Angeles'
699
+ },
700
+ {
701
+ code: 'NY',
702
+ title: 'New York',
703
+ native: 'New York',
704
+ timezone: 'America/New_York'
705
+ },
706
+ {
707
+ code: 'ON',
708
+ title: 'Ontario',
709
+ native: 'Ontario',
710
+ timezone: 'America/Toronto'
655
711
  }
656
- this.authConfig = this.aXMAuthConfigs.authConfig;
657
- }
658
- this.oauthService.configure(this.authConfig);
659
- this.oauthService.setStorage(localStorage);
660
- this.openidConfigurationInfo = await this.oauthService.loadDiscoveryDocument();
661
- if (!this.openidConfigurationInfo) {
662
- throw new Error('openidConfigurationInfo is missing');
663
- }
664
- this.oauthService.events.subscribe(async (event) => {
665
- // console.log('event', event);
666
- // if (event.type === 'token_received') {
667
- // console.log('Token has been refreshed');
668
- // }
669
- // if (event.type === 'token_expires') {
670
- // console.log('Token is about to expire. Triggering silent refresh...');
671
- // }
672
- });
673
- const oidcJson = localStorage.getItem(AXPSessionService.SESSION_KEY);
674
- if (oidcJson) {
675
- const authData = JSON.parse(oidcJson);
676
- if (authData) {
677
- this.sessionService.setSession(authData);
678
- if (authData.expiresIn && new Date(authData.expiresIn) < new Date()) {
679
- if (authData.expiresIn) {
680
- this.sessionService.refreshToken();
681
- }
682
- else {
683
- this.signout();
684
- }
685
- }
712
+ ];
713
+ this.fallbackCities = [
714
+ {
715
+ code: 'NYC',
716
+ title: 'New York City',
717
+ native: 'New York City',
718
+ timezone: 'America/New_York'
719
+ },
720
+ {
721
+ code: 'LA',
722
+ title: 'Los Angeles',
723
+ native: 'Los Angeles',
724
+ timezone: 'America/Los_Angeles'
725
+ },
726
+ {
727
+ code: 'TOR',
728
+ title: 'Toronto',
729
+ native: 'Toronto',
730
+ timezone: 'America/Toronto'
686
731
  }
687
- }
732
+ ];
733
+ this.fallbackCurrencies = [
734
+ {
735
+ code: 'USD',
736
+ title: 'United States Dollar',
737
+ symbol: '$',
738
+ format: '${amount}'
739
+ },
740
+ {
741
+ code: 'CAD',
742
+ title: 'Canadian Dollar',
743
+ symbol: 'CA$',
744
+ format: 'CA${amount}'
745
+ },
746
+ {
747
+ code: 'GBP',
748
+ title: 'British Pound',
749
+ symbol: '£',
750
+ format: '£{amount}'
751
+ }
752
+ ];
753
+ this.fallbackLocaleProfiles = [
754
+ {
755
+ ...AXUSLocaleProfile,
756
+ code: 'en-US',
757
+ title: 'English (United States)',
758
+ nativeTitle: 'English (United States)',
759
+ },
760
+ {
761
+ ...AXIRLocaleProfile,
762
+ code: 'fa-IR',
763
+ title: 'Persian (Iran)',
764
+ nativeTitle: 'فارسی (ایران)',
765
+ }
766
+ ];
767
+ this.fallbackLanguages = [
768
+ {
769
+ code: 'en',
770
+ title: 'English'
771
+ },
772
+ {
773
+ code: 'fa',
774
+ title: 'Persian'
775
+ },
776
+ {
777
+ code: 'es',
778
+ title: 'Spanish'
779
+ }
780
+ ];
781
+ this.fallbackTimeZones = [
782
+ {
783
+ code: 'America/New_York',
784
+ title: 'Eastern Time (US & Canada)',
785
+ offset: '-05:00',
786
+ iana: 'America/New_York',
787
+ abbr: 'EST'
788
+ },
789
+ {
790
+ code: 'America/Los_Angeles',
791
+ title: 'Pacific Time (US & Canada)',
792
+ offset: '-08:00',
793
+ iana: 'America/Los_Angeles',
794
+ abbr: 'PST'
795
+ },
796
+ {
797
+ code: 'Europe/London',
798
+ title: 'Greenwich Mean Time',
799
+ offset: '+00:00',
800
+ iana: 'Europe/London',
801
+ abbr: 'GMT'
802
+ }
803
+ ];
688
804
  }
689
- async signin(credentials) {
690
- // If OIDC with username/password
691
- if (credentials.strategy === 'oidc' && credentials.username && credentials.password) {
692
- return this.handleOidcPasswordSignin(credentials);
693
- }
694
- // If OIDC with idToken/accessToken (OAuth callback)
695
- if (credentials.strategy === 'oidc' && credentials['idToken'] && credentials['accessToken']) {
696
- const payload = JwtUtil.parseJwt(credentials['idToken']);
697
- const user = {
698
- id: payload['sub'] || payload['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier'] || '',
699
- title: payload['name'] || payload['email'] || '',
700
- name: payload['name'] || payload['email'] || '',
701
- avatar: payload['picture'] || '',
702
- };
703
- const tenant = payload['tenantid'] || payload['tenant']
704
- ? {
705
- id: payload['tenantid'] || payload['tenant'] || '',
706
- name: payload['tenantname'] || 'test',
707
- title: payload['tenanttitle'] || '',
805
+ //#endregion
806
+ async getCountries() {
807
+ const lang = await firstValueFrom(this.languageService.langChanges$);
808
+ try {
809
+ const countries = await firstValueFrom(this.http.get(`${this.baseUrl}/countries`).pipe(catchError(() => of(this.fallbackCountries))));
810
+ return countries.map((country) => {
811
+ if (lang == country.regional) {
812
+ return {
813
+ ...country,
814
+ title: country.native,
815
+ };
708
816
  }
709
- : undefined;
710
- const application = payload['applicationid'] || payload['application']
711
- ? {
712
- id: payload['applicationid'] || payload['application'] || '',
713
- name: payload['applicationname'] || '',
714
- title: payload['applicationtitle'] || '',
817
+ else {
818
+ return country;
715
819
  }
716
- : undefined;
717
- return {
718
- succeed: true,
719
- data: {
720
- accessToken: credentials['accessToken'],
721
- refreshToken: credentials['refreshToken'],
722
- idToken: credentials['idToken'],
723
- user,
724
- tenant,
725
- application,
726
- },
727
- };
820
+ });
728
821
  }
729
- throw new Error(`Unsupported authentication strategy or credentials: ${credentials.strategy}`);
730
- }
731
- /**
732
- * Handles OIDC password-based authentication
733
- */
734
- async handleOidcPasswordSignin(credentials) {
735
- await this.configureOAuth();
736
- const loginRes = await fetch(this.authConfig.issuer + '/api/auth/manual-login', {
737
- method: 'POST',
738
- headers: { 'Content-Type': 'application/json' },
739
- body: JSON.stringify({ username: credentials.username, password: credentials.password }),
740
- credentials: 'include',
741
- });
742
- if (!loginRes.ok) {
743
- let errorText = 'Login failed';
744
- try {
745
- const errorJson = await loginRes.json();
746
- if (errorJson && errorJson.error && errorJson.error.description) {
747
- errorText = errorJson.error.description;
822
+ catch {
823
+ return this.fallbackCountries.map((country) => {
824
+ if (lang == country.regional) {
825
+ return {
826
+ ...country,
827
+ title: country.native,
828
+ };
748
829
  }
749
- }
750
- catch {
751
- try {
752
- const text = await loginRes.text();
753
- if (text) {
754
- errorText = text;
755
- }
830
+ else {
831
+ return country;
756
832
  }
757
- catch { }
758
- }
759
- throw new Error(errorText);
833
+ });
760
834
  }
761
- // Redirect to authorization endpoint (this will reload the page)
762
- await this.startAuthorizationFlow('', '');
763
- // Return a Promise that never resolves, so the sessionService/component does not proceed
764
- return new Promise(() => { });
765
835
  }
766
- // private async handleOidcPasswordSignin(credentials: AXPUserPassCredentials): Promise<AXPSignInResult> {
767
- // await this.configureOAuth();
768
- // try {
769
- // const body = new HttpParams()
770
- // .set('grant_type', 'password')
771
- // .set('client_id', this.authConfig.clientId!)
772
- // .set('username', credentials.username)
773
- // .set('password', credentials.password)
774
- // .set('scope', this.authConfig.scope!);
775
- // const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
776
- // const response = await firstValueFrom(
777
- // this.http.post<IAuthenticationDataModel>(
778
- // this.openidConfigurationInfo.info.discoveryDocument.token_endpoint,
779
- // body.toString(),
780
- // { headers },
781
- // ),
782
- // );
783
- // // Parse id_token to extract user, tenant, and application info
784
- // const payload = JwtUtil.parseJwt(response.id_token);
785
- // const user = {
786
- // id: payload['sub'] || payload['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier'] || '',
787
- // title: payload['name'] || payload['email'] || '',
788
- // name: payload['name'] || payload['email'] || '',
789
- // avatar: payload['picture'] || '',
790
- // } as AXPUser;
791
- // const tenant =
792
- // payload['tenantid'] || payload['tenant']
793
- // ? {
794
- // id: payload['tenantid'] || payload['tenant'] || '',
795
- // name: payload['tenantname'] || '',
796
- // title: payload['tenanttitle'] || '',
797
- // }
798
- // : undefined;
799
- // const application =
800
- // payload['applicationid'] || payload['application']
801
- // ? {
802
- // id: payload['applicationid'] || payload['application'] || '',
803
- // name: payload['applicationname'] || '',
804
- // title: payload['applicationtitle'] || '',
805
- // }
806
- // : undefined;
807
- // return {
808
- // succeed: true,
809
- // data: {
810
- // accessToken: response.access_token,
811
- // expiresIn: this.calculateExpireInDate(response.expires_in ?? 0),
812
- // idToken: response.id_token,
813
- // refreshToken: response.refresh_token!,
814
- // user,
815
- // tenant,
816
- // application,
817
- // },
818
- // };
819
- // } catch (error: any) {
820
- // this.handleError(error);
821
- // }
822
- // }
823
- async signout() {
824
- localStorage.removeItem('pkce_code_verifier');
825
- localStorage.removeItem('oauth_provider');
826
- const logoutUrl = `${this.aXMAuthConfigs?.authConfig?.issuer}/api/auth/logout`;
827
- await firstValueFrom(this.http.post(logoutUrl, {}, { withCredentials: true }));
828
- }
829
- async refreshToken(context) {
836
+ async getProvinces(countryId) {
837
+ let params = new HttpParams();
838
+ if (countryId) {
839
+ params = params.set('countryId', countryId);
840
+ }
830
841
  try {
831
- await this.configureOAuth();
832
- if (!this.authConfig || !this.authConfig.clientId) {
833
- throw new Error('authConfig or clientId is missing');
834
- }
835
- const authData = this.loadAuthData();
836
- if (!authData) {
837
- return { succeed: false };
838
- }
839
- const refreshToken = authData.refreshToken;
840
- if (!refreshToken) {
841
- return { succeed: false };
842
- }
843
- const body = new HttpParams()
844
- .set('grant_type', 'refresh_token')
845
- .set('client_id', this.authConfig.clientId)
846
- .set('refresh_token', refreshToken);
847
- const headers = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
848
- const response = await firstValueFrom(this.http.post(this.openidConfigurationInfo.info.discoveryDocument.token_endpoint, body.toString(), { headers }));
849
- // Extract user, tenant, and application from id_token
850
- const payload = JwtUtil.parseJwt(response.id_token);
851
- const user = {
852
- id: payload['sub'] || payload['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier'] || '',
853
- title: payload['name'] || payload['email'] || '',
854
- name: payload['name'] || payload['email'] || '',
855
- avatar: payload['picture'] || '',
856
- };
857
- const tenant = payload['tenantid'] || payload['tenant']
858
- ? {
859
- id: payload['tenantid'] || payload['tenant'] || '',
860
- name: payload['tenantname'] || '',
861
- title: payload['tenanttitle'] || '',
862
- }
863
- : undefined;
864
- const application = payload['applicationid'] || payload['application']
865
- ? {
866
- id: payload['applicationid'] || payload['application'] || '',
867
- name: payload['applicationname'] || '',
868
- title: payload['applicationtitle'] || '',
869
- }
870
- : undefined;
871
- const sessionData = {
872
- accessToken: response.access_token,
873
- refreshToken: response.refresh_token,
874
- idToken: response.id_token,
875
- strategy: 'oidc',
876
- expiresIn: this.calculateExpireInDate(response.expires_in ?? 0),
877
- user,
878
- tenant,
879
- application,
880
- };
881
- // this.setServiceProps(sessionData);
882
- return {
883
- succeed: true,
884
- data: sessionData,
885
- };
842
+ return await firstValueFrom(this.http.get(`${this.baseUrl}/provinces`, { params }).pipe(catchError(() => of(this.fallbackProvinces))));
886
843
  }
887
- catch (error) {
888
- console.error('Error refreshing token', error);
889
- return { succeed: false };
844
+ catch {
845
+ return this.fallbackProvinces;
890
846
  }
891
847
  }
892
- /**
893
- * Starts the OIDC authorization code flow, redirecting to the authorize endpoint with tenant_id and application_id as query params.
894
- */
895
- async startAuthorizationFlow(tenantId, applicationId) {
896
- if (!this.openidConfigurationInfo) {
897
- await this.configureOAuth();
848
+ async getCities(filter) {
849
+ let params = new HttpParams();
850
+ if (filter?.countryId) {
851
+ params = params.set('countryId', filter.countryId);
898
852
  }
899
- // فقط اینجا مقداردهی شود:
900
- const codeVerifier = this.generateRandomString(128);
901
- localStorage.setItem('pkce_code_verifier', codeVerifier);
902
- const codeChallenge = await this.generateCodeChallenge(codeVerifier);
903
- const authorizeEndpoint = this.openidConfigurationInfo.info.discoveryDocument.authorization_endpoint;
904
- const clientId = this.authConfig.clientId;
905
- const redirectUri = this.authConfig.redirectUri;
906
- const scope = this.authConfig.scope;
907
- const responseType = 'code';
908
- const state = Math.random().toString(36).substring(2);
909
- const url = `${authorizeEndpoint}?response_type=${encodeURIComponent(responseType)}&client_id=${encodeURIComponent(clientId)}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${encodeURIComponent(scope)}&state=${encodeURIComponent(state)}&tenant_id=${encodeURIComponent(tenantId)}&application_id=${encodeURIComponent(applicationId)}&code_challenge=${encodeURIComponent(codeChallenge)}&code_challenge_method=S256`;
910
- window.location.href = url;
911
- }
912
- /**
913
- * Unified method to complete the authorization code flow.
914
- */
915
- async completeAuthorizationCodeFlow(options) {
916
- // Ensure OAuth is configured first
917
- if (!this.openidConfigurationInfo) {
918
- await this.configureOAuth();
853
+ if (filter?.provinceId) {
854
+ params = params.set('provinceId', filter.provinceId);
919
855
  }
920
- const codeVerifier = localStorage.getItem('pkce_code_verifier');
921
- localStorage.removeItem('pkce_code_verifier');
922
- if (!codeVerifier) {
923
- throw new Error('Code verifier not found. Please try signing in again.');
856
+ try {
857
+ return await firstValueFrom(this.http.get(`${this.baseUrl}/cities`, { params }).pipe(catchError(() => of(this.fallbackCities))));
924
858
  }
925
- // Removed provider logic
926
- const tokenEndpoint = options.tokenEndpoint ||
927
- this.openidConfigurationInfo?.info?.discoveryDocument?.token_endpoint ||
928
- `${this.aXMAuthConfigs?.authConfig?.issuer}/connect/token`;
929
- const clientId = options.clientId || this.authConfig?.clientId || this.aXMAuthConfigs?.authConfig?.clientId || 'spa-client';
930
- // Use the passed redirectUri parameter
931
- const redirectUri = options.redirectUri;
932
- const body = new URLSearchParams({
933
- grant_type: 'authorization_code',
934
- client_id: clientId,
935
- code_verifier: codeVerifier,
936
- code: options.code,
937
- redirect_uri: redirectUri,
938
- });
939
- const response = await fetch(tokenEndpoint, {
940
- method: 'POST',
941
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
942
- body: body.toString(),
943
- });
944
- if (!response.ok) {
945
- throw new Error(`Token exchange failed: ${response.status} ${response.statusText}`);
859
+ catch {
860
+ return this.fallbackCities;
946
861
  }
947
- const tokenData = await response.json();
948
- const credentials = {
949
- strategy: 'oidc',
950
- accessToken: tokenData.access_token,
951
- refreshToken: tokenData.refresh_token,
952
- idToken: tokenData.id_token,
953
- // Optionally, you can add user info if your signin supports it
954
- };
955
- await this.sessionService.signin(credentials);
956
- }
957
- // Helper methods:
958
- generateRandomString(length) {
959
- const array = new Uint8Array(length);
960
- crypto.getRandomValues(array);
961
- return this.base64UrlEncode(array);
962
- }
963
- async generateCodeChallenge(codeVerifier) {
964
- const encoder = new TextEncoder();
965
- const data = encoder.encode(codeVerifier);
966
- const digest = await crypto.subtle.digest('SHA-256', data);
967
- return this.base64UrlEncode(new Uint8Array(digest));
968
- }
969
- base64UrlEncode(array) {
970
- return btoa(String.fromCharCode(...array))
971
- .replace(/\+/g, '-')
972
- .replace(/\//g, '_')
973
- .replace(/=/g, '');
974
- }
975
- expires_in_milisecound(expires_in_date) {
976
- return new Date(expires_in_date).getTime() - new Date().getTime();
977
- }
978
- loadAuthData() {
979
- const sessionData = this.sessionService.getSessionData();
980
- return sessionData || undefined;
981
- }
982
- async loadUserInfo() {
983
- return this.oauthService.loadUserProfile();
984
- }
985
- calculateExpireInDate(expireInMilisecound) {
986
- return new Date(Date.now() + expireInMilisecound * 1000).toISOString();
987
- }
988
- // private logout(): void {
989
- // // this.oauthService.logOut();
990
- // // Use the public signout method instead of private clearSession
991
- // this.sessionService.signout();
992
- // }
993
- handleError(error) {
994
- console.error('Authentication error:', error);
995
- throw error;
996
862
  }
997
- //#region getter
998
- get name() {
999
- return 'oidc';
1000
- }
1001
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXCAPIOidcStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
1002
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXCAPIOidcStrategy }); }
1003
- }
1004
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXCAPIOidcStrategy, decorators: [{
1005
- type: Injectable
1006
- }] });
1007
- class JwtUtil {
1008
- /**
1009
- * Decodes a JWT token and returns its payload as an object.
1010
- * @param token JWT string
1011
- */
1012
- static parseJwt(token) {
863
+ async getCurrencies() {
1013
864
  try {
1014
- return JSON.parse(atob(token.split('.')[1]));
865
+ return await firstValueFrom(this.http.get(`${this.baseUrl}/currencies`).pipe(catchError(() => of(this.fallbackCurrencies))));
1015
866
  }
1016
- catch (e) {
1017
- return null;
867
+ catch {
868
+ return this.fallbackCurrencies;
1018
869
  }
1019
870
  }
1020
- static createJwt(payload) {
1021
- // Create a proper JWT token with header, payload, and signature
1022
- const header = {
1023
- alg: 'HS256',
1024
- typ: 'JWT'
1025
- };
1026
- const headerEncoded = JwtUtil.base64url(header);
1027
- const payloadEncoded = JwtUtil.base64url(payload);
1028
- const signature = 'mock-signature-for-testing'; // Mock signature
1029
- const signatureEncoded = JwtUtil.base64url(signature);
1030
- const idToken = `${headerEncoded}.${payloadEncoded}.${signatureEncoded}`;
1031
- return idToken;
1032
- }
1033
- // For mock, just JSON stringify as the idToken
1034
- // Convert idTokenPayload to a JWT-like string (header.payload.signature) so jwtutil can parse it
1035
- // Use base64url encoding for header and payload, and a dummy signature
1036
- static base64url(obj) {
1037
- const json = JSON.stringify(obj);
1038
- // Encode to UTF-8 bytes
1039
- let utf8 = [];
1040
- for (let i = 0; i < json.length; i++) {
1041
- const charcode = json.charCodeAt(i);
1042
- if (charcode < 0x80)
1043
- utf8.push(charcode);
1044
- else if (charcode < 0x800) {
1045
- utf8.push(0xc0 | (charcode >> 6));
1046
- utf8.push(0x80 | (charcode & 0x3f));
1047
- }
1048
- else if (charcode < 0xd800 || charcode >= 0xe000) {
1049
- utf8.push(0xe0 | (charcode >> 12));
1050
- utf8.push(0x80 | ((charcode >> 6) & 0x3f));
1051
- utf8.push(0x80 | (charcode & 0x3f));
1052
- }
1053
- else {
1054
- // surrogate pair
1055
- i++;
1056
- // UTF-16 encodes 0x10000-0x10FFFF by subtracting 0x10000 and
1057
- // splitting the 20 bits of 0x0-0xFFFFF into two halves
1058
- const surrogatePair = 0x10000 + (((charcode & 0x3ff) << 10) | (json.charCodeAt(i) & 0x3ff));
1059
- utf8.push(0xf0 | (surrogatePair >> 18));
1060
- utf8.push(0x80 | ((surrogatePair >> 12) & 0x3f));
1061
- utf8.push(0x80 | ((surrogatePair >> 6) & 0x3f));
1062
- utf8.push(0x80 | (surrogatePair & 0x3f));
1063
- }
1064
- }
1065
- // Manual base64 encoding (no Buffer, no btoa)
1066
- const base64abc = [
1067
- 'A',
1068
- 'B',
1069
- 'C',
1070
- 'D',
1071
- 'E',
1072
- 'F',
1073
- 'G',
1074
- 'H',
1075
- 'I',
1076
- 'J',
1077
- 'K',
1078
- 'L',
1079
- 'M',
1080
- 'N',
1081
- 'O',
1082
- 'P',
1083
- 'Q',
1084
- 'R',
1085
- 'S',
1086
- 'T',
1087
- 'U',
1088
- 'V',
1089
- 'W',
1090
- 'X',
1091
- 'Y',
1092
- 'Z',
1093
- 'a',
1094
- 'b',
1095
- 'c',
1096
- 'd',
1097
- 'e',
1098
- 'f',
1099
- 'g',
1100
- 'h',
1101
- 'i',
1102
- 'j',
1103
- 'k',
1104
- 'l',
1105
- 'm',
1106
- 'n',
1107
- 'o',
1108
- 'p',
1109
- 'q',
1110
- 'r',
1111
- 's',
1112
- 't',
1113
- 'u',
1114
- 'v',
1115
- 'w',
1116
- 'x',
1117
- 'y',
1118
- 'z',
1119
- '0',
1120
- '1',
1121
- '2',
1122
- '3',
1123
- '4',
1124
- '5',
1125
- '6',
1126
- '7',
1127
- '8',
1128
- '9',
1129
- '+',
1130
- '/',
1131
- ];
1132
- let result = '', i;
1133
- for (i = 0; i + 2 < utf8.length; i += 3) {
1134
- result += base64abc[utf8[i] >> 2];
1135
- result += base64abc[((utf8[i] & 0x03) << 4) | (utf8[i + 1] >> 4)];
1136
- result += base64abc[((utf8[i + 1] & 0x0f) << 2) | (utf8[i + 2] >> 6)];
1137
- result += base64abc[utf8[i + 2] & 0x3f];
871
+ async getLocaleProfiles() {
872
+ try {
873
+ return await firstValueFrom(this.http.get(`${this.baseUrl}/locale-profiles`).pipe(catchError(() => of(this.fallbackLocaleProfiles))));
1138
874
  }
1139
- if (i < utf8.length) {
1140
- result += base64abc[utf8[i] >> 2];
1141
- if (i === utf8.length - 1) {
1142
- result += base64abc[(utf8[i] & 0x03) << 4];
1143
- // result += '==';
1144
- }
1145
- else {
1146
- result += base64abc[((utf8[i] & 0x03) << 4) | (utf8[i + 1] >> 4)];
1147
- result += base64abc[(utf8[i + 1] & 0x0f) << 2];
1148
- // result += '=';
1149
- }
875
+ catch {
876
+ return this.fallbackLocaleProfiles;
1150
877
  }
1151
- // base64url encoding: replace + with -, / with _, remove =
1152
- return result.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
1153
- }
1154
- }
1155
-
1156
- class AXMOidcPermissionLoader {
1157
- constructor(http) {
1158
- this.http = http;
1159
- this.configs = inject(AXP_ROOT_CONFIG_TOKEN);
1160
- this.apiGetConfig = `${this.configs.baseUrl}/abp/application-configuration`;
1161
- }
1162
- getList(context) {
1163
- return this.http.get(this.apiGetConfig).pipe(map((response) => this.mapTo(response)));
1164
- // if (context.user == null)
1165
- // return of([]);
1166
- // else if (context.user.name.toLowerCase() == 'admin')
1167
- // return of(['axp.admin.console', 'asc.admin.message', 'asc.admin.settings', 'asc.admin.gliding', 'asc.user.gliding']);
1168
- // else
1169
- // return of(['asc.user.gliding']);
1170
- // return of(['axp.admin.console', 'asc.admin.message', 'asc.admin.settings', 'asc.admin.gliding', 'asc.user.gliding']);
1171
- }
1172
- mapTo(jsonObj) {
1173
- const policies = jsonObj.auth.grantedPolicies;
1174
- const truePolicies = Object.keys(policies).filter((key) => policies[key] === true);
1175
- return truePolicies;
1176
878
  }
1177
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcPermissionLoader, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
1178
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcPermissionLoader }); }
1179
- }
1180
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcPermissionLoader, decorators: [{
1181
- type: Injectable
1182
- }], ctorParameters: () => [{ type: i1.HttpClient }] });
1183
-
1184
- class AXMOidcTenantLoader {
1185
- constructor(http) {
1186
- this.http = http;
1187
- this.configs = inject(AXP_ROOT_CONFIG_TOKEN);
1188
- this.apiGetTenants = `${this.configs.baseUrl}/tenants/available-for-user`;
879
+ async getLanguages() {
880
+ try {
881
+ return await firstValueFrom(this.http.get(`${this.baseUrl}/languages`).pipe(catchError(() => of(this.fallbackLanguages))));
882
+ }
883
+ catch {
884
+ return this.fallbackLanguages;
885
+ }
1189
886
  }
1190
- getList() {
1191
- return this.http.get(this.apiGetTenants).pipe(map((response) => response.items.map((item) => {
1192
- return this.mapToAXPTenant(item);
1193
- })));
887
+ async getAvailableLanguages() {
888
+ try {
889
+ return await firstValueFrom(this.http.get(`${this.baseUrl}/available-languages`).pipe(catchError(() => of(this.fallbackLanguages))));
890
+ }
891
+ catch {
892
+ return this.fallbackLanguages;
893
+ }
1194
894
  }
1195
- async set(tenant) {
1196
- return Promise.resolve();
895
+ async getBrowserTimeZoneCode() {
896
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
1197
897
  }
1198
- mapToAXPTenant(item) {
1199
- return {
1200
- id: item.id,
1201
- name: item.name || 'defaultName',
1202
- title: item.title || 'defaultTitle',
1203
- // Add other fields and defaults as needed, and handle the logo if applicable
1204
- };
898
+ async getTimeZones() {
899
+ try {
900
+ return await firstValueFrom(this.http.get(`${this.baseUrl}/timezones`).pipe(catchError(() => of(this.fallbackTimeZones))));
901
+ }
902
+ catch {
903
+ return this.fallbackTimeZones;
904
+ }
1205
905
  }
1206
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcTenantLoader, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
1207
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcTenantLoader }); }
1208
906
  }
1209
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMOidcTenantLoader, decorators: [{
1210
- type: Injectable
1211
- }], ctorParameters: () => [{ type: i1.HttpClient }] });
1212
907
 
1213
908
  class AXCApiModule {
1214
909
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXCApiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
@@ -1226,10 +921,10 @@ class AXCApiModule {
1226
921
  provide: AXPFileStorageService,
1227
922
  useClass: AXCFileStorageApiService,
1228
923
  },
1229
- {
1230
- provide: AXP_TENANT_LOADER,
1231
- useClass: AXMOidcTenantLoader,
1232
- },
924
+ // {
925
+ // provide: AXP_TENANT_LOADER,
926
+ // useClass: AXMOidcTenantLoader,
927
+ // },
1233
928
  {
1234
929
  provide: AXP_APPLICATION_LOADER,
1235
930
  useClass: AXMOidcApplicationLoader,
@@ -1251,7 +946,7 @@ class AXCApiModule {
1251
946
  },
1252
947
  ], imports: [OAuthModule.forRoot(),
1253
948
  AXPAuthModule.forRoot({
1254
- strategies: [AXCAPIOidcStrategy],
949
+ strategies: [],
1255
950
  })] }); }
1256
951
  }
1257
952
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXCApiModule, decorators: [{
@@ -1260,7 +955,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
1260
955
  imports: [
1261
956
  OAuthModule.forRoot(),
1262
957
  AXPAuthModule.forRoot({
1263
- strategies: [AXCAPIOidcStrategy],
958
+ strategies: [],
1264
959
  }),
1265
960
  ],
1266
961
  providers: [
@@ -1276,10 +971,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
1276
971
  provide: AXPFileStorageService,
1277
972
  useClass: AXCFileStorageApiService,
1278
973
  },
1279
- {
1280
- provide: AXP_TENANT_LOADER,
1281
- useClass: AXMOidcTenantLoader,
1282
- },
974
+ // {
975
+ // provide: AXP_TENANT_LOADER,
976
+ // useClass: AXMOidcTenantLoader,
977
+ // },
1283
978
  {
1284
979
  provide: AXP_APPLICATION_LOADER,
1285
980
  useClass: AXMOidcApplicationLoader,
@@ -1307,5 +1002,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
1307
1002
  * Generated bundle index. Do not edit.
1308
1003
  */
1309
1004
 
1310
- export { AXCAPIOidcStrategy, AXCApiEntityStorageService, AXCApiModule, AXMConfigurationService, AXMOidcApplicationLoader, AXMOidcFeatureLoader, AXMOidcPermissionLoader, AXMOidcTenantLoader, JwtUtil };
1005
+ export { AXCApiEntityStorageService, AXCApiModule, AXMConfigurationService, AXMOidcApplicationLoader, AXMOidcFeatureLoader, AXMOidcPermissionLoader, AXMOidcStrategy, AXMOidcTenantLoader };
1311
1006
  //# sourceMappingURL=acorex-connectivity-api.mjs.map