mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
AAE-26321 Custom JWT storage service optional injection token (#10292)
* AAE-26321 Custom JWT storage service optional injection token * AAE-26321 custom storage service test * AAE-26321 Use only the injection token with factory * AAE-26321 improve custom storage test
This commit is contained in:
@@ -15,17 +15,34 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { JwtHelperService } from './jwt-helper.service';
|
import { JWT_STORAGE_SERVICE, JwtHelperService } from './jwt-helper.service';
|
||||||
import { mockToken } from '../mock/jwt-helper.service.spec';
|
import { mockToken } from '../mock/jwt-helper.service.spec';
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { StorageService } from '../../common';
|
||||||
|
import { OAuthStorage } from 'angular-oauth2-oidc';
|
||||||
|
|
||||||
|
const mockStorage = {
|
||||||
|
access_token: 'my-access_token',
|
||||||
|
id_token: 'my-id_token',
|
||||||
|
getItem(key: string) {
|
||||||
|
return this[key];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockCustomStorage = {
|
||||||
|
access_token: 'my-custom-access_token',
|
||||||
|
id_token: 'my-custom-id_token',
|
||||||
|
getItem(key: string) {
|
||||||
|
return this[key];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
describe('JwtHelperService', () => {
|
describe('JwtHelperService', () => {
|
||||||
|
|
||||||
let jwtHelperService: JwtHelperService;
|
let jwtHelperService: JwtHelperService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [JwtHelperService]
|
providers: [JwtHelperService, { provide: StorageService, useValue: mockStorage }]
|
||||||
});
|
});
|
||||||
jwtHelperService = TestBed.inject(JwtHelperService);
|
jwtHelperService = TestBed.inject(JwtHelperService);
|
||||||
});
|
});
|
||||||
@@ -44,12 +61,8 @@ describe('JwtHelperService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('RealmRole ', () => {
|
describe('RealmRole ', () => {
|
||||||
|
|
||||||
it('Should be true if the realm_access contains the single role', () => {
|
it('Should be true if the realm_access contains the single role', () => {
|
||||||
spyOn(jwtHelperService, 'getAccessToken').and.returnValue('my-access_token');
|
spyOn(jwtHelperService, 'decodeToken').and.returnValue({
|
||||||
|
|
||||||
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
|
|
||||||
{
|
|
||||||
realm_access: { roles: ['role1'] }
|
realm_access: { roles: ['role1'] }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -58,10 +71,7 @@ describe('JwtHelperService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Should be true if the realm_access contains at least one of the roles', () => {
|
it('Should be true if the realm_access contains at least one of the roles', () => {
|
||||||
spyOn(jwtHelperService, 'getAccessToken').and.returnValue('my-access_token');
|
spyOn(jwtHelperService, 'decodeToken').and.returnValue({
|
||||||
|
|
||||||
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
|
|
||||||
{
|
|
||||||
realm_access: { roles: ['role1'] }
|
realm_access: { roles: ['role1'] }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -70,9 +80,7 @@ describe('JwtHelperService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Should be false if the realm_access does not contain the role', () => {
|
it('Should be false if the realm_access does not contain the role', () => {
|
||||||
spyOn(jwtHelperService, 'getAccessToken').and.returnValue('my-access_token');
|
spyOn(jwtHelperService, 'decodeToken').and.returnValue({
|
||||||
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
|
|
||||||
{
|
|
||||||
realm_access: { roles: ['role3'] }
|
realm_access: { roles: ['role3'] }
|
||||||
});
|
});
|
||||||
const result = jwtHelperService.hasRealmRole('role1');
|
const result = jwtHelperService.hasRealmRole('role1');
|
||||||
@@ -80,9 +88,7 @@ describe('JwtHelperService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Should be false if the realm_access does not contain at least one of the roles', () => {
|
it('Should be false if the realm_access does not contain at least one of the roles', () => {
|
||||||
spyOn(jwtHelperService, 'getAccessToken').and.returnValue('my-access_token');
|
spyOn(jwtHelperService, 'decodeToken').and.returnValue({
|
||||||
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
|
|
||||||
{
|
|
||||||
realm_access: { roles: ['role1'] }
|
realm_access: { roles: ['role1'] }
|
||||||
});
|
});
|
||||||
const result = jwtHelperService.hasRealmRoles(['role3', 'role2']);
|
const result = jwtHelperService.hasRealmRoles(['role3', 'role2']);
|
||||||
@@ -91,12 +97,8 @@ describe('JwtHelperService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('ClientRole ', () => {
|
describe('ClientRole ', () => {
|
||||||
|
|
||||||
it('Should be true if the resource_access contains the single role', () => {
|
it('Should be true if the resource_access contains the single role', () => {
|
||||||
spyOn(jwtHelperService, 'getAccessToken').and.returnValue('my-access_token');
|
spyOn(jwtHelperService, 'decodeToken').and.returnValue({
|
||||||
|
|
||||||
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
|
|
||||||
{
|
|
||||||
resource_access: { fakeApp: { roles: ['role1'] } }
|
resource_access: { fakeApp: { roles: ['role1'] } }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -105,10 +107,7 @@ describe('JwtHelperService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Should be true if the resource_access contains at least one of the roles', () => {
|
it('Should be true if the resource_access contains at least one of the roles', () => {
|
||||||
spyOn(jwtHelperService, 'getAccessToken').and.returnValue('my-access_token');
|
spyOn(jwtHelperService, 'decodeToken').and.returnValue({
|
||||||
|
|
||||||
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
|
|
||||||
{
|
|
||||||
resource_access: { fakeApp: { roles: ['role1'] } }
|
resource_access: { fakeApp: { roles: ['role1'] } }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -117,9 +116,7 @@ describe('JwtHelperService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Should be false if the resource_access does not contain the role', () => {
|
it('Should be false if the resource_access does not contain the role', () => {
|
||||||
spyOn(jwtHelperService, 'getAccessToken').and.returnValue('my-access_token');
|
spyOn(jwtHelperService, 'decodeToken').and.returnValue({
|
||||||
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
|
|
||||||
{
|
|
||||||
resource_access: { fakeApp: { roles: ['role3'] } }
|
resource_access: { fakeApp: { roles: ['role3'] } }
|
||||||
});
|
});
|
||||||
const result = jwtHelperService.hasRealmRolesForClientRole('fakeApp', ['role1', 'role2']);
|
const result = jwtHelperService.hasRealmRolesForClientRole('fakeApp', ['role1', 'role2']);
|
||||||
@@ -127,9 +124,7 @@ describe('JwtHelperService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Should be false if the resource_access does not contain the client role related to the app', () => {
|
it('Should be false if the resource_access does not contain the client role related to the app', () => {
|
||||||
spyOn(jwtHelperService, 'getAccessToken').and.returnValue('my-access_token');
|
spyOn(jwtHelperService, 'decodeToken').and.returnValue({
|
||||||
spyOn(jwtHelperService, 'decodeToken').and.returnValue(
|
|
||||||
{
|
|
||||||
resource_access: { anotherFakeApp: { roles: ['role1'] } }
|
resource_access: { anotherFakeApp: { roles: ['role1'] } }
|
||||||
});
|
});
|
||||||
const result = jwtHelperService.hasRealmRolesForClientRole('fakeApp', ['role1', 'role2']);
|
const result = jwtHelperService.hasRealmRolesForClientRole('fakeApp', ['role1', 'role2']);
|
||||||
@@ -137,3 +132,33 @@ describe('JwtHelperService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('JwtHelperService with custom storage service', () => {
|
||||||
|
let jwtHelperService: JwtHelperService;
|
||||||
|
let defaultStorage: StorageService;
|
||||||
|
let customStorage: OAuthStorage;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [
|
||||||
|
JwtHelperService,
|
||||||
|
{ provide: StorageService, useValue: mockStorage },
|
||||||
|
{ provide: JWT_STORAGE_SERVICE, useValue: mockCustomStorage }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
jwtHelperService = TestBed.inject(JwtHelperService);
|
||||||
|
defaultStorage = TestBed.inject(StorageService);
|
||||||
|
customStorage = TestBed.inject(JWT_STORAGE_SERVICE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use the custom storage service', () => {
|
||||||
|
const customStorageGetItemSpy = spyOn(customStorage, 'getItem').and.callThrough();
|
||||||
|
const defaultStorageGetItemSpy = spyOn(defaultStorage, 'getItem').and.callThrough();
|
||||||
|
const result = jwtHelperService.getIdToken();
|
||||||
|
|
||||||
|
expect(customStorage).toBeDefined();
|
||||||
|
expect(customStorageGetItemSpy).toHaveBeenCalled();
|
||||||
|
expect(defaultStorageGetItemSpy).not.toHaveBeenCalled();
|
||||||
|
expect(result).toBe('my-custom-id_token');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@@ -15,14 +15,19 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { inject, Injectable, InjectionToken } from '@angular/core';
|
||||||
|
import { OAuthStorage } from 'angular-oauth2-oidc';
|
||||||
import { StorageService } from '../../common/services/storage.service';
|
import { StorageService } from '../../common/services/storage.service';
|
||||||
|
|
||||||
|
export const JWT_STORAGE_SERVICE = new InjectionToken<OAuthStorage>('JWT_STORAGE_SERVICE', {
|
||||||
|
providedIn: 'root',
|
||||||
|
factory: () => inject(StorageService)
|
||||||
|
});
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class JwtHelperService {
|
export class JwtHelperService {
|
||||||
|
|
||||||
static USER_NAME = 'name';
|
static USER_NAME = 'name';
|
||||||
static FAMILY_NAME = 'family_name';
|
static FAMILY_NAME = 'family_name';
|
||||||
static GIVEN_NAME = 'given_name';
|
static GIVEN_NAME = 'given_name';
|
||||||
@@ -34,8 +39,7 @@ export class JwtHelperService {
|
|||||||
static USER_PREFERRED_USERNAME = 'preferred_username';
|
static USER_PREFERRED_USERNAME = 'preferred_username';
|
||||||
static HXP_AUTHORIZATION = 'hxp_authorization';
|
static HXP_AUTHORIZATION = 'hxp_authorization';
|
||||||
|
|
||||||
constructor(private storageService: StorageService) {
|
private storageService: OAuthStorage = inject(JWT_STORAGE_SERVICE);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes a JSON web token into a JS object.
|
* Decodes a JSON web token into a JS object.
|
||||||
|
Reference in New Issue
Block a user