firebase-edge-auth
Version:
Firebase token decoder for edge runtimes
97 lines (96 loc) • 4.11 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fetch_mock_1 = __importDefault(require("fetch-mock"));
const jose_1 = require("jose");
const index_1 = require("./index");
jest.mock("jose", () => ({
jwtVerify: jest.fn(),
importX509: jest.fn(),
}));
const FIREBASE_PUBLIC_KEYS_URL = "https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com";
describe("decodeFirebaseToken", () => {
beforeEach(() => {
fetch_mock_1.default.restore();
jest.resetAllMocks();
});
it("should fetch public keys if not already cached", async () => {
const publicKeyResponse = {
key_id_1: "public_key_1",
key_id_2: "public_key_2",
};
fetch_mock_1.default.getOnce(FIREBASE_PUBLIC_KEYS_URL, publicKeyResponse);
jose_1.jwtVerify.mockImplementation(async (token, getKey) => {
await getKey({ kid: "key_id_1" });
return {
payload: {
sub: "user123",
aud: "project_id",
iss: "https://securetoken.google.com/project_id",
},
};
});
jose_1.importX509.mockResolvedValue("decoded_public_key");
const token = "test_token";
const projectId = "project_id";
const result = await (0, index_1.decodeFirebaseToken)(token, projectId);
expect(fetch_mock_1.default.called(FIREBASE_PUBLIC_KEYS_URL)).toBe(true);
expect(jose_1.importX509).toHaveBeenCalledWith("public_key_1", "RS256");
expect(jose_1.jwtVerify).toHaveBeenCalledWith(token, expect.any(Function), {
audience: projectId,
issuer: `https://securetoken.google.com/${projectId}`,
});
expect(result).toEqual({
sub: "user123",
aud: "project_id",
iss: "https://securetoken.google.com/project_id",
});
});
it("should throw an error if the public key is not found", async () => {
const publicKeyResponse = {
key_id_1: "public_key_1",
};
fetch_mock_1.default.getOnce(FIREBASE_PUBLIC_KEYS_URL, publicKeyResponse);
jose_1.jwtVerify.mockImplementation(async (token, getKey) => {
await getKey({ kid: "non_existent_key" });
});
const token = "test_token";
const projectId = "project_id";
await expect((0, index_1.decodeFirebaseToken)(token, projectId)).rejects.toThrow("Invalid Firebase token");
});
it("should return the payload if token is valid", async () => {
const publicKeyResponse = {
key_id_1: "public_key_1",
};
fetch_mock_1.default.getOnce(FIREBASE_PUBLIC_KEYS_URL, publicKeyResponse);
jose_1.jwtVerify.mockResolvedValue({
payload: {
sub: "user123",
aud: "project_id",
iss: "https://securetoken.google.com/project_id",
},
});
jose_1.importX509.mockResolvedValue("decoded_public_key");
const token = "test_token";
const projectId = "project_id";
const result = await (0, index_1.decodeFirebaseToken)(token, projectId);
expect(result).toEqual({
sub: "user123",
aud: "project_id",
iss: "https://securetoken.google.com/project_id",
});
});
it("should throw an error if jwtVerify throws", async () => {
const publicKeyResponse = {
key_id_1: "public_key_1",
};
fetch_mock_1.default.getOnce(FIREBASE_PUBLIC_KEYS_URL, publicKeyResponse);
jose_1.jwtVerify.mockRejectedValue(new Error("Invalid token"));
jose_1.importX509.mockResolvedValue("decoded_public_key");
const token = "test_token";
const projectId = "project_id";
await expect((0, index_1.decodeFirebaseToken)(token, projectId)).rejects.toThrow("Invalid Firebase token");
});
});