Merge pull request #3983 from atmire/no-platform-specific-code-in-abstract-services-7_x

No platform specific code in abstract services 7_x
This commit is contained in:
Tim Donohue
2025-04-03 12:11:45 -05:00
committed by GitHub
5 changed files with 79 additions and 34 deletions

View File

@@ -260,7 +260,7 @@ describe('AuthService test', () => {
(state as any).core = Object.create({}); (state as any).core = Object.create({});
(state as any).core.auth = authenticatedState; (state as any).core.auth = authenticatedState;
}); });
authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
})); }));
it('should return true when user is logged in', () => { it('should return true when user is logged in', () => {
@@ -345,7 +345,7 @@ describe('AuthService test', () => {
(state as any).core = Object.create({}); (state as any).core = Object.create({});
(state as any).core.auth = authenticatedState; (state as any).core.auth = authenticatedState;
}); });
authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
storage = (authService as any).storage; storage = (authService as any).storage;
routeServiceMock = TestBed.inject(RouteService); routeServiceMock = TestBed.inject(RouteService);
routerStub = TestBed.inject(Router); routerStub = TestBed.inject(Router);
@@ -565,7 +565,7 @@ describe('AuthService test', () => {
(state as any).core = Object.create({}); (state as any).core = Object.create({});
(state as any).core.auth = unAuthenticatedState; (state as any).core.auth = unAuthenticatedState;
}); });
authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
})); }));
it('should return null for the shortlived token', () => { it('should return null for the shortlived token', () => {
@@ -605,7 +605,7 @@ describe('AuthService test', () => {
(state as any).core = Object.create({}); (state as any).core = Object.create({});
(state as any).core.auth = idleState; (state as any).core.auth = idleState;
}); });
authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService);
})); }));
it('isUserIdle should return true when user is not idle', () => { it('isUserIdle should return true when user is not idle', () => {

View File

@@ -1,7 +1,6 @@
import { Inject, Injectable, Optional } from '@angular/core'; import { Inject, Injectable } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { HttpHeaders } from '@angular/common/http'; import { HttpHeaders } from '@angular/common/http';
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
import { Observable, of as observableOf } from 'rxjs'; import { Observable, of as observableOf } from 'rxjs';
import { filter, map, startWith, switchMap, take } from 'rxjs/operators'; import { filter, map, startWith, switchMap, take } from 'rxjs/operators';
@@ -79,18 +78,17 @@ export class AuthService {
*/ */
private tokenRefreshTimer; private tokenRefreshTimer;
constructor(@Inject(REQUEST) protected req: any, constructor(
@Inject(NativeWindowService) protected _window: NativeWindowRef, @Inject(NativeWindowService) protected _window: NativeWindowRef,
@Optional() @Inject(RESPONSE) private response: any, protected authRequestService: AuthRequestService,
protected authRequestService: AuthRequestService, protected epersonService: EPersonDataService,
protected epersonService: EPersonDataService, protected router: Router,
protected router: Router, protected routeService: RouteService,
protected routeService: RouteService, protected storage: CookieService,
protected storage: CookieService, protected store: Store<AppState>,
protected store: Store<AppState>, protected hardRedirectService: HardRedirectService,
protected hardRedirectService: HardRedirectService, protected notificationService: NotificationsService,
private notificationService: NotificationsService, protected translateService: TranslateService
private translateService: TranslateService
) { ) {
this.store.pipe( this.store.pipe(
// when this service is constructed the store is not fully initialized yet // when this service is constructed the store is not fully initialized yet
@@ -473,10 +471,6 @@ export class AuthService {
if (this._window.nativeWindow.location) { if (this._window.nativeWindow.location) {
// Hard redirect to login page, so that all state is definitely lost // Hard redirect to login page, so that all state is definitely lost
this._window.nativeWindow.location.href = redirectUrl; this._window.nativeWindow.location.href = redirectUrl;
} else if (this.response) {
if (!this.response._headerSent) {
this.response.redirect(302, redirectUrl);
}
} else { } else {
this.router.navigateByUrl(redirectUrl); this.router.navigateByUrl(redirectUrl);
} }

View File

@@ -1,15 +1,25 @@
import { Injectable } from '@angular/core'; import { Injectable, Inject, Optional } from '@angular/core';
import { HttpHeaders } from '@angular/common/http'; import { HttpHeaders } from '@angular/common/http';
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { hasValue, isNotEmpty } from '../../shared/empty.util';
import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { HttpOptions } from '../dspace-rest/dspace-rest.service';
import { AuthService } from './auth.service'; import { AuthService, LOGIN_ROUTE } from './auth.service';
import { AuthStatus } from './models/auth-status.model'; import { AuthStatus } from './models/auth-status.model';
import { AuthTokenInfo } from './models/auth-token-info.model'; import { AuthTokenInfo } from './models/auth-token-info.model';
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { NativeWindowService, NativeWindowRef } from '../services/window.service';
import { AuthRequestService } from './auth-request.service';
import { EPersonDataService } from '../eperson/eperson-data.service';
import { Router } from '@angular/router';
import { RouteService } from '../services/route.service';
import { CookieService } from '../services/cookie.service';
import { Store } from '@ngrx/store';
import { AppState } from '../../app.reducer';
import { HardRedirectService } from '../services/hard-redirect.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core';
/** /**
* The auth service. * The auth service.
@@ -17,6 +27,34 @@ import { RemoteData } from '../data/remote-data';
@Injectable() @Injectable()
export class ServerAuthService extends AuthService { export class ServerAuthService extends AuthService {
constructor(
@Inject(REQUEST) protected req: any,
@Optional() @Inject(RESPONSE) private response: any,
@Inject(NativeWindowService) protected _window: NativeWindowRef,
protected authRequestService: AuthRequestService,
protected epersonService: EPersonDataService,
protected router: Router,
protected routeService: RouteService,
protected storage: CookieService,
protected store: Store<AppState>,
protected hardRedirectService: HardRedirectService,
protected notificationService: NotificationsService,
protected translateService: TranslateService
) {
super(
_window,
authRequestService,
epersonService,
router,
routeService,
storage,
store,
hardRedirectService,
notificationService,
translateService
);
}
/** /**
* Returns the authenticated user * Returns the authenticated user
* @returns {User} * @returns {User}
@@ -60,4 +98,18 @@ export class ServerAuthService extends AuthService {
map((rd: RemoteData<AuthStatus>) => Object.assign(new AuthStatus(), rd.payload)) map((rd: RemoteData<AuthStatus>) => Object.assign(new AuthStatus(), rd.payload))
); );
} }
override redirectToLoginWhenTokenExpired() {
const redirectUrl = LOGIN_ROUTE + '?expired=true';
if (this._window.nativeWindow.location) {
// Hard redirect to login page, so that all state is definitely lost
this._window.nativeWindow.location.href = redirectUrl;
} else if (this.response) {
if (!this.response._headerSent) {
this.response.redirect(302, redirectUrl);
}
} else {
this.router.navigateByUrl(redirectUrl);
}
}
} }

View File

@@ -1,7 +1,4 @@
import { Inject, Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { REQUEST } from '@nguniversal/express-engine/tokens';
import { Subject , Observable } from 'rxjs'; import { Subject , Observable } from 'rxjs';
import { CookieAttributes } from 'js-cookie'; import { CookieAttributes } from 'js-cookie';
@@ -22,9 +19,6 @@ export abstract class CookieService implements ICookieService {
protected readonly cookieSource = new Subject<{ readonly [key: string]: any }>(); protected readonly cookieSource = new Subject<{ readonly [key: string]: any }>();
public readonly cookies$ = this.cookieSource.asObservable(); public readonly cookies$ = this.cookieSource.asObservable();
constructor(@Inject(REQUEST) protected req: any) {
}
public abstract set(name: string, value: any, options?: CookieAttributes): void; public abstract set(name: string, value: any, options?: CookieAttributes): void;
public abstract remove(name: string, options?: CookieAttributes): void; public abstract remove(name: string, options?: CookieAttributes): void;

View File

@@ -1,10 +1,15 @@
import { Injectable } from '@angular/core'; import { Injectable, Inject } from '@angular/core';
import { CookieAttributes } from 'js-cookie'; import { CookieAttributes } from 'js-cookie';
import { CookieService, ICookieService } from './cookie.service'; import { CookieService, ICookieService } from './cookie.service';
import { REQUEST } from '@nguniversal/express-engine/tokens';
@Injectable() @Injectable()
export class ServerCookieService extends CookieService implements ICookieService { export class ServerCookieService extends CookieService implements ICookieService {
constructor(@Inject(REQUEST) protected req: any) {
super();
}
public set(name: string, value: any, options?: CookieAttributes): void { public set(name: string, value: any, options?: CookieAttributes): void {
return; return;
} }