From 0df76b87f3b3b1e6470f64437de43aa27583eb17 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Fri, 29 Sep 2023 16:25:57 +0300 Subject: [PATCH] Add Tenant-not found handler by token --- .../packages/core/src/lib/tokens/index.ts | 3 +- .../lib/tokens/tenant-not-found-by-name.ts | 7 +- .../core/src/lib/utils/multi-tenancy-utils.ts | 64 +++++++++++-------- .../theme-shared/src/lib/providers/index.ts | 1 + .../providers/tenant-not-found.provider.ts | 20 ++++++ .../src/lib/theme-shared.module.ts | 9 +-- 6 files changed, 69 insertions(+), 35 deletions(-) create mode 100644 npm/ng-packs/packages/theme-shared/src/lib/providers/tenant-not-found.provider.ts diff --git a/npm/ng-packs/packages/core/src/lib/tokens/index.ts b/npm/ng-packs/packages/core/src/lib/tokens/index.ts index d01f652b98..12f4aae15a 100644 --- a/npm/ng-packs/packages/core/src/lib/tokens/index.ts +++ b/npm/ng-packs/packages/core/src/lib/tokens/index.ts @@ -12,4 +12,5 @@ export * from './pipe-to-login.token'; export * from './set-token-response-to-storage.token'; export * from './check-authentication-state'; export * from './http-context.token'; -export * from './others-group.token' \ No newline at end of file +export * from './others-group.token'; +export * from './tenant-not-found-by-name'; diff --git a/npm/ng-packs/packages/core/src/lib/tokens/tenant-not-found-by-name.ts b/npm/ng-packs/packages/core/src/lib/tokens/tenant-not-found-by-name.ts index febfaf4e57..639c1a3d1e 100644 --- a/npm/ng-packs/packages/core/src/lib/tokens/tenant-not-found-by-name.ts +++ b/npm/ng-packs/packages/core/src/lib/tokens/tenant-not-found-by-name.ts @@ -1,3 +1,6 @@ -import { InjectionToken } from "@angular/core"; +import { InjectionToken } from '@angular/core'; +import { HttpErrorResponse } from '@angular/common/http'; -export const TENANT_NOT_FOUND_BY_NAME = new InjectionToken('TENANT_NOT_FOUND_BY_NAME'); +export const TENANT_NOT_FOUND_BY_NAME = new InjectionToken< + (HttpErrorResponse: HttpErrorResponse) => void +>('TENANT_NOT_FOUND_BY_NAME'); diff --git a/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts index 338bf72e77..cd1b9fe50e 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts @@ -1,7 +1,5 @@ import { Injector } from '@angular/core'; import clone from 'just-clone'; - -import { tap } from 'rxjs/operators'; import { Environment } from '../models/environment'; import { FindTenantResultDto } from '../proxy/volo/abp/asp-net-core/mvc/multi-tenancy/models'; @@ -9,6 +7,8 @@ import { EnvironmentService } from '../services/environment.service'; import { MultiTenancyService } from '../services/multi-tenancy.service'; import { createTokenParser } from './string-utils'; import { firstValueFrom } from 'rxjs'; +import { TENANT_NOT_FOUND_BY_NAME } from '../tokens/tenant-not-found-by-name'; +import { HttpErrorResponse } from '@angular/common/http'; const tenancyPlaceholder = '{0}'; @@ -25,10 +25,10 @@ function getCurrentTenancyNameFromUrl(tenantKey: string) { return urlParams.get(tenantKey); } - export async function parseTenantFromUrl(injector: Injector) { const environmentService = injector.get(EnvironmentService); const multiTenancyService = injector.get(MultiTenancyService); + const tenantNotFoundHandler = injector.get(TENANT_NOT_FOUND_BY_NAME, null); const baseUrl = environmentService.getEnvironment()?.application?.baseUrl || ''; const tenancyName = getCurrentTenancyName(baseUrl); @@ -51,37 +51,39 @@ export async function parseTenantFromUrl(injector: Injector) { }; if (tenancyName) { - debugger /** * We have to replace tenant name within the urls from environment, * because the code below will make a http request to find information about the domain tenant. * Before this request takes place, we need to replace placeholders aka "{0}". */ replaceTenantNameWithinEnvironment(injector, tenancyName); - - const tenant$ = multiTenancyService - .setTenantByName(tenancyName) - .pipe(tap(setEnvironmentWithDomainTenant)) - try { - const result = await firstValueFrom(tenant$) - return result; - } - catch (error) { - - console.log(error) - debugger - } - } else { - /** - * If there is no tenant, we still have to clean up {0}. from baseUrl to avoid incorrect http requests. - */ - replaceTenantNameWithinEnvironment(injector, '', tenancyPlaceholder + '.'); - const tenantIdFromQueryParams = getCurrentTenancyNameFromUrl(multiTenancyService.tenantKey); - if (tenantIdFromQueryParams) { - return multiTenancyService.setTenantById(tenantIdFromQueryParams).toPromise(); + const tenant$ = multiTenancyService.setTenantByName(tenancyName); + try { + const result = await firstValueFrom(tenant$); + setEnvironmentWithDomainTenant(result); + return Promise.resolve(result); + } catch (httpError: HttpErrorResponse | any) { + if ( + httpError instanceof HttpErrorResponse && + httpError.status === 404 && + tenantNotFoundHandler + ) { + tenantNotFoundHandler(httpError); + } + return Promise.reject(); } } + /** + * If there is no tenant, we still have to clean up {0}. from baseUrl to avoid incorrect http requests. + */ + replaceTenantNameWithinEnvironment(injector, '', tenancyPlaceholder + '.'); + + const tenantIdFromQueryParams = getCurrentTenancyNameFromUrl(multiTenancyService.tenantKey); + if (tenantIdFromQueryParams) { + const tenantById$ = multiTenancyService.setTenantById(tenantIdFromQueryParams); + return firstValueFrom(tenantById$); + } return Promise.resolve(); } @@ -109,14 +111,20 @@ function replaceTenantNameWithinEnvironment( ); } - if(!environment.oAuthConfig) { + if (!environment.oAuthConfig) { environment.oAuthConfig = {}; } - environment.oAuthConfig.issuer = (environment.oAuthConfig.issuer || '').replace(placeholder, tenancyName); + environment.oAuthConfig.issuer = (environment.oAuthConfig.issuer || '').replace( + placeholder, + tenancyName, + ); Object.keys(environment.apis).forEach(api => { Object.keys(environment.apis[api]).forEach(key => { - environment.apis[api][key] = (environment.apis[api][key] || '').replace(placeholder, tenancyName); + environment.apis[api][key] = (environment.apis[api][key] || '').replace( + placeholder, + tenancyName, + ); }); }); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/providers/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/providers/index.ts index 40efb9df39..076d6169ba 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/providers/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/providers/index.ts @@ -1,2 +1,3 @@ export * from './ng-bootstrap-config.provider'; export * from './route.provider'; +export * from './tenant-not-found.provider'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/providers/tenant-not-found.provider.ts b/npm/ng-packs/packages/theme-shared/src/lib/providers/tenant-not-found.provider.ts new file mode 100644 index 0000000000..ac98f613b4 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/providers/tenant-not-found.provider.ts @@ -0,0 +1,20 @@ +import { TENANT_NOT_FOUND_BY_NAME } from '@abp/ng.core'; +import { inject, Provider } from '@angular/core'; +import { ConfirmationService } from '../services'; +import { HttpErrorResponse } from '@angular/common/http'; + +export const tenantNotFoundProvider: Provider = { + provide: TENANT_NOT_FOUND_BY_NAME, + useFactory: function () { + const confirm = inject(ConfirmationService); + return (response: HttpErrorResponse) => { + const { error } = response.error; + // hide loading donut + const appRoot = document.querySelector('app-root div.donut'); + if (appRoot) { + appRoot.remove(); + } + confirm.error(error.details, error.message, { hideCancelBtn: true, hideYesBtn: true }); + }; + }, +}; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts index 0fea3f166c..030418eadf 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts @@ -40,6 +40,7 @@ import { CardModule } from './components/card/card.module'; import { AbpVisibleDirective } from './directives'; import { FormInputComponent } from './components/form-input/form-input.component'; import { FormCheckboxComponent } from './components/checkbox/checkbox.component'; +import { tenantNotFoundProvider } from './providers/tenant-not-found.provider'; const declarationsWithExports = [ BreadcrumbComponent, @@ -58,7 +59,7 @@ const declarationsWithExports = [ ModalCloseDirective, AbpVisibleDirective, FormInputComponent, - FormCheckboxComponent + FormCheckboxComponent, ]; @NgModule({ @@ -69,7 +70,6 @@ const declarationsWithExports = [ NgbPaginationModule, EllipsisModule, CardModule, - ], declarations: [...declarationsWithExports, HttpErrorWrapperComponent], exports: [ @@ -77,11 +77,11 @@ const declarationsWithExports = [ EllipsisModule, NgxValidateCoreModule, CardModule, - ...declarationsWithExports + ...declarationsWithExports, ], providers: [DatePipe], }) -export class BaseThemeSharedModule { } +export class BaseThemeSharedModule {} @NgModule({ imports: [BaseThemeSharedModule], @@ -144,6 +144,7 @@ export class ThemeSharedModule { ...(confirmationIcons || {}), }, }, + tenantNotFoundProvider, ], }; }