🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@vercel/oidc

Package Overview
Dependencies
Maintainers
4
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vercel/oidc - npm Package Compare versions

Comparing version
3.4.1
to
3.5.0
+22
dist/get-vercel-oidc-token-sync.d.ts
/**
* Gets the current OIDC token from the request context or the environment variable.
*
* Do not cache this value, as it is subject to change in production!
*
* This function is used to retrieve the OIDC token from the request context or the environment variable.
* It checks for the `x-vercel-oidc-token` header in the request context and falls back to the `VERCEL_OIDC_TOKEN` environment variable if the header is not present.
*
* This function will not refresh the token if it is expired. For refreshing the token, use the @{link getVercelOidcToken} function.
*
* @returns {string} The OIDC token.
* @throws {Error} If the `x-vercel-oidc-token` header is missing from the request context and the environment variable `VERCEL_OIDC_TOKEN` is not set.
*
* @example
*
* ```js
* // Using the OIDC token
* const token = getVercelOidcTokenSync();
* console.log('OIDC Token:', token);
* ```
*/
export declare function getVercelOidcTokenSync(): string;
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var get_vercel_oidc_token_sync_exports = {};
__export(get_vercel_oidc_token_sync_exports, {
getVercelOidcTokenSync: () => getVercelOidcTokenSync
});
module.exports = __toCommonJS(get_vercel_oidc_token_sync_exports);
var import_get_context = require("./get-context");
function getVercelOidcTokenSync() {
const token = (0, import_get_context.getContext)().headers?.["x-vercel-oidc-token"] ?? process.env.VERCEL_OIDC_TOKEN;
if (!token) {
throw new Error(
`The 'x-vercel-oidc-token' header is missing from the request.`
);
}
return token;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
getVercelOidcTokenSync
});
/**
* Options for getting the Vercel OIDC token.
*/
export interface GetVercelOidcTokenOptions {
/**
* Optional team ID (team_*) or slug to use for token refresh.
* When provided, this team will be used instead of reading from `.vercel/project.json`.
*/
team?: string;
/**
* Optional project ID (prj_*) or slug to use for token refresh.
* When provided, this project will be used instead of reading from `.vercel/project.json`.
*/
project?: string;
/**
* Optional time buffer in milliseconds before token expiry to consider it expired.
* When provided, the token will be refreshed if it expires within this buffer time.
* @default 0
*/
expirationBufferMs?: number;
}
/**
* Gets the current OIDC token from the request context or the environment variable.
*
* Do not cache this value, as it is subject to change in production!
*
* This function is used to retrieve the OIDC token from the request context or the environment variable.
* It checks for the `x-vercel-oidc-token` header in the request context and falls back to the `VERCEL_OIDC_TOKEN` environment variable if the header is not present.
*
* Unlike the `getVercelOidcTokenSync` function, this function will refresh the token if it is expired in a development environment.
*
* @param {GetVercelOidcTokenOptions} [options] - Optional configuration for token retrieval.
* @returns {Promise<string>} A promise that resolves to the OIDC token.
* @throws {Error} If the `x-vercel-oidc-token` header is missing from the request context and the environment variable `VERCEL_OIDC_TOKEN` is not set. If the token
* is expired in a development environment, will also throw an error if the token cannot be refreshed: no CLI credentials are available, CLI credentials are expired, no project configuration is available
* or the token refresh request fails.
*
* @example
*
* ```js
* // Using the OIDC token
* getVercelOidcToken().then((token) => {
* console.log('OIDC Token:', token);
* }).catch((error) => {
* console.error('Error:', error.message);
* });
* ```
*
* @example
*
* ```js
* // Using the OIDC token with explicit team and project (supports IDs and slugs)
* getVercelOidcToken({ team: 'my-team', project: 'my-project' }).then((token) => {
* console.log('OIDC Token:', token);
* }).catch((error) => {
* console.error('Error:', error.message);
* });
* ```
*/
export declare function getVercelOidcToken(options?: GetVercelOidcTokenOptions): Promise<string>;
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var get_vercel_oidc_token_with_refresh_exports = {};
__export(get_vercel_oidc_token_with_refresh_exports, {
getVercelOidcToken: () => getVercelOidcToken
});
module.exports = __toCommonJS(get_vercel_oidc_token_with_refresh_exports);
var import_get_vercel_oidc_token_sync = require("./get-vercel-oidc-token-sync");
var import_token_error = require("./token-error");
async function getVercelOidcToken(options) {
let token = "";
let err;
try {
token = (0, import_get_vercel_oidc_token_sync.getVercelOidcTokenSync)();
} catch (error) {
err = error;
}
try {
const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([
await import("./token-util.js"),
await import("./token.js")
]);
if (!token || isExpired(getTokenPayload(token), options?.expirationBufferMs)) {
await refreshToken(options);
token = (0, import_get_vercel_oidc_token_sync.getVercelOidcTokenSync)();
}
} catch (error) {
let message = err instanceof Error ? err.message : "";
if (error instanceof Error) {
message = `${message}
${error.message}`;
}
if (message) {
throw new import_token_error.VercelOidcTokenError(message);
}
throw error;
}
return token;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
getVercelOidcToken
});
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var import_crypto = require("crypto");
var import_vitest = require("vitest");
var os = __toESM(require("os"));
var path = __toESM(require("path"));
var fs = __toESM(require("fs"));
var import_token_io = require("./token-io");
var import_get_vercel_oidc_token_with_refresh = require("./get-vercel-oidc-token-with-refresh");
var tokenUtil = __toESM(require("./token-util"));
import_vitest.vi.mock("./token-io");
import_vitest.vi.mock("./get-context", () => ({
getContext: () => ({ headers: {} })
}));
(0, import_vitest.describe)("getVercelOidcToken - Error Scenarios", () => {
let rootDir;
let userDataDir;
let cliDataDir;
let tokenDataDir;
const projectId = "prj_test123";
const teamId = "team_test456";
(0, import_vitest.beforeEach)(() => {
import_vitest.vi.clearAllMocks();
import_vitest.vi.restoreAllMocks();
process.env.VERCEL_OIDC_TOKEN = void 0;
const random = `test-${(0, import_crypto.randomUUID)()}`;
rootDir = path.join(os.tmpdir(), random);
userDataDir = path.join(rootDir, "data");
cliDataDir = path.join(userDataDir, "com.vercel.cli");
tokenDataDir = path.join(userDataDir, "com.vercel.token");
fs.mkdirSync(cliDataDir, { recursive: true });
fs.mkdirSync(tokenDataDir, { recursive: true });
fs.mkdirSync(path.join(rootDir, ".vercel"), {
recursive: true
});
import_vitest.vi.spyOn(process, "cwd").mockReturnValue(rootDir);
import_vitest.vi.mocked(import_token_io.findRootDir).mockReturnValue(rootDir);
import_vitest.vi.mocked(import_token_io.getUserDataDir).mockReturnValue(userDataDir);
});
(0, import_vitest.afterEach)(() => {
if (fs.existsSync(rootDir)) {
fs.rmSync(rootDir, { recursive: true, force: true });
}
});
(0, import_vitest.test)("should throw AccessTokenMissingError when CLI auth file is missing", async () => {
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)()).rejects.toThrow(
/No authentication found/
);
});
(0, import_vitest.test)("should throw helpful error when project.json is missing", async () => {
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)()).rejects.toThrow(
/project\.json not found, have you linked your project with `vc link\?`/
);
});
(0, import_vitest.test)("should throw helpful error when root directory cannot be found", async () => {
import_vitest.vi.mocked(import_token_io.findRootDir).mockReturnValue(null);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)()).rejects.toThrow(
/Unable to find project root directory\. Have you linked your project with `vc link\?`/
);
});
(0, import_vitest.test)("should throw helpful error when user data directory cannot be found", async () => {
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
import_vitest.vi.mocked(import_token_io.getUserDataDir).mockReturnValue(null);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)()).rejects.toThrow(
/Unable to find user data directory\. Please reach out to Vercel support\./
);
});
(0, import_vitest.test)("should throw helpful error when API returns non-200", async () => {
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockRejectedValue(
new Error("Failed to refresh OIDC token: Unauthorized")
);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)()).rejects.toThrow(
/Failed to refresh OIDC token: Unauthorized/
);
});
(0, import_vitest.test)("should throw helpful error when token response is malformed", async () => {
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockRejectedValue(
new TypeError(
"Vercel OIDC token is malformed. Expected a string-valued token property. Please run `vc env pull` and try again"
)
);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)()).rejects.toThrow(
/Vercel OIDC token is malformed\. Expected a string-valued token property\. Please run `vc env pull` and try again/
);
});
(0, import_vitest.test)("should throw helpful error when token has invalid format", async () => {
process.env.VERCEL_OIDC_TOKEN = "not-a-valid-jwt-token";
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockImplementation(() => {
throw new Error("Invalid token. Please run `vc env pull` and try again");
});
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)()).rejects.toThrow(
/Invalid token\. Please run `vc env pull` and try again/
);
});
(0, import_vitest.test)("should throw error when token expiry check fails", async () => {
process.env.VERCEL_OIDC_TOKEN = "not-a-jwt-token";
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)()).rejects.toThrow(
/Invalid token\. Please run `vc env pull` and try again/
);
});
(0, import_vitest.test)("should fail when no token exists and no CLI credentials available", async () => {
process.env.VERCEL_OIDC_TOKEN = void 0;
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)()).rejects.toThrow(/Invalid token/);
});
(0, import_vitest.test)("should propagate filesystem errors when saving token fails", async () => {
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: "new-valid-token"
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 - 1e3
});
import_vitest.vi.spyOn(tokenUtil, "saveToken").mockImplementation(() => {
throw new Error("EACCES: permission denied");
});
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)()).rejects.toThrow(/EACCES|permission/i);
});
(0, import_vitest.test)("should succeed when valid token exists in env", async () => {
const validToken = createValidToken();
process.env.VERCEL_OIDC_TOKEN = validToken;
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
const token = await (0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)();
(0, import_vitest.expect)(token).toBe(validToken);
});
(0, import_vitest.test)("should refresh when token is expired but all configs are valid", async () => {
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
const newToken = createValidToken("new-token");
import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: newToken
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValueOnce({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 - 1e3
}).mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
const token = await (0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)();
(0, import_vitest.expect)(token).toBe(newToken);
});
(0, import_vitest.test)("should use provided team and project for refresh instead of reading project.json", async () => {
const customProjectId = "prj_custom123";
const customTeamId = "team_custom456";
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
const newToken = createValidToken("custom-token");
const getVercelOidcTokenSpy = import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: newToken
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValueOnce({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 - 1e3
}).mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
const token = await (0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)({
team: customTeamId,
project: customProjectId
});
(0, import_vitest.expect)(token).toBe(newToken);
(0, import_vitest.expect)(getVercelOidcTokenSpy).toHaveBeenCalledWith(
"test-auth-token",
customProjectId,
customTeamId
);
});
(0, import_vitest.test)("should use provided project and read team from project.json", async () => {
const customProjectId = "prj_custom234";
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId: "original-project-id", orgId: teamId })
);
const newToken = createValidToken("partial-custom-token");
const getVercelOidcTokenSpy = import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: newToken
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValueOnce({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 - 1e3
}).mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
const token = await (0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)({
project: customProjectId
});
(0, import_vitest.expect)(token).toBe(newToken);
(0, import_vitest.expect)(getVercelOidcTokenSpy).toHaveBeenCalledWith(
"test-auth-token",
customProjectId,
teamId
);
});
(0, import_vitest.test)("should use provided team and read project from project.json", async () => {
const customTeamId = "team_custom789";
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: "original-team-id" })
);
const newToken = createValidToken("partial-custom-token-2");
const getVercelOidcTokenSpy = import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: newToken
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValueOnce({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 - 1e3
}).mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
const token = await (0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)({
team: customTeamId
});
(0, import_vitest.expect)(token).toBe(newToken);
(0, import_vitest.expect)(getVercelOidcTokenSpy).toHaveBeenCalledWith(
"test-auth-token",
projectId,
customTeamId
);
});
(0, import_vitest.test)("should not refresh when token is valid even with options provided", async () => {
const validToken = createValidToken();
process.env.VERCEL_OIDC_TOKEN = validToken;
const getVercelOidcTokenSpy = import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: "should-not-be-called"
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
const token = await (0, import_get_vercel_oidc_token_with_refresh.getVercelOidcToken)({
team: "custom-team",
project: "custom-project"
});
(0, import_vitest.expect)(token).toBe(validToken);
(0, import_vitest.expect)(getVercelOidcTokenSpy).not.toHaveBeenCalled();
});
});
function createExpiredToken() {
const header = Buffer.from(
JSON.stringify({ alg: "RS256", typ: "JWT" })
).toString("base64url");
const payload = Buffer.from(
JSON.stringify({
sub: "test-sub",
exp: 1,
iat: 1
})
).toString("base64url");
return `${header}.${payload}.fake_signature`;
}
function createValidToken(value = "valid-token") {
const header = Buffer.from(
JSON.stringify({ alg: "RS256", typ: "JWT" })
).toString("base64url");
const payload = Buffer.from(
JSON.stringify({
sub: "test-sub",
exp: Math.floor(Date.now() / 1e3) + 43200,
iat: Math.floor(Date.now() / 1e3)
})
).toString("base64url");
return `${header}.${payload}.fake_signature_${value}`;
}
export { getContext } from './get-context';
export { AccessTokenMissingError, RefreshAccessTokenFailedError, } from './auth-errors';
export { getVercelOidcTokenSync } from './get-vercel-oidc-token-sync';
/**
* Gets the current OIDC token in Edge Runtime.
*
* Edge Runtime does not support automatic token refresh, so this returns the
* request-scoped token without checking expiration.
*/
export declare function getVercelOidcToken(): Promise<string>;
export declare function getVercelToken(): Promise<string>;
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var index_edge_light_exports = {};
__export(index_edge_light_exports, {
AccessTokenMissingError: () => import_auth_errors.AccessTokenMissingError,
RefreshAccessTokenFailedError: () => import_auth_errors.RefreshAccessTokenFailedError,
getContext: () => import_get_context.getContext,
getVercelOidcToken: () => getVercelOidcToken,
getVercelOidcTokenSync: () => import_get_vercel_oidc_token_sync2.getVercelOidcTokenSync,
getVercelToken: () => getVercelToken
});
module.exports = __toCommonJS(index_edge_light_exports);
var import_get_vercel_oidc_token_sync = require("./get-vercel-oidc-token-sync");
var import_get_context = require("./get-context");
var import_auth_errors = require("./auth-errors");
var import_get_vercel_oidc_token_sync2 = require("./get-vercel-oidc-token-sync");
async function getVercelOidcToken() {
return (0, import_get_vercel_oidc_token_sync.getVercelOidcTokenSync)();
}
async function getVercelToken() {
throw new Error("getVercelToken is not supported in Edge Runtime");
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
AccessTokenMissingError,
RefreshAccessTokenFailedError,
getContext,
getVercelOidcToken,
getVercelOidcTokenSync,
getVercelToken
});
+6
-0
# @vercel/oidc
## 3.5.0
### Minor Changes
- 5a700dc: Add conditional edge-light export to support Edge Runtime
## 3.4.1

@@ -4,0 +10,0 @@

+2
-1

@@ -1,4 +0,5 @@

export { getVercelOidcToken, getVercelOidcTokenSync, } from './get-vercel-oidc-token';
export { getVercelOidcToken } from './get-vercel-oidc-token-with-refresh';
export { getVercelOidcTokenSync } from './get-vercel-oidc-token-sync';
export { getContext } from './get-context';
export { AccessTokenMissingError, RefreshAccessTokenFailedError, } from './auth-errors';
export { getVercelToken } from './token-util';

@@ -24,8 +24,9 @@ "use strict";

getContext: () => import_get_context.getContext,
getVercelOidcToken: () => import_get_vercel_oidc_token.getVercelOidcToken,
getVercelOidcTokenSync: () => import_get_vercel_oidc_token.getVercelOidcTokenSync,
getVercelOidcToken: () => import_get_vercel_oidc_token_with_refresh.getVercelOidcToken,
getVercelOidcTokenSync: () => import_get_vercel_oidc_token_sync.getVercelOidcTokenSync,
getVercelToken: () => import_token_util.getVercelToken
});
module.exports = __toCommonJS(src_exports);
var import_get_vercel_oidc_token = require("./get-vercel-oidc-token");
var import_get_vercel_oidc_token_with_refresh = require("./get-vercel-oidc-token-with-refresh");
var import_get_vercel_oidc_token_sync = require("./get-vercel-oidc-token-sync");
var import_get_context = require("./get-context");

@@ -32,0 +33,0 @@ var import_auth_errors = require("./auth-errors");

@@ -9,3 +9,3 @@ [**@vercel/oidc**](../README.md)

Defined in: [packages/oidc/src/get-vercel-oidc-token.ts:64](https://github.com/vercel/vercel/blob/main/packages/oidc/src/get-vercel-oidc-token.ts#L64)
Defined in: [packages/oidc/src/get-vercel-oidc-token-with-refresh.ts:64](https://github.com/vercel/vercel/blob/main/packages/oidc/src/get-vercel-oidc-token-with-refresh.ts#L64)

@@ -12,0 +12,0 @@ Gets the current OIDC token from the request context or the environment variable.

@@ -9,3 +9,3 @@ [**@vercel/oidc**](../README.md)

Defined in: [packages/oidc/src/get-vercel-oidc-token.ts:124](https://github.com/vercel/vercel/blob/main/packages/oidc/src/get-vercel-oidc-token.ts#L124)
Defined in: [packages/oidc/src/get-vercel-oidc-token-sync.ts:24](https://github.com/vercel/vercel/blob/main/packages/oidc/src/get-vercel-oidc-token-sync.ts#L24)

@@ -12,0 +12,0 @@ Gets the current OIDC token from the request context or the environment variable.

@@ -13,2 +13,3 @@ {

".": {
"edge-light": "./dist/index-edge-light.js",
"browser": "./dist/index-browser.js",

@@ -21,3 +22,3 @@ "react-native": "./dist/index-browser.js",

},
"version": "3.4.1",
"version": "3.5.0",
"repository": {

@@ -24,0 +25,0 @@ "directory": "packages/oidc",

/**
* Options for getting the Vercel OIDC token.
*/
export interface GetVercelOidcTokenOptions {
/**
* Optional team ID (team_*) or slug to use for token refresh.
* When provided, this team will be used instead of reading from `.vercel/project.json`.
*/
team?: string;
/**
* Optional project ID (prj_*) or slug to use for token refresh.
* When provided, this project will be used instead of reading from `.vercel/project.json`.
*/
project?: string;
/**
* Optional time buffer in milliseconds before token expiry to consider it expired.
* When provided, the token will be refreshed if it expires within this buffer time.
* @default 0
*/
expirationBufferMs?: number;
}
/**
* Gets the current OIDC token from the request context or the environment variable.
*
* Do not cache this value, as it is subject to change in production!
*
* This function is used to retrieve the OIDC token from the request context or the environment variable.
* It checks for the `x-vercel-oidc-token` header in the request context and falls back to the `VERCEL_OIDC_TOKEN` environment variable if the header is not present.
*
* Unlike the `getVercelOidcTokenSync` function, this function will refresh the token if it is expired in a development environment.
*
* @param {GetVercelOidcTokenOptions} [options] - Optional configuration for token retrieval.
* @returns {Promise<string>} A promise that resolves to the OIDC token.
* @throws {Error} If the `x-vercel-oidc-token` header is missing from the request context and the environment variable `VERCEL_OIDC_TOKEN` is not set. If the token
* is expired in a development environment, will also throw an error if the token cannot be refreshed: no CLI credentials are available, CLI credentials are expired, no project configuration is available
* or the token refresh request fails.
*
* @example
*
* ```js
* // Using the OIDC token
* getVercelOidcToken().then((token) => {
* console.log('OIDC Token:', token);
* }).catch((error) => {
* console.error('Error:', error.message);
* });
* ```
*
* @example
*
* ```js
* // Using the OIDC token with explicit team and project (supports IDs and slugs)
* getVercelOidcToken({ team: 'my-team', project: 'my-project' }).then((token) => {
* console.log('OIDC Token:', token);
* }).catch((error) => {
* console.error('Error:', error.message);
* });
* ```
*/
export declare function getVercelOidcToken(options?: GetVercelOidcTokenOptions): Promise<string>;
/**
* Gets the current OIDC token from the request context or the environment variable.
*
* Do not cache this value, as it is subject to change in production!
*
* This function is used to retrieve the OIDC token from the request context or the environment variable.
* It checks for the `x-vercel-oidc-token` header in the request context and falls back to the `VERCEL_OIDC_TOKEN` environment variable if the header is not present.
*
* This function will not refresh the token if it is expired. For refreshing the token, use the @{link getVercelOidcToken} function.
*
* @returns {string} The OIDC token.
* @throws {Error} If the `x-vercel-oidc-token` header is missing from the request context and the environment variable `VERCEL_OIDC_TOKEN` is not set.
*
* @example
*
* ```js
* // Using the OIDC token
* const token = getVercelOidcTokenSync();
* console.log('OIDC Token:', token);
* ```
*/
export declare function getVercelOidcTokenSync(): string;
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var get_vercel_oidc_token_exports = {};
__export(get_vercel_oidc_token_exports, {
getVercelOidcToken: () => getVercelOidcToken,
getVercelOidcTokenSync: () => getVercelOidcTokenSync
});
module.exports = __toCommonJS(get_vercel_oidc_token_exports);
var import_get_context = require("./get-context");
var import_token_error = require("./token-error");
async function getVercelOidcToken(options) {
let token = "";
let err;
try {
token = getVercelOidcTokenSync();
} catch (error) {
err = error;
}
try {
const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([
await import("./token-util.js"),
await import("./token.js")
]);
if (!token || isExpired(getTokenPayload(token), options?.expirationBufferMs)) {
await refreshToken(options);
token = getVercelOidcTokenSync();
}
} catch (error) {
let message = err instanceof Error ? err.message : "";
if (error instanceof Error) {
message = `${message}
${error.message}`;
}
if (message) {
throw new import_token_error.VercelOidcTokenError(message);
}
throw error;
}
return token;
}
function getVercelOidcTokenSync() {
const token = (0, import_get_context.getContext)().headers?.["x-vercel-oidc-token"] ?? process.env.VERCEL_OIDC_TOKEN;
if (!token) {
throw new Error(
`The 'x-vercel-oidc-token' header is missing from the request. Do you have the OIDC option enabled in the Vercel project settings?`
);
}
return token;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
getVercelOidcToken,
getVercelOidcTokenSync
});
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var import_crypto = require("crypto");
var import_vitest = require("vitest");
var os = __toESM(require("os"));
var path = __toESM(require("path"));
var fs = __toESM(require("fs"));
var import_token_io = require("./token-io");
var import_get_vercel_oidc_token = require("./get-vercel-oidc-token");
var tokenUtil = __toESM(require("./token-util"));
import_vitest.vi.mock("./token-io");
import_vitest.vi.mock("./get-context", () => ({
getContext: () => ({ headers: {} })
}));
(0, import_vitest.describe)("getVercelOidcToken - Error Scenarios", () => {
let rootDir;
let userDataDir;
let cliDataDir;
let tokenDataDir;
const projectId = "prj_test123";
const teamId = "team_test456";
(0, import_vitest.beforeEach)(() => {
import_vitest.vi.clearAllMocks();
import_vitest.vi.restoreAllMocks();
process.env.VERCEL_OIDC_TOKEN = void 0;
const random = `test-${(0, import_crypto.randomUUID)()}`;
rootDir = path.join(os.tmpdir(), random);
userDataDir = path.join(rootDir, "data");
cliDataDir = path.join(userDataDir, "com.vercel.cli");
tokenDataDir = path.join(userDataDir, "com.vercel.token");
fs.mkdirSync(cliDataDir, { recursive: true });
fs.mkdirSync(tokenDataDir, { recursive: true });
fs.mkdirSync(path.join(rootDir, ".vercel"), {
recursive: true
});
import_vitest.vi.spyOn(process, "cwd").mockReturnValue(rootDir);
import_vitest.vi.mocked(import_token_io.findRootDir).mockReturnValue(rootDir);
import_vitest.vi.mocked(import_token_io.getUserDataDir).mockReturnValue(userDataDir);
});
(0, import_vitest.afterEach)(() => {
if (fs.existsSync(rootDir)) {
fs.rmSync(rootDir, { recursive: true, force: true });
}
});
(0, import_vitest.test)("should throw AccessTokenMissingError when CLI auth file is missing", async () => {
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token.getVercelOidcToken)()).rejects.toThrow(
/No authentication found/
);
});
(0, import_vitest.test)("should throw helpful error when project.json is missing", async () => {
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token.getVercelOidcToken)()).rejects.toThrow(
/project\.json not found, have you linked your project with `vc link\?`/
);
});
(0, import_vitest.test)("should throw helpful error when root directory cannot be found", async () => {
import_vitest.vi.mocked(import_token_io.findRootDir).mockReturnValue(null);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token.getVercelOidcToken)()).rejects.toThrow(
/Unable to find project root directory\. Have you linked your project with `vc link\?`/
);
});
(0, import_vitest.test)("should throw helpful error when user data directory cannot be found", async () => {
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
import_vitest.vi.mocked(import_token_io.getUserDataDir).mockReturnValue(null);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token.getVercelOidcToken)()).rejects.toThrow(
/Unable to find user data directory\. Please reach out to Vercel support\./
);
});
(0, import_vitest.test)("should throw helpful error when API returns non-200", async () => {
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockRejectedValue(
new Error("Failed to refresh OIDC token: Unauthorized")
);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token.getVercelOidcToken)()).rejects.toThrow(
/Failed to refresh OIDC token: Unauthorized/
);
});
(0, import_vitest.test)("should throw helpful error when token response is malformed", async () => {
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockRejectedValue(
new TypeError(
"Vercel OIDC token is malformed. Expected a string-valued token property. Please run `vc env pull` and try again"
)
);
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token.getVercelOidcToken)()).rejects.toThrow(
/Vercel OIDC token is malformed\. Expected a string-valued token property\. Please run `vc env pull` and try again/
);
});
(0, import_vitest.test)("should throw helpful error when token has invalid format", async () => {
process.env.VERCEL_OIDC_TOKEN = "not-a-valid-jwt-token";
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockImplementation(() => {
throw new Error("Invalid token. Please run `vc env pull` and try again");
});
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token.getVercelOidcToken)()).rejects.toThrow(
/Invalid token\. Please run `vc env pull` and try again/
);
});
(0, import_vitest.test)("should throw error when token expiry check fails", async () => {
process.env.VERCEL_OIDC_TOKEN = "not-a-jwt-token";
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token.getVercelOidcToken)()).rejects.toThrow(
/Invalid token\. Please run `vc env pull` and try again/
);
});
(0, import_vitest.test)("should fail when no token exists and no CLI credentials available", async () => {
process.env.VERCEL_OIDC_TOKEN = void 0;
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token.getVercelOidcToken)()).rejects.toThrow(/Invalid token/);
});
(0, import_vitest.test)("should propagate filesystem errors when saving token fails", async () => {
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: "new-valid-token"
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 - 1e3
});
import_vitest.vi.spyOn(tokenUtil, "saveToken").mockImplementation(() => {
throw new Error("EACCES: permission denied");
});
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
await (0, import_vitest.expect)((0, import_get_vercel_oidc_token.getVercelOidcToken)()).rejects.toThrow(/EACCES|permission/i);
});
(0, import_vitest.test)("should succeed when valid token exists in env", async () => {
const validToken = createValidToken();
process.env.VERCEL_OIDC_TOKEN = validToken;
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
const token = await (0, import_get_vercel_oidc_token.getVercelOidcToken)();
(0, import_vitest.expect)(token).toBe(validToken);
});
(0, import_vitest.test)("should refresh when token is expired but all configs are valid", async () => {
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: teamId })
);
const newToken = createValidToken("new-token");
import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: newToken
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValueOnce({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 - 1e3
}).mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
const token = await (0, import_get_vercel_oidc_token.getVercelOidcToken)();
(0, import_vitest.expect)(token).toBe(newToken);
});
(0, import_vitest.test)("should use provided team and project for refresh instead of reading project.json", async () => {
const customProjectId = "prj_custom123";
const customTeamId = "team_custom456";
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
const newToken = createValidToken("custom-token");
const getVercelOidcTokenSpy = import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: newToken
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValueOnce({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 - 1e3
}).mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
const token = await (0, import_get_vercel_oidc_token.getVercelOidcToken)({
team: customTeamId,
project: customProjectId
});
(0, import_vitest.expect)(token).toBe(newToken);
(0, import_vitest.expect)(getVercelOidcTokenSpy).toHaveBeenCalledWith(
"test-auth-token",
customProjectId,
customTeamId
);
});
(0, import_vitest.test)("should use provided project and read team from project.json", async () => {
const customProjectId = "prj_custom234";
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId: "original-project-id", orgId: teamId })
);
const newToken = createValidToken("partial-custom-token");
const getVercelOidcTokenSpy = import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: newToken
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValueOnce({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 - 1e3
}).mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
const token = await (0, import_get_vercel_oidc_token.getVercelOidcToken)({
project: customProjectId
});
(0, import_vitest.expect)(token).toBe(newToken);
(0, import_vitest.expect)(getVercelOidcTokenSpy).toHaveBeenCalledWith(
"test-auth-token",
customProjectId,
teamId
);
});
(0, import_vitest.test)("should use provided team and read project from project.json", async () => {
const customTeamId = "team_custom789";
fs.writeFileSync(
path.join(cliDataDir, "auth.json"),
JSON.stringify({ token: "test-auth-token" })
);
fs.writeFileSync(
path.join(rootDir, ".vercel", "project.json"),
JSON.stringify({ projectId, orgId: "original-team-id" })
);
const newToken = createValidToken("partial-custom-token-2");
const getVercelOidcTokenSpy = import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: newToken
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValueOnce({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 - 1e3
}).mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
process.env.VERCEL_OIDC_TOKEN = createExpiredToken();
const token = await (0, import_get_vercel_oidc_token.getVercelOidcToken)({
team: customTeamId
});
(0, import_vitest.expect)(token).toBe(newToken);
(0, import_vitest.expect)(getVercelOidcTokenSpy).toHaveBeenCalledWith(
"test-auth-token",
projectId,
customTeamId
);
});
(0, import_vitest.test)("should not refresh when token is valid even with options provided", async () => {
const validToken = createValidToken();
process.env.VERCEL_OIDC_TOKEN = validToken;
const getVercelOidcTokenSpy = import_vitest.vi.spyOn(tokenUtil, "getVercelOidcToken").mockResolvedValue({
token: "should-not-be-called"
});
import_vitest.vi.spyOn(tokenUtil, "getTokenPayload").mockReturnValue({
sub: "test-sub",
name: "test-name",
exp: Date.now() / 1e3 + 43200
});
const token = await (0, import_get_vercel_oidc_token.getVercelOidcToken)({
team: "custom-team",
project: "custom-project"
});
(0, import_vitest.expect)(token).toBe(validToken);
(0, import_vitest.expect)(getVercelOidcTokenSpy).not.toHaveBeenCalled();
});
});
function createExpiredToken() {
const header = Buffer.from(
JSON.stringify({ alg: "RS256", typ: "JWT" })
).toString("base64url");
const payload = Buffer.from(
JSON.stringify({
sub: "test-sub",
exp: 1,
iat: 1
})
).toString("base64url");
return `${header}.${payload}.fake_signature`;
}
function createValidToken(value = "valid-token") {
const header = Buffer.from(
JSON.stringify({ alg: "RS256", typ: "JWT" })
).toString("base64url");
const payload = Buffer.from(
JSON.stringify({
sub: "test-sub",
exp: Math.floor(Date.now() / 1e3) + 43200,
iat: Math.floor(Date.now() / 1e3)
})
).toString("base64url");
return `${header}.${payload}.fake_signature_${value}`;
}