diff --git a/npm/ng-packs/apps/dev-app/src/environments/environment.prod.ts b/npm/ng-packs/apps/dev-app/src/environments/environment.prod.ts index bf9e904522..a4a80e11ad 100644 --- a/npm/ng-packs/apps/dev-app/src/environments/environment.prod.ts +++ b/npm/ng-packs/apps/dev-app/src/environments/environment.prod.ts @@ -16,6 +16,7 @@ export const environment = { clientId: 'MyProjectName_App', responseType: 'code', scope: 'offline_access MyProjectName', + ssrAuthenticationUrl: '/authorize' }, apis: { default: { diff --git a/npm/ng-packs/apps/dev-app/src/environments/environment.ts b/npm/ng-packs/apps/dev-app/src/environments/environment.ts index 1e014dcaa7..1020d8a7ee 100644 --- a/npm/ng-packs/apps/dev-app/src/environments/environment.ts +++ b/npm/ng-packs/apps/dev-app/src/environments/environment.ts @@ -16,6 +16,7 @@ export const environment = { scope: 'offline_access MyProjectName', responseType: 'code', redirectUri: baseUrl, + ssrAuthorizationUrl: '/authorize' }, apis: { default: { diff --git a/npm/ng-packs/apps/dev-app/src/server.ts b/npm/ng-packs/apps/dev-app/src/server.ts index 0642a43894..110392109f 100644 --- a/npm/ng-packs/apps/dev-app/src/server.ts +++ b/npm/ng-packs/apps/dev-app/src/server.ts @@ -135,7 +135,7 @@ app.get('/', async (req, res, next) => { const returnUrl = req.cookies.returnUrl || '/'; res.clearCookie('returnUrl', secureCookie); - return res.redirect('/'); + return res.redirect(returnUrl); } catch (e) { console.error('OIDC error:', e); return res.status(500).send('oidc error'); diff --git a/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts b/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts index 020f750555..8a24e465cd 100644 --- a/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts +++ b/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts @@ -26,4 +26,4 @@ export const authGuard: CanActivateFn = () => { export const asyncAuthGuard: CanActivateFn = () => { console.error('You should add @abp/ng-oauth packages or create your own auth packages.'); return false; -}; \ No newline at end of file +}; diff --git a/npm/ng-packs/packages/core/src/lib/models/environment.ts b/npm/ng-packs/packages/core/src/lib/models/environment.ts index 069fb9bd7c..feb14aa2dd 100644 --- a/npm/ng-packs/packages/core/src/lib/models/environment.ts +++ b/npm/ng-packs/packages/core/src/lib/models/environment.ts @@ -7,7 +7,7 @@ export interface Environment { hmr?: boolean; test?: boolean; localization?: { defaultResourceName?: string }; - oAuthConfig?: AuthConfig & { impersonation?: Impersonation }; + oAuthConfig?: AuthConfig & { impersonation?: Impersonation, ssrAuthorizationUrl?: string }; production: boolean; remoteEnv?: RemoteEnv; [key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any 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 1311a8d7a8..954094fe00 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,15 +1,16 @@ -import { Injectable, inject } from '@angular/core'; +import { Injectable, inject, PLATFORM_ID, RESPONSE_INIT } from '@angular/core'; import { UrlTree, ActivatedRouteSnapshot, RouterStateSnapshot, - CanActivateFn, + CanActivateFn, Params, } from '@angular/router'; import { Observable, timer, filter, take, map, firstValueFrom, timeout, catchError, of } from 'rxjs'; import { OAuthService } from 'angular-oauth2-oidc'; import { AuthService, IAbpGuard, EnvironmentService } from '@abp/ng.core'; +import { isPlatformServer } from '@angular/common'; /** * @deprecated Use `abpOAuthGuard` *function* instead. @@ -42,6 +43,9 @@ export const abpOAuthGuard: CanActivateFn = ( ) => { const oAuthService = inject(OAuthService); const authService = inject(AuthService); + const platformId = inject(PLATFORM_ID); + const resInit = inject(RESPONSE_INIT); + const environmentService = inject(EnvironmentService); const hasValidAccessToken = oAuthService.hasValidAccessToken(); @@ -50,10 +54,30 @@ export const abpOAuthGuard: CanActivateFn = ( } const params = { returnUrl: state.url }; + if (isPlatformServer(platformId) && resInit) { + const ssrAuthorizationUrl = environmentService.getEnvironment().oAuthConfig.ssrAuthorizationUrl; + const url = buildLoginUrl(ssrAuthorizationUrl, params); + const headers = new Headers(resInit.headers); + headers.set('Location', url); + resInit.status = 302; + resInit.statusText = 'Found'; + resInit.headers = headers; + return; + } authService.navigateToLogin(params); return false; }; +export const buildLoginUrl = (path: string, params?: Params): string => { + if (!params || Object.keys(params).length === 0) return path; + const usp = new URLSearchParams(); + for (const [k, v] of Object.entries(params)) { + if (v == null) continue; + Array.isArray(v) ? v.forEach(x => usp.append(k, String(x))) : usp.set(k, String(v)); + } + return `${path}?${usp.toString()}`; +} + export const asyncAbpOAuthGuard: CanActivateFn = ( route: ActivatedRouteSnapshot, state: RouterStateSnapshot,