From a348c870103d43d38dfbe3460c15c364f0d5592f Mon Sep 17 00:00:00 2001 From: Masum ULU Date: Tue, 16 May 2023 17:30:08 +0300 Subject: [PATCH] Redirect to previous url after login Allowed --- .../oauth/src/lib/guards/oauth.guard.ts | 10 +++++-- .../lib/strategies/auth-code-flow-strategy.ts | 10 ++++++- .../src/lib/strategies/auth-flow-strategy.ts | 30 +++++++++++++++++-- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts b/npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts index 357e861ba0..4b2d95af74 100644 --- a/npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts +++ b/npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { CanActivate, UrlTree } from '@angular/router'; +import { CanActivate, UrlTree, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { OAuthService } from 'angular-oauth2-oidc'; import { Observable } from 'rxjs'; import { AuthService, IAuthGuard } from '@abp/ng.core'; @@ -10,13 +10,17 @@ import { AuthService, IAuthGuard } from '@abp/ng.core'; export class AbpOAuthGuard implements CanActivate, IAuthGuard { constructor(private oauthService: OAuthService, private authService: AuthService) {} - canActivate(): Observable | boolean | UrlTree { + canActivate( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot, + ): Observable | boolean | UrlTree { const hasValidAccessToken = this.oauthService.hasValidAccessToken(); if (hasValidAccessToken) { return true; } - this.authService.navigateToLogin(); + const params = { returnUrl: state.url }; + this.authService.navigateToLogin(params); return false; } } diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts index 946d1295ca..ab70febb3c 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts @@ -14,7 +14,10 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { } navigateToLogin(queryParams?: Params) { - this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams)); + this.oAuthService.initCodeFlow( + this.getAdditionalState(queryParams), + this.getCultureParams(queryParams), + ); } checkIfInternalAuth(queryParams?: Params) { @@ -31,6 +34,11 @@ export class AuthCodeFlowStrategy extends AuthFlowStrategy { return of(null); } + private getAdditionalState(queryParams?: Params): string { + const { returnUrl } = queryParams; + return returnUrl; + } + private getCultureParams(queryParams?: Params) { const lang = this.sessionState.getLanguage(); const culture = { culture: lang, 'ui-culture': lang }; diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts index 7a07cb8985..039565f8cf 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts @@ -1,5 +1,5 @@ import { Injector } from '@angular/core'; -import { Params } from '@angular/router'; +import { Params, Router } from '@angular/router'; import { AuthConfig, OAuthErrorEvent, @@ -7,7 +7,7 @@ import { OAuthStorage, } from 'angular-oauth2-oidc'; import { Observable, of } from 'rxjs'; -import { filter, switchMap, tap } from 'rxjs/operators'; +import { filter, map, switchMap, tap } from 'rxjs/operators'; import { ConfigStateService, EnvironmentService, @@ -30,6 +30,7 @@ export abstract class AuthFlowStrategy { protected oAuthConfig!: AuthConfig; protected sessionState: SessionStateService; protected tenantKey: string; + protected router: Router; abstract checkIfInternalAuth(queryParams?: Params): boolean; @@ -52,6 +53,7 @@ export abstract class AuthFlowStrategy { this.sessionState = injector.get(SessionStateService); this.oAuthConfig = this.environment.getEnvironment().oAuthConfig || {}; this.tenantKey = injector.get(TENANT_KEY); + this.router = injector.get(Router); this.listenToOauthErrors(); } @@ -68,6 +70,8 @@ export abstract class AuthFlowStrategy { .pipe(filter(event => event.type === 'token_refresh_error')) .subscribe(() => this.navigateToLogin()); + this.navigateToPreviousUrl(); + return this.oAuthService .loadDiscoveryDocument() .then(() => { @@ -80,6 +84,28 @@ export abstract class AuthFlowStrategy { .catch(this.catchError); } + protected navigateToPreviousUrl() { + this.oAuthService.events + .pipe( + filter(event => event.type === 'token_received' && !!this.oAuthService.state), + map(() => { + const redirect_uri = decodeURIComponent(this.oAuthService.state); + + if (redirect_uri && redirect_uri !== '/') { + return redirect_uri; + } + return '/'; + }), + switchMap(redirectUri => + this.configState.getOne$('currentUser').pipe( + filter(user => Boolean(user?.isAuthenticated)), + tap(() => this.router.navigate([redirectUri])), + ), + ), + ) + .subscribe(); + } + protected refreshToken() { return this.oAuthService.refreshToken().catch(() => clearOAuthStorage()); }