diff --git a/lib/core/src/lib/auth/guard/auth-guard-base.ts b/lib/core/src/lib/auth/guard/auth-guard-base.ts deleted file mode 100644 index 63f3456a267..00000000000 --- a/lib/core/src/lib/auth/guard/auth-guard-base.ts +++ /dev/null @@ -1,132 +0,0 @@ -/*! - * @license - * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, CanActivateChild, UrlTree } from '@angular/router'; -import { AuthenticationService } from '../services/authentication.service'; -import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service'; -import { OauthConfigModel } from '../models/oauth-config.model'; -import { MatDialog } from '@angular/material/dialog'; -import { StorageService } from '../../common/services/storage.service'; -import { Observable } from 'rxjs'; -import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.service'; -import { OidcAuthenticationService } from '../oidc/oidc-authentication.service'; - -export abstract class AuthGuardBase implements CanActivate, CanActivateChild { - protected get withCredentials(): boolean { - return this.appConfigService.get('auth.withCredentials', false); - } - - constructor( - protected authenticationService: AuthenticationService, - protected basicAlfrescoAuthService: BasicAlfrescoAuthService, - protected oidcAuthenticationService: OidcAuthenticationService, - protected router: Router, - protected appConfigService: AppConfigService, - protected dialog: MatDialog, - private storageService: StorageService - ) {} - - abstract checkLogin( - activeRoute: ActivatedRouteSnapshot, - redirectUrl: string - ): Observable | Promise | boolean | UrlTree; - - canActivate( - route: ActivatedRouteSnapshot, - state: RouterStateSnapshot - ): Observable | Promise | boolean | UrlTree { - if (this.authenticationService.isLoggedIn() && this.authenticationService.isOauth() && this.isLoginFragmentPresent()) { - return this.redirectSSOSuccessURL(); - } - - return this.checkLogin(route, state.url); - } - - canActivateChild( - route: ActivatedRouteSnapshot, - state: RouterStateSnapshot - ): Observable | Promise | boolean | UrlTree { - return this.canActivate(route, state); - } - - protected async redirectSSOSuccessURL(): Promise { - const redirectFragment = this.storageService.getItem('loginFragment'); - - if (redirectFragment && this.getLoginRoute() !== redirectFragment) { - await this.navigate(redirectFragment); - this.storageService.removeItem('loginFragment'); - return false; - } - - return true; - } - - protected isLoginFragmentPresent(): boolean { - return !!this.storageService.getItem('loginFragment'); - } - - protected async redirectToUrl(url: string): Promise { - let urlToRedirect = `/${this.getLoginRoute()}`; - - if (!this.authenticationService.isOauth()) { - this.basicAlfrescoAuthService.setRedirect({ - provider: this.getProvider(), - url - }); - - urlToRedirect = `${urlToRedirect}?redirectUrl=${url}`; - return this.navigate(urlToRedirect); - } else if (this.getOauthConfig().silentLogin && !this.oidcAuthenticationService.isPublicUrl()) { - if (!this.oidcAuthenticationService.hasValidIdToken() || !this.oidcAuthenticationService.hasValidAccessToken()) { - this.oidcAuthenticationService.ssoLogin(url); - } - } else { - return this.navigate(urlToRedirect); - } - - return false; - } - - protected async navigate(url: string): Promise { - this.dialog.closeAll(); - await this.router.navigateByUrl(this.router.parseUrl(url)); - return false; - } - - protected getOauthConfig(): OauthConfigModel { - return this.appConfigService && this.appConfigService.get(AppConfigValues.OAUTHCONFIG, null); - } - - protected getLoginRoute(): string { - return this.appConfigService.get(AppConfigValues.LOGIN_ROUTE, 'login'); - } - - protected getProvider(): string { - return this.appConfigService.get(AppConfigValues.PROVIDERS, 'ALL'); - } - - protected isOAuthWithoutSilentLogin(): boolean { - const oauth = this.appConfigService.get(AppConfigValues.OAUTHCONFIG, null); - return this.authenticationService.isOauth() && !!oauth && !oauth.silentLogin; - } - - protected isSilentLogin(): boolean { - const oauth = this.appConfigService.get(AppConfigValues.OAUTHCONFIG, null); - - return this.authenticationService.isOauth() && oauth && oauth.silentLogin; - } -} diff --git a/lib/core/src/lib/auth/guard/auth-guard-bpm.service.ts b/lib/core/src/lib/auth/guard/auth-guard-bpm.service.ts index eb575e3cbdf..3d7a2b9961e 100644 --- a/lib/core/src/lib/auth/guard/auth-guard-bpm.service.ts +++ b/lib/core/src/lib/auth/guard/auth-guard-bpm.service.ts @@ -15,36 +15,27 @@ * limitations under the License. */ -import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, Router, UrlTree } from '@angular/router'; -import { AppConfigService } from '../../app-config/app-config.service'; +import { inject } from '@angular/core'; +import { ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router'; import { AuthenticationService } from '../services/authentication.service'; -import { AuthGuardBase } from './auth-guard-base'; -import { MatDialog } from '@angular/material/dialog'; -import { StorageService } from '../../common/services/storage.service'; -import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.service'; -import { OidcAuthenticationService } from '../oidc/oidc-authentication.service'; +import { isLoginFragmentPresent, redirectSSOSuccessURL, redirectToUrl, withCredentials } from './auth-guard-functions'; +import { Observable } from 'rxjs'; -@Injectable({ - providedIn: 'root' -}) -export class AuthGuardBpm extends AuthGuardBase { - constructor( - authenticationService: AuthenticationService, - basicAlfrescoAuthService: BasicAlfrescoAuthService, - oidcAuthenticationService: OidcAuthenticationService, - router: Router, - appConfigService: AppConfigService, - dialog: MatDialog, - storageService: StorageService - ) { - super(authenticationService, basicAlfrescoAuthService, oidcAuthenticationService, router, appConfigService, dialog, storageService); +const authenticationService = inject(AuthenticationService); + +const checkLogin = async (_: ActivatedRouteSnapshot, redirectUrl: string): Promise => { + if (authenticationService.isBpmLoggedIn() || withCredentials) { + return true; } + return redirectToUrl(redirectUrl); +}; - async checkLogin(_: ActivatedRouteSnapshot, redirectUrl: string): Promise { - if (this.authenticationService.isBpmLoggedIn() || this.withCredentials) { - return true; - } - return this.redirectToUrl(redirectUrl); +export const AuthGuardBpm = ( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot +): Observable | Promise | boolean | UrlTree => { + if (authenticationService.isLoggedIn() && authenticationService.isOauth() && isLoginFragmentPresent()) { + return redirectSSOSuccessURL(); } -} + return checkLogin(route, state.url); +}; diff --git a/lib/core/src/lib/auth/guard/auth-guard-ecm.service.ts b/lib/core/src/lib/auth/guard/auth-guard-ecm.service.ts index d5bdf482e54..4b32b048160 100644 --- a/lib/core/src/lib/auth/guard/auth-guard-ecm.service.ts +++ b/lib/core/src/lib/auth/guard/auth-guard-ecm.service.ts @@ -15,37 +15,27 @@ * limitations under the License. */ -import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, Router, UrlTree } from '@angular/router'; +import { inject } from '@angular/core'; +import { ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router'; import { AuthenticationService } from '../services/authentication.service'; -import { AppConfigService } from '../../app-config/app-config.service'; -import { AuthGuardBase } from './auth-guard-base'; -import { MatDialog } from '@angular/material/dialog'; -import { StorageService } from '../../common/services/storage.service'; -import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.service'; -import { OidcAuthenticationService } from '../oidc/oidc-authentication.service'; +import { isLoginFragmentPresent, redirectSSOSuccessURL, redirectToUrl, withCredentials } from './auth-guard-functions'; +import { Observable } from 'rxjs'; -@Injectable({ - providedIn: 'root' -}) -export class AuthGuardEcm extends AuthGuardBase { - constructor( - authenticationService: AuthenticationService, - basicAlfrescoAuthService: BasicAlfrescoAuthService, - oidcAuthenticationService: OidcAuthenticationService, - router: Router, - appConfigService: AppConfigService, - dialog: MatDialog, - storageService: StorageService - ) { - super(authenticationService, basicAlfrescoAuthService, oidcAuthenticationService, router, appConfigService, dialog, storageService); - } +const authenticationService = inject(AuthenticationService); - async checkLogin(_: ActivatedRouteSnapshot, redirectUrl: string): Promise { - if (this.authenticationService.isEcmLoggedIn() || this.withCredentials) { - return true; - } +const checkLogin = async (_: ActivatedRouteSnapshot, redirectUrl: string): Promise => { + if (authenticationService.isEcmLoggedIn() || withCredentials()) { + return true; + } + return redirectToUrl(redirectUrl); +}; - return this.redirectToUrl(redirectUrl); +export const AuthGuardEcm = ( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot +): Observable | Promise | boolean | UrlTree => { + if (authenticationService.isLoggedIn() && authenticationService.isOauth() && isLoginFragmentPresent()) { + return redirectSSOSuccessURL(); } -} + return checkLogin(route, state.url); +}; diff --git a/lib/core/src/lib/auth/guard/auth-guard-functions.ts b/lib/core/src/lib/auth/guard/auth-guard-functions.ts new file mode 100644 index 00000000000..98a9ee670ee --- /dev/null +++ b/lib/core/src/lib/auth/guard/auth-guard-functions.ts @@ -0,0 +1,82 @@ +/*! + * @license + * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Router, UrlTree } from '@angular/router'; +import { inject } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { AuthenticationService } from '../services/authentication.service'; +import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service'; +import { OauthConfigModel } from '../models/oauth-config.model'; +import { StorageService } from '../../common/services/storage.service'; +import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.service'; +import { OidcAuthenticationService } from '../oidc/oidc-authentication.service'; + +const authenticationService = inject(AuthenticationService); +const basicAlfrescoAuthService = inject(BasicAlfrescoAuthService); +const oidcAuthenticationService = inject(OidcAuthenticationService); +const router = inject(Router); +const appConfigService = inject(AppConfigService); +const dialog = inject(MatDialog); +const storageService = inject(StorageService); + +const getOauthConfig = (): OauthConfigModel => appConfigService?.get(AppConfigValues.OAUTHCONFIG, null); + +const getLoginRoute = (): string => appConfigService.get(AppConfigValues.LOGIN_ROUTE, 'login'); + +const getProvider = (): string => appConfigService.get(AppConfigValues.PROVIDERS, 'ALL'); + +export const isLoginFragmentPresent = (): boolean => !!storageService.getItem('loginFragment'); + +export const withCredentials = (): boolean => appConfigService.get('auth.withCredentials', false); + +export const navigate = async (url: string): Promise => { + dialog.closeAll(); + await router.navigateByUrl(router.parseUrl(url)); + return false; +}; + +export const redirectToUrl = async (url: string): Promise => { + let urlToRedirect = `/${getLoginRoute()}`; + + if (!authenticationService.isOauth()) { + basicAlfrescoAuthService.setRedirect({ + provider: getProvider(), + url + }); + + urlToRedirect = `${urlToRedirect}?redirectUrl=${url}`; + return navigate(urlToRedirect); + } else if (getOauthConfig().silentLogin && !oidcAuthenticationService.isPublicUrl()) { + if (!oidcAuthenticationService.hasValidIdToken() || !oidcAuthenticationService.hasValidAccessToken()) { + oidcAuthenticationService.ssoLogin(url); + } + } else { + return navigate(urlToRedirect); + } + + return false; +}; + +export const redirectSSOSuccessURL = async (): Promise => { + const redirectFragment = storageService.getItem('loginFragment'); + if (redirectFragment && getLoginRoute() !== redirectFragment) { + await navigate(redirectFragment); + storageService.removeItem('loginFragment'); + return false; + } + return true; +}; diff --git a/lib/core/src/lib/auth/guard/auth-guard.service.ts b/lib/core/src/lib/auth/guard/auth-guard.service.ts index 62d9bcef2b4..1a14b05de68 100644 --- a/lib/core/src/lib/auth/guard/auth-guard.service.ts +++ b/lib/core/src/lib/auth/guard/auth-guard.service.ts @@ -15,36 +15,26 @@ * limitations under the License. */ -import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, Router, UrlTree } from '@angular/router'; +import { inject, Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, UrlTree } from '@angular/router'; import { AuthenticationService } from '../services/authentication.service'; -import { AppConfigService } from '../../app-config/app-config.service'; -import { AuthGuardBase } from './auth-guard-base'; +import { isLoginFragmentPresent, navigate, redirectSSOSuccessURL, redirectToUrl, withCredentials } from './auth-guard-functions'; import { JwtHelperService } from '../services/jwt-helper.service'; -import { MatDialog } from '@angular/material/dialog'; -import { StorageService } from '../../common/services/storage.service'; -import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.service'; -import { OidcAuthenticationService } from '../oidc/oidc-authentication.service'; +import { Observable } from 'rxjs'; + +const authenticationService = inject(AuthenticationService); @Injectable({ providedIn: 'root' }) -export class AuthGuard extends AuthGuardBase { +class TicketChangeRedirectService { ticketChangeBind: any; constructor( private jwtHelperService: JwtHelperService, - authenticationService: AuthenticationService, - basicAlfrescoAuthService: BasicAlfrescoAuthService, - oidcAuthenticationService: OidcAuthenticationService, - router: Router, - appConfigService: AppConfigService, - dialog: MatDialog, - storageService: StorageService + private router: Router ) { - super(authenticationService, basicAlfrescoAuthService, oidcAuthenticationService, router, appConfigService, dialog, storageService); this.ticketChangeBind = this.ticketChange.bind(this); - window.addEventListener('storage', this.ticketChangeBind); } @@ -68,16 +58,27 @@ export class AuthGuard extends AuthGuardBase { private ticketChangeRedirect(event: StorageEvent) { if (event.newValue) { - this.navigate(this.router.url); + navigate(this.router.url); } else { window.location.reload(); } } +} - async checkLogin(_: ActivatedRouteSnapshot, redirectUrl: string): Promise { - if (this.authenticationService.isLoggedIn() || this.withCredentials) { - return true; - } - return this.redirectToUrl(redirectUrl); +const checkLogin = async (_: ActivatedRouteSnapshot, redirectUrl: string): Promise => { + if (authenticationService.isLoggedIn() || withCredentials()) { + return true; } -} + return redirectToUrl(redirectUrl); +}; + +export const AuthGuard = ( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot +): Observable | Promise | boolean | UrlTree => { + inject(TicketChangeRedirectService); + if (authenticationService.isLoggedIn() && authenticationService.isOauth() && isLoginFragmentPresent()) { + return redirectSSOSuccessURL(); + } + return checkLogin(route, state.url); +}; diff --git a/lib/core/src/lib/auth/public-api.ts b/lib/core/src/lib/auth/public-api.ts index ceeda1f08b9..40533c20e8f 100644 --- a/lib/core/src/lib/auth/public-api.ts +++ b/lib/core/src/lib/auth/public-api.ts @@ -17,7 +17,7 @@ export * from './authentication-interceptor/auth-bearer.interceptor'; -export * from './guard/auth-guard-base'; +export * from './guard/auth-guard-functions'; export * from './guard/auth-guard.service'; export * from './guard/auth-guard-ecm.service'; export * from './guard/auth-guard-bpm.service';