Skip to content

Commit

Permalink
allow custom headers in SubIdentityMapper
Browse files Browse the repository at this point in the history
  • Loading branch information
gimmyxd committed Oct 27, 2023
1 parent 5a1b5a8 commit a758da0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 20 deletions.
21 changes: 16 additions & 5 deletions __tests__/authorizer/mapper/identity/sub.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import { InvalidTokenError } from "jwt-decode";
import nJwt from "njwt";
import httpMocks from "node-mocks-http";

import SubIdentityMapper from "../../../../lib/authorizer/mapper/identity/sub";
import identityContext from "../../../../lib/authorizer/model/identityContext";
describe("SubIdentityMapper", () => {
const subMapper = SubIdentityMapper();

it("throws an error if the JWT token is invalid", async () => {
const req = httpMocks.createRequest({
headers: {
authorization: "Bearer invalidToken",
},
});

await expect(SubIdentityMapper(req)).rejects.toMatch(/Invalid JWT token/);
await expect(subMapper(req)).rejects.toEqual(
new InvalidTokenError(
"Invalid token specified: Cannot read properties of undefined (reading 'replace')"
)
);
});

it("throws an error if the token is missing in the authorization header", async () => {
Expand All @@ -21,14 +28,18 @@ describe("SubIdentityMapper", () => {
},
});

await expect(SubIdentityMapper(req)).rejects.toMatch(/Invalid JWT token/);
await expect(subMapper(req)).rejects.toEqual(
new InvalidTokenError(
"Invalid token specified: Cannot read properties of undefined (reading 'replace')"
)
);
});

it("throws an error if the authorization header is missing", async () => {
const req = httpMocks.createRequest({});

await expect(SubIdentityMapper(req)).rejects.toEqual(
"Missing authorization header"
await expect(subMapper(req)).rejects.toEqual(
new Error("Missing Authorization header")
);
});

Expand All @@ -40,7 +51,7 @@ describe("SubIdentityMapper", () => {
},
});

const result = await SubIdentityMapper(req);
const result = await subMapper(req);

expect(result).toEqual(identityContext("test", "IDENTITY_TYPE_SUB"));
});
Expand Down
29 changes: 14 additions & 15 deletions lib/authorizer/mapper/identity/sub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@ import { Request } from "express";
import jwt_decode, { JwtPayload } from "jwt-decode";
import { IdentityContext } from "@aserto/node-authorizer/pkg/aserto/authorizer/v2/api/identity_context_pb";

import { IdentityMapper } from "../../middleware";
import identityContext from "../../model/identityContext";

const SubIdentityMapper = async (req: Request): Promise<IdentityContext> => {
return new Promise((resolve, reject) => {
try {
// decode the JWT to make sure it's valid
if (req.headers && req.headers.authorization) {
const token: JwtPayload = jwt_decode(req.headers.authorization);
if (token && token.sub) {
resolve(identityContext(token.sub, "IDENTITY_TYPE_SUB"));
} else {
reject("Invalid JWT token, missing sub");
}
const SubIdentityMapper = (
header: string = "Authorization"
): IdentityMapper => {
return async (req: Request): Promise<IdentityContext> => {
const authHeader = req.header(header);
if (authHeader) {
const token: JwtPayload = jwt_decode(authHeader);
if (token && token.sub) {
return identityContext(token.sub, "IDENTITY_TYPE_SUB");
} else {
reject("Missing authorization header");
throw new Error("Missing token");
}
} catch (error) {
reject(`Invalid JWT token: ${(error as Error).message}`);
} else {
throw new Error(`Missing ${header} header`);
}
});
};
};

export default SubIdentityMapper;

0 comments on commit a758da0

Please sign in to comment.