added tenant code to url

This commit is contained in:
Diamantis Tziotzios 2024-06-06 17:31:20 +03:00
parent db25687dd5
commit a4df13a051
18 changed files with 306 additions and 213 deletions

View File

@ -3,12 +3,11 @@ import { RouterModule, Routes } from '@angular/router';
import { AppPermission } from './core/common/enum/permission.enum'; import { AppPermission } from './core/common/enum/permission.enum';
import { BreadcrumbService } from './ui/misc/breadcrumb/breadcrumb.service'; import { BreadcrumbService } from './ui/misc/breadcrumb/breadcrumb.service';
import { ReloadHelperComponent } from './ui/misc/reload-helper/reload-helper.component'; import { ReloadHelperComponent } from './ui/misc/reload-helper/reload-helper.component';
import { DepositOauth2DialogComponent } from './ui/misc/deposit-oauth2-dialog/deposit-oauth2-dialog.component';
const appRoutes: Routes = [ const appRoutes: Routes = [
{ {
path: '', path: '',
redirectTo:'home', redirectTo: 'home',
pathMatch: 'full' pathMatch: 'full'
}, },
{ {
@ -35,7 +34,7 @@ const appRoutes: Routes = [
}, },
{ {
path: 'explore-descriptions', path: 'explore-descriptions',
loadChildren: () => import('./ui/description/description.module').then(m => m.DescriptionModule), loadChildren: () => import('./ui/description/description.module').then(m => m.PublicDescriptionModule),
data: { data: {
breadcrumb: true, breadcrumb: true,
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({
@ -60,7 +59,7 @@ const appRoutes: Routes = [
}, },
{ {
path: 'explore-plans', path: 'explore-plans',
loadChildren: () => import('./ui/dmp/dmp.module').then(m => m.DmpModule), loadChildren: () => import('./ui/dmp/dmp.module').then(m => m.PublicDmpModule),
data: { data: {
breadcrumb: true, breadcrumb: true,
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({
@ -183,14 +182,6 @@ const appRoutes: Routes = [
title: 'GENERAL.TITLES.COOKIES-POLICY' title: 'GENERAL.TITLES.COOKIES-POLICY'
} }
}, },
// {
// path: 'splash',
// loadChildren: () => import('./ui/splash/splash.module').then(m => m.SplashModule),
// data: {
// breadcrumb: true
// }
// },
{ {
path: 'unauthorized', path: 'unauthorized',
loadChildren: () => import('./ui/misc/unauthorized/unauthorized.module').then(m => m.UnauthorizedModule), loadChildren: () => import('./ui/misc/unauthorized/unauthorized.module').then(m => m.UnauthorizedModule),
@ -387,8 +378,18 @@ const appRoutes: Routes = [
} }
]; ];
const tenantEnrichedRoutes: Routes = [
{
path: 't/:tenant_code',
children: [
...appRoutes
]
},
...appRoutes
];
@NgModule({ @NgModule({
imports: [RouterModule.forRoot(appRoutes, {})], imports: [RouterModule.forRoot(tenantEnrichedRoutes, {})],
exports: [RouterModule], exports: [RouterModule],
}) })
export class AppRoutingModule { } export class AppRoutingModule { }

View File

@ -3,7 +3,7 @@ import { of as observableOf, Subscription } from 'rxjs';
import { switchMap, filter, map, takeUntil } from 'rxjs/operators'; import { switchMap, filter, map, takeUntil } from 'rxjs/operators';
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'; import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { ActivatedRoute, NavigationEnd, NavigationStart, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { AuthService, LoginStatus } from './core/services/auth/auth.service'; import { AuthService, LoginStatus } from './core/services/auth/auth.service';
import { CultureService } from './core/services/culture/culture-service'; import { CultureService } from './core/services/culture/culture-service';
@ -23,6 +23,7 @@ import { TenantConfigurationService } from './core/services/tenant-configuration
import { TenantConfigurationType } from './core/common/enum/tenant-configuration-type'; import { TenantConfigurationType } from './core/common/enum/tenant-configuration-type';
import { CssColorsTenantConfiguration, TenantConfiguration } from './core/model/tenant-configuaration/tenant-configuration'; import { CssColorsTenantConfiguration, TenantConfiguration } from './core/model/tenant-configuaration/tenant-configuration';
import { nameof } from 'ts-simple-nameof'; import { nameof } from 'ts-simple-nameof';
import { TenantHandlingService } from './core/services/tenant/tenant-handling.service';
declare const gapi: any; declare const gapi: any;
@ -43,7 +44,7 @@ export class AppComponent implements OnInit, AfterViewInit {
onlySplash = true; onlySplash = true;
showOnlyRouterOutlet = false; showOnlyRouterOutlet = false;
@ViewChild('sidenav') sidenav:MatSidenav; @ViewChild('sidenav') sidenav: MatSidenav;
constructor( constructor(
private router: Router, private router: Router,
@ -61,7 +62,8 @@ export class AppComponent implements OnInit, AfterViewInit {
private location: Location, private location: Location,
private matomoService: MatomoService, private matomoService: MatomoService,
private tenantConfigurationService: TenantConfigurationService, private tenantConfigurationService: TenantConfigurationService,
private sidenavService: SideNavService private sidenavService: SideNavService,
private tenantHandlingService: TenantHandlingService
) { ) {
this.initializeServices(); this.initializeServices();
this.matomoService.init(); this.matomoService.init();
@ -69,30 +71,30 @@ export class AppComponent implements OnInit, AfterViewInit {
} }
ngAfterViewInit(): void { ngAfterViewInit(): void {
setTimeout(() => { setTimeout(() => {
this.sideNavSubscription = this.sidenavService.status().subscribe(isopen=>{ this.sideNavSubscription = this.sidenavService.status().subscribe(isopen => {
const hamburger = document.getElementById('hamburger'); const hamburger = document.getElementById('hamburger');
if(isopen){ if (isopen) {
//update value of hamburfer //update value of hamburfer
if(!hamburger){//try later if (!hamburger) {//try later
setTimeout(() => { setTimeout(() => {
const hamburger = document.getElementById('hamburger'); const hamburger = document.getElementById('hamburger');
if(hamburger){ if (hamburger) {
hamburger.classList.add('change'); hamburger.classList.add('change');
} }
}, 300); }, 300);
}else{ } else {
hamburger.classList.add('change'); hamburger.classList.add('change');
} }
this.sidenav.open() this.sidenav.open()
}else{//closed } else {//closed
if(!hamburger){//try later if (!hamburger) {//try later
setTimeout(() => { setTimeout(() => {
const hamburger = document.getElementById('hamburger'); const hamburger = document.getElementById('hamburger');
if(hamburger){ if (hamburger) {
hamburger.classList.remove('change'); hamburger.classList.remove('change');
} }
}, 300); }, 300);
}else{ } else {
hamburger.classList.remove('change'); hamburger.classList.remove('change');
} }
this.sidenav.close(); this.sidenav.close();
@ -114,7 +116,7 @@ export class AppComponent implements OnInit, AfterViewInit {
if (this.location.path() === '') { if (this.location.path() === '') {
if (!this.configurationService.useSplash) { if (!this.configurationService.useSplash) {
this.onlySplash = false; this.onlySplash = false;
this.router.navigate(['/reload']).then(() => this.router.navigate(['/home'])); this.router.navigate(['/home']);
} else { } else {
this.onlySplash = true; this.onlySplash = true;
this.router.navigate(['/reload']).then(() => this.router.navigate(['/splash'])); this.router.navigate(['/reload']).then(() => this.router.navigate(['/splash']));
@ -126,7 +128,7 @@ export class AppComponent implements OnInit, AfterViewInit {
} }
if (!this.cookieService.check("cookiesConsent")) { if (!this.cookieService.check("cookiesConsent")) {
// this.cookieService.set("cookiesConsent", "false", 356); // this.cookieService.set("cookiesConsent", "false", 356);
this.cookieService.set("cookiesConsent", "false", 356,null,null,false, 'Lax'); this.cookieService.set("cookiesConsent", "false", 356, null, null, false, 'Lax');
} }
@ -171,17 +173,32 @@ export class AppComponent implements OnInit, AfterViewInit {
return { title: child.snapshot.data['title'], usePrefix: usePrefix }; return { title: child.snapshot.data['title'], usePrefix: usePrefix };
} }
} }
return { title: appTitle, usePrefix: true}; return { title: appTitle, usePrefix: true };
}) })
).subscribe((titleOptions: { title: string, usePrefix: boolean}) => { ).subscribe((titleOptions: { title: string, usePrefix: boolean }) => {
this.translateTitle(titleOptions.title, titleOptions.usePrefix); this.translateTitle(titleOptions.title, titleOptions.usePrefix);
this.translate.onLangChange.subscribe(() => this.translateTitle(titleOptions.title, titleOptions.usePrefix)); this.translate.onLangChange.subscribe(() => this.translateTitle(titleOptions.title, titleOptions.usePrefix));
}); });
this.router
.events.pipe(
filter(event => event instanceof NavigationEnd)
)
.subscribe((event: NavigationStart) => {
const enrichedUrl = this.tenantHandlingService.getUrlEnrichedWithTenantCode(event.url, this.authentication.selectedTenant() ?? 'default');
if (event.url != enrichedUrl) {
this.router.navigate([enrichedUrl]);
console.log('enriched')
console.log(event.url)
console.log(enrichedUrl)
}
});
this.statusChangeSubscription = this.ccService.statusChange$.subscribe((event: NgcStatusChangeEvent) => { this.statusChangeSubscription = this.ccService.statusChange$.subscribe((event: NgcStatusChangeEvent) => {
if (event.status == "dismiss") { if (event.status == "dismiss") {
// this.cookieService.set("cookiesConsent", "true", 365); // this.cookieService.set("cookiesConsent", "true", 365);
this.cookieService.set("cookiesConsent", "true", 356,null,null,false, 'Lax'); this.cookieService.set("cookiesConsent", "true", 356, null, null, false, 'Lax');
} }
}); });
@ -203,7 +220,7 @@ export class AppComponent implements OnInit, AfterViewInit {
} }
this.ccService.destroy(); this.ccService.destroy();
this.ccService.init(this.ccService.getConfig()); this.ccService.init(this.ccService.getConfig());
}); });
} }
translateTitle(ttl: string, usePrefix: boolean) { translateTitle(ttl: string, usePrefix: boolean) {
@ -226,7 +243,7 @@ export class AppComponent implements OnInit, AfterViewInit {
ngOnDestroy() { ngOnDestroy() {
this.statusChangeSubscription.unsubscribe(); this.statusChangeSubscription.unsubscribe();
if(this.sideNavSubscription){ if (this.sideNavSubscription) {
this.sideNavSubscription.unsubscribe(); this.sideNavSubscription.unsubscribe();
} }
} }
@ -269,24 +286,24 @@ export class AppComponent implements OnInit, AfterViewInit {
private loadCssColors() { private loadCssColors() {
if (this.authentication.currentAccountIsAuthenticated() && this.authentication.selectedTenant()) { if (this.authentication.currentAccountIsAuthenticated() && this.authentication.selectedTenant()) {
this.tenantConfigurationService.getCurrentTenantType(TenantConfigurationType.CssColors, [ this.tenantConfigurationService.getCurrentTenantType(TenantConfigurationType.CssColors, [
nameof<TenantConfiguration>(x => x.type), nameof<TenantConfiguration>(x => x.type),
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor)].join('.'), [nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor)].join('.'),
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor2)].join('.'), [nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor2)].join('.'),
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor3)].join('.'), [nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.primaryColor3)].join('.'),
[nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.secondaryColor)].join('.'), [nameof<TenantConfiguration>(x => x.cssColors), nameof<CssColorsTenantConfiguration>(x => x.secondaryColor)].join('.'),
]) ])
.pipe(map(data => data as TenantConfiguration)) .pipe(map(data => data as TenantConfiguration))
.subscribe( .subscribe(
data => { data => {
if (data?.cssColors) { if (data?.cssColors) {
if (data.cssColors.primaryColor) document.documentElement.style.setProperty(`--primary-color`, data.cssColors.primaryColor); if (data.cssColors.primaryColor) document.documentElement.style.setProperty(`--primary-color`, data.cssColors.primaryColor);
if (data.cssColors.primaryColor2) document.documentElement.style.setProperty(`--primary-color-2`, data.cssColors.primaryColor2); if (data.cssColors.primaryColor2) document.documentElement.style.setProperty(`--primary-color-2`, data.cssColors.primaryColor2);
if (data.cssColors.primaryColor3) document.documentElement.style.setProperty(`--primary-color-3`, data.cssColors.primaryColor3); if (data.cssColors.primaryColor3) document.documentElement.style.setProperty(`--primary-color-3`, data.cssColors.primaryColor3);
if (data.cssColors.secondaryColor) document.documentElement.style.setProperty(`--secondary-color`, data.cssColors.secondaryColor); if (data.cssColors.secondaryColor) document.documentElement.style.setProperty(`--secondary-color`, data.cssColors.secondaryColor);
} }
}, },
); );
} }
} }

View File

@ -41,6 +41,7 @@ import { CoreAnnotationServiceModule } from 'annotation-service/services/core-se
import { CoreNotificationServiceModule } from '@notification-service/services/core-service.module'; import { CoreNotificationServiceModule } from '@notification-service/services/core-service.module';
import { DepositOauth2DialogModule } from './ui/misc/deposit-oauth2-dialog/deposit-oauth2-dialog.module'; import { DepositOauth2DialogModule } from './ui/misc/deposit-oauth2-dialog/deposit-oauth2-dialog.module';
import { AnalyticsService } from './core/services/matomo/analytics-service'; import { AnalyticsService } from './core/services/matomo/analytics-service';
import { TenantHandlingService } from './core/services/tenant/tenant-handling.service';
// AoT requires an exported function for factories // AoT requires an exported function for factories
export function HttpLoaderFactory(languageHttpService: LanguageHttpService) { export function HttpLoaderFactory(languageHttpService: LanguageHttpService) {
@ -82,7 +83,7 @@ const appearance: MatFormFieldDefaultOptions = {
// appearance: 'standard' // appearance: 'standard'
}; };
export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService, languageService: LanguageService) { export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService, languageService: LanguageService, tenantHandlingService:TenantHandlingService) {
return () => appConfig.loadConfiguration().then(() => { return () => appConfig.loadConfiguration().then(() => {
return languageService.loadAvailableLanguages().toPromise(); return languageService.loadAvailableLanguages().toPromise();
}).then(x => keycloak.init({ }).then(x => keycloak.init({
@ -109,8 +110,10 @@ export function InstallationConfigurationFactory(appConfig: ConfigurationService
InterceptorType.UnauthorizedResponse, InterceptorType.UnauthorizedResponse,
] ]
}; };
const tenantCode = tenantHandlingService.extractTenantCodeFromUrlPath(window.location.pathname) ?? authService.selectedTenant() ?? 'default';
const tokenPromise = keycloak.getToken(); const tokenPromise = keycloak.getToken();
return authService.prepareAuthRequest(from(tokenPromise), { params }).toPromise().catch(error => authService.onAuthenticateError(error)); return authService.prepareAuthRequest(from(tokenPromise), tenantCode, { params }).toPromise().catch(error => authService.onAuthenticateError(error));
})); }));
} }

View File

@ -45,6 +45,7 @@ import { VisibilityRulesService } from '@app/ui/description/editor/description-f
import { StorageFileService } from './services/storage-file/storage-file.service'; import { StorageFileService } from './services/storage-file/storage-file.service';
import { TenantConfigurationService } from './services/tenant-configuration/tenant-configuration.service'; import { TenantConfigurationService } from './services/tenant-configuration/tenant-configuration.service';
import { DefaultUserLocaleService } from './services/default-user-locale/default-user-locale.service'; import { DefaultUserLocaleService } from './services/default-user-locale/default-user-locale.service';
import { TenantHandlingService } from './services/tenant/tenant-handling.service';
// //
// //
// This is shared module that provides all the services. Its imported only once on the AppModule. // This is shared module that provides all the services. Its imported only once on the AppModule.
@ -109,7 +110,8 @@ export class CoreServiceModule {
PrefillingSourceService, PrefillingSourceService,
VisibilityRulesService, VisibilityRulesService,
TenantConfigurationService, TenantConfigurationService,
StorageFileService StorageFileService,
TenantHandlingService
], ],
}; };
} }

View File

@ -154,11 +154,11 @@ export class AuthService extends BaseService {
public isLoggedIn(): boolean { public isLoggedIn(): boolean {
return this.authState(); return this.authState();
} }
public prepareAuthRequest(observable: Observable<string>, httpParams?: Object): Observable<boolean> { public prepareAuthRequest(observable: Observable<string>, tenantCode: string, httpParams?: Object): Observable<boolean> {
return observable.pipe( return observable.pipe(
map((x) => this.currentAuthenticationToken(x)), map((x) => this.currentAuthenticationToken(x)),
exhaustMap(() => forkJoin([ exhaustMap(() => forkJoin([
this.accessToken ? this.ensureTenant() : of(false), this.accessToken ? this.ensureTenant(tenantCode ?? this.selectedTenant() ?? 'default') : of(false),
this.accessToken ? this.principalService.me(httpParams) : of(null), this.accessToken ? this.principalService.me(httpParams) : of(null),
])), ])),
map((item) => { map((item) => {
@ -176,10 +176,10 @@ export class AuthService extends BaseService {
); );
} }
public ensureTenant(): Observable<string> { private ensureTenant(tenantCode: string): Observable<string> {
if (!this.selectedTenant()) { // if (!this.selectedTenant()) {
this.selectedTenant('default'); // this.selectedTenant('default');
} // }
const params = new BaseHttpParams(); const params = new BaseHttpParams();
params.interceptorContext = { params.interceptorContext = {
excludedInterceptors: [InterceptorType.TenantHeaderInterceptor] excludedInterceptors: [InterceptorType.TenantHeaderInterceptor]
@ -188,16 +188,21 @@ export class AuthService extends BaseService {
map( map(
(myTenants) => { (myTenants) => {
if (myTenants) { if (myTenants) {
if (this.selectedTenant()) { if (myTenants.some(x => x.code.toLocaleLowerCase() == tenantCode.toLocaleLowerCase())) {
if (myTenants.findIndex(x => x.code.toLocaleLowerCase() == this.selectedTenant().toLocaleLowerCase()) < 0) { this.selectedTenant(tenantCode);
this.selectedTenant(null); } else {
} this.selectedTenant(null);
}
if (!this.selectedTenant()) {
if (myTenants.length > 0) {
this.selectedTenant(myTenants[0]?.code);
}
} }
// if (this.selectedTenant()) {
// if (myTenants.findIndex(x => x.code.toLocaleLowerCase() == this.selectedTenant().toLocaleLowerCase()) < 0) {
// this.selectedTenant(null);
// }
// }
// if (!this.selectedTenant()) {
// if (myTenants.length > 0) {
// this.selectedTenant(myTenants[0]?.code);
// }
// }
} else { } else {
this.selectedTenant(null); this.selectedTenant(null);
} }
@ -326,6 +331,7 @@ export class AuthService extends BaseService {
return this.prepareAuthRequest( return this.prepareAuthRequest(
from(this.keycloakService.getToken()), from(this.keycloakService.getToken()),
this.selectedTenant(),
httpParams httpParams
) )
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))

View File

@ -57,21 +57,34 @@ export class CultureService {
// Set angular locale based on user selection. // Set angular locale based on user selection.
// This is a very hacky way to map cultures with angular cultures, since there is no mapping. We first try to // This is a very hacky way to map cultures with angular cultures, since there is no mapping. We first try to
// use the culture with the specialization (ex en-US), and if not exists we import the base culture (first part). // use the culture with the specialization (ex en-US), and if not exists we import the base culture (first part).
let locale = newCulture.name; // let locale = newCulture.name;
import(`/node_modules/@angular/common/locales/${locale}.mjs`).catch(reason => { // const base = import(
this.logger.error('Could not load locale: ' + locale); // /* webpackExclude: /\.d\.ts$/ */
}).then(selectedLocale => { // /* webpackMode: "lazy-once" */
if (selectedLocale) { // /* webpackChunkName: "i18n-base" */
registerLocaleData(selectedLocale.default); // `@angular/common/locales/${locale}.mjs`)//.then(m => m[basePkg]);
} else {
locale = newCulture.name.split('-')[0]; // const extra = import(
import(`/node_modules/@angular/common/locales/${locale}.mjs`).catch(reason => { // /* webpackExclude: /\.d\.ts$/ */
this.logger.error('Could not load locale: ' + locale); // /* webpackMode: "lazy-once" */
}).then(selectedDefaultLocale => { // /* webpackChunkName: "i18n-extra" */
registerLocaleData(selectedDefaultLocale.default); // `@angular/common/locales/extra/${locale.split('-')[0]}.mjs`)//.then(m => m[extraPkg]);
});
}
}); // import(`/node_modules/ @angular/common/locales/${locale}.mjs`).catch(reason => {
// this.logger.error('Could not load locale: ' + locale);
// }).then(selectedLocale => {
// if (selectedLocale) {
// registerLocaleData(selectedLocale.default);
// } else {
// locale = newCulture.name.split('-')[0];
// import(`/node_modules/@angular/common/locales/${locale}.mjs`).catch(reason => {
// this.logger.error('Could not load locale: ' + locale);
// }).then(selectedDefaultLocale => {
// registerLocaleData(selectedDefaultLocale.default);
// });
// }
// });
} }
getCultureChangeObservable(): Observable<CultureInfo> { getCultureChangeObservable(): Observable<CultureInfo> {

View File

@ -0,0 +1,58 @@
import { DOCUMENT, LocationStrategy } from '@angular/common';
import { Inject, Injectable } from '@angular/core';
import { PRIMARY_OUTLET, Router, UrlSegment, UrlSegmentGroup, UrlTree } from '@angular/router';
@Injectable()
export class TenantHandlingService {
constructor(
@Inject(DOCUMENT) private readonly document: Document,
private readonly locationStrategy: LocationStrategy,
private readonly router: Router,
) {
}
extractTenantCodeFromUrlPath(path: string): string {
//Searches for "/t/<tenant_code>/" in a url;
const tenantRegex = new RegExp("\/t\/([^\/]+)");
const regexResult = tenantRegex.exec(path);
let tenantCode = null;
if (Array.isArray(regexResult) && regexResult.length > 0) {
tenantCode = regexResult[1];
}
return tenantCode;
}
getCurrentUrlEnrichedWithTenantCode(tenantCode: string, withOrigin: boolean) {
const path = this.getUrlEnrichedWithTenantCode(this.router.routerState.snapshot.url, tenantCode)
return withOrigin ? this.getBaseUrl() + path.substring(1) : path;
}
getUrlEnrichedWithTenantCode(url: string, tenantCode: string) {
const urlTree: UrlTree = this.router.parseUrl(url);
const urlSegmentGroup: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET];
const urlSegments: UrlSegment[] = urlSegmentGroup.segments;
const tenantParamIndex = urlSegments.findIndex(x => x.path == 't');
if (tenantParamIndex >= 0) {
if (tenantCode == 'default') {
urlSegments.splice(tenantParamIndex, 2);
} else {
const tenantCodeSegment = urlSegments.at(tenantParamIndex + 1);
tenantCodeSegment.path = tenantCode;
}
} else {
if (tenantCode != 'default') {
urlTree.root.children[PRIMARY_OUTLET].segments = [new UrlSegment('t', {}), new UrlSegment(tenantCode, {}), ...urlSegments];
}
}
return urlTree.toString();
}
getBaseUrl(): string {
return this.document.location.origin + this.locationStrategy.getBaseHref();
}
}

View File

@ -31,13 +31,13 @@
<div style="position: relative;" class="col-12" *ngIf="hasFocus" [@fade-in]> <div style="position: relative;" class="col-12" *ngIf="hasFocus" [@fade-in]>
<div *ngIf="showDescription" class="mb-4"> <div *ngIf="showDescription" class="mb-4">
<h5 style="font-weight: bold" class="row">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION' | translate}}</h5> <h5 style="font-weight: bold" class="row">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION' | translate}}</h5>
<rich-text-editor-component [form]="form.get('description')" [id]="'editor1'" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION'" [wrapperClasses]="'row'" [editable]="!viewOnly"> <rich-text-editor-component [form]="form.get('description')" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION'" [wrapperClasses]="'row'" [editable]="!viewOnly">
</rich-text-editor-component> </rich-text-editor-component>
<mat-error *ngIf="this.form.get('description').hasError('backendError')">{{form.get('description').getError('backendError').message}}</mat-error> <mat-error *ngIf="this.form.get('description').hasError('backendError')">{{form.get('description').getError('backendError').message}}</mat-error>
</div> </div>
<div *ngIf="showExtendedDescription" class="mb-4"> <div *ngIf="showExtendedDescription" class="mb-4">
<h5 style="font-weight: bold" class="row">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION' | translate}}</h5> <h5 style="font-weight: bold" class="row">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION' | translate}}</h5>
<rich-text-editor-component [form]="form.get('extendedDescription')" [id]="'editor2'" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION'" [wrapperClasses]="'row'" [editable]="!viewOnly"> <rich-text-editor-component [form]="form.get('extendedDescription')" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION'" [wrapperClasses]="'row'" [editable]="!viewOnly">
</rich-text-editor-component> </rich-text-editor-component>
<mat-error *ngIf="this.form.get('extendedDescription').hasError('backendError')">{{form.get('extendedDescription').getError('backendError').message}}</mat-error> <mat-error *ngIf="this.form.get('extendedDescription').hasError('backendError')">{{form.get('extendedDescription').getError('backendError').message}}</mat-error>
</div> </div>

View File

@ -1,10 +1,8 @@
import { Component, Input, NgZone, OnInit } from '@angular/core'; import { Component, Input, NgZone, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { AuthService } from '@app/core/services/auth/auth.service'; import { AuthService } from '@app/core/services/auth/auth.service';
import { PrincipalService } from '@app/core/services/http/principal.service'; import { TenantHandlingService } from '@app/core/services/tenant/tenant-handling.service';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { BaseHttpParams } from '@common/http/base-http-params';
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
import { KeycloakService } from 'keycloak-angular'; import { KeycloakService } from 'keycloak-angular';
import { from } from 'rxjs'; import { from } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
@ -27,7 +25,7 @@ export class LoginComponent extends BaseComponent implements OnInit {
private router: Router, private router: Router,
private authService: AuthService, private authService: AuthService,
private route: ActivatedRoute, private route: ActivatedRoute,
private principalService: PrincipalService, private tenantHandlingService: TenantHandlingService,
private keycloakService: KeycloakService private keycloakService: KeycloakService
) { super(); } ) { super(); }
@ -36,7 +34,8 @@ export class LoginComponent extends BaseComponent implements OnInit {
if (!this.keycloakService.isLoggedIn()) { if (!this.keycloakService.isLoggedIn()) {
this.authService.authenticate(this.returnUrl); this.authService.authenticate(this.returnUrl);
} else { } else {
this.authService.prepareAuthRequest(from(this.keycloakService.getToken())).pipe(takeUntil(this._destroyed)).subscribe( const tenantCode = this.tenantHandlingService.extractTenantCodeFromUrlPath(this.returnUrl) ?? this.authService.selectedTenant() ?? 'default';
this.authService.prepareAuthRequest(from(this.keycloakService.getToken()), tenantCode).pipe(takeUntil(this._destroyed)).subscribe(
() => { () => {
let returnUrL = this.returnUrl; let returnUrL = this.returnUrl;
this.zone.run(() => this.router.navigateByUrl(returnUrL)); this.zone.run(() => this.router.navigateByUrl(returnUrL));

View File

@ -15,13 +15,10 @@ export class LogoutComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.authService.clear(); this.authService.clear();
debugger;
this.keycloak.logout(location.origin).then(() => { this.keycloak.logout(location.origin).then(() => {
localStorage.clear(); localStorage.clear();
// this.router.navigate(['./'], { replaceUrl: true }); // this.router.navigate(['./'], { replaceUrl: true });
}); });
// this.tokenService.logout(() => {
// localStorage.clear();
// this.router.navigate(["./"], { replaceUrl: true });
// });
} }
} }

View File

@ -1,6 +1,6 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { FormattingModule } from '@app/core/formatting.module'; import { FormattingModule } from '@app/core/formatting.module';
import { DescriptionRoutingModule } from '@app/ui/description/description.routing'; import { DescriptionRoutingModule, PublicDescriptionRoutingModule } from '@app/ui/description/description.routing';
import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonFormsModule } from '@common/forms/common-forms.module';
import { CommonUiModule } from '@common/ui/common-ui.module'; import { CommonUiModule } from '@common/ui/common-ui.module';
@ -17,3 +17,17 @@ import { CommonUiModule } from '@common/ui/common-ui.module';
] ]
}) })
export class DescriptionModule { } export class DescriptionModule { }
@NgModule({
imports: [
CommonUiModule,
CommonFormsModule,
FormattingModule,
PublicDescriptionRoutingModule,
],
declarations: [
],
exports: [
]
})
export class PublicDescriptionModule { }

View File

@ -1,13 +1,13 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from '@app/core/auth-guard.service';
import { BreadcrumbService } from '../misc/breadcrumb/breadcrumb.service'; import { BreadcrumbService } from '../misc/breadcrumb/breadcrumb.service';
// import { DescriptionWizardComponent } from './description-wizard/description-wizard.component';
// import { DescriptionOverviewComponent } from './overview/description-overview.component';
const routes: Routes = [ const routes: Routes = [
{ {
path: 'overview', path: 'overview',
loadChildren: () => import('./overview/description-overview.module').then(m => m.DescriptionOverviewModule), loadChildren: () => import('./overview/description-overview.module').then(m => m.DescriptionOverviewModule),
canActivate: [AuthGuard],
data: { data: {
breadcrumb: true, breadcrumb: true,
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({
@ -18,6 +18,28 @@ const routes: Routes = [
{ {
path: 'edit', path: 'edit',
loadChildren: () => import('./editor/description-editor.module').then(m => m.DescriptionEditorModule), loadChildren: () => import('./editor/description-editor.module').then(m => m.DescriptionEditorModule),
canActivate: [AuthGuard],
data: {
breadcrumb: true,
...BreadcrumbService.generateRouteDataConfiguration({
hideNavigationItem: true
}),
}
},
{
path: '',
canActivate: [AuthGuard],
loadChildren: () => import('./listing/description-listing.module').then(m => m.DescriptionListingModule),
data: {
breadcrumb: true
},
},
];
const publicRoutes: Routes = [
{
path: 'overview',
loadChildren: () => import('./overview/description-overview.module').then(m => m.DescriptionOverviewModule),
data: { data: {
breadcrumb: true, breadcrumb: true,
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({
@ -40,3 +62,10 @@ const routes: Routes = [
providers: [] providers: []
}) })
export class DescriptionRoutingModule { } export class DescriptionRoutingModule { }
@NgModule({
imports: [RouterModule.forChild(publicRoutes)],
exports: [RouterModule],
providers: []
})
export class PublicDescriptionRoutingModule { }

View File

@ -1,6 +1,6 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { FormattingModule } from '@app/core/formatting.module'; import { FormattingModule } from '@app/core/formatting.module';
import { DmpRoutingModule } from '@app/ui/dmp/dmp.routing'; import { DmpRoutingModule, PublicDmpRoutingModule } from '@app/ui/dmp/dmp.routing';
import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonFormsModule } from '@common/forms/common-forms.module';
import { CommonUiModule } from '@common/ui/common-ui.module'; import { CommonUiModule } from '@common/ui/common-ui.module';
@ -17,3 +17,17 @@ import { CommonUiModule } from '@common/ui/common-ui.module';
] ]
}) })
export class DmpModule { } export class DmpModule { }
@NgModule({
imports: [
CommonUiModule,
CommonFormsModule,
FormattingModule,
PublicDmpRoutingModule,
],
declarations: [
],
exports: [
]
})
export class PublicDmpModule { }

View File

@ -1,11 +1,13 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { BreadcrumbService } from '../misc/breadcrumb/breadcrumb.service'; import { BreadcrumbService } from '../misc/breadcrumb/breadcrumb.service';
import { AuthGuard } from '@app/core/auth-guard.service';
const routes: Routes = [ const routes: Routes = [
{ {
path: 'overview', path: 'overview',
loadChildren: () => import('./overview/dmp-overview.module').then(m => m.DmpOverviewModule), loadChildren: () => import('./overview/dmp-overview.module').then(m => m.DmpOverviewModule),
canActivate:[AuthGuard],
data: { data: {
breadcrumb: true, breadcrumb: true,
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({
@ -16,6 +18,7 @@ const routes: Routes = [
{ {
path: 'new', path: 'new',
loadChildren: () => import('./dmp-editor-blueprint/dmp-editor.module').then(m => m.DmpEditorModule), loadChildren: () => import('./dmp-editor-blueprint/dmp-editor.module').then(m => m.DmpEditorModule),
canActivate:[AuthGuard],
data: { data: {
breadcrumb: true, breadcrumb: true,
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({
@ -27,6 +30,7 @@ const routes: Routes = [
{ {
path: 'edit', path: 'edit',
loadChildren: () => import('./dmp-editor-blueprint/dmp-editor.module').then(m => m.DmpEditorModule), loadChildren: () => import('./dmp-editor-blueprint/dmp-editor.module').then(m => m.DmpEditorModule),
canActivate:[AuthGuard],
data: { data: {
breadcrumb: true, breadcrumb: true,
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({
@ -37,80 +41,32 @@ const routes: Routes = [
}, },
{ {
path: '', path: '',
canActivate:[AuthGuard],
loadChildren: () => import('./listing/dmp-listing.module').then(m => m.DmpListingModule), loadChildren: () => import('./listing/dmp-listing.module').then(m => m.DmpListingModule),
data: { data: {
breadcrumb: true breadcrumb: true
}, },
}, },
];
const publicRoutes: Routes = [
{
// { path: 'overview',
// path: 'publicEdit/:publicId', loadChildren: () => import('./overview/dmp-overview.module').then(m => m.DmpOverviewModule),
// component: DmpEditorComponent, data: {
// data: { breadcrumb: true,
// breadcrumb: true, ...BreadcrumbService.generateRouteDataConfiguration({
// title: 'GENERAL.TITLES.DMP-PUBLIC-EDIT' hideNavigationItem: true
// }, }),
// canDeactivate: [CanDeactivateGuard] }
// }, },
{
// { path: '',
// path: 'publicOverview/:publicId', loadChildren: () => import('./listing/dmp-listing.module').then(m => m.DmpListingModule),
// component: DmpOverviewComponent, data: {
// data: { breadcrumb: true
// breadcrumb: true, },
// title: 'GENERAL.TITLES.DMP-OVERVIEW' },
// },
// },
// {
// path: 'new/dataset',
// component: DmpEditorComponent,
// canActivate: [AuthGuard],
// data: {
// breadcrumbs: 'new/dataset',
// title: 'GENERAL.TITLES.DATASET-NEW'
// }
// },
// {
// path: 'new/dataset/:dmpId',
// component: DmpEditorComponent,
// canActivate: [AuthGuard],
// data: {
// breadcrumbs: 'new/dataset',
// title: 'GENERAL.TITLES.DATASET-NEW'
// }
// },
// {
// path: 'new_version/:id',
// // component: DmpWizardComponent,
// component: DmpCloneComponent,
// data: {
// clone: false,
// breadcrumb: true,
// title: 'GENERAL.TITLES.DMP-NEW-VERSION'
// },
// },
// {
// path: 'clone/:id',
// component: DmpCloneComponent,
// data: {
// clone: false,
// breadcrumb: true,
// title: 'GENERAL.TITLES.DMP-CLONE'
// },
// },
// {
// path: 'invitation/:id',
// component: InvitationAcceptedComponent,
// data: {
// breadcrumb: true
// },
// }
]; ];
@NgModule({ @NgModule({
@ -118,3 +74,9 @@ const routes: Routes = [
exports: [RouterModule] exports: [RouterModule]
}) })
export class DmpRoutingModule { } export class DmpRoutingModule { }
@NgModule({
imports: [RouterModule.forChild(publicRoutes)],
exports: [RouterModule]
})
export class PublicDmpRoutingModule { }

View File

@ -90,14 +90,20 @@ export class NavbarComponent extends BaseComponent implements OnInit {
this.authentication.getAuthenticationStateObservable().subscribe(authenticationState => { this.authentication.getAuthenticationStateObservable().subscribe(authenticationState => {
if (authenticationState.loginStatus === LoginStatus.LoggedIn) { if (authenticationState.loginStatus === LoginStatus.LoggedIn) {
this.loadLogo(); this.loadLogo();
this.loadUser();
} }
}); });
this.loadLogo(); this.loadLogo();
this.loadUser();
}
this.userService.getSingle(this.authentication.userId(), [ private loadUser() {
nameof<User>(x => x.id), if (this.authentication.currentAccountIsAuthenticated() && this.authentication.userId()) {
nameof<User>(x => x.name) this.userService.getSingle(this.authentication.userId(), [
]).subscribe(u => this.userName = u.name); //TODO HANDLE-ERRORS nameof<User>(x => x.id),
nameof<User>(x => x.name)
]).subscribe(u => this.userName = u.name); //TODO HANDLE-ERRORS
}
} }
private loadLogo() { private loadLogo() {

View File

@ -1,15 +1,13 @@
import { Component, EventEmitter, OnInit, Output } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { MatButtonToggleChange } from "@angular/material/button-toggle"; import { MatButtonToggleChange } from "@angular/material/button-toggle";
import { Router } from "@angular/router";
import { Tenant } from "@app/core/model/tenant/tenant"; import { Tenant } from "@app/core/model/tenant/tenant";
import { AuthService } from "@app/core/services/auth/auth.service"; import { AuthService } from "@app/core/services/auth/auth.service";
import { PrincipalService } from "@app/core/services/http/principal.service"; import { PrincipalService } from "@app/core/services/http/principal.service";
import { TenantHandlingService } from "@app/core/services/tenant/tenant-handling.service";
import { BaseComponent } from "@common/base/base.component"; import { BaseComponent } from "@common/base/base.component";
import { BaseHttpParams } from "@common/http/base-http-params"; import { BaseHttpParams } from "@common/http/base-http-params";
import { InterceptorType } from "@common/http/interceptors/interceptor-type"; import { InterceptorType } from "@common/http/interceptors/interceptor-type";
import { KeycloakService } from "keycloak-angular"; import { Observable } from "rxjs";
import { Observable, from } from "rxjs";
import { takeUntil } from "rxjs/operators";
@Component({ @Component({
selector: 'app-tenant-switch', selector: 'app-tenant-switch',
@ -20,10 +18,9 @@ export class TenantSwitchComponent extends BaseComponent implements OnInit {
tenants: Observable<Array<Tenant>>; tenants: Observable<Array<Tenant>>;
constructor( constructor(
private router: Router,
private keycloakService: KeycloakService,
private principalService: PrincipalService, private principalService: PrincipalService,
private authService: AuthService, private authService: AuthService,
private tenantHandlingService: TenantHandlingService
) { ) {
super(); super();
} }
@ -34,7 +31,6 @@ export class TenantSwitchComponent extends BaseComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.tenants = this.loadUserTenants(); //TODO this.tenants = this.loadUserTenants(); //TODO
//this.tenantChange.emit(this.getCurrentLanguage())
} }
loadUserTenants(): Observable<Array<Tenant>> { loadUserTenants(): Observable<Array<Tenant>> {
@ -48,22 +44,7 @@ export class TenantSwitchComponent extends BaseComponent implements OnInit {
onTenantSelected(selectedTenant: MatButtonToggleChange) { onTenantSelected(selectedTenant: MatButtonToggleChange) {
if (selectedTenant.value === undefined || selectedTenant.value === '') return; if (selectedTenant.value === undefined || selectedTenant.value === '') return;
this.formSubmit(selectedTenant.value); this.authService.selectedTenant(selectedTenant.value);
this.loadUser(); window.location.href = this.tenantHandlingService.getCurrentUrlEnrichedWithTenantCode(selectedTenant.value, true);
}
formSubmit(selectedTenant: string): void {
this.authService.selectedTenant(selectedTenant);
}
loadUser(): void {
this.authService.prepareAuthRequest(from(this.keycloakService.getToken()), {})
.pipe(takeUntil(this._destroyed))
.subscribe(
() => {
this.authService.onAuthenticateSuccessReload();
},
(error) => this.authService.onAuthenticateError(error)
);
} }
} }

View File

@ -1,4 +1,3 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
@ -18,6 +17,7 @@ import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service'; import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { ReferenceService } from '@app/core/services/reference/reference.service'; import { ReferenceService } from '@app/core/services/reference/reference.service';
import { TenantHandlingService } from '@app/core/services/tenant/tenant-handling.service';
import { UserService } from '@app/core/services/user/user.service'; import { UserService } from '@app/core/services/user/user.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
@ -28,16 +28,15 @@ import { FormValidationErrorsDialogComponent } from '@common/forms/form-validati
import { BaseHttpParams } from '@common/http/base-http-params'; import { BaseHttpParams } from '@common/http/base-http-params';
import { InterceptorType } from '@common/http/interceptors/interceptor-type'; import { InterceptorType } from '@common/http/interceptors/interceptor-type';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
import { Guid } from '@common/types/guid'; import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { KeycloakService } from 'keycloak-angular';
import * as moment from 'moment-timezone'; import * as moment from 'moment-timezone';
import { Observable, from, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators'; import { map, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof'; import { nameof } from 'ts-simple-nameof';
import { AddAccountDialogComponent } from './add-account/add-account-dialog.component'; import { AddAccountDialogComponent } from './add-account/add-account-dialog.component';
import { UserProfileEditorModel } from './user-profile-editor.model'; import { UserProfileEditorModel } from './user-profile-editor.model';
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
@Component({ @Component({
selector: 'app-user-profile', selector: 'app-user-profile',
@ -81,7 +80,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
private dialog: MatDialog, private dialog: MatDialog,
public enumUtils: EnumUtils, public enumUtils: EnumUtils,
private formBuilder: UntypedFormBuilder, private formBuilder: UntypedFormBuilder,
private keycloakService: KeycloakService, private tenantHandlingService: TenantHandlingService,
private principalService: PrincipalService, private principalService: PrincipalService,
private formService: FormService, private formService: FormService,
private referenceService: ReferenceService, private referenceService: ReferenceService,
@ -281,7 +280,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
}, maxWidth: '30em' }, maxWidth: '30em'
}); });
}, },
error => this.httpErrorHandlingService.handleBackedRequestError(error)); error => this.httpErrorHandlingService.handleBackedRequestError(error));
} }
}); });
} }
@ -309,7 +308,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
}); });
} }
}, },
error => this.httpErrorHandlingService.handleBackedRequestError(error)); //TODO how to handle this error => this.httpErrorHandlingService.handleBackedRequestError(error)); //TODO how to handle this
} }
}); });
} }
@ -367,17 +366,9 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
if (this.tenantFormGroup.valid === false) return; if (this.tenantFormGroup.valid === false) return;
const selectedTenant = this.tenantFormGroup.get('tenantCode').value; const selectedTenant = this.tenantFormGroup.get('tenantCode').value;
this.formSubmit(selectedTenant);
this.loadUser();
}
formSubmit(selectedTenant: string): void { this.authService.selectedTenant(selectedTenant.value);
this.authService.selectedTenant(selectedTenant); window.location.href = this.tenantHandlingService.getCurrentUrlEnrichedWithTenantCode(selectedTenant.value, true);
}
loadUser(): void {
const returnUrl = '/profile';
this.authService.prepareAuthRequest(from(this.keycloakService.getToken()), {}).pipe(takeUntil(this._destroyed)).subscribe(() => this.authService.onAuthenticateSuccess(returnUrl), (error) => this.authService.onAuthenticateError(error));
} }
//Preferences //Preferences

View File

@ -43,13 +43,13 @@ export class UnauthorizedResponseInterceptor extends BaseInterceptor {
this.authService.refreshToken().then((isRefreshed) => { this.authService.refreshToken().then((isRefreshed) => {
this.accountRefresh$ = null; this.accountRefresh$ = null;
if (!isRefreshed) { if (!isRefreshed) {
this.logoutUser(); this.handleUnauthorized();
return false; return false;
} }
return true; return true;
}).catch(x => { }).catch(x => {
this.logoutUser(); this.handleUnauthorized();
return false; return false;
}) })
).pipe(filter((x) => x)); ).pipe(filter((x) => x));
@ -67,10 +67,10 @@ export class UnauthorizedResponseInterceptor extends BaseInterceptor {
return next.handle(newRequest); return next.handle(newRequest);
} }
private logoutUser() { private handleUnauthorized() {
if (!this.isLoginRoute() && !this.isSignupRoute()) { if (!this.isLoginRoute() && !this.isSignupRoute()) {
this.authService.clear(); this.authService.clear();
this.router.navigate(['/unauthorized']); this.router.navigate(['/unauthorized', { queryParams: { returnUrl: this.router.url } }]);
} }
} }