I am struggling with implementing JHipster Auth-guard. I am facing an issue where canActivate is not triggered for a user without permission for a specific route.
I have carefully examined my code, but the console shows that .then() is undefined at the specified line. I even checked the principal through console logging and it appears to be defined. Can anyone in the Stack Overflow community help me identify what I might be doing wrong?
checkLogin(authorities: string[], url: string): Promise<boolean> {
var principal = this.principal;
return Promise.resolve(principal.identity().then((account) => {
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'then' of undefined
TypeError: Cannot read property 'then' of undefined
at AuthGuard.checkLogin (auth-guard.ts:27)
at AuthGuard.canActivate (auth-guard.ts:21)
This is how my code looks:
app.module
const routes: Routes = [
{
path: '**',
component: DashboardComponent,
canActivate: [AuthGuard],
resolve: {
data: DashboardService
}
}
];
@NgModule({
declarations: [
DashboardComponent
],
imports: [
RouterModule.forChild(routes),
HttpClientModule,
HttpModule,
CdkTableModule,
MatButtonModule,
MatDividerModule,
MatFormFieldModule,
MatIconModule,
MatMenuModule,
MatSelectModule,
MatSidenavModule,
MatTableModule,
MatTabsModule,
NgxChartsModule,
],
providers: [
ProjectDashboardService, AuthGuard, Principal, StateStorageService
]
})
Auth-guard.ts
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { Principal } from './principal.service';
import { StateStorageService } from './state-storage.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router,
private principal: Principal,
private stateStorageService: StateStorageService) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Promise<boolean> {
const authorities = route.data['authorities'];
// It's important to call checkLogin / and thus the principal.identity() function, to ensure that the client also has a principal if they were previously 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> {
var principal = this.principal;
return Promise.resolve(principal.identity().then((account) => {
if (!authorities || authorities.length === 0) {
return true;
}
if (account) {
return principal.hasAnyAuthority(authorities).then((response) => {
if (response) {
return true;
}
return false;
});
}
this.stateStorageService.storeUrl(url);
window.location.href = "http://stackoverflow.com";
return false;
}));
}
}
principal service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class Principal {
private userIdentity: any;
private authenticated = false;
private authenticationState = new Subject<any>();
constructor(
) { }
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;
}
if (this.userIdentity) {
return Promise.resolve(this.userIdentity);
}
}
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;
}
}