Repository: jhipster/generator-jhipster
Pull request #8513 (2018-10-09 13:09:26)

Angular: Unify Principal and Account Service
We have two services who manages the same things IMO: the user account. I think we should merge them into the `AccountService` which will provide the necessary functions.
I also removed the async `hasAnyAuthority`, I don't know it was async as we don't need any network calls.

-   [ ] [Travis tests](https://travis-ci.org/jhipster/generator-jhipster/pull_requests) are green
-   [ ] Tests are added where necessary
-   [ ] Documentation is added/updated where necessary
-   [ ] Coding Rules & Commit Guidelines as per our [CONTRIBUTING.md document](https://github.com/jhipster/generator-jhipster/blob/master/CONTRIBUTING.md) are followed

<!--
Please also reference the issue number in a commit message to [automatically close the related Github issue](https://help.github.com/articles/closing-issues-via-commit-messages/)

Note: It is also possible to add `[skip ci]` to your commit message to skip Travis tests
-->


deepu105: @jdubois seems like I do not have access to retry jobs on azure pipeline, could you give me access
deepu105: ye but I can't even restart the entire PR build

Thanks & Regards,
Deepu


On Thu, Oct 11, 2018 at 9:23 AM Julien Dubois <notifications@github.com>
wrote:

> That's one of the issues with Azure Pipelines, in fact you can't restart
> jobs!
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/jhipster/generator-jhipster/pull/8513#issuecomment-428848976>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ABDlF1zcrh_mtF_Uf1vNOWZxr0z5xnmvks5ujvIDgaJpZM4XTPgs>
> .
>


Patch:
diff --git a/generators/cleanup.js b/generators/cleanup.js
index 10f40e8b69..55dfb93e64 100644
--- a/generators/cleanup.js
+++ b/generators/cleanup.js
@@ -50,7 +50,6 @@ function cleanupOldFiles(generator) {
         generator.removeFile(`${ANGULAR_DIR}shared/auth/auth-jwt.service.ts`);
         generator.removeFile(`${ANGULAR_DIR}shared/auth/auth-session.service.ts`);
         generator.removeFile(`${ANGULAR_DIR}shared/auth/csrf.service.ts`);
-        generator.removeFile(`${ANGULAR_DIR}shared/auth/principal.service.ts`);
         generator.removeFile(`${ANGULAR_DIR}shared/auth/state-storage.service.ts`);
         generator.removeFile(`${ANGULAR_DIR}shared/auth/user-route-access-service.ts`);
         generator.removeFile(`${ANGULAR_DIR}shared/language/language.constants.ts`);
diff --git a/generators/client/files-angular.js b/generators/client/files-angular.js
index a49353eaad..fe04f51308 100644
--- a/generators/client/files-angular.js
+++ b/generators/client/files-angular.js
@@ -392,7 +392,6 @@ const files = {
             templates: [
                 'core/auth/csrf.service.ts',
                 'core/auth/state-storage.service.ts',
-                'core/auth/principal.service.ts',
                 'shared/auth/has-any-authority.directive.ts',
                 'core/auth/account.service.ts',
                 'core/auth/user-route-access-service.ts'
@@ -425,9 +424,9 @@ const files = {
                 'spec/app/admin/metrics/metrics.component.spec.ts',
                 'spec/app/admin/metrics/metrics.service.spec.ts',
                 'spec/app/admin/metrics/metrics-modal.component.spec.ts',
+                'spec/app/core/user/account.service.spec.ts',
                 'spec/helpers/spyobject.ts',
                 'spec/helpers/mock-account.service.ts',
-                'spec/helpers/mock-principal.service.ts',
                 'spec/helpers/mock-route.service.ts',
                 'spec/helpers/mock-login.service.ts',
                 'spec/helpers/mock-event-manager.service.ts',
diff --git a/generators/client/templates/angular/src/main/webapp/app/account/password/password.component.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/account/password/password.component.ts.ejs
index aab7a90af6..dbd767681b 100644
--- a/generators/client/templates/angular/src/main/webapp/app/account/password/password.component.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/account/password/password.component.ts.ejs
@@ -18,7 +18,7 @@
 -%>
 import { Component, OnInit } from '@angular/core';
 
-import { Principal } from 'app/core';
+import { AccountService } from 'app/core';
 import { PasswordService } from './password.service';
 
 @Component({
@@ -36,12 +36,12 @@ export class PasswordComponent implements OnInit {
 
     constructor(
         private passwordService: PasswordService,
-        private principal: Principal
+        private accountService: AccountService
     ) {
     }
 
     ngOnInit() {
-        this.principal.identity().then((account) => {
+        this.accountService.identity().then((account) => {
             this.account = account;
         });
     }
diff --git a/generators/client/templates/angular/src/main/webapp/app/account/sessions/sessions.component.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/account/sessions/sessions.component.ts.ejs
index 565712a9d9..7cba53a885 100644
--- a/generators/client/templates/angular/src/main/webapp/app/account/sessions/sessions.component.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/account/sessions/sessions.component.ts.ejs
@@ -18,7 +18,7 @@
 -%>
 import { Component, OnInit } from '@angular/core';
 
-import { Principal } from 'app/core';
+import { AccountService } from 'app/core';
 import { Session } from './session.model';
 import { SessionsService } from './sessions.service';
 
@@ -35,14 +35,14 @@ export class SessionsComponent implements OnInit {
 
     constructor(
         private sessionsService: SessionsService,
-        private principal: Principal
+        private accountService: AccountService
     ) {
     }
 
     ngOnInit() {
         this.sessionsService.findAll().subscribe((sessions) => this.sessions = sessions);
 
-        this.principal.identity().then((account) => {
+        this.accountService.identity().then((account) => {
             this.account = account;
         });
     }
diff --git a/generators/client/templates/angular/src/main/webapp/app/account/settings/settings.component.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/account/settings/settings.component.ts.ejs
index 003544b741..de2fd4a9cf 100644
--- a/generators/client/templates/angular/src/main/webapp/app/account/settings/settings.component.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/account/settings/settings.component.ts.ejs
@@ -19,7 +19,7 @@
 import { Component, OnInit } from '@angular/core';
 import { JhiLanguageService } from 'ng-jhipster';
 
-import { Principal, AccountService<% if (enableTranslation) { %>, JhiLanguageHelper<% } %> } from 'app/core';
+import { AccountService<% if (enableTranslation) { %>, JhiLanguageHelper<% } %> } from 'app/core';
 
 @Component({
     selector: '<%= jhiPrefixDashed %>-settings',
@@ -32,15 +32,14 @@ export class SettingsComponent implements OnInit {
     languages: any[];
 
     constructor(
-        private account: AccountService,
-        private principal: Principal<% if (enableTranslation) { %>,
+        private accountService: AccountService<% if (enableTranslation) { %>,
         private languageService: JhiLanguageService,
         private languageHelper: JhiLanguageHelper<% } %>
     ) {
     }
 
     ngOnInit() {
-        this.principal.identity().then((account) => {
+        this.accountService.identity().then((account) => {
             this.settingsAccount = this.copyAccount(account);
         });
         <%_ if (enableTranslation) { _%>
@@ -51,10 +50,10 @@ export class SettingsComponent implements OnInit {
     }
 
     save() {
-        this.account.save(this.settingsAccount).subscribe(() => {
+        this.accountService.save(this.settingsAccount).subscribe(() => {
             this.error = null;
             this.success = 'OK';
-            this.principal.identity(true).then((account) => {
+            this.accountService.identity(true).then((account) => {
                 this.settingsAccount = this.copyAccount(account);
             });
             <%_ if (enableTranslation) { _%>
diff --git a/generators/client/templates/angular/src/main/webapp/app/admin/user-management/user-management.component.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/admin/user-management/user-management.component.ts.ejs
index 7d8fbe1143..f7531b64cd 100644
--- a/generators/client/templates/angular/src/main/webapp/app/admin/user-management/user-management.component.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/admin/user-management/user-management.component.ts.ejs
@@ -28,7 +28,7 @@ import { ITEMS_PER_PAGE } from 'app/shared';
 <%_ } else { _%>
 import { JhiEventManager, JhiAlertService } from 'ng-jhipster';
 <%_ } _%>
-import { Principal, UserService, User } from 'app/core';
+import { AccountService, UserService, User } from 'app/core';
 import { UserMgmtDeleteDialogComponent } from 'app/admin';
 
 @Component({
@@ -56,7 +56,7 @@ export class UserMgmtComponent implements OnInit, OnDestroy {
     constructor(
         private userService: UserService,
         private alertService: JhiAlertService,
-        private principal: Principal,
+        private accountService: AccountService,
         <%_ if (prodDatabaseType !== 'cassandra') { _%>
         private parseLinks: JhiParseLinks,
         private activatedRoute: ActivatedRoute,
@@ -77,7 +77,7 @@ export class UserMgmtComponent implements OnInit, OnDestroy {
     }
 
     ngOnInit() {
-        this.principal.identity().then((account) => {
+        this.accountService.identity().then((account) => {
             this.currentAccount = account;
             this.loadAll();
             this.registerChangeInUsers();
diff --git a/generators/client/templates/angular/src/main/webapp/app/admin/user-management/user-management.route.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/admin/user-management/user-management.route.ts.ejs
index 9ddfc635f1..cec6021c8e 100644
--- a/generators/client/templates/angular/src/main/webapp/app/admin/user-management/user-management.route.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/admin/user-management/user-management.route.ts.ejs
@@ -20,7 +20,7 @@ import { Injectable } from '@angular/core';
 import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes, CanActivate } from '@angular/router';
 import { JhiPaginationUtil, JhiResolvePagingParams } from 'ng-jhipster';
 
-import { Principal, User, UserService } from 'app/core';
+import { AccountService, User, UserService } from 'app/core';
 import { UserMgmtComponent } from './user-management.component';
 import { UserMgmtDetailComponent } from './user-management-detail.component';
 import { UserMgmtUpdateComponent } from './user-management-update.component';
@@ -28,10 +28,10 @@ import { UserMgmtUpdateComponent } from './user-management-update.component';
 @Injectable({providedIn: 'root'})
 export class UserResolve implements CanActivate {
 
-    constructor(private principal: Principal) { }
+    constructor(private accountService: AccountService) { }
 
     canActivate() {
-        return this.principal.identity().then((account) => this.principal.hasAnyAuthority(['ROLE_ADMIN']));
+        return this.accountService.identity().then((account) => this.accountService.hasAnyAuthority(['ROLE_ADMIN']));
     }
 }
 
diff --git a/generators/client/templates/angular/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts.ejs
index 4f8ed94894..c51640a894 100644
--- a/generators/client/templates/angular/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts.ejs
@@ -25,7 +25,7 @@ import { tap } from 'rxjs/operators';
 import { Router } from '@angular/router';
 
 import { LoginModalService } from 'app/core/login/login-modal.service';
-import { Principal } from 'app/core/auth/principal.service';
+import { AccountService } from 'app/core/auth/account.service';
     <%_ } _%>
 import { LoginService } from 'app/core/login/login.service';
 <%_ } _%>
@@ -49,7 +49,7 @@ export class AuthExpiredInterceptor implements HttpInterceptor {
         <%_ if (['oauth2', 'jwt', 'uaa'].includes(authenticationType)) { _%>
             <%_ if (authenticationType === 'uaa') { _%>
         private loginModalService: LoginModalService,
-        private principal: Principal,
+        private accountService: AccountService,
         private router: Router,
             <%_ } _%>
             <%_ if (authenticationType === 'oauth2') { _%>
@@ -67,8 +67,8 @@ export class AuthExpiredInterceptor implements HttpInterceptor {
 <%_ if (authenticationType === 'jwt') { _%>
                     this.loginService.logout();
 <% } if (authenticationType === 'uaa') { %>
-                    if (this.principal.isAuthenticated()) {
-                        this.principal.authenticate(null);
+                    if (this.accountService.isAuthenticated()) {
+                        this.accountService.authenticate(null);
                         this.loginModalService.open();
                     } else {
                         this.loginService.logout();
diff --git a/generators/client/templates/angular/src/main/webapp/app/core/auth/account.service.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/core/auth/account.service.ts.ejs
index e3c308c5fe..b97fcaa9c7 100644
--- a/generators/client/templates/angular/src/main/webapp/app/core/auth/account.service.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/core/auth/account.service.ts.ejs
@@ -17,21 +17,132 @@
  limitations under the License.
 -%>
 import { Injectable } from '@angular/core';
+<%_ if (enableTranslation && authenticationType !== 'oauth2') { _%>
+import { JhiLanguageService } from 'ng-jhipster';
+import { SessionStorageService } from 'ngx-webstorage';
+<%_ } _%>
 import { HttpClient, HttpResponse } from '@angular/common/http';
-import { Observable } from 'rxjs';
+import { Observable, Subject } from 'rxjs';
 
 import { SERVER_API_URL } from 'app/app.constants';
 import { Account } from 'app/core/user/account.model';
+<%_ if (websocket === 'spring-websocket') { _%>
+import { <%=jhiPrefixCapitalized%>TrackerService } from '../tracker/tracker.service';
+<%_ } _%>
 
 @Injectable({providedIn: 'root'})
 export class AccountService  {
-    constructor(private http: HttpClient) { }
+    private userIdentity: any;
+    private authenticated = false;
+    private authenticationState = new Subject<any>();
 
-    get(): Observable<HttpResponse<Account>> {
+
+    constructor(
+        <%_ if (enableTranslation && authenticationType !== 'oauth2') { _%>
+        private languageService: JhiLanguageService,
+        private sessionStorage: SessionStorageService,
+        <%_ } _%>
+        private http: HttpClient<% if (websocket === 'spring-websocket') { %>,
+        private trackerService: <%=jhiPrefixCapitalized%>TrackerService<% } %>) { }
+
+    fetch(): Observable<HttpResponse<Account>> {
         return this.http.get<Account>(SERVER_API_URL + '<%- apiUaaPath %>api/account', {observe : 'response'});
     }
 
     save(account: any): Observable<HttpResponse<any>> {
         return this.http.post(SERVER_API_URL + '<%- apiUaaPath %>api/account', account, {observe: 'response'});
     }
+
+    authenticate(identity) {
+        this.userIdentity = identity;
+        this.authenticated = identity !== null;
+        this.authenticationState.next(this.userIdentity);
+    }
+
+    hasAnyAuthority(authorities: string[]): boolean {
+        if (!this.authenticated || !this.userIdentity || !this.userIdentity.authorities) {
+            return false;
+        }
+
+        for (let i = 0; i < authorities.length; i++) {
+            if (this.userIdentity.authorities.includes(authorities[i])) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    hasAuthority(authority: string): Promise<boolean> {
+        if (!this.authenticated) {
+           return Promise.resolve(false);
+        }
+
+        return this.identity().then((id) => {
+            return Promise.resolve(id.authorities && id.authorities.includes(authority));
+        }, () => {
+            return Promise.resolve(false);
+        });
+    }
+
+    identity(force?: boolean): Promise<any> {
+        if (force) {
+            this.userIdentity = undefined;
+        }
+
+        // check and see if we have retrieved the userIdentity data from the server.
+        // if we have, reuse it by immediately resolving
+        if (this.userIdentity) {
+            return Promise.resolve(this.userIdentity);
+        }
+
+        // retrieve the userIdentity data from the server, update the identity object, and then resolve.
+        return this.fetch().toPromise().then((response) => {
+            const account = response.body;
+            if (account) {
+                this.userIdentity = account;
+                this.authenticated = true;
+                <%_ if (websocket === 'spring-websocket') { _%>
+                this.trackerService.connect();
+                <%_ } _%>
+                <%_ if (enableTranslation && authenticationType !== 'oauth2') { _%>
+                // After retrieve the account info, the language will be changed to
+                // the user's preferred language configured in the account setting
+                const langKey = this.sessionStorage.retrieve('locale') || this.userIdentity.langKey;
+                this.languageService.changeLanguage(langKey);
+                <%_ } _%>
+            } else {
+                this.userIdentity = null;
+                this.authenticated = false;
+            }
+            this.authenticationState.next(this.userIdentity);
+            return this.userIdentity;
+        }).catch((err) => {
+            <%_ if (websocket === 'spring-websocket') { _%>
+            if (this.trackerService.stompClient && this.trackerService.stompClient.connected) {
+                this.trackerService.disconnect();
+            }
+            <%_ } _%>
+            this.userIdentity = null;
+            this.authenticated = false;
+            this.authenticationState.next(this.userIdentity);
+            return null;
+        });
+    }
+
+    isAuthenticated(): boolean {
+        return this.authenticated;
+    }
+
+    isIdentityResolved(): boolean {
+        return this.userIdentity !== undefined;
+    }
+
+    getAuthenticationState(): Observable<any> {
+        return this.authenticationState.asObservable();
+    }
+
+    getImageUrl(): string {
+        return this.isIdentityResolved() ? this.userIdentity.imageUrl : null;
+    }
 }
diff --git a/generators/client/templates/angular/src/main/webapp/app/core/auth/principal.service.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/core/auth/principal.service.ts.ejs
deleted file mode 100644
index ae958ebf94..0000000000
--- a/generators/client/templates/angular/src/main/webapp/app/core/auth/principal.service.ts.ejs
+++ /dev/null
@@ -1,143 +0,0 @@
-<%#
- Copyright 2013-2018 the original author or authors from the JHipster project.
-
- This file is part of the JHipster project, see https://www.jhipster.tech/
- for more information.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--%>
-import { Injectable } from '@angular/core';
-<%_ if (enableTranslation && authenticationType !== 'oauth2') { _%>
-import { JhiLanguageService } from 'ng-jhipster';
-import { SessionStorageService } from 'ngx-webstorage';
-<%_ } _%>
-import { Observable, Subject } from 'rxjs';
-import { AccountService } from './account.service';
-<%_ if (websocket === 'spring-websocket') { _%>
-import { <%=jhiPrefixCapitalized%>TrackerService } from '../tracker/tracker.service';
-<%_ } _%>
-
-@Injectable({providedIn: 'root'})
-export class Principal {
-    private userIdentity: any;
-    private authenticated = false;
-    private authenticationState = new Subject<any>();
-
-    constructor(
-        <%_ if (enableTranslation && authenticationType !== 'oauth2') { _%>
-        private languageService: JhiLanguageService,
-        private sessionStorage: SessionStorageService,
-        <%_ } _%>
-        private account: AccountService<% if (websocket === 'spring-websocket') { %>,
-        private trackerService: <%=jhiPrefixCapitalized%>TrackerService<% } %>
-    ) {}
-
-    authenticate(identity) {
-        this.userIdentity = identity;
-        this.authenticated = identity !== null;
-        this.authenticationState.next(this.userIdentity);
-    }
-
-    hasAnyAuthority(authorities: string[]): Promise<boolean> {
-        return Promise.resolve(this.hasAnyAuthorityDirect(authorities));
-    }
-
-    hasAnyAuthorityDirect(authorities: string[]): boolean {
-        if (!this.authenticated || !this.userIdentity || !this.userIdentity.authorities) {
-            return false;
-        }
-
-        for (let i = 0; i < authorities.length; i++) {
-            if (this.userIdentity.authorities.includes(authorities[i])) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    hasAuthority(authority: string): Promise<boolean> {
-        if (!this.authenticated) {
-           return Promise.resolve(false);
-        }
-
-        return this.identity().then((id) => {
-            return Promise.resolve(id.authorities && id.authorities.includes(authority));
-        }, () => {
-            return Promise.resolve(false);
-        });
-    }
-
-    identity(force?: boolean): Promise<any> {
-        if (force === true) {
-            this.userIdentity = undefined;
-        }
-
-        // check and see if we have retrieved the userIdentity data from the server.
-        // if we have, reuse it by immediately resolving
-        if (this.userIdentity) {
-            return Promise.resolve(this.userIdentity);
-        }
-
-        // retrieve the userIdentity data from the server, update the identity object, and then resolve.
-        return this.account.get().toPromise().then((response) => {
-            const account = response.body;
-            if (account) {
-                this.userIdentity = account;
-                this.authenticated = true;
-                <%_ if (websocket === 'spring-websocket') { _%>
-                this.trackerService.connect();
-                <%_ } _%>
-
-                <%_ if (enableTranslation && authenticationType !== 'oauth2') { _%>
-                // After retrieve the account info, the language will be changed to
-                // the user's preferred language configured in the account setting
-                const langKey = this.sessionStorage.retrieve('locale') || this.userIdentity.langKey;
-                this.languageService.changeLanguage(langKey);
-                <%_ } _%>
-
-            } else {
-                this.userIdentity = null;
-                this.authenticated = false;
-            }
-            this.authenticationState.next(this.userIdentity);
-            return this.userIdentity;
-        }).catch((err) => {
-            <%_ if (websocket === 'spring-websocket') { _%>
-            if (this.trackerService.stompClient && this.trackerService.stompClient.connected) {
-                this.trackerService.disconnect();
-            }
-            <%_ } _%>
-            this.userIdentity = null;
-            this.authenticated = false;
-            this.authenticationState.next(this.userIdentity);
-            return null;
-        });
-    }
-
-    isAuthenticated(): boolean {
-        return this.authenticated;
-    }
-
-    isIdentityResolved(): boolean {
-        return this.userIdentity !== undefined;
-    }
-
-    getAuthenticationState(): Observable<any> {
-        return this.authenticationState.asObservable();
-    }
-
-    getImageUrl(): string {
-        return this.isIdentityResolved() ? this.userIdentity.imageUrl : null;
-    }
-}
diff --git a/generators/client/templates/angular/src/main/webapp/app/core/auth/user-route-access-service.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/core/auth/user-route-access-service.ts.ejs
index 68d48b311f..087bcb9bc4 100644
--- a/generators/client/templates/angular/src/main/webapp/app/core/auth/user-route-access-service.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/core/auth/user-route-access-service.ts.ejs
@@ -19,7 +19,7 @@
 import { Injectable, isDevMode } from '@angular/core';
 import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
 
-import { Principal } from '../';
+import { AccountService } from '../';
 <%_ if (authenticationType !== 'oauth2') { _%>
 import { LoginModalService } from '../login/login-modal.service';
 <%_ } else { _%>
@@ -36,37 +36,35 @@ export class UserRouteAccessService implements CanActivate {
                 <%_ } else { _%>
                 private loginService: LoginService,
                 <%_ } _%>
-                private principal: Principal,
+                private accountService: AccountService,
                 private stateStorageService: StateStorageService) {
     }
 
     canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Promise<boolean> {
 
         const authorities = route.data['authorities'];
-        // We need to call the checkLogin / and so the principal.identity() function, to ensure,
+        // We need to call the checkLogin / and so the accountService.identity() function, to ensure,
         // that the client has a principal too, if they already logged in by the server.
         // This could happen on a page refresh.
         return this.checkLogin(authorities, state.url);
     }
 
     checkLogin(authorities: string[], url: string): Promise<boolean> {
-        const principal = this.principal;
-        return Promise.resolve(principal.identity().then((account) => {
+        return this.accountService.identity().then((account) => {
 
             if (!authorities || authorities.length === 0) {
                 return true;
             }
 
             if (account) {
-                return principal.hasAnyAuthority(authorities).then((response) => {
-                    if (response) {
-                        return true;
-                    }
-                    if (isDevMode()) {
-                        console.error('User has not any of required authorities: ', authorities);
-                    }
-                    return false;
-                });
+                const hasAnyAuthority = this.accountService.hasAnyAuthority(authorities);
+                if (hasAnyAuthority) {
+                    return true;
+                }
+                if (isDevMode()) {
+                    console.error('User has not any of required authorities: ', authorities);
+                }
+                return false;
             }
 
             this.stateStorageService.storeUrl(url);
@@ -81,6 +79,6 @@ export class UserRouteAccessService implements CanActivate {
                 }
             });
             return false;
-        }));
+        });
     }
 }
diff --git a/generators/client/templates/angular/src/main/webapp/app/core/index.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/core/index.ts.ejs
index 80e7d7078f..4a711c4527 100644
--- a/generators/client/templates/angular/src/main/webapp/app/core/index.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/core/index.ts.ejs
@@ -18,7 +18,6 @@ export * from './user/account.model';
 <%_ if (!skipUserManagement || authenticationType === 'oauth2') { _%>
 export * from './user/user.model';
 <%_ } _%>
-export * from './auth/principal.service';
 export * from './auth/user-route-access-service';
 <%_ if (authenticationType !== 'oauth2') { _%>
 export * from './login/login-modal.service';
diff --git a/generators/client/templates/angular/src/main/webapp/app/core/language/language.helper.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/core/language/language.helper.ts.ejs
index 1e3bf7ffc0..f8eb976837 100644
--- a/generators/client/templates/angular/src/main/webapp/app/core/language/language.helper.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/core/language/language.helper.ts.ejs
@@ -34,13 +34,12 @@ export class JhiLanguageHelper {
 
     constructor(
         private translateService: TranslateService,
-        // tslint:disable-next-line: no-unused-variable
-        private rootRenderer: RendererFactory2,
         <%_ if (enableI18nRTL) { _%>
         private findLanguageFromKeyPipe: FindLanguageFromKeyPipe,
         <%_ } _%>
         private titleService: Title,
-        private router: Router
+        private router: Router,
+        rootRenderer: RendererFactory2
     ) {
         this._language = new BehaviorSubject<string>(this.translateService.currentLang);
         this.renderer = rootRenderer.createRenderer(document.querySelector('html'), null);
diff --git a/generators/client/templates/angular/src/main/webapp/app/core/login/login.service.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/core/login/login.service.ts.ejs
index 2e2c83508f..f40c8ce6cc 100644
--- a/generators/client/templates/angular/src/main/webapp/app/core/login/login.service.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/core/login/login.service.ts.ejs
@@ -18,7 +18,7 @@
 -%>
 import { Injectable } from '@angular/core';
 
-import { Principal } from '../auth/principal.service';
+import { AccountService } from '../auth/account.service';
 <%_ if (authenticationType === 'jwt' || authenticationType === 'uaa') { _%>
 import { AuthServerProvider } from '../auth/auth-jwt.service';
 <%_ } else if (authenticationType === 'session' || authenticationType === 'oauth2') { _%>
@@ -32,7 +32,7 @@ import { <%=jhiPrefixCapitalized%>TrackerService } from '../tracker/tracker.serv
 export class LoginService {
 
     constructor(
-        private principal: Principal,
+        private accountService: AccountService,
         <%_ if (websocket === 'spring-websocket') { _%>
         private trackerService: <%=jhiPrefixCapitalized%>TrackerService,
         <%_ } _%>
@@ -53,7 +53,7 @@ export class LoginService {
 
         return new Promise((resolve, reject) => {
             this.authServerProvider.login(credentials).subscribe((data) => {
-                this.principal.identity(true).then((account) => {
+                this.accountService.identity(true).then((account) => {
                     <%_ if (websocket === 'spring-websocket') { _%>
                     this.trackerService.sendActivity();
                     <%_ } _%>
@@ -77,14 +77,14 @@ export class LoginService {
 
     logout() {
         <%_ if (authenticationType === 'uaa') { _%>
-        if (this.principal.isAuthenticated()) {
-            this.authServerProvider.logout().subscribe(() => this.principal.authenticate(null));
+        if (this.accountService.isAuthenticated()) {
+            this.authServerProvider.logout().subscribe(() => this.accountService.authenticate(null));
         } else {
-            this.principal.authenticate(null);
+            this.accountService.authenticate(null);
         }
         <%_ } else { _%>
         this.authServerProvider.logout().subscribe();
-        this.principal.authenticate(null);
+        this.accountService.authenticate(null);
         <%_ } _%>
     }
 }
diff --git a/generators/client/templates/angular/src/main/webapp/app/home/home.component.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/home/home.component.ts.ejs
index 866d15929c..e98c829c9c 100644
--- a/generators/client/templates/angular/src/main/webapp/app/home/home.component.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/home/home.component.ts.ejs
@@ -22,7 +22,7 @@ import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { JhiEventManager } from 'ng-jhipster';
 <%_ } _%>
 
-import { <% if (authenticationType !== 'oauth2') { %>LoginModalService<% } else { %>LoginService<% } %>, Principal, Account } from 'app/core';
+import { <% if (authenticationType !== 'oauth2') { %>LoginModalService<% } else { %>LoginService<% } %>, AccountService, Account } from 'app/core';
 
 @Component({
     selector: '<%= jhiPrefixDashed %>-home',
@@ -43,7 +43,7 @@ export class HomeComponent implements OnInit {
     <%_ } _%>
 
     constructor(
-        private principal: Principal,
+        private accountService: AccountService,
         <%_ if (authenticationType !== 'oauth2') { _%>
         private loginModalService: LoginModalService,
         private eventManager: JhiEventManager
@@ -54,7 +54,7 @@ export class HomeComponent implements OnInit {
     }
 
     ngOnInit() {
-        this.principal.identity().then((account) => {
+        this.accountService.identity().then((account) => {
             this.account = account;
         });
         <%_ if (authenticationType !== 'oauth2') { _%>
@@ -63,7 +63,7 @@ export class HomeComponent implements OnInit {
 
     registerAuthenticationSuccess() {
         this.eventManager.subscribe('authenticationSuccess', (message) => {
-            this.principal.identity().then((account) => {
+            this.accountService.identity().then((account) => {
                 this.account = account;
             });
         });
@@ -71,7 +71,7 @@ export class HomeComponent implements OnInit {
     }
 
     isAuthenticated() {
-        return this.principal.isAuthenticated();
+        return this.accountService.isAuthenticated();
     }
 
     login() {
diff --git a/generators/client/templates/angular/src/main/webapp/app/layouts/navbar/navbar.component.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/layouts/navbar/navbar.component.ts.ejs
index 8598b73f0e..68560a645d 100644
--- a/generators/client/templates/angular/src/main/webapp/app/layouts/navbar/navbar.component.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/layouts/navbar/navbar.component.ts.ejs
@@ -27,7 +27,7 @@ import { SessionStorageService } from 'ngx-webstorage';
 <%_ } _%>
 
 import { VERSION } from 'app/app.constants';
-import { <% if (enableTranslation) { %>JhiLanguageHelper, <% } %>Principal, <% if (authenticationType !== 'oauth2') { %>LoginModalService, <% } %>LoginService } from 'app/core';
+import { <% if (enableTranslation) { %>JhiLanguageHelper, <% } %>AccountService, <% if (authenticationType !== 'oauth2') { %>LoginModalService, <% } %>LoginService } from 'app/core';
 import { ProfileService } from '../profiles/profile.service';
 
 @Component({
@@ -58,7 +58,7 @@ export class NavbarComponent implements OnInit {
         private languageHelper: JhiLanguageHelper,
         private sessionStorage: SessionStorageService,
         <%_ } _%>
-        private principal: Principal,
+        private accountService: AccountService,
         <%_ if (authenticationType !== 'oauth2') { _%>
         private loginModalService: LoginModalService,
         <%_ } _%>
@@ -94,7 +94,7 @@ export class NavbarComponent implements OnInit {
     }
 
     isAuthenticated() {
-        return this.principal.isAuthenticated();
+        return this.accountService.isAuthenticated();
     }
 
     login() {
@@ -116,6 +116,6 @@ export class NavbarComponent implements OnInit {
     }
 
     getImageUrl() {
-        return this.isAuthenticated() ? this.principal.getImageUrl() : null;
+        return this.isAuthenticated() ? this.accountService.getImageUrl() : null;
     }
 }
diff --git a/generators/client/templates/angular/src/main/webapp/app/shared/auth/has-any-authority.directive.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/shared/auth/has-any-authority.directive.ts.ejs
index 0d067b58ef..f4b2b29bee 100644
--- a/generators/client/templates/angular/src/main/webapp/app/shared/auth/has-any-authority.directive.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/shared/auth/has-any-authority.directive.ts.ejs
@@ -17,7 +17,7 @@
  limitations under the License.
 -%>
 import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
-import { Principal } from 'app/core/auth/principal.service';
+import { AccountService } from 'app/core/auth/account.service';
 
 /**
  * @whatItDoes Conditionally includes an HTML element if current user has any
@@ -37,7 +37,7 @@ export class HasAnyAuthorityDirective {
 
     private authorities: string[];
 
-    constructor(private principal: Principal, private templateRef: TemplateRef<any>, private viewContainerRef: ViewContainerRef) {
+    constructor(private accountService: AccountService, private templateRef: TemplateRef<any>, private viewContainerRef: ViewContainerRef) {
     }
 
     @Input()
@@ -45,15 +45,14 @@ export class HasAnyAuthorityDirective {
         this.authorities = typeof value === 'string' ? [ value ] : value;
         this.updateView();
         // Get notified each time authentication state changes.
-        this.principal.getAuthenticationState().subscribe((identity) => this.updateView());
+        this.accountService.getAuthenticationState().subscribe((identity) => this.updateView());
     }
 
     private updateView(): void {
-        this.principal.hasAnyAuthority(this.authorities).then((result) => {
-            this.viewContainerRef.clear();
-            if (result) {
-                this.viewContainerRef.createEmbeddedView(this.templateRef);
-            }
-        });
+        const hasAnyAuthority = this.accountService.hasAnyAuthority(this.authorities)
+        this.viewContainerRef.clear();
+        if (hasAnyAuthority) {
+            this.viewContainerRef.createEmbeddedView(this.templateRef);
+        }
     }
 }
diff --git a/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity-management.component.ts.ejs b/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity-management.component.ts.ejs
index c1a15193fe..7091dd4f45 100644
--- a/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity-management.component.ts.ejs
+++ b/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity-management.component.ts.ejs
@@ -27,7 +27,7 @@ import { Subscription } from 'rxjs';
 import { JhiEventManager, <% if (pagination !== 'no') { %>JhiParseLinks, <% } %>JhiAlertService<% if (fieldsContainBlob) { %>, JhiDataUtils<% } %> } from 'ng-jhipster';
 
 import { I<%= entityAngularName %> } from 'app/shared/model/<%= entityModelFileName %>.model';
-import { Principal } from 'app/core';
+import { AccountService } from 'app/core';
 <%_ if (pagination !== 'no') { %>
 import { ITEMS_PER_PAGE } from 'app/shared';
 <%_ } _%>
@@ -48,7 +48,7 @@ export class <%= entityAngularName %>Component implements OnInit, OnDestroy {
 
     ngOnInit() {
         this.loadAll();
-        this.principal.identity().then((account) => {
+        this.accountService.identity().then((account) => {
             this.currentAccount = account;
         });
         this.registerChangeIn<%= entityClassPlural %>();
diff --git a/generators/entity-client/templates/angular/src/main/webapp/app/entities/infinite-scroll-template.ejs b/generators/entity-client/templates/angular/src/main/webapp/app/entities/infinite-scroll-template.ejs
index 37023056ed..b9c770cd66 100644
--- a/generators/entity-client/templates/angular/src/main/webapp/app/entities/infinite-scroll-template.ejs
+++ b/generators/entity-client/templates/angular/src/main/webapp/app/entities/infinite-scroll-template.ejs
@@ -41,7 +41,7 @@
         <%_ if (searchEngine === 'elasticsearch') { _%>
         private activatedRoute: ActivatedRoute,
         <%_ } _%>
-        private principal: Principal
+        private accountService: AccountService
     ) {
         this.<%= entityInstancePlural %> = [];
         this.itemsPerPage = ITEMS_PER_PAGE;
diff --git a/generators/entity-client/templates/angular/src/main/webapp/app/entities/no-pagination-template.ejs b/generators/entity-client/templates/angular/src/main/webapp/app/entities/no-pagination-template.ejs
index f80cb31a69..d21ec39f62 100644
--- a/generators/entity-client/templates/angular/src/main/webapp/app/entities/no-pagination-template.ejs
+++ b/generators/entity-client/templates/angular/src/main/webapp/app/entities/no-pagination-template.ejs
@@ -33,7 +33,7 @@
         <%_ if (searchEngine === 'elasticsearch') { _%>
         private activatedRoute: ActivatedRoute,
         <%_ } _%>
-        private principal: Principal
+        private accountService: AccountService
     ) {
         <%_ if (searchEngine === 'elasticsearch') { _%>
         this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.params['search'] ?
diff --git a/generators/entity-client/templates/angular/src/main/webapp/app/entities/pagination-template.ejs b/generators/entity-client/templates/angular/src/main/webapp/app/entities/pagination-template.ejs
index a45aa31fdc..f1c16f96ec 100644
--- a/generators/entity-client/templates/angular/src/main/webapp/app/entities/pagination-template.ejs
+++ b/generators/entity-client/templates/angular/src/main/webapp/app/entities/pagination-template.ejs
@@ -40,7 +40,7 @@
         private <%= entityInstance %>Service: <%= entityAngularName %>Service,
         private parseLinks: JhiParseLinks,
         private jhiAlertService: JhiAlertService,
-        private principal: Principal,
+        private accountService: AccountService,
         private activatedRoute: ActivatedRoute,
         <%_ if (fieldsContainBlob) { _%>
         private dataUtils: JhiDataUtils,


Test patch:
diff --git a/generators/client/templates/angular/src/test/javascript/spec/app/account/sessions/sessions.component.spec.ts.ejs b/generators/client/templates/angular/src/test/javascript/spec/app/account/sessions/sessions.component.spec.ts.ejs
index 8ae4dc1bb1..e17a2fad7d 100644
--- a/generators/client/templates/angular/src/test/javascript/spec/app/account/sessions/sessions.component.spec.ts.ejs
+++ b/generators/client/templates/angular/src/test/javascript/spec/app/account/sessions/sessions.component.spec.ts.ejs
@@ -23,8 +23,8 @@ import { <%=angularXAppName%>TestModule } from '../../../test.module';
 import { Session } from 'app/account/sessions/session.model';
 import { SessionsComponent } from 'app/account/sessions/sessions.component';
 import { SessionsService } from 'app/account/sessions/sessions.service';
-import { MockPrincipal } from '../../../helpers/mock-principal.service';
-import { Principal } from 'app/core/auth/principal.service';
+import { MockAccountService } from '../../../helpers/mock-account.service';
+import { AccountService } from 'app/core/auth/account.service';
 
 describe('Component Tests', () => {
 
@@ -47,9 +47,9 @@ describe('Component Tests', () => {
         });
 
         it('should define its initial state',
-            inject([Principal, SessionsService],
-                fakeAsync((mockPrincipal: MockPrincipal, service: SessionsService) => {
-                    mockPrincipal.spy('identity').and.returnValue(Promise.resolve({
+            inject([AccountService, SessionsService],
+                fakeAsync((mockAccountService: MockAccountService, service: SessionsService) => {
+                    mockAccountService.spy('identity').and.returnValue(Promise.resolve({
                         id: 'fuzzer'
                     }));
                     spyOn(service, 'findAll').and.returnValue(of(sessions));
@@ -57,7 +57,7 @@ describe('Component Tests', () => {
                     comp.ngOnInit();
                     tick();
 
-                    expect(mockPrincipal.identitySpy).toHaveBeenCalled();
+                    expect(mockAccountService.identitySpy).toHaveBeenCalled();
                     expect(service.findAll).toHaveBeenCalled();
                     expect(comp.success).toBeUndefined();
                     expect(comp.error).toBeUndefined();
@@ -70,9 +70,9 @@ describe('Component Tests', () => {
         );
 
         it('should call delete on Sessions to invalidate a session',
-            inject([Principal, SessionsService],
-                fakeAsync((mockPrincipal: MockPrincipal, service: SessionsService) => {
-                    mockPrincipal.spy('identity').and.returnValue(Promise.resolve({
+            inject([AccountService, SessionsService],
+                fakeAsync((mockAccountService: MockAccountService, service: SessionsService) => {
+                    mockAccountService.spy('identity').and.returnValue(Promise.resolve({
                         id: 'fuzzer'
                     }));
                     spyOn(service, 'findAll').and.returnValue(of(sessions));
@@ -88,9 +88,9 @@ describe('Component Tests', () => {
         );
 
         it('should call delete on Sessions and notify of error',
-            inject([Principal, SessionsService],
-                fakeAsync((mockPrincipal: MockPrincipal, service: SessionsService) => {
-                    mockPrincipal.spy('identity').and.returnValue(Promise.resolve({
+            inject([AccountService, SessionsService],
+                fakeAsync((mockAccountService: MockAccountService, service: SessionsService) => {
+                    mockAccountService.spy('identity').and.returnValue(Promise.resolve({
                         id: 'fuzzer'
                     }));
                     spyOn(service, 'findAll').and.returnValue(of(sessions));
@@ -109,9 +109,9 @@ describe('Component Tests', () => {
         );
 
         it('should call notify of success upon session invalidation',
-            inject([Principal, SessionsService],
-                fakeAsync((mockPrincipal: MockPrincipal, service: SessionsService) => {
-                    mockPrincipal.spy('identity').and.returnValue(Promise.resolve({
+            inject([AccountService, SessionsService],
+                fakeAsync((mockAccountService: MockAccountService, service: SessionsService) => {
+                    mockAccountService.spy('identity').and.returnValue(Promise.resolve({
                         id: 'fuzzer'
                     }));
                     spyOn(service, 'findAll').and.returnValue(of(sessions));
diff --git a/generators/client/templates/angular/src/test/javascript/spec/app/account/settings/settings.component.spec.ts.ejs b/generators/client/templates/angular/src/test/javascript/spec/app/account/settings/settings.component.spec.ts.ejs
index c29aedb41c..622a3fa2c6 100644
--- a/generators/client/templates/angular/src/test/javascript/spec/app/account/settings/settings.component.spec.ts.ejs
+++ b/generators/client/templates/angular/src/test/javascript/spec/app/account/settings/settings.component.spec.ts.ejs
@@ -20,7 +20,7 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing';
 import { Observable, throwError } from 'rxjs';
 
 import { <%=angularXAppName%>TestModule } from '../../../test.module';
-import { Principal, AccountService } from 'app/core';
+import { AccountService } from 'app/core';
 import { SettingsComponent } from 'app/account/settings/settings.component';
 <%_ if (websocket === 'spring-websocket') { _%>
 import { <%=jhiPrefixCapitalized%>TrackerService } from 'app/core/tracker/tracker.service';
@@ -34,7 +34,6 @@ describe('Component Tests', () => {
         let comp: SettingsComponent;
         let fixture: ComponentFixture<SettingsComponent>;
         let mockAuth: any;
-        let mockPrincipal: any;
 
         beforeEach(async(() => {
             TestBed.configureTestingModule({
@@ -57,7 +56,6 @@ describe('Component Tests', () => {
             fixture = TestBed.createComponent(SettingsComponent);
             comp = fixture.componentInstance;
             mockAuth = fixture.debugElement.injector.get(AccountService);
-            mockPrincipal = fixture.debugElement.injector.get(Principal);
         });
 
         it('should send the current identity upon save', () => {
@@ -71,14 +69,14 @@ describe('Component Tests', () => {
                 langKey: '<%= nativeLanguage %>',
                 login: 'john'
             };
-            mockPrincipal.setResponse(accountValues);
+            mockAuth.setIdentityResponse(accountValues);
 
             // WHEN
             comp.settingsAccount = accountValues;
             comp.save();
 
             // THEN
-            expect(mockPrincipal.identitySpy).toHaveBeenCalled();
+            expect(mockAuth.identitySpy).toHaveBeenCalled();
             expect(mockAuth.saveSpy).toHaveBeenCalledWith(accountValues);
             expect(comp.settingsAccount).toEqual(accountValues);
         });
@@ -89,7 +87,7 @@ describe('Component Tests', () => {
                 firstName: 'John',
                 lastName: 'Doe'
             };
-            mockPrincipal.setResponse(accountValues);
+            mockAuth.setIdentityResponse(accountValues);
 
             // WHEN
             comp.save();
diff --git a/generators/client/templates/angular/src/test/javascript/spec/app/core/user/account.service.spec.ts.ejs b/generators/client/templates/angular/src/test/javascript/spec/app/core/user/account.service.spec.ts.ejs
new file mode 100644
index 0000000000..5a674856b9
--- /dev/null
+++ b/generators/client/templates/angular/src/test/javascript/spec/app/core/user/account.service.spec.ts.ejs
@@ -0,0 +1,118 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+import { SERVER_API_URL } from 'app/app.constants';
+import { AccountService } from 'app/core';
+import { JhiDateUtils
+<%_ if (enableTranslation && authenticationType !== 'oauth2') { _%>
+    ,JhiLanguageService
+<%_ } _%>
+} from 'ng-jhipster';
+import { SessionStorageService } from 'ngx-webstorage';
+<%_ if (enableTranslation && authenticationType !== 'oauth2') { _%>
+import { MockLanguageService } from '../../../helpers/mock-language.service';
+<%_ } _%>
+
+describe('Service Tests', () => {
+    describe('Account Service', () => {
+        let service: AccountService;
+        let httpMock;
+
+        beforeEach(() => {
+            TestBed.configureTestingModule({
+                imports: [HttpClientTestingModule],
+                providers: [
+                    JhiDateUtils,
+                    SessionStorageService,
+                    <%_ if (enableTranslation && authenticationType !== 'oauth2') { _%>
+                    {
+                        provide: JhiLanguageService,
+                        useClass: MockLanguageService
+                    }
+                    <%_ } _%>
+                ]
+            });
+
+            service = TestBed.get(AccountService);
+            httpMock = TestBed.get(HttpTestingController);
+        });
+
+        afterEach(() => {
+            httpMock.verify();
+        });
+
+        describe('Service methods', () => {
+            it('should call /account if user is undefined', () => {
+                service.identity().then(() => {});
+                const req = httpMock.expectOne({ method: 'GET' });
+                const resourceUrl = SERVER_API_URL + '<%- apiUaaPath %>api/account';
+
+                expect(req.request.url).toEqual(`${resourceUrl}`);
+            });
+
+            it('should call /account only once', () => {
+                service.identity().then(() => service.identity().then(() => {}));
+                const req = httpMock.expectOne({ method: 'GET' });
+                const resourceUrl = SERVER_API_URL + '<%- apiUaaPath %>api/account';
+
+                expect(req.request.url).toEqual(`${resourceUrl}`);
+                req.flush({
+                    firstName: 'John'
+                });
+            });
+
+            describe('hasAuthority', () => {
+                it('should return false if user is not logged', async () => {
+                    const hasAuthority = await service.hasAuthority('ROLE_USER');
+                    expect(hasAuthority).toBeFalsy();
+                });
+
+                it('should return false if user is logged and has not authority', async () => {
+                    service.authenticate({
+                        authorities: ['ROLE_USER']
+                    });
+
+                    const hasAuthority = await service.hasAuthority('ROLE_ADMIN');
+
+                    expect(hasAuthority).toBeFalsy();
+                });
+
+                it('should return true if user is logged and has authority', async () => {
+                    service.authenticate({
+                        authorities: ['ROLE_USER']
+                    });
+
+                    const hasAuthority = await service.hasAuthority('ROLE_USER');
+
+                    expect(hasAuthority).toBeTruthy();
+                });
+            });
+
+            describe('hasAnyAuthority', () => {
+                it('should return false if user is not logged', async () => {
+                    const hasAuthority = await service.hasAnyAuthority(['ROLE_USER']);
+                    expect(hasAuthority).toBeFalsy();
+                });
+
+                it('should return false if user is logged and has not authority', async () => {
+                    service.authenticate({
+                        authorities: ['ROLE_USER']
+                    });
+
+                    const hasAuthority = await service.hasAnyAuthority(['ROLE_ADMIN']);
+
+                    expect(hasAuthority).toBeFalsy();
+                });
+
+                it('should return true if user is logged and has authority', async () => {
+                    service.authenticate({
+                        authorities: ['ROLE_USER']
+                    });
+
+                    const hasAuthority = await service.hasAnyAuthority(['ROLE_USER', 'ROLE_ADMIN']);
+
+                    expect(hasAuthority).toBeTruthy();
+                });
+            });
+        });
+    });
+});
diff --git a/generators/client/templates/angular/src/test/javascript/spec/helpers/mock-account.service.ts.ejs b/generators/client/templates/angular/src/test/javascript/spec/helpers/mock-account.service.ts.ejs
index 6204c20f7f..6b43b6d3b6 100644
--- a/generators/client/templates/angular/src/test/javascript/spec/helpers/mock-account.service.ts.ejs
+++ b/generators/client/templates/angular/src/test/javascript/spec/helpers/mock-account.service.ts.ejs
@@ -25,6 +25,7 @@ export class MockAccountService extends SpyObject {
     getSpy: Spy;
     saveSpy: Spy;
     fakeResponse: any;
+    identitySpy: Spy;
 
     constructor() {
         super(AccountService);
@@ -32,6 +33,7 @@ export class MockAccountService extends SpyObject {
         this.fakeResponse = null;
         this.getSpy = this.spy('get').andReturn(this);
         this.saveSpy = this.spy('save').andReturn(this);
+        this.setIdentitySpy({});
     }
 
     subscribe(callback: any) {
@@ -41,4 +43,12 @@ export class MockAccountService extends SpyObject {
     setResponse(json: any): void {
         this.fakeResponse = json;
     }
+
+    setIdentitySpy(json: any): any {
+        this.identitySpy = this.spy('identity').andReturn(Promise.resolve(json));
+    }
+
+    setIdentityResponse(json: any): void {
+        this.setIdentitySpy(json);
+    }
 }
diff --git a/generators/client/templates/angular/src/test/javascript/spec/helpers/mock-principal.service.ts.ejs b/generators/client/templates/angular/src/test/javascript/spec/helpers/mock-principal.service.ts.ejs
deleted file mode 100644
index 7111b801d5..0000000000
--- a/generators/client/templates/angular/src/test/javascript/spec/helpers/mock-principal.service.ts.ejs
+++ /dev/null
@@ -1,39 +0,0 @@
-<%#
- Copyright 2013-2018 the original author or authors from the JHipster project.
-
- This file is part of the JHipster project, see https://www.jhipster.tech/
- for more information.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--%>
-import { SpyObject } from './spyobject';
-import { Principal } from 'app/core/auth/principal.service';
-import Spy = jasmine.Spy;
-
-export class MockPrincipal extends SpyObject {
-
-    identitySpy: Spy;
-
-    constructor() {
-        super(Principal);
-
-        this.setIdentitySpy({});
-    }
-    setIdentitySpy(json: any): any {
-        this.identitySpy = this.spy('identity').andReturn(Promise.resolve(json));
-    }
-
-    setResponse(json: any): void {
-        this.setIdentitySpy(json);
-    }
-}
diff --git a/generators/client/templates/angular/src/test/javascript/spec/test.module.ts.ejs b/generators/client/templates/angular/src/test/javascript/spec/test.module.ts.ejs
index 1a47eb7c3b..96a08756c6 100644
--- a/generators/client/templates/angular/src/test/javascript/spec/test.module.ts.ejs
+++ b/generators/client/templates/angular/src/test/javascript/spec/test.module.ts.ejs
@@ -25,13 +25,12 @@ import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
 import { JhiLanguageService, JhiDataUtils, JhiDateUtils, JhiEventManager, JhiAlertService, JhiParseLinks } from 'ng-jhipster';
 
 import { MockLanguageService, MockLanguageHelper } from './helpers/mock-language.service';
-import { JhiLanguageHelper, Principal, AccountService<% if (authenticationType !== 'oauth2') { %>, LoginModalService<% } %><% if (websocket === 'spring-websocket') { %>, <%=jhiPrefixCapitalized%>TrackerService<% } %> } from 'app/core';
+import { JhiLanguageHelper, AccountService<% if (authenticationType !== 'oauth2') { %>, LoginModalService<% } %><% if (websocket === 'spring-websocket') { %>, <%=jhiPrefixCapitalized%>TrackerService<% } %> } from 'app/core';
 <%_ } else { _%>
 import { JhiDataUtils, JhiDateUtils, JhiEventManager, JhiAlertService, JhiParseLinks } from 'ng-jhipster';
 
-import { Principal, AccountService<% if (authenticationType !== 'oauth2') { %>, LoginModalService<% } %><% if (websocket === 'spring-websocket') { %>, <%=jhiPrefixCapitalized%>TrackerService<% } %> } from 'app/core';
+import { AccountService<% if (authenticationType !== 'oauth2') { %>, LoginModalService<% } %><% if (websocket === 'spring-websocket') { %>, <%=jhiPrefixCapitalized%>TrackerService<% } %> } from 'app/core';
 <%_ } _%>
-import { MockPrincipal } from './helpers/mock-principal.service';
 import { MockAccountService } from './helpers/mock-account.service';
 import { MockActivatedRoute, MockRouter } from './helpers/mock-route.service';
 import { MockActiveModal } from './helpers/mock-active-modal.service';
@@ -78,10 +77,6 @@ _%>
             provide: Router,
             useClass: MockRouter
         },
-        {
-            provide: Principal,
-            useClass: MockPrincipal
-        },
         {
             provide: AccountService,
             useClass: MockAccountService
diff --git a/test/utils/expected-files.js b/test/utils/expected-files.js
index 91640882f9..769b823569 100644
--- a/test/utils/expected-files.js
+++ b/test/utils/expected-files.js
@@ -390,7 +390,6 @@ const expectedFiles = {
         `${CLIENT_MAIN_SRC_DIR}app/core/auth/account.service.ts`,
         `${CLIENT_MAIN_SRC_DIR}app/core/auth/csrf.service.ts`,
         `${CLIENT_MAIN_SRC_DIR}app/shared/auth/has-any-authority.directive.ts`,
-        `${CLIENT_MAIN_SRC_DIR}app/core/auth/principal.service.ts`,
         `${CLIENT_MAIN_SRC_DIR}app/core/auth/state-storage.service.ts`,
         `${CLIENT_MAIN_SRC_DIR}app/core/auth/user-route-access-service.ts`,
         `${CLIENT_MAIN_SRC_DIR}app/shared/constants/error.constants.ts`,
@@ -450,6 +449,7 @@ const expectedFiles = {
         `${CLIENT_TEST_SRC_DIR}spec/app/admin/metrics/metrics.component.spec.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/app/admin/metrics/metrics.service.spec.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/app/admin/metrics/metrics-modal.component.spec.ts`,
+        `${CLIENT_TEST_SRC_DIR}spec/app/core/user/account.service.spec.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/app/shared/alert/alert-error.component.spec.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/app/shared/login/login.component.spec.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/helpers/mock-account.service.ts`,
@@ -458,7 +458,6 @@ const expectedFiles = {
         `${CLIENT_TEST_SRC_DIR}spec/helpers/mock-event-manager.service.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/helpers/mock-language.service.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/helpers/mock-login.service.ts`,
-        `${CLIENT_TEST_SRC_DIR}spec/helpers/mock-principal.service.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/helpers/mock-route.service.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/helpers/mock-state-storage.service.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/helpers/spyobject.ts`,