Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion src/app/guards/login-guard/login.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ export class LoginGuard implements CanActivate {

canActivate() {
if (this.azureAdB2CService.isLogin()) {
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
46 changes: 32 additions & 14 deletions src/app/modules/login/services/azure.ad.b2c.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { inject, TestBed } from '@angular/core/testing';
import { Account, UserAgentApplication } from 'msal';
import { AzureAdB2CService } from './azure.ad.b2c.service';

import { CookieService } from 'ngx-cookie-service';

describe('AzureAdB2CService', () => {
let service: AzureAdB2CService;

let cookieService: CookieService;
let account: Account;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [],
});
service = TestBed.inject(AzureAdB2CService);
cookieService = TestBed.inject(CookieService);
account = {
accountIdentifier: 'abc',
homeAccountIdentifier: 'abc',
Expand Down Expand Up @@ -75,60 +76,77 @@ describe('AzureAdB2CService', () => {
expect(isAdmin).toBeTruthy();
});

it('isLogin returns true if UserAgentApplication has a defined Account', () => {
it('isLogin returns true if UserAgentApplication has a defined Account and token cookie exist', () => {
spyOn(UserAgentApplication.prototype, 'getAccount').and.returnValue(account);
spyOn(cookieService, 'check').and.returnValue(true);

const isLogin = service.isLogin();

expect(UserAgentApplication.prototype.getAccount).toHaveBeenCalled();
expect(cookieService.check).toHaveBeenCalled();
expect(isLogin).toEqual(true);
});

it('isLogin returns false if UserAgentApplication has a defined Account and token cookie does not exist', () => {
spyOn(UserAgentApplication.prototype, 'getAccount').and.returnValue(account);
spyOn(cookieService, 'check').and.returnValue(false);

const isLogin = service.isLogin();

expect(UserAgentApplication.prototype.getAccount).toHaveBeenCalled();
expect(cookieService.check).toHaveBeenCalled();
expect(isLogin).toEqual(false);
});

it('isLogin returns false if UserAgentApplication has a null value for Account', () => {
spyOn(UserAgentApplication.prototype, 'getAccount').and.returnValue(null);

const isLogin = service.isLogin();

expect(UserAgentApplication.prototype.getAccount).toHaveBeenCalled();
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(cookieService, 'check').and.returnValue(true);
spyOn(localStorage, 'setItem').withArgs('tenant_id', '12345');

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

expect(UserAgentApplication.prototype.getAccount).toHaveBeenCalled();
expect(cookieService.check).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
29 changes: 24 additions & 5 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.client.info');
this.msal.logout();
}

Expand All @@ -39,22 +48,32 @@ export class AzureAdB2CService {
}

isLogin() {
return this.msal.getAccount() ? true : false;
return this.msal.getAccount() && this.cookieService.check('msal.idtoken') ? true : false;
}

setCookies() {
this.cookieService.set('msal.idtoken', this.getBearerToken(), 2);
this.cookieService.set('msal.client.info', this.getBearerClientInfo(), 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