Skip to content

Commit

Permalink
feat: keycloak-js@24 update and apply changes of #523 into v14
Browse files Browse the repository at this point in the history
  • Loading branch information
mauriciovigolo committed Mar 19, 2024
1 parent 1626893 commit 4045770
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 45 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Note that `keycloak-js` is a peer dependency of Keycloak Angular. This change al

| Angular | keycloak-js | keycloak-angular | Support |
| :-----: |:-----------:| :--------------: | :-----------------: |
| 16.x | 18 - 23 | 14.x.x | New Features / Bugs |
| 16.x | 18 - 24 | 14.x.x | New Features / Bugs |
| 15.x | 18 - 21 | 13.x.x | Bugs |
| 14.x | 18 - 19 | 12.x.x | - |
| 14.x | 10 - 17 | 11.x.x | - |
Expand Down
36 changes: 17 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "keycloak-angular",
"version": "14.2.0",
"version": "14.3.0",
"description": "Easy Keycloak setup for Angular applications",
"scripts": {
"clean": "shx rm -rf ./dist/",
Expand Down Expand Up @@ -62,7 +62,7 @@
"karma-coverage-istanbul-reporter": "~3.0.3",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "^2.0.0",
"keycloak-js": "^23.0.5",
"keycloak-js": "^24.0.1",
"ng-packagr": "^16.0.0",
"prettier": "^2.8.8",
"rxjs": "^7.8.1",
Expand Down
2 changes: 1 addition & 1 deletion projects/example/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: '3'
services:
keycloak:
image: quay.io/keycloak/keycloak:23.0.5
image: quay.io/keycloak/keycloak:24.0.1
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
Expand Down
4 changes: 2 additions & 2 deletions projects/keycloak-angular/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "keycloak-angular",
"version": "14.2.0",
"version": "14.3.0",
"description": "Easy Keycloak setup for Angular applications",
"repository": {
"type": "git",
Expand Down Expand Up @@ -29,7 +29,7 @@
"@angular/common": "^16",
"@angular/core": "^16",
"@angular/router": "^16",
"keycloak-js": "^18 || ^19 || ^20 || ^21 || ^22|| ^23"
"keycloak-js": "^18 || ^19 || ^20 || ^21 || ^22|| ^23 || ^24"
},
"dependencies": {
"tslib": "^2.3.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,18 @@
*/

import { TestBed, inject } from '@angular/core/testing';
import Keycloak from "keycloak-js";

import { KeycloakService } from './keycloak.service';


describe('KeycloakService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [KeycloakService]
});
});

it('should be created', inject(
[KeycloakService],
(service: KeycloakService) => {
expect(service).toBeTruthy();
}
));

describe('#loadExcludedUrls', () => {
it('should create the ExcludedUrlRegex objects if the bearerExcludedUrls arg is a string array', inject(
[KeycloakService],
Expand Down Expand Up @@ -87,4 +82,123 @@ describe('KeycloakService', () => {
}
));
});

describe('#getUserRoles', () => {
it('should return all resource and realm roles', inject(
[KeycloakService],
async (service: KeycloakService) => {
(service['_instance'] as Partial<Keycloak>) = {
resourceAccess: {
client1: {
roles: ['client1Role1', 'client1Role2']
},
client2: {
roles: ['client2Role1', 'client2Role2']
}
},
realmAccess: {
roles: ['realmRole1', 'realmRole2']
}
};

const userRoles = service.getUserRoles();

expect(userRoles).toEqual(
jasmine.arrayWithExactContents([
'client1Role1',
'client1Role2',
'client2Role1',
'client2Role2',
'realmRole1',
'realmRole2'
])
);
}
));

it('should return only resource roles if realmRoles is set to false', inject(
[KeycloakService],
async (service: KeycloakService) => {
(service['_instance'] as Partial<Keycloak>) = {
resourceAccess: {
client1: {
roles: ['client1Role1', 'client1Role2']
},
client2: {
roles: ['client2Role1', 'client2Role2']
}
},
realmAccess: {
roles: ['realmRole1', 'realmRole2']
}
};

const userRoles = service.getUserRoles(false);

expect(userRoles).toEqual(
jasmine.arrayWithExactContents([
'client1Role1',
'client1Role2',
'client2Role1',
'client2Role2'
])
);
}
));

it('should return only resource roles from the given resource if realmRoles is set to false and resource is specified', inject(
[KeycloakService],
async (service: KeycloakService) => {
(service['_instance'] as Partial<Keycloak>) = {
resourceAccess: {
client1: {
roles: ['client1Role1', 'client1Role2']
},
client2: {
roles: ['client2Role1', 'client2Role2']
}
},
realmAccess: {
roles: ['realmRole1', 'realmRole2']
}
};

const userRoles = service.getUserRoles(false, 'client2');

expect(userRoles).toEqual(
jasmine.arrayWithExactContents(['client2Role1', 'client2Role2'])
);
}
));

it('should return only resource roles from the given resource and realm roles if realmRoles is set to true and resource is specified', inject(
[KeycloakService],
async (service: KeycloakService) => {
(service['_instance'] as Partial<Keycloak>) = {
resourceAccess: {
client1: {
roles: ['client1Role1', 'client1Role2']
},
client2: {
roles: ['client2Role1', 'client2Role2']
}
},
realmAccess: {
roles: ['realmRole1', 'realmRole2']
}
};

const userRoles = service.getUserRoles(true, 'client1');

expect(userRoles).toEqual(
jasmine.arrayWithExactContents([
'client1Role1',
'client1Role2',
'realmRole1',
'realmRole2'
])
);
}
));
});
});
31 changes: 18 additions & 13 deletions projects/keycloak-angular/src/lib/core/services/keycloak.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,12 @@ export class KeycloakService {

/**
* Check if the user has access to the specified role. It will look for roles in
* realm and clientId, but will not check if the user is logged in for better performance.
* realm and the given resource, but will not check if the user is logged in for better performance.
*
* @param role
* role name
* @param resource
* resource name If not specified, `clientId` is used
* resource name. If not specified, `clientId` is used
* @returns
* A boolean meaning if the user has the specified Role.
*/
Expand All @@ -332,27 +332,32 @@ export class KeycloakService {
}

/**
* Return the roles of the logged user. The allRoles parameter, with default value
* true, will return the clientId and realm roles associated with the logged user. If set to false
* it will only return the user roles associated with the clientId.
* Return the roles of the logged user. The realmRoles parameter, with default value
* true, will return the resource roles and realm roles associated with the logged user. If set to false
* it will only return the resource roles. The resource parameter, if specified, will return only resource roles
* associated with the given resource.
*
* @param allRoles
* Flag to set if all roles should be returned.(Optional: default value is true)
* @param realmRoles
* Set to false to exclude realm roles (only client roles)
* @param resource
* resource name If not specified, returns roles from all resources
* @returns
* Array of Roles associated with the logged user.
*/
getUserRoles(allRoles: boolean = true): string[] {
getUserRoles(realmRoles: boolean = true, resource?: string): string[] {
let roles: string[] = [];
if (this._instance.resourceAccess) {
for (const key in this._instance.resourceAccess) {
if (this._instance.resourceAccess.hasOwnProperty(key)) {
const resourceAccess = this._instance.resourceAccess[key];
const clientRoles = resourceAccess['roles'] || [];
roles = roles.concat(clientRoles);
if (!resource || resource == key) {
const resourceAccess = this._instance.resourceAccess[key];
const clientRoles = resourceAccess['roles'] || [];
roles = roles.concat(clientRoles);
}
}
}
}
if (allRoles && this._instance.realmAccess) {
if (realmRoles && this._instance.realmAccess) {
const realmRoles = this._instance.realmAccess['roles'] || [];
roles.push(...realmRoles);
}
Expand Down Expand Up @@ -446,7 +451,7 @@ export class KeycloakService {
}

/**
* Returns the authenticated token, calling updateToken to get a refreshed one if necessary.
* Returns the authenticated token.
*/
public async getToken() {
return this._instance.token;
Expand Down

0 comments on commit 4045770

Please sign in to comment.