diff --git a/package-lock.json b/package-lock.json index c9da019ae..5e5abcd0c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18521,7 +18521,7 @@ }, "packages/auth0": { "name": "@pristine-ts/auth0", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18534,7 +18534,7 @@ }, "packages/aws": { "name": "@pristine-ts/aws", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@aws-sdk/client-cloudformation": "^3.211.0", @@ -18557,7 +18557,7 @@ }, "packages/aws-api-gateway": { "name": "@pristine-ts/aws-api-gateway", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/aws": "file:../common", @@ -18576,7 +18576,7 @@ }, "packages/aws-cognito": { "name": "@pristine-ts/aws-cognito", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18591,7 +18591,7 @@ }, "packages/aws-scheduling": { "name": "@pristine-ts/aws-scheduling", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/aws": "file:../aws", @@ -18602,7 +18602,7 @@ }, "packages/aws-xray": { "name": "@pristine-ts/aws-xray", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18613,7 +18613,7 @@ }, "packages/cli": { "name": "@pristine-ts/cli", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18633,7 +18633,7 @@ }, "packages/cloudflare": { "name": "@pristine-ts/cloudflare", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18648,7 +18648,7 @@ }, "packages/common": { "name": "@pristine-ts/common", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "reflect-metadata": "^0.1.13", @@ -18657,7 +18657,7 @@ }, "packages/configuration": { "name": "@pristine-ts/configuration", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common" @@ -18665,7 +18665,7 @@ }, "packages/core": { "name": "@pristine-ts/core", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18692,7 +18692,7 @@ }, "packages/express": { "name": "@pristine-ts/express", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18705,7 +18705,7 @@ }, "packages/file": { "name": "@pristine-ts/file", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common" @@ -18713,7 +18713,7 @@ }, "packages/http": { "name": "@pristine-ts/http", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18723,7 +18723,7 @@ }, "packages/jwt": { "name": "@pristine-ts/jwt", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18737,7 +18737,7 @@ }, "packages/logging": { "name": "@pristine-ts/logging", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18747,7 +18747,7 @@ }, "packages/networking": { "name": "@pristine-ts/networking", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18759,7 +18759,7 @@ }, "packages/opensearch": { "name": "@pristine-ts/opensearch", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@opensearch-project/opensearch": "^2.1.0", @@ -18770,7 +18770,7 @@ }, "packages/redis": { "name": "@pristine-ts/redis", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@camaro/redis": "^2.2.5", @@ -18780,7 +18780,7 @@ }, "packages/scheduling": { "name": "@pristine-ts/scheduling", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18790,7 +18790,7 @@ }, "packages/security": { "name": "@pristine-ts/security", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18802,7 +18802,7 @@ }, "packages/sentry": { "name": "@pristine-ts/sentry", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18812,7 +18812,7 @@ }, "packages/stripe": { "name": "@pristine-ts/stripe", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18824,7 +18824,7 @@ }, "packages/telemetry": { "name": "@pristine-ts/telemetry", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/common": "file:../common", @@ -18837,7 +18837,7 @@ }, "packages/validation": { "name": "@pristine-ts/validation", - "version": "0.0.247", + "version": "0.0.254", "license": "ISC", "dependencies": { "@pristine-ts/class-validator": "^1.0.5", diff --git a/packages/security/src/guards/role.guard.spec.ts b/packages/security/src/guards/role.guard.spec.ts index 9341cc4db..9b6ce9bcb 100644 --- a/packages/security/src/guards/role.guard.spec.ts +++ b/packages/security/src/guards/role.guard.spec.ts @@ -1,10 +1,32 @@ import "reflect-metadata"; import {RoleGuard} from "./role.guard"; import {HttpMethod, Request} from "@pristine-ts/common"; +import {LogHandlerInterface} from "@pristine-ts/logging"; + +class LogHandlerMock implements LogHandlerInterface { + debug(message: string, extra?: any) { + } + + info(message: string, extra?: any) { + } + + error(message: string, extra?: any) { + } + + critical(message: string, extra?: any) { + } + + warning(message: string, extra?: any) { + } + + terminate() { + + } +} describe("Auth0 roles Guard", () => { it("should return true when no role is needed", async () => { - const roleGuard = new RoleGuard("http://pristine.com/roles"); + const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock()); roleGuard.setContext({ CognitoGroupGuard: RoleGuard, @@ -23,7 +45,7 @@ describe("Auth0 roles Guard", () => { }) it("should return false when groups are needed but identity does not provide groups.", async () => { - const roleGuard = new RoleGuard("http://pristine.com/roles"); + const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock()); roleGuard.setContext({ CognitoGroupGuard: RoleGuard, @@ -42,7 +64,7 @@ describe("Auth0 roles Guard", () => { }) it("should return false when groups are needed but identity groups is not an array.", async () => { - const roleGuard = new RoleGuard("http://pristine.com/roles"); + const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock()); roleGuard.setContext({ CognitoGroupGuard: RoleGuard, @@ -62,7 +84,7 @@ describe("Auth0 roles Guard", () => { }) it("should return false when groups are needed that are not in the identity groups.", async () => { - const roleGuard = new RoleGuard("http://pristine.com/roles"); + const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock()); roleGuard.setContext({ CognitoGroupGuard: RoleGuard, @@ -82,7 +104,7 @@ describe("Auth0 roles Guard", () => { }) it("should return true when all groups needed are in the identity groups.", async () => { - const roleGuard = new RoleGuard("http://pristine.com/roles"); + const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock()); roleGuard.setContext({ CognitoGroupGuard: RoleGuard, @@ -102,7 +124,7 @@ describe("Auth0 roles Guard", () => { }) it("should return find the claim when specified in options", async () => { - const roleGuard = new RoleGuard("http://pristine.com/roles"); + const roleGuard = new RoleGuard("http://pristine.com/roles", new LogHandlerMock()); roleGuard.setContext({ CognitoGroupGuard: RoleGuard, diff --git a/packages/security/src/guards/role.guard.ts b/packages/security/src/guards/role.guard.ts index e04a9b12e..f4bad7ac3 100644 --- a/packages/security/src/guards/role.guard.ts +++ b/packages/security/src/guards/role.guard.ts @@ -3,6 +3,8 @@ import {IdentityInterface} from "@pristine-ts/common"; import {GuardInterface} from "../interfaces/guard.interface"; import {GuardContextInterface} from "../interfaces/guard-context.interface"; import {Request} from "@pristine-ts/common"; +import {LogHandlerInterface} from "@pristine-ts/logging"; +import {SecurityModuleKeyname} from "../security.module.keyname"; /** * The role guard is a guard that validates if the identity making the request has the required roles. @@ -23,16 +25,19 @@ export class RoleGuard implements GuardInterface { * The role guard is a guard that validates if the identity making the request has the required roles. * @param rolesClaimKey The key in the claims of the access token where the roles are defined. */ - constructor(@inject("%pristine.security.rolesClaimKey%") private readonly rolesClaimKey: string) { + constructor(@inject("%pristine.security.rolesClaimKey%") private readonly rolesClaimKey: string, + @inject("LogHandlerInterface") private readonly logHandler: LogHandlerInterface) { } /** * Sets the context for the guard. * @param context The context for the guard to use. */ - setContext(context: any): Promise { + async setContext(context: any): Promise { this.guardContext = context; + this.logHandler.debug("Setting the context", {context}, SecurityModuleKeyname); + return Promise.resolve(); } @@ -58,12 +63,14 @@ export class RoleGuard implements GuardInterface { // If the identity does not have a roles claim, we deny. if(neededRoles.length > 0 && (identity?.claims?.hasOwnProperty(this.rolesClaimKey) === false || !Array.isArray(identity?.claims[this.rolesClaimKey]))){ + this.logHandler.debug("Identity doesn't have a roles claim. Denying.", {request, identity, neededRoles}, SecurityModuleKeyname); return false; } // If the identity is missing one of the needed roles, we deny. for(const role of neededRoles) { if(!identity?.claims[this.rolesClaimKey].includes(role)){ + this.logHandler.debug("Role not found in claims. Denying.", {request, identity, neededRoles, role}, SecurityModuleKeyname); return false; } }