Merge branch 'no-platform-specific-code-in-abstract-services-7.6' into no-platform-specific-code-in-abstract-services-main

# Conflicts:
#	src/app/core/auth/auth.service.ts
#	src/app/core/auth/server-auth.service.ts
#	src/app/core/services/cookie.service.ts
#	src/app/core/services/server-cookie.service.ts
This commit is contained in:
Andreas Awouters
2025-02-13 14:38:40 +01:00
5 changed files with 94 additions and 37 deletions

View File

@@ -288,7 +288,7 @@ describe('AuthService test', () => {
(state as any).core = Object.create({});
(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', () => {
@@ -373,7 +373,7 @@ describe('AuthService test', () => {
(state as any).core = Object.create({});
(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;
routeServiceMock = TestBed.inject(RouteService);
routerStub = TestBed.inject(Router);
@@ -593,7 +593,7 @@ describe('AuthService test', () => {
(state as any).core = Object.create({});
(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', () => {
@@ -633,7 +633,7 @@ describe('AuthService test', () => {
(state as any).core = Object.create({});
(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', () => {

View File

@@ -2,7 +2,6 @@ import { HttpHeaders } from '@angular/common/http';
import {
Inject,
Injectable,
Optional,
} from '@angular/core';
import { Router } from '@angular/router';
import {
@@ -24,10 +23,6 @@ import {
} from 'rxjs/operators';
import { environment } from '../../../environments/environment';
import {
REQUEST,
RESPONSE,
} from '../../../express.tokens';
import { AppState } from '../../app.reducer';
import {
hasNoValue,
@@ -111,18 +106,17 @@ export class AuthService {
*/
private tokenRefreshTimer;
constructor(@Inject(REQUEST) protected req: any,
@Inject(NativeWindowService) protected _window: NativeWindowRef,
@Optional() @Inject(RESPONSE) private response: any,
protected authRequestService: AuthRequestService,
protected epersonService: EPersonDataService,
protected router: Router,
protected routeService: RouteService,
protected storage: CookieService,
protected store: Store<AppState>,
protected hardRedirectService: HardRedirectService,
private notificationService: NotificationsService,
private translateService: TranslateService,
constructor(
@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,
) {
this.store.pipe(
// when this service is constructed the store is not fully initialized yet
@@ -504,10 +498,6 @@ export class AuthService {
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,15 +1,40 @@
import { HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import {
Inject,
Injectable,
Optional,
} from '@angular/core';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import {
REQUEST,
RESPONSE,
} from '../../../express.tokens';
import { AppState } from '../../app.reducer';
import {
hasValue,
isNotEmpty,
} from '../../shared/empty.util';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { RemoteData } from '../data/remote-data';
import { HttpOptions } from '../dspace-rest/dspace-rest.service';
import { AuthService } from './auth.service';
import { EPersonDataService } from '../eperson/eperson-data.service';
import { CookieService } from '../services/cookie.service';
import { HardRedirectService } from '../services/hard-redirect.service';
import { RouteService } from '../services/route.service';
import {
NativeWindowRef,
NativeWindowService,
} from '../services/window.service';
import {
AuthService,
LOGIN_ROUTE,
} from './auth.service';
import { AuthRequestService } from './auth-request.service';
import { AuthStatus } from './models/auth-status.model';
import { AuthTokenInfo } from './models/auth-token-info.model';
@@ -19,6 +44,34 @@ import { AuthTokenInfo } from './models/auth-token-info.model';
@Injectable()
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 {User}
@@ -62,4 +115,18 @@ export class ServerAuthService extends AuthService {
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,15 +1,10 @@
import {
Inject,
Injectable,
} from '@angular/core';
import { Injectable } from '@angular/core';
import { CookieAttributes } from 'js-cookie';
import {
Observable,
Subject,
} from 'rxjs';
import { REQUEST } from '../../../express.tokens';
export interface ICookieService {
readonly cookies$: Observable<{ readonly [key: string]: any }>;
@@ -27,9 +22,6 @@ export abstract class CookieService implements ICookieService {
protected readonly cookieSource = new Subject<{ readonly [key: string]: any }>();
public readonly cookies$ = this.cookieSource.asObservable();
constructor(@Inject(REQUEST) protected req: any) {
}
public abstract set(name: string, value: any, options?: CookieAttributes): void;
public abstract remove(name: string, options?: CookieAttributes): void;

View File

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