From 3833b338a060e16161768f8238716a40048d4250 Mon Sep 17 00:00:00 2001
From: Homada Boumedane <homada.boumedane@unige.ch>
Date: Fri, 5 Jul 2019 15:22:11 +0200
Subject: [PATCH] refactor(dlcm-portal): refactor code

Create core folder and move all singletons services inside
---
 src/app/access/access.state.ts                |  2 +-
 src/app/app-routing.module.ts                 |  2 +-
 src/app/app.component.ts                      |  5 +-
 src/app/app.module.ts                         | 55 ++++++++++++++-----
 src/app/app.state.ts                          |  4 +-
 src/app/auth.config.ts                        |  4 +-
 src/app/components/home/home.component.ts     |  4 +-
 src/app/components/login/login.component.ts   |  4 +-
 .../main-toolbar-mobile.component.ts          |  4 +-
 .../main-toolbar/main-toolbar.component.ts    |  9 +--
 src/app/{oauth => core/auth}/auth.config.ts   |  0
 src/app/{oauth => core/auth}/base64-helper.ts |  0
 src/app/{oauth => core/auth}/encoder.ts       |  3 +-
 src/app/{oauth => core/auth}/events.ts        |  0
 .../auth}/oauth-module.config.ts              |  0
 .../auth/oauth2.service.ts}                   | 22 +++-----
 src/app/{oauth => core/auth}/types.ts         |  6 +-
 .../custom-mat-paginator-intl.service.ts      |  4 +-
 .../services => core}/error.service.ts        |  0
 .../global-errors-handler.service.ts          | 10 ++--
 .../guards}/auth-guard.service.ts             |  4 +-
 .../helpers}/url-helper.service.ts            |  6 +-
 .../services => core/http}/api.service.ts     |  4 +-
 .../http/oauth2-interceptor.service.spec.ts   | 12 ++++
 .../http/oauth2-interceptor.service.ts}       | 19 ++++---
 .../services => core}/logging.service.ts      |  0
 .../services => core}/notification.service.ts |  2 +-
 src/app/deposit/deposit.state.ts              |  4 +-
 .../directives/main-toolbar.directive.spec.ts |  6 +-
 src/app/directives/main-toolbar.directive.ts  |  4 +-
 src/app/dlcm.storage.ts                       | 31 -----------
 src/app/oauth/dlcm-oauth-oidic.module.ts      | 51 -----------------
 .../resource-server-error-handler.ts          | 13 -----
 src/app/shared/crud.state.ts                  |  5 +-
 src/app/shared/language.state.ts              |  4 +-
 src/app/shared/license.state.ts               |  4 +-
 src/app/shared/organizational-unit.state.ts   |  4 +-
 src/app/shared/preservation-policy.state.ts   |  4 +-
 src/app/shared/services/clickevent.service.ts |  9 ---
 src/app/shared/shared.module.ts               | 22 +-------
 src/app/shared/submission-policy.state.ts     |  4 +-
 41 files changed, 134 insertions(+), 216 deletions(-)
 rename src/app/{oauth => core/auth}/auth.config.ts (100%)
 rename src/app/{oauth => core/auth}/base64-helper.ts (100%)
 rename src/app/{oauth => core/auth}/encoder.ts (88%)
 rename src/app/{oauth => core/auth}/events.ts (100%)
 rename src/app/{oauth => core/auth}/oauth-module.config.ts (100%)
 rename src/app/{oauth/oauth-service.ts => core/auth/oauth2.service.ts} (97%)
 rename src/app/{oauth => core/auth}/types.ts (91%)
 rename src/app/{shared/services => core}/custom-mat-paginator-intl.service.ts (98%)
 rename src/app/{shared/services => core}/error.service.ts (100%)
 rename src/app/{ => core}/global-errors-handler.service.ts (83%)
 rename src/app/{shared/services => core/guards}/auth-guard.service.ts (95%)
 rename src/app/{oauth => core/helpers}/url-helper.service.ts (97%)
 rename src/app/{shared/services => core/http}/api.service.ts (99%)
 create mode 100644 src/app/core/http/oauth2-interceptor.service.spec.ts
 rename src/app/{oauth/interceptors/default-oauth.interceptor.ts => core/http/oauth2-interceptor.service.ts} (74%)
 rename src/app/{shared/services => core}/logging.service.ts (100%)
 rename src/app/{shared/services => core}/notification.service.ts (96%)
 delete mode 100644 src/app/dlcm.storage.ts
 delete mode 100644 src/app/oauth/dlcm-oauth-oidic.module.ts
 delete mode 100644 src/app/oauth/interceptors/resource-server-error-handler.ts
 delete mode 100644 src/app/shared/services/clickevent.service.ts

diff --git a/src/app/access/access.state.ts b/src/app/access/access.state.ts
index 91eff44b5..baa5541bf 100644
--- a/src/app/access/access.state.ts
+++ b/src/app/access/access.state.ts
@@ -5,7 +5,7 @@ import {StateEnum} from "@app/shared/enums/state.enum";
 import {ArchiveMetadataModel} from "@app/shared/models/business/archive-metadata.model";
 import {CollectionTypedModel} from "@app/shared/models/collection-typed.model";
 import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
-import {ApiService} from "@app/shared/services/api.service";
+import {ApiService} from "@app/core/http/api.service";
 import {CrudHelperUtil} from "@app/shared/utils/crud-helper.util";
 import {MapUtil} from "@app/shared/utils/map.util";
 import {StringUtil} from "@app/shared/utils/string.util";
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index faf229b09..83932fc4d 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -3,7 +3,7 @@ import {RouterModule, Routes} from "@angular/router";
 import {LoginComponent} from "@app/components/login/login.component";
 import {PageNotFoundComponent} from "@app/components/page-not-found/page-not-found.component";
 import {AppRoutesEnum} from "@app/shared/enums/routes.enum";
-import {AuthGuardService} from "@app/shared/services/auth-guard.service";
+import {AuthGuardService} from "@app/core/guards/auth-guard.service";
 import {TRANSLATE} from "@app/shared/utils/translate.util";
 
 
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index bfb8dcaca..250e8c5b6 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -2,13 +2,12 @@ import {Component, OnInit} from "@angular/core";
 import {Router, RouterStateSnapshot} from "@angular/router";
 import {ChangeAppLanguage, Logout} from "@app/app.action";
 import {AppStateModel} from "@app/app.state";
-import {OAuthService} from "@app/oauth/oauth-service";
+import {OAuth2Service} from "@app/core/auth/oauth2.service";
 import {BaseDirective} from "@app/shared/directives/base.directive";
 import {LanguagesEnum} from "@app/shared/enums/languages.enum";
 import {RoutesEnum, urlSeparator} from "@app/shared/enums/routes.enum";
 import {StateEnum} from "@app/shared/enums/state.enum";
 import {ThemeEnum} from "@app/shared/enums/theme.enum";
-import {SharedAction} from "@app/shared/shared.action";
 import {TranslateService} from "@ngx-translate/core";
 import {Navigate, RouterStateModel} from "@ngxs/router-plugin";
 import {Select, Store} from "@ngxs/store";
@@ -31,7 +30,7 @@ export class AppComponent extends BaseDirective implements OnInit {
   @Select((state) => (state[StateEnum.application] as AppStateModel).isLoggedIn) isLogged$: Observable<boolean>;
 
   constructor(private store: Store,
-              private oauthService: OAuthService,
+              private oauthService: OAuth2Service,
               private router: Router,
               private translate: TranslateService) {
     super();
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index d182925cd..646d8415b 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,16 +1,15 @@
-import {HttpClient, HttpClientModule} from "@angular/common/http";
-import {ErrorHandler, NgModule} from "@angular/core";
+import {HTTP_INTERCEPTORS, HttpClient, HttpClientModule} from "@angular/common/http";
+import {APP_INITIALIZER, ErrorHandler, NgModule} from "@angular/core";
 import {BrowserModule} from "@angular/platform-browser";
 import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
 import {AppRoutingModule} from "@app/app-routing.module";
 import {AppState} from "@app/app.state";
 import {MainToolbarMobileComponent} from "@app/components/main-toolbar-mobile/main-toolbar-mobile.component";
 import {ApiModule} from "@app/generated-api/api.module";
-import {GlobalErrorsHandlerService} from "@app/global-errors-handler.service";
-import {AuthConfig} from "@app/oauth/auth.config";
-import {DlcmOauthOidicModule} from "@app/oauth/dlcm-oauth-oidic.module";
-import {OAuthModuleConfig} from "@app/oauth/oauth-module.config";
-import {OAuthStorage} from "@app/oauth/types";
+import {GlobalErrorsHandlerService} from "@app/core/global-errors-handler.service";
+
+import {OAuthModuleConfig} from "@app/core/auth/oauth-module.config";
+
 import {SharedModule} from "@app/shared/shared.module";
 import {TranslateLoader, TranslateModule} from "@ngx-translate/core";
 import {TranslateHttpLoader} from "@ngx-translate/http-loader";
@@ -28,7 +27,12 @@ import {LoginComponent} from "./components/login/login.component";
 import {MainToolbarComponent} from "./components/main-toolbar/main-toolbar.component";
 import {PageNotFoundComponent} from "./components/page-not-found/page-not-found.component";
 import {MainToolbarDirective} from "./directives/main-toolbar.directive";
-import {CookieService} from "ngx-cookie-service";
+import {AppConfigService} from "@app/core/config/app-config.service";
+import {OAuth2Interceptor} from "@app/core/http/oauth2-interceptor.service";
+import {MatPaginatorIntl} from "@angular/material";
+import {CustomMatPaginatorIntlService} from "@app/core/custom-mat-paginator-intl.service";
+import {OAuthStorage} from "@app/core/auth/types";
+import {AuthConfig} from "@app/core/auth/auth.config";
 
 const components = [
   AppComponent,
@@ -41,6 +45,16 @@ const components = [
   PageNotFoundComponent,
 ];
 
+const appInitializerFn = (appConfig: AppConfigService) => {
+  return () => {
+    return appConfig.mergeConfig(environment).toPromise();
+  };
+};
+
+export function createDefaultStorage() {
+  return typeof sessionStorage !== "undefined" ? sessionStorage : null;
+}
+
 @NgModule({
   declarations: [
     ...components,
@@ -74,9 +88,6 @@ const components = [
     }),
     NgxsRouterPluginModule.forRoot(),
 
-    // Oauth2
-    DlcmOauthOidicModule.forRoot(authModuleConfig),
-
     // NgTranslate
     TranslateModule.forRoot({
       loader: {
@@ -94,6 +105,24 @@ const components = [
     AppRoutingModule,
   ],
   providers: [
+    {
+      provide: APP_INITIALIZER,
+      useFactory: appInitializerFn,
+      multi: true,
+      deps: [AppConfigService]
+    },
+    {
+      provide: HTTP_INTERCEPTORS,
+      useClass: OAuth2Interceptor,
+      multi: true
+    },
+    { provide: OAuthStorage,
+      useFactory: createDefaultStorage
+    },
+    {
+      provide: MatPaginatorIntl,
+      useClass: CustomMatPaginatorIntlService,
+    },
     {
       provide: ErrorHandler,
       useClass: GlobalErrorsHandlerService,
@@ -109,10 +138,6 @@ const components = [
     {
       provide: AuthConfig,
       useValue: authConfig,
-    },
-    {
-      provide: CookieService,
-      useClass: CookieService
     }
   ],
   bootstrap: [AppComponent],
diff --git a/src/app/app.state.ts b/src/app/app.state.ts
index 27af4e0b7..1b791aa94 100644
--- a/src/app/app.state.ts
+++ b/src/app/app.state.ts
@@ -1,7 +1,6 @@
 import {ChangeAppLanguage, Login, LoginFail, LoginSuccess, Logout, SetDefaultLanguage, SetMomentLocal} from "@app/app.action";
 import {authConfig} from "@app/auth.config";
 import {BaseStateModel} from "@app/base.state";
-import {OAuthService} from "@app/oauth/oauth-service";
 import {LanguagesEnum} from "@app/shared/enums/languages.enum";
 import {RoutesEnum} from "@app/shared/enums/routes.enum";
 import {SessionStorageEnum} from "@app/shared/enums/session-storage.enum";
@@ -13,6 +12,7 @@ import {Action, InitState, State, StateContext, Store} from "@ngxs/store";
 import * as moment from "moment";
 import {tap} from "rxjs/operators";
 import {environment} from "../environments/environment";
+import {OAuth2Service} from "@app/core/auth/oauth2.service";
 
 export interface AppStateModel extends BaseStateModel {
   appLanguage: LanguagesEnum;
@@ -30,7 +30,7 @@ export interface AppStateModel extends BaseStateModel {
 export class AppState {
   constructor(private store: Store,
               private translate: TranslateService,
-              private oauthService: OAuthService) {
+              private oauthService: OAuth2Service) {
     this.oauthService.configure(authConfig);
     this.oauthService.setupAutomaticRefreshToken();
   }
diff --git a/src/app/auth.config.ts b/src/app/auth.config.ts
index 7346c4634..15ef5e342 100644
--- a/src/app/auth.config.ts
+++ b/src/app/auth.config.ts
@@ -1,6 +1,6 @@
-import {AuthConfig} from "@app/oauth/auth.config";
-import {OAuthModuleConfig} from "@app/oauth/oauth-module.config";
+import {OAuthModuleConfig} from "@app/core/auth/oauth-module.config";
 import {environment} from "../environments/environment";
+import {AuthConfig} from "@app/core/auth/auth.config";
 
 export const authConfig: AuthConfig = {
   oidc: false,
diff --git a/src/app/components/home/home.component.ts b/src/app/components/home/home.component.ts
index 3e9870f1e..7800f6e7c 100644
--- a/src/app/components/home/home.component.ts
+++ b/src/app/components/home/home.component.ts
@@ -1,5 +1,5 @@
 import {ChangeDetectionStrategy, Component} from "@angular/core";
-import {OAuthService} from "@app/oauth/oauth-service";
+import {OAuth2Service} from "@app/core/auth/oauth2.service";
 
 @Component({
   selector: "dlcm-home",
@@ -9,7 +9,7 @@ import {OAuthService} from "@app/oauth/oauth-service";
 })
 export class HomeComponent {
 
-  constructor(private oauthService: OAuthService) {
+  constructor(private oauthService: OAuth2Service) {
   }
 
   get token() {
diff --git a/src/app/components/login/login.component.ts b/src/app/components/login/login.component.ts
index cb2a87103..e651535b1 100644
--- a/src/app/components/login/login.component.ts
+++ b/src/app/components/login/login.component.ts
@@ -1,5 +1,5 @@
 import {ChangeDetectionStrategy, Component, OnInit} from "@angular/core";
-import {OAuthService} from "@app/oauth/oauth-service";
+import {OAuth2Service} from "@app/core/auth/oauth2.service";
 
 @Component({
   selector: "dlcm-login",
@@ -9,7 +9,7 @@ import {OAuthService} from "@app/oauth/oauth-service";
 })
 export class LoginComponent implements OnInit {
 
-  constructor(private oauthService: OAuthService) {
+  constructor(private oauthService: OAuth2Service) {
   }
 
   ngOnInit() {
diff --git a/src/app/components/main-toolbar-mobile/main-toolbar-mobile.component.ts b/src/app/components/main-toolbar-mobile/main-toolbar-mobile.component.ts
index 15fa5bb50..cce5b1532 100644
--- a/src/app/components/main-toolbar-mobile/main-toolbar-mobile.component.ts
+++ b/src/app/components/main-toolbar-mobile/main-toolbar-mobile.component.ts
@@ -1,6 +1,6 @@
 import {ChangeDetectionStrategy, Component} from "@angular/core";
 import {MainToolbarDirective} from "@app/directives/main-toolbar.directive";
-import {OAuthService} from "@app/oauth/oauth-service";
+import {OAuth2Service} from "@app/core/auth/oauth2.service";
 
 @Component({
   selector: "dlcm-main-toolbar-mobile",
@@ -9,7 +9,7 @@ import {OAuthService} from "@app/oauth/oauth-service";
   changeDetection: ChangeDetectionStrategy.OnPush,
 })
 export class MainToolbarMobileComponent extends MainToolbarDirective {
-  constructor(private oauth: OAuthService) {
+  constructor(private oauth: OAuth2Service) {
     super(oauth);
   }
 }
diff --git a/src/app/components/main-toolbar/main-toolbar.component.ts b/src/app/components/main-toolbar/main-toolbar.component.ts
index 7cd9b42bd..97d64e468 100644
--- a/src/app/components/main-toolbar/main-toolbar.component.ts
+++ b/src/app/components/main-toolbar/main-toolbar.component.ts
@@ -1,9 +1,6 @@
-import {ChangeDetectionStrategy, Component, EventEmitter, Input, Output} from "@angular/core";
+import {ChangeDetectionStrategy, Component} from "@angular/core";
 import {MainToolbarDirective} from "@app/directives/main-toolbar.directive";
-import {OAuthService} from "@app/oauth/oauth-service";
-import {Router} from "@angular/router";
-import {RoutesEnum} from "@app/shared/enums/routes.enum";
-import {LanguagesEnum} from "@app/shared/enums/languages.enum";
+import {OAuth2Service} from "@app/core/auth/oauth2.service";
 
 @Component({
   selector: "dlcm-main-toolbar",
@@ -13,7 +10,7 @@ import {LanguagesEnum} from "@app/shared/enums/languages.enum";
 })
 export class MainToolbarComponent extends MainToolbarDirective {
 
-  constructor(private oauth: OAuthService) {
+  constructor(private oauth: OAuth2Service) {
     super(oauth);
   }
 }
diff --git a/src/app/oauth/auth.config.ts b/src/app/core/auth/auth.config.ts
similarity index 100%
rename from src/app/oauth/auth.config.ts
rename to src/app/core/auth/auth.config.ts
diff --git a/src/app/oauth/base64-helper.ts b/src/app/core/auth/base64-helper.ts
similarity index 100%
rename from src/app/oauth/base64-helper.ts
rename to src/app/core/auth/base64-helper.ts
diff --git a/src/app/oauth/encoder.ts b/src/app/core/auth/encoder.ts
similarity index 88%
rename from src/app/oauth/encoder.ts
rename to src/app/core/auth/encoder.ts
index b2aa9f820..679b00d95 100644
--- a/src/app/oauth/encoder.ts
+++ b/src/app/core/auth/encoder.ts
@@ -1,4 +1,5 @@
-import { HttpParameterCodec } from "@angular/common/http";
+import {HttpParameterCodec} from "@angular/common/http";
+
 /**
  * This custom encoder allows charactes like +, % and / to be used in passwords
  */
diff --git a/src/app/oauth/events.ts b/src/app/core/auth/events.ts
similarity index 100%
rename from src/app/oauth/events.ts
rename to src/app/core/auth/events.ts
diff --git a/src/app/oauth/oauth-module.config.ts b/src/app/core/auth/oauth-module.config.ts
similarity index 100%
rename from src/app/oauth/oauth-module.config.ts
rename to src/app/core/auth/oauth-module.config.ts
diff --git a/src/app/oauth/oauth-service.ts b/src/app/core/auth/oauth2.service.ts
similarity index 97%
rename from src/app/oauth/oauth-service.ts
rename to src/app/core/auth/oauth2.service.ts
index d5ea1fd7b..82cf2544a 100644
--- a/src/app/oauth/oauth-service.ts
+++ b/src/app/core/auth/oauth2.service.ts
@@ -1,18 +1,20 @@
 import {Injectable, NgZone, Optional} from "@angular/core";
-import {HttpClient, HttpHeaders, HttpParams} from "@angular/common/http";
+import {AuthConfig} from "@app/core/auth/auth.config";
 import {Observable, of, Subject, Subscription} from "rxjs";
+import {OAuthErrorEvent, OAuthEvent, OAuthInfoEvent, OAuthSuccessEvent} from "@app/core/auth/events";
+import {LoginOptions, OAuthStorage, TokenResponse} from "@app/core/auth/types";
+import {HttpClient, HttpHeaders, HttpParams} from "@angular/common/http";
 import {delay, filter} from "rxjs/operators";
-import {OAuthErrorEvent, OAuthEvent, OAuthInfoEvent, OAuthSuccessEvent} from "./events";
-import {LoginOptions, OAuthStorage, TokenResponse} from "./types";
-import {AuthConfig} from "./auth.config";
-import {CookieService} from "ngx-cookie-service";
 
+
+@Injectable({
+  providedIn: "root"
+})
 /**
  * Service for logging in and logging out with
  * OIDC and OAuth2. Supports code flow.
  */
-@Injectable()
-export class OAuthService extends AuthConfig {
+export class OAuth2Service extends AuthConfig {
   // extending AuthConfig ist just for LEGACY reasons
   // to not break existing code
 
@@ -29,7 +31,6 @@ export class OAuthService extends AuthConfig {
 
   constructor(private ngZone: NgZone,
               private http: HttpClient,
-              private _cookieService: CookieService,
               @Optional() storage: OAuthStorage,
               @Optional() private config: AuthConfig) {
     super();
@@ -472,11 +473,6 @@ export class OAuthService extends AuthConfig {
   }
 
   private fetchToken(params: HttpParams) {
-
-    if (this._cookieService.check("JSESSIONID")) {
-      this._cookieService.delete("JSESSIONID");
-    }
-
     if (!this.validateUrlForHttps(this.tokenEndpoint)) {
       throw new Error("tokenEndpoint must use Http. Also check property requireHttps.");
     }
diff --git a/src/app/oauth/types.ts b/src/app/core/auth/types.ts
similarity index 91%
rename from src/app/oauth/types.ts
rename to src/app/core/auth/types.ts
index 515b9d3da..1ea959d41 100644
--- a/src/app/oauth/types.ts
+++ b/src/app/core/auth/types.ts
@@ -6,13 +6,13 @@ export class LoginOptions {
    * Is called, after a token has been received and
    * successfully validated.
    *
-   * Deprecated:  Use property ``events`` on OAuthService instead.
+   * Deprecated:  Use property ``events`` on Oauth2Service instead.
    */
   onTokenReceived?: (receivedTokens: ReceivedTokens) => void;
 
   /**
    * Hook, to validate the received tokens.
-   * Deprecated:  Use property ``tokenValidationHandler`` on OAuthService instead.
+   * Deprecated:  Use property ``tokenValidationHandler`` on Oauth2Service instead.
    */
   validationHandler?: (receivedTokens: ReceivedTokens) => Promise<any>;
 
@@ -20,7 +20,7 @@ export class LoginOptions {
    * Called when tryLogin detects that the auth server
    * included an error message into the hash fragment.
    *
-   * Deprecated:  Use property ``events`` on OAuthService instead.
+   * Deprecated:  Use property ``events`` on Oauth2Service instead.
    */
   onLoginError?: (params: object) => void;
 
diff --git a/src/app/shared/services/custom-mat-paginator-intl.service.ts b/src/app/core/custom-mat-paginator-intl.service.ts
similarity index 98%
rename from src/app/shared/services/custom-mat-paginator-intl.service.ts
rename to src/app/core/custom-mat-paginator-intl.service.ts
index 13285021d..89313783c 100644
--- a/src/app/shared/services/custom-mat-paginator-intl.service.ts
+++ b/src/app/core/custom-mat-paginator-intl.service.ts
@@ -4,7 +4,9 @@ import {TranslateService} from "@ngx-translate/core";
 import {Subject} from "rxjs";
 import {takeUntil} from "rxjs/operators";
 
-@Injectable()
+@Injectable({
+  providedIn: "root"
+})
 export class CustomMatPaginatorIntlService extends MatPaginatorIntl implements OnDestroy {
 
   unsubscribe: Subject<void> = new Subject<void>();
diff --git a/src/app/shared/services/error.service.ts b/src/app/core/error.service.ts
similarity index 100%
rename from src/app/shared/services/error.service.ts
rename to src/app/core/error.service.ts
diff --git a/src/app/global-errors-handler.service.ts b/src/app/core/global-errors-handler.service.ts
similarity index 83%
rename from src/app/global-errors-handler.service.ts
rename to src/app/core/global-errors-handler.service.ts
index 875741989..7948095d4 100644
--- a/src/app/global-errors-handler.service.ts
+++ b/src/app/core/global-errors-handler.service.ts
@@ -1,10 +1,12 @@
 import {HttpErrorResponse} from "@angular/common/http";
 import {ErrorHandler, Injectable, Injector} from "@angular/core";
-import {ErrorService} from "@app/shared/services/error.service";
-import {LoggingService} from "@app/shared/services/logging.service";
-import {NotificationService} from "@app/shared/services/notification.service";
+import {ErrorService} from "@app/core/error.service";
+import {LoggingService} from "@app/core/logging.service";
+import {NotificationService} from "@app/core/notification.service";
 
-@Injectable()
+@Injectable({
+  providedIn: "root"
+})
 export class GlobalErrorsHandlerService implements ErrorHandler {
   // Error handling is important and needs to be loaded first.
   // Because of this we should manually inject the services with Injector.
diff --git a/src/app/shared/services/auth-guard.service.ts b/src/app/core/guards/auth-guard.service.ts
similarity index 95%
rename from src/app/shared/services/auth-guard.service.ts
rename to src/app/core/guards/auth-guard.service.ts
index dd4b70b00..e6a2cdd36 100644
--- a/src/app/shared/services/auth-guard.service.ts
+++ b/src/app/core/guards/auth-guard.service.ts
@@ -6,7 +6,9 @@ import {StateEnum} from "@app/shared/enums/state.enum";
 import {Navigate} from "@ngxs/router-plugin";
 import {Store} from "@ngxs/store";
 
-@Injectable()
+@Injectable({
+  providedIn: "root"
+})
 export class AuthGuardService implements CanActivate {
   constructor(public router: Router, public store: Store) {
   }
diff --git a/src/app/oauth/url-helper.service.ts b/src/app/core/helpers/url-helper.service.ts
similarity index 97%
rename from src/app/oauth/url-helper.service.ts
rename to src/app/core/helpers/url-helper.service.ts
index 21e800420..0b86179f3 100644
--- a/src/app/oauth/url-helper.service.ts
+++ b/src/app/core/helpers/url-helper.service.ts
@@ -1,4 +1,4 @@
-import { Injectable } from "@angular/core";
+import {Injectable} from "@angular/core";
 
 /**
  * Represents the response from the user info endpoint
@@ -44,7 +44,9 @@ export interface OidcDiscoveryDoc {
   ui_locales_supported: string[];
 }
 
-@Injectable()
+@Injectable({
+  providedIn: "root"
+})
 export class UrlHelperService {
   public getHashFragmentParams(customHashFragment?: string): object {
     let hash = customHashFragment || window.location.hash;
diff --git a/src/app/shared/services/api.service.ts b/src/app/core/http/api.service.ts
similarity index 99%
rename from src/app/shared/services/api.service.ts
rename to src/app/core/http/api.service.ts
index 9a45da7b8..265970d0c 100644
--- a/src/app/shared/services/api.service.ts
+++ b/src/app/core/http/api.service.ts
@@ -8,7 +8,9 @@ import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
 import {QueryParametersUtil} from "@app/shared/utils/queryParametersUtil";
 import {Observable} from "rxjs";
 
-@Injectable()
+@Injectable({
+  providedIn: "root"
+})
 export class ApiService {
   public defaultHeaders = new HttpHeaders();
   public configuration = new Configuration();
diff --git a/src/app/core/http/oauth2-interceptor.service.spec.ts b/src/app/core/http/oauth2-interceptor.service.spec.ts
new file mode 100644
index 000000000..4427cb5cd
--- /dev/null
+++ b/src/app/core/http/oauth2-interceptor.service.spec.ts
@@ -0,0 +1,12 @@
+import {TestBed} from "@angular/core/testing";
+
+import {OAuth2Interceptor} from "./oauth2-interceptor.service";
+
+describe("Oauth2InterceptorService", () => {
+  beforeEach(() => TestBed.configureTestingModule({}));
+
+  it("should be created", () => {
+    const service: OAuth2Interceptor = TestBed.get(OAuth2Interceptor);
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/oauth/interceptors/default-oauth.interceptor.ts b/src/app/core/http/oauth2-interceptor.service.ts
similarity index 74%
rename from src/app/oauth/interceptors/default-oauth.interceptor.ts
rename to src/app/core/http/oauth2-interceptor.service.ts
index a8782203b..b0b11f1a4 100644
--- a/src/app/oauth/interceptors/default-oauth.interceptor.ts
+++ b/src/app/core/http/oauth2-interceptor.service.ts
@@ -1,16 +1,16 @@
 import {Injectable, Optional} from "@angular/core";
-import {OAuthStorage} from "../types";
 import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/http";
-import {Observable} from "rxjs";
+import {OAuthStorage} from "@app/core/auth/types";
+import {OAuthModuleConfig} from "@app/core/auth/oauth-module.config";
+import {Observable, throwError} from "rxjs";
 import {catchError} from "rxjs/operators";
-import {OAuthResourceServerErrorHandler} from "./resource-server-error-handler";
-import {OAuthModuleConfig} from "../oauth-module.config";
 
-@Injectable()
-export class DefaultOAuthInterceptor implements HttpInterceptor {
+@Injectable({
+  providedIn: "root"
+})
+export class OAuth2Interceptor implements HttpInterceptor {
 
   constructor(private authStorage: OAuthStorage,
-              private errorHandler: OAuthResourceServerErrorHandler,
               @Optional() private moduleConfig: OAuthModuleConfig) {
   }
 
@@ -44,6 +44,9 @@ export class DefaultOAuthInterceptor implements HttpInterceptor {
 
     return next
       .handle(req)
-      .pipe(catchError(err => this.errorHandler.handleError(err)));
+      .pipe(catchError(err => {
+        return throwError(err);
+      }));
   }
+
 }
diff --git a/src/app/shared/services/logging.service.ts b/src/app/core/logging.service.ts
similarity index 100%
rename from src/app/shared/services/logging.service.ts
rename to src/app/core/logging.service.ts
diff --git a/src/app/shared/services/notification.service.ts b/src/app/core/notification.service.ts
similarity index 96%
rename from src/app/shared/services/notification.service.ts
rename to src/app/core/notification.service.ts
index 6ec31943f..85800d7fe 100644
--- a/src/app/shared/services/notification.service.ts
+++ b/src/app/core/notification.service.ts
@@ -2,7 +2,7 @@ import {Injectable} from "@angular/core";
 import {MatSnackBar} from "@angular/material/snack-bar";
 import {NotificationTypeEnum} from "@app/shared/enums/notification-type.enum";
 import {TranslateService} from "@ngx-translate/core";
-import {environment} from "../../../environments/environment";
+import {environment} from "../../environments/environment";
 
 @Injectable({
   providedIn: "root",
diff --git a/src/app/deposit/deposit.state.ts b/src/app/deposit/deposit.state.ts
index 43101d764..98004a287 100644
--- a/src/app/deposit/deposit.state.ts
+++ b/src/app/deposit/deposit.state.ts
@@ -13,9 +13,9 @@ import {LicenseAction} from "@app/shared/license.action";
 import {CollectionTypedModel} from "@app/shared/models/collection-typed.model";
 import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
 import {PreservationPolicyAction} from "@app/shared/preservation-policy.action";
-import {ApiService} from "@app/shared/services/api.service";
+import {ApiService} from "@app/core/http/api.service";
 import {SubmissionPolicyAction} from "@app/shared/submission-policy.action";
-import {NotificationService} from "@app/shared/services/notification.service";
+import {NotificationService} from "@app/core/notification.service";
 import {Action, State, StateContext, Store} from "@ngxs/store";
 import {Observable} from "rxjs";
 import {tap} from "rxjs/internal/operators/tap";
diff --git a/src/app/directives/main-toolbar.directive.spec.ts b/src/app/directives/main-toolbar.directive.spec.ts
index a9178a1ac..ca3f8a456 100644
--- a/src/app/directives/main-toolbar.directive.spec.ts
+++ b/src/app/directives/main-toolbar.directive.spec.ts
@@ -1,15 +1,15 @@
 import {MainToolbarDirective} from "./main-toolbar.directive";
 import {async, TestBed} from "@angular/core/testing";
 import {FooterComponent} from "@app/components/footer/footer.component";
-import {OAuthService} from "@app/oauth/oauth-service";
+import {OAuth2Service} from "@app/core/auth/oauth2.service";
 
 describe("MainToolbarDirective", () => {
-  const oauthService = jasmine.createSpyObj("OAuthService", ["initAuthorizationCodeFlow"]);
+  const oauthService = jasmine.createSpyObj("Oauth2Service", ["initAuthorizationCodeFlow"]);
   beforeEach(async(() => {
     TestBed.configureTestingModule({
       declarations: [FooterComponent],
       providers: [
-        {provide: OAuthService, useValue: oauthService}
+        {provide: OAuth2Service, useValue: OAuth2Service}
       ]
     })
       .compileComponents();
diff --git a/src/app/directives/main-toolbar.directive.ts b/src/app/directives/main-toolbar.directive.ts
index 7a10d5fbd..ab9b73e6e 100644
--- a/src/app/directives/main-toolbar.directive.ts
+++ b/src/app/directives/main-toolbar.directive.ts
@@ -2,7 +2,7 @@ import {Directive, EventEmitter, Input, Output} from "@angular/core";
 import {BaseDirective} from "@app/shared/directives/base.directive";
 import {LanguagesEnum} from "@app/shared/enums/languages.enum";
 import {RoutesEnum} from "@app/shared/enums/routes.enum";
-import {OAuthService} from "@app/oauth/oauth-service";
+import {OAuth2Service} from "@app/core/auth/oauth2.service";
 
 @Directive({
   selector: "[dlcmMainToolbar]"
@@ -41,7 +41,7 @@ export class MainToolbarDirective extends BaseDirective {
     this.logged = val;
   }
 
-  constructor(private oauthService: OAuthService) {
+  constructor(private oauthService: OAuth2Service) {
     super();
     this.navigateEvent = new EventEmitter();
     this.languageEvent = new EventEmitter();
diff --git a/src/app/dlcm.storage.ts b/src/app/dlcm.storage.ts
deleted file mode 100644
index 0c2beb243..000000000
--- a/src/app/dlcm.storage.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import {Injectable} from "@angular/core";
-import {OAuthStorage} from "@app/oauth/types";
-
-/**
- * Custom storage in memory for sensible data like token
- * (cf best practice https://auth0.com/docs/security/store-tokens)
- */
-@Injectable()
-export class DlcmStorage extends OAuthStorage {
-  private storageValues: Map<string, string>;
-
-  constructor() {
-    super();
-    this.storageValues = new Map<string, string>();
-  }
-
-  getItem(key: string): string | null {
-    console.log("retrieve " + key);
-    return this.storageValues[key];
-  }
-
-  removeItem(key: string): void {
-    this.storageValues.delete(key);
-  }
-
-  setItem(key: string, data: string): void {
-    console.log("store " + key, data);
-    this.storageValues.set(key, data);
-  }
-
-}
diff --git a/src/app/oauth/dlcm-oauth-oidic.module.ts b/src/app/oauth/dlcm-oauth-oidic.module.ts
deleted file mode 100644
index c07dad23f..000000000
--- a/src/app/oauth/dlcm-oauth-oidic.module.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import {OAuthStorage} from "./types";
-import {ModuleWithProviders, NgModule} from "@angular/core";
-import {CommonModule} from "@angular/common";
-import {HTTP_INTERCEPTORS} from "@angular/common/http";
-
-import {OAuthService} from "./oauth-service";
-import {UrlHelperService} from "./url-helper.service";
-
-import {OAuthModuleConfig} from "./oauth-module.config";
-import {
-  OAuthNoopResourceServerErrorHandler,
-  OAuthResourceServerErrorHandler
-} from "./interceptors/resource-server-error-handler";
-import {DefaultOAuthInterceptor} from "./interceptors/default-oauth.interceptor";
-
-
-export function createDefaultStorage() {
-  return typeof sessionStorage !== "undefined" ? sessionStorage : null;
-}
-
-@NgModule({
-  imports: [CommonModule],
-  declarations: [],
-  exports: []
-})
-export class DlcmOauthOidicModule {
-  static forRoot(
-    config: OAuthModuleConfig = null
-  ): ModuleWithProviders {
-    // const setupInterceptor = config && config.resourceServer && config.resourceServer.allowedUrls;
-
-    return {
-      ngModule: DlcmOauthOidicModule,
-      providers: [
-        OAuthService,
-        UrlHelperService,
-        { provide: OAuthStorage, useFactory: createDefaultStorage },
-        {
-          provide: OAuthResourceServerErrorHandler,
-          useClass: OAuthNoopResourceServerErrorHandler
-        },
-        { provide: OAuthModuleConfig, useValue: config },
-        {
-          provide: HTTP_INTERCEPTORS,
-          useClass: DefaultOAuthInterceptor,
-          multi: true
-        }
-      ]
-    };
-  }
-}
diff --git a/src/app/oauth/interceptors/resource-server-error-handler.ts b/src/app/oauth/interceptors/resource-server-error-handler.ts
deleted file mode 100644
index c001967ea..000000000
--- a/src/app/oauth/interceptors/resource-server-error-handler.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { HttpResponse } from "@angular/common/http";
-import { Observable, throwError } from "rxjs";
-
-export abstract class OAuthResourceServerErrorHandler {
-  abstract handleError(err: HttpResponse<any>): Observable<any>;
-}
-
-export class OAuthNoopResourceServerErrorHandler
-  implements OAuthResourceServerErrorHandler {
-  handleError(err: HttpResponse<any>): Observable<any> {
-    return throwError(err);
-  }
-}
diff --git a/src/app/shared/crud.state.ts b/src/app/shared/crud.state.ts
index 7339097fc..5b7844920 100644
--- a/src/app/shared/crud.state.ts
+++ b/src/app/shared/crud.state.ts
@@ -8,12 +8,11 @@ import {StateEnum} from "@app/shared/enums/state.enum";
 import {CollectionTypedModel} from "@app/shared/models/collection-typed.model";
 import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
 import {SubResourceUpdateModel} from "@app/shared/models/sub-resource-update.model";
-import {ApiService} from "@app/shared/services/api.service";
-import {NotificationService} from "@app/shared/services/notification.service";
+import {ApiService} from "@app/core/http/api.service";
+import {NotificationService} from "@app/core/notification.service";
 import {CrudActionUtil} from "@app/shared/utils/crud-action.util";
 import {CrudHelperUtil} from "@app/shared/utils/crud-helper.util";
 import {CrudRouteUtil} from "@app/shared/utils/crud-route.util";
-import {ObjectUtil} from "@app/shared/utils/object.util";
 import {TRANSLATE} from "@app/shared/utils/translate.util";
 import {Navigate} from "@ngxs/router-plugin";
 import {StateContext, Store} from "@ngxs/store";
diff --git a/src/app/shared/language.state.ts b/src/app/shared/language.state.ts
index c9cb9bee0..91e8ea986 100644
--- a/src/app/shared/language.state.ts
+++ b/src/app/shared/language.state.ts
@@ -5,8 +5,8 @@ import {AdminResourceApiEnum, ResourceApiEnum} from "@app/shared/enums/api.enum"
 import {StateEnum} from "@app/shared/enums/state.enum";
 import {LanguageAction} from "@app/shared/language.action";
 import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
-import {ApiService} from "@app/shared/services/api.service";
-import {NotificationService} from "@app/shared/services/notification.service";
+import {ApiService} from "@app/core/http/api.service";
+import {NotificationService} from "@app/core/notification.service";
 import {Action, State, StateContext, Store} from "@ngxs/store";
 import {Observable} from "rxjs";
 
diff --git a/src/app/shared/license.state.ts b/src/app/shared/license.state.ts
index 88074a5cc..04685d812 100644
--- a/src/app/shared/license.state.ts
+++ b/src/app/shared/license.state.ts
@@ -5,8 +5,8 @@ import {AdminResourceApiEnum, ResourceApiEnum} from "@app/shared/enums/api.enum"
 import {StateEnum} from "@app/shared/enums/state.enum";
 import {LicenseAction} from "@app/shared/license.action";
 import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
-import {ApiService} from "@app/shared/services/api.service";
-import {NotificationService} from "@app/shared/services/notification.service";
+import {ApiService} from "@app/core/http/api.service";
+import {NotificationService} from "@app/core/notification.service";
 import {Action, State, StateContext, Store} from "@ngxs/store";
 import {Observable} from "rxjs";
 
diff --git a/src/app/shared/organizational-unit.state.ts b/src/app/shared/organizational-unit.state.ts
index af9320762..29e3b0f40 100644
--- a/src/app/shared/organizational-unit.state.ts
+++ b/src/app/shared/organizational-unit.state.ts
@@ -11,10 +11,10 @@ import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
 import {OrgUnitAction} from "@app/shared/organizational-unit.action";
 import {PreservationPolicyAction} from "@app/shared/preservation-policy.action";
 
-import {ApiService} from "@app/shared/services/api.service";
+import {ApiService} from "@app/core/http/api.service";
 import {SubmissionPolicyAction} from "@app/shared/submission-policy.action";
 import {CrudActionUtil} from "@app/shared/utils/crud-action.util";
-import {NotificationService} from "@app/shared/services/notification.service";
+import {NotificationService} from "@app/core/notification.service";
 import {Action, ActionCompletion, Actions, ofActionCompleted, State, StateContext, Store} from "@ngxs/store";
 import _ from "lodash";
 import {Observable} from "rxjs";
diff --git a/src/app/shared/preservation-policy.state.ts b/src/app/shared/preservation-policy.state.ts
index b80a239da..80ce913de 100644
--- a/src/app/shared/preservation-policy.state.ts
+++ b/src/app/shared/preservation-policy.state.ts
@@ -5,8 +5,8 @@ import {AdminResourceApiEnum, ResourceApiEnum} from "@app/shared/enums/api.enum"
 import {StateEnum} from "@app/shared/enums/state.enum";
 import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
 import {PreservationPolicyAction} from "@app/shared/preservation-policy.action";
-import {ApiService} from "@app/shared/services/api.service";
-import {NotificationService} from "@app/shared/services/notification.service";
+import {ApiService} from "@app/core/http/api.service";
+import {NotificationService} from "@app/core/notification.service";
 import {Action, State, StateContext, Store} from "@ngxs/store";
 import {Observable} from "rxjs";
 
diff --git a/src/app/shared/services/clickevent.service.ts b/src/app/shared/services/clickevent.service.ts
deleted file mode 100644
index cd6da4a77..000000000
--- a/src/app/shared/services/clickevent.service.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import {Injectable} from "@angular/core";
-import {fromEvent, Observable} from "rxjs";
-
-@Injectable()
-export class ClickEventService {
-  static clickEvent(): Observable<any> {
-    return fromEvent(document, "click");
-  }
-}
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index d60b35d33..60fb3c990 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -1,7 +1,6 @@
 import {CommonModule} from "@angular/common";
 import {NgModule} from "@angular/core";
 import {FormsModule, ReactiveFormsModule} from "@angular/forms";
-import {MatPaginatorIntl} from "@angular/material";
 import {MaterialModule} from "@app/material.module";
 import {DataTableComponent} from "@app/shared/components/data-table/data-table.component";
 import {SearchComponent} from "@app/shared/components/search/search.component";
@@ -11,13 +10,6 @@ import {LanguageState} from "@app/shared/language.state";
 import {LicenseState} from "@app/shared/license.state";
 import {OrganizationalUnitState} from "@app/shared/organizational-unit.state";
 import {PreservationPolicyState} from "@app/shared/preservation-policy.state";
-import {ApiService} from "@app/shared/services/api.service";
-import {AuthGuardService} from "@app/shared/services/auth-guard.service";
-import {ClickEventService} from "@app/shared/services/clickevent.service";
-import {ErrorService} from "@app/shared/services/error.service";
-import {LoggingService} from "@app/shared/services/logging.service";
-import {NotificationService} from "@app/shared/services/notification.service";
-import {CustomMatPaginatorIntlService} from "@app/shared/services/custom-mat-paginator-intl.service";
 import {SharedState} from "@app/shared/shared.state";
 import {SubmissionPolicyState} from "@app/shared/submission-policy.state";
 import {FontAwesomeModule} from "@fortawesome/angular-fontawesome";
@@ -74,19 +66,7 @@ const modules = [
     ...dialogs,
     ...components,
     ...directives,
-  ],
-  providers: [
-    ClickEventService,
-    ApiService,
-    AuthGuardService,
-    LoggingService,
-    ErrorService,
-    NotificationService,
-    {
-      provide: MatPaginatorIntl,
-      useClass: CustomMatPaginatorIntlService,
-    },
-  ],
+  ]
 })
 export class SharedModule {
 }
diff --git a/src/app/shared/submission-policy.state.ts b/src/app/shared/submission-policy.state.ts
index 9ffd3f073..a5944001e 100644
--- a/src/app/shared/submission-policy.state.ts
+++ b/src/app/shared/submission-policy.state.ts
@@ -4,8 +4,8 @@ import {ApiResourceNameEnum} from "@app/shared/enums/api-resource-name.enum";
 import {AdminResourceApiEnum, ResourceApiEnum} from "@app/shared/enums/api.enum";
 import {StateEnum} from "@app/shared/enums/state.enum";
 import {QueryParametersModel} from "@app/shared/models/query-parameters.model";
-import {ApiService} from "@app/shared/services/api.service";
-import {NotificationService} from "@app/shared/services/notification.service";
+import {ApiService} from "@app/core/http/api.service";
+import {NotificationService} from "@app/core/notification.service";
 import {SubmissionPolicyAction} from "@app/shared/submission-policy.action";
 import {Action, State, StateContext, Store} from "@ngxs/store";
 import {Observable} from "rxjs";
-- 
GitLab