Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"minimist": "^1.2.5",
"moment": "^2.25.3",
"msal": "^1.2.1",
"ngx-cookie-service": "^11.0.2",
"ngx-mask": "^9.1.2",
"ngx-pagination": "^5.0.0",
"ngx-toastr": "^12.0.1",
Expand Down
4 changes: 3 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { AutocompleteLibModule } from 'angular-ng-autocomplete';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CookieService } from 'ngx-cookie-service';
import { NavbarComponent } from './modules/shared/components/navbar/navbar.component';
import { UserComponent } from './modules/shared/components/user/user.component';
import { SidebarComponent } from './modules/shared/components/sidebar/sidebar.component';
Expand Down Expand Up @@ -159,7 +160,8 @@ const maskConfig: Partial<IConfig> = {
useClass: InjectTokenInterceptor,
multi: true,
},
DatePipe
DatePipe,
CookieService,
],
bootstrap: [AppComponent],
})
Expand Down
7 changes: 6 additions & 1 deletion src/app/guards/login-guard/login.guard.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { TestBed, inject } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { Router } from '@angular/router';
import { CookieService } from 'ngx-cookie-service';

import { AzureAdB2CService } from '../../modules/login/services/azure.ad.b2c.service';
import { LoginGuard } from './login.guard';
Expand All @@ -10,6 +11,7 @@ describe('LoginGuard', () => {

let loginGuard: LoginGuard;
let azureAdB2CService: AzureAdB2CService;
let cookieService: CookieService;
const azureAdB2CServiceStub = {
isLogin() {
return true;
Expand All @@ -24,16 +26,19 @@ describe('LoginGuard', () => {
});
loginGuard = TestBed.inject(LoginGuard);
azureAdB2CService = TestBed.inject(AzureAdB2CService);
cookieService = TestBed.inject(CookieService);
});

it('should be created', () => {
expect(loginGuard).toBeTruthy();
});

it('can activate the route when user is logged-in', () => {
it('can activate the route when user is logged-in && the token cookie exists', () => {
spyOn(azureAdB2CService, 'isLogin').and.returnValue(true);
spyOn(cookieService, 'check').and.returnValue(true);
const canActivate = loginGuard.canActivate();
expect(azureAdB2CService.isLogin).toHaveBeenCalled();
expect(cookieService.check).toHaveBeenCalled();
expect(canActivate).toEqual(true);
});

Expand Down
8 changes: 5 additions & 3 deletions src/app/guards/login-guard/login.guard.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';
import { AzureAdB2CService } from '../../modules/login/services/azure.ad.b2c.service';
import { CookieService } from 'ngx-cookie-service';

@Injectable({
providedIn: 'root'
})
export class LoginGuard implements CanActivate {

constructor(private azureAdB2CService: AzureAdB2CService, private router: Router) { }
constructor(private azureAdB2CService: AzureAdB2CService, private router: Router, private cookieService: CookieService) { }

canActivate() {
if (this.azureAdB2CService.isLogin()) {
if (this.azureAdB2CService.isLogin() && this.cookieService.check('msal.idtoken')) {
this.azureAdB2CService.setCookies();
return true;
} else {
this.router.navigate(['login']);
return false;
}
}
}
}
6 changes: 5 additions & 1 deletion src/app/modules/login/login.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ describe('LoginComponent', () => {
},
signIn() {
return of();
},
setCookies() {
}
};

Expand Down Expand Up @@ -51,9 +53,11 @@ describe('LoginComponent', () => {

it('should sign up or login with google if is not logged-in into the app', inject([Router], (router: Router) => {
spyOn(azureAdB2CService, 'isLogin').and.returnValue(false);
spyOn(azureAdB2CService, 'signIn').and.returnValue(of());
spyOn(azureAdB2CService, 'setCookies').and.returnValue();
spyOn(azureAdB2CService, 'signIn').and.returnValue(of(() => {}));
component.login();
expect(azureAdB2CService.signIn).toHaveBeenCalled();
expect(azureAdB2CService.setCookies).toHaveBeenCalled();
}));

it('should not sign-up or login with google if is already logged-in into the app', inject([Router], (router: Router) => {
Expand Down
1 change: 1 addition & 0 deletions src/app/modules/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class LoginComponent {
this.router.navigate(['']);
} else {
this.azureAdB2CService.signIn().subscribe(() => {
this.azureAdB2CService.setCookies();
this.router.navigate(['']);
});
}
Expand Down
22 changes: 11 additions & 11 deletions src/app/modules/login/services/azure.ad.b2c.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,44 +91,44 @@ describe('AzureAdB2CService', () => {
expect(isLogin).toEqual(false);
});

it('setTenantId should save a tenantId in session storage', () => {
it('setTenantId should save a tenantId in local storage', () => {
spyOn(UserAgentApplication.prototype, 'getAccount').and.returnValue(account);
spyOn(sessionStorage, 'setItem').withArgs('tenant_id', '12345');
spyOn(localStorage, 'setItem').withArgs('tenant_id', '12345');

const isLogin = service.isLogin();
service.setTenantId();

expect(UserAgentApplication.prototype.getAccount).toHaveBeenCalled();
expect(isLogin).toEqual(true);
expect(sessionStorage.setItem).toHaveBeenCalledWith('tenant_id', '12345');
expect(localStorage.setItem).toHaveBeenCalledWith('tenant_id', '12345');
});

it('setTenantId should not save tenantId if login is false ', () => {
spyOn(UserAgentApplication.prototype, 'getAccount').and.returnValue(null);
spyOn(sessionStorage, 'setItem');
spyOn(localStorage, 'setItem');
const isLogin = service.isLogin();
expect(UserAgentApplication.prototype.getAccount).toHaveBeenCalled();
expect(isLogin).toEqual(false);
expect(sessionStorage.setItem).not.toHaveBeenCalled();
expect(localStorage.setItem).not.toHaveBeenCalled();
});

it('getTenantId should get the tenantId from session storage', () => {
it('getTenantId should get the tenantId from local storage', () => {
const tenantId = '12345';
spyOn(sessionStorage, 'getItem').and.returnValue(tenantId);
spyOn(localStorage, 'getItem').and.returnValue(tenantId);

const resp = service.getTenantId();

expect(sessionStorage.getItem).toHaveBeenCalled();
expect(localStorage.getItem).toHaveBeenCalled();
expect(resp).toEqual(tenantId);
});

it('getBearerToken should get the bearer token from session storage', () => {
it('getBearerToken should get the bearer token from local storage', () => {
const token = '12345abc';
spyOn(sessionStorage, 'getItem').and.returnValue(token);
spyOn(localStorage, 'getItem').and.returnValue(token);

const resp = service.getBearerToken();

expect(sessionStorage.getItem).toHaveBeenCalled();
expect(localStorage.getItem).toHaveBeenCalled();
expect(resp).toEqual(token);
});

Expand Down
27 changes: 23 additions & 4 deletions src/app/modules/login/services/azure.ad.b2c.service.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import { Injectable } from '@angular/core';
import { UserAgentApplication } from 'msal';
import { from, Observable } from 'rxjs';
import { CookieService } from 'ngx-cookie-service';

import { AUTHORITY, CLIENT_ID, SCOPES } from '../../../../environments/environment';

@Injectable({
providedIn: 'root',
})
export class AzureAdB2CService {
msalConfig = {

constructor(private cookieService?: CookieService) {}

msalConfig: any = {
auth: {
clientId: CLIENT_ID,
authority: AUTHORITY,
validateAuthority: false,
},
cache: {
cacheLocation: 'localStorage',
},
};

tokenRequest = {
Expand All @@ -27,6 +34,8 @@ export class AzureAdB2CService {
}

logout() {
this.cookieService.delete('msal.idtoken');
this.cookieService.delete('msal.idtoken');
this.msal.logout();
}

Expand All @@ -42,19 +51,29 @@ export class AzureAdB2CService {
return this.msal.getAccount() ? true : false;
}

setCookies() {
this.cookieService.set('msal.client.info', this.getBearerClientInfo(), 2);
this.cookieService.set('msal.idtoken', this.getBearerToken(), 2);
}

setTenantId() {
if (this.msal.getAccount() && this.msal.getAccount().idToken) {
const pathArray = this.msal.getAccount().idToken.iss.split('/');
const tenantId = pathArray[3];
sessionStorage.setItem('tenant_id', tenantId);
localStorage.setItem('tenant_id', tenantId);
}
}

getTenantId(): string {
return sessionStorage.getItem('tenant_id');
return localStorage.getItem('tenant_id');
}

getBearerClientInfo(): string {
return localStorage.getItem('msal.client.info');
}

getBearerToken(): string {
return sessionStorage.getItem('msal.idtoken');
return localStorage.getItem('msal.idtoken');
}

getUserEmail(): string {
Expand Down