diff --git a/frontend/package.json b/frontend/package.json index 2fb2dbc92..1b724b7d4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -32,8 +32,8 @@ "cookieconsent": "^3.1.1", "dragula": "^3.7.3", "file-saver": "^2.0.5", - "keycloak-angular": "^15.2.1", - "keycloak-js": "^24.0.5", + "keycloak-angular": "^16.0.1", + "keycloak-js": "^25.0.0", "moment": "^2.30.1", "moment-timezone": "^0.5.45", "ng-dialog-animation": "^9.0.4", diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 5950e4efc..6df99ec8c 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -80,7 +80,7 @@ const cookieConfig: NgcCookieConsentConfig = { type: 'info' }; -export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService, languageService: LanguageService, tenantHandlingService: TenantHandlingService, router: Router) { +export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService, languageService: LanguageService, tenantHandlingService: TenantHandlingService) { return () => appConfig.loadConfiguration().then(() => { return languageService.loadAvailableLanguages().toPromise(); }).then(x => keycloak.init({ @@ -109,15 +109,11 @@ export function InstallationConfigurationFactory(appConfig: ConfigurationService }; const tenantCode = tenantHandlingService.extractTenantCodeFromUrlPath(window.location.pathname) ?? authService.selectedTenant() ?? 'default'; - const tokenPromise = keycloak.getToken(); - return authService.prepareAuthRequest(from(tokenPromise), tenantCode, { params }) - .toPromise() - .then(() => { - if (authService.selectedTenant() != tenantCode) { - router.navigate(['/']); - } - }) - .catch(error => authService.onAuthenticateError(error)); + const token = keycloak.getToken(); + return authService.prepareAuthRequest(from(token), tenantCode, { params }).toPromise().catch(error => { + authService.onAuthenticateError(error); + window.location.pathname = "/"; + }); })); } diff --git a/frontend/src/app/core/services/auth/auth.service.ts b/frontend/src/app/core/services/auth/auth.service.ts index b212e57c7..821b82996 100644 --- a/frontend/src/app/core/services/auth/auth.service.ts +++ b/frontend/src/app/core/services/auth/auth.service.ts @@ -171,13 +171,18 @@ export class AuthService extends BaseService { return observable.pipe( map((x) => this.currentAuthenticationToken(x)), concatMap(response => { - return this.ensureTenant(tenantCode ?? this.selectedTenant() ?? 'default'); + return response ? this.ensureTenant(tenantCode ?? this.selectedTenant() ?? 'default') : null; }), concatMap(response => { - return this.principalService.me(httpParams); + return response ? this.principalService.me(httpParams) : null; + }), + concatMap(response => { + if (response) { + this.currentAccount(response) + } + return of(response); }), concatMap(response => { - this.currentAccount(response); return this.tenantHandlingService.loadTenantCssColors(); }), concatMap(response => { @@ -207,16 +212,10 @@ export class AuthService extends BaseService { if (myTenants.some(x => x.code.toLocaleLowerCase() == tenantCode.toLocaleLowerCase())) { this.selectedTenant(tenantCode); - } else { + } + else { this.selectedTenant(null); } - if (!this.selectedTenant()) { - if (myTenants.length > 0) { - this.selectedTenant(myTenants[0]?.code); - } - } - } else { - this.selectedTenant(null); } return this.selectedTenant(); } diff --git a/frontend/src/app/ui/auth/login/login.component.ts b/frontend/src/app/ui/auth/login/login.component.ts index a3ed7065d..a0bf187fa 100644 --- a/frontend/src/app/ui/auth/login/login.component.ts +++ b/frontend/src/app/ui/auth/login/login.component.ts @@ -37,15 +37,9 @@ export class LoginComponent extends BaseComponent implements OnInit { this.authService.authenticate(this.returnUrl); } else { 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; - - if (this.authService.selectedTenant() != tenantCode) returnUrL = this.routerUtils.generateUrl('/'); - - this.zone.run(() => this.router.navigateByUrl(this.routerUtils.generateUrl(returnUrL))); - }, - (error) => this.authService.authenticate('/')); + let returnUrL = this.returnUrl; + if (this.authService.selectedTenant() != tenantCode) returnUrL = this.routerUtils.generateUrl('/'); + this.zone.run(() => this.router.navigateByUrl(this.routerUtils.generateUrl(returnUrL))); } } } diff --git a/frontend/src/app/ui/description/editor/resolvers/description-editor-entity.resolver.ts b/frontend/src/app/ui/description/editor/resolvers/description-editor-entity.resolver.ts index 9b9669e60..379d45ccf 100644 --- a/frontend/src/app/ui/description/editor/resolvers/description-editor-entity.resolver.ts +++ b/frontend/src/app/ui/description/editor/resolvers/description-editor-entity.resolver.ts @@ -46,6 +46,14 @@ export class DescriptionEditorEntityResolver extends BaseEditorResolver { ] } + public static permissionLookupFields(): string[] { + return [ + nameof(x => x.id), + [nameof(x => x.plan), nameof(x => x.id)].join('.'), + [nameof(x => x.planDescriptionTemplate), nameof(x => x.sectionId)].join('.'), + ] + } + public static descriptionLookupFields(): string[] { return [ ...BaseEditorResolver.lookupFields(), diff --git a/frontend/src/app/ui/description/editor/resolvers/description-editor-permissions.resolver.ts b/frontend/src/app/ui/description/editor/resolvers/description-editor-permissions.resolver.ts index 2809a850b..1dc99a1dd 100644 --- a/frontend/src/app/ui/description/editor/resolvers/description-editor-permissions.resolver.ts +++ b/frontend/src/app/ui/description/editor/resolvers/description-editor-permissions.resolver.ts @@ -27,7 +27,7 @@ export class DescriptionEditorPermissionsResolver extends BaseEditorResolver { resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { const fields = [ - ...DescriptionEditorEntityResolver.lookupFields() + ...DescriptionEditorEntityResolver.permissionLookupFields() ]; const id = route.paramMap.get('id'); const planId = route.paramMap.get('planId'); @@ -36,7 +36,7 @@ export class DescriptionEditorPermissionsResolver extends BaseEditorResolver { // const cloneid = route.paramMap.get('cloneid'); if (id != null && copyPlanId == null && planSectionId == null) { return this.descriptionService.getSingle(Guid.parse(id), fields).pipe(tap(d => this.breadcrumbService.addIdResolvedValue(d.id.toString(), d.label))) - .pipe(mergeMap( description => { + .pipe(mergeMap(description => { const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = { planId: description.plan.id, sectionIds: [description.planDescriptionTemplate.sectionId], @@ -46,54 +46,20 @@ export class DescriptionEditorPermissionsResolver extends BaseEditorResolver { })); } else if (planId != null && planSectionId != null && copyPlanId == null) { - return this.planService.getSingle(Guid.parse(planId), DescriptionEditorEntityResolver.planLookupFields()) - .pipe(tap(x => { - this.breadcrumbService.addExcludedParam(planId, true); - this.breadcrumbService.addIdResolvedValue(planSectionId, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW")); - }), takeUntil(this._destroyed), map(plan => { - const description: Description = {}; - description.plan = plan; - description.planDescriptionTemplate = { - sectionId: Guid.parse(planSectionId) - } - return description; - })) - .pipe(mergeMap( description => { - const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = { - planId: description.plan.id, - sectionIds: [description.planDescriptionTemplate.sectionId], - permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.AnnotateDescription] - } - return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed)); - })); - } else if (copyPlanId != null && id != null && planSectionId != null) { - return this.planService.getSingle(Guid.parse(copyPlanId), DescriptionEditorEntityResolver.planLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(plan => { - //TODO - return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorEntityResolver.cloneLookupFields()) - .pipe(tap(x => { - this.breadcrumbService.addExcludedParam(copyPlanId, true) - this.breadcrumbService.addExcludedParam(planSectionId, true) - this.breadcrumbService.addIdResolvedValue(id, x.label) - }), takeUntil(this._destroyed), map(description => { - description.id = null; - description.hash = null; - description.status = DescriptionStatus.Draft; - description.plan = plan; - description.planDescriptionTemplate = { - id: plan.planDescriptionTemplates.filter(x => x.sectionId == Guid.parse(planSectionId) && x.descriptionTemplateGroupId == description.descriptionTemplate.groupId)[0].id, - sectionId: Guid.parse(planSectionId) - } - return description; - })); - })).pipe(mergeMap( description => { - const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = { - planId: description.plan.id, - sectionIds: [description.planDescriptionTemplate.sectionId], - permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.AnnotateDescription] - } - return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed)); - })); + const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = { + planId: Guid.parse(planId), + sectionIds: [Guid.parse(planSectionId)], + permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.AnnotateDescription] + } + return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed)); + } else if (copyPlanId != null && id != null && planSectionId != null) { + const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = { + planId: Guid.parse(copyPlanId), + sectionIds: [Guid.parse(planSectionId)], + permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.AnnotateDescription] + } + return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed)); } } }