Skip to content

Commit df741f7

Browse files
Merge pull request #180 from Real-Dev-Squad/develop
Dev to main sync
2 parents ca4282d + 1d253c5 commit df741f7

File tree

4 files changed

+67
-6
lines changed

4 files changed

+67
-6
lines changed

src/constants/responses.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,8 @@ export const OVERDUE_CUSTOM_MESSAGE =
7272
export const ONBOARDING_DEFAULT_MESSAGE = `You currently have an onboarding status. Please provide an update explaining any challenges you're facing in completing your tasks. If you're finished, consider assigning new tasks to Admin.`;
7373

7474
export const ONBOARDING_CUSTOM_MESSAGE = `Please update your status explaining why you are unable to complete your onboarding tasks within {{days}} days.`;
75+
76+
export const INVALID_TOKEN_FORMAT =
77+
"Invalid Authentication header format. Expected 'Bearer <token>'";
78+
79+
export const AUTHENTICATION_ERROR = "Invalid Authentication token";

src/controllers/getMembersInServer.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { env } from "../typeDefinitions/default.types";
55
import JSONResponse from "../utils/JsonResponse";
66
import { User } from "../typeDefinitions/user.types";
77
import { getMembersInServer } from "../utils/getMembersInServer";
8+
import { verifyAuthToken } from "../utils/verifyAuthToken";
89

910
export const getMembersInServerHandler = async (
1011
request: IRequest,
@@ -16,10 +17,7 @@ export const getMembersInServerHandler = async (
1617
return new JSONResponse(response.BAD_SIGNATURE);
1718
}
1819
try {
19-
const authToken = authHeader.split(" ")[1];
20-
await jwt.verify(authToken, env.RDS_SERVERLESS_PUBLIC_KEY, {
21-
algorithm: "RS256",
22-
});
20+
await verifyAuthToken(authHeader, env);
2321

2422
const users = (await getMembersInServer(env)) as User[];
2523

src/utils/verifyAuthToken.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import {
2+
AUTHENTICATION_ERROR,
3+
INVALID_TOKEN_FORMAT,
4+
} from "../constants/responses";
15
import { env } from "../typeDefinitions/default.types";
26
import jwt from "@tsndr/cloudflare-worker-jwt";
37

@@ -8,8 +12,15 @@ import jwt from "@tsndr/cloudflare-worker-jwt";
812
*/
913

1014
export async function verifyAuthToken(authHeader: string, env: env) {
11-
const authToken = authHeader.split(" ")[1];
12-
await jwt.verify(authToken, env.RDS_SERVERLESS_PUBLIC_KEY, {
15+
const parts = authHeader.split(" ");
16+
if (parts.length !== 2 || parts[0] !== "Bearer") {
17+
throw new Error(INVALID_TOKEN_FORMAT);
18+
}
19+
const authToken = parts[1];
20+
const isValid = await jwt.verify(authToken, env.RDS_SERVERLESS_PUBLIC_KEY, {
1321
algorithm: "RS256",
1422
});
23+
if (!isValid) {
24+
throw new Error(AUTHENTICATION_ERROR);
25+
}
1526
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import jwt from "@tsndr/cloudflare-worker-jwt";
2+
import { verifyAuthToken } from "../../../src/utils/verifyAuthToken";
3+
import {
4+
AUTHENTICATION_ERROR,
5+
INVALID_TOKEN_FORMAT,
6+
} from "../../../src/constants/responses";
7+
8+
describe("verifyAuthToken", () => {
9+
const authToken = "validToken";
10+
const mockEnv = { RDS_SERVERLESS_PUBLIC_KEY: "publicKey" };
11+
12+
afterEach(() => {
13+
jest.clearAllMocks();
14+
});
15+
16+
it("should verify a valid token successfully", async () => {
17+
jwt.verify = jest.fn().mockResolvedValue(true);
18+
const authHeader = `Bearer ${authToken}`;
19+
await expect(verifyAuthToken(authHeader, mockEnv)).resolves.not.toThrow();
20+
expect(jwt.verify).toHaveBeenCalledWith(
21+
authToken,
22+
mockEnv.RDS_SERVERLESS_PUBLIC_KEY,
23+
{ algorithm: "RS256" }
24+
);
25+
});
26+
27+
it("should throw an error for an invalid token", async () => {
28+
const authHeader = "Bearer invalidToken";
29+
jwt.verify = jest.fn().mockResolvedValue(false);
30+
await expect(verifyAuthToken(authHeader, mockEnv)).rejects.toThrow(
31+
AUTHENTICATION_ERROR
32+
);
33+
});
34+
it("should throw an error when Bearer is not passed", async () => {
35+
const authHeader = "Beaer invalidToken";
36+
await expect(verifyAuthToken(authHeader, mockEnv)).rejects.toThrow(
37+
INVALID_TOKEN_FORMAT
38+
);
39+
});
40+
41+
it("should throw an error for a malformed auth header", async () => {
42+
const malformedHeader = "invalidformat";
43+
await expect(verifyAuthToken(malformedHeader, mockEnv)).rejects.toThrow(
44+
INVALID_TOKEN_FORMAT
45+
);
46+
});
47+
});

0 commit comments

Comments
 (0)