UNPKG

meilisearch

Version:

The Meilisearch JS client for Node.js and the browser.

124 lines (123 loc) 4.81 kB
"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 )); Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); function getOptionsWithDefaults(options) { const { searchRules = ["*"], algorithm = "HS256", force = false, ...restOfOptions } = options; return { searchRules, algorithm, force, ...restOfOptions }; } const UUID_V4_REGEXP = /^[0-9a-f]{8}\b(?:-[0-9a-f]{4}\b){3}-[0-9a-f]{12}$/i; function isValidUUIDv4(uuid) { return UUID_V4_REGEXP.test(uuid); } function encodeToBase64(data) { return btoa(typeof data === "string" ? data : JSON.stringify(data)); } let cryptoPonyfill; function getCrypto() { if (cryptoPonyfill === void 0) { cryptoPonyfill = typeof crypto === "undefined" ? import("node:crypto").then((v) => v.webcrypto) : Promise.resolve(crypto); } return cryptoPonyfill; } const textEncoder = new TextEncoder(); async function sign({ apiKey, algorithm }, encodedPayload, encodedHeader) { const crypto2 = await getCrypto(); const cryptoKey = await crypto2.subtle.importKey( // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#raw "raw", textEncoder.encode(apiKey), // https://developer.mozilla.org/en-US/docs/Web/API/HmacImportParams#instance_properties { name: "HMAC", hash: `SHA-${algorithm.slice(2)}` }, // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#extractable false, // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#keyusages ["sign"] ); const signature = await crypto2.subtle.sign( "HMAC", cryptoKey, textEncoder.encode(`${encodedHeader}.${encodedPayload}`) ); const digest = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); return digest; } function getHeader({ algorithm: alg }) { const header = { alg, typ: "JWT" }; return encodeToBase64(header).replace(/=/g, ""); } function getPayload({ searchRules, apiKeyUid, expiresAt }) { if (!isValidUUIDv4(apiKeyUid)) { throw new Error("the uid of your key is not a valid UUIDv4"); } const payload = { searchRules, apiKeyUid }; if (expiresAt !== void 0) { payload.exp = typeof expiresAt === "number" ? expiresAt : ( // To get from a Date object the number of seconds since Unix epoch, i.e. Unix timestamp: Math.floor(expiresAt.getTime() / 1e3) ); } return encodeToBase64(payload).replace(/=/g, ""); } function tryDetectEnvironment() { if (typeof navigator !== "undefined" && "userAgent" in navigator) { const { userAgent } = navigator; if (userAgent.startsWith("Node") || userAgent.startsWith("Deno") || userAgent.startsWith("Bun") || userAgent.startsWith("Cloudflare-Workers")) { return; } } const versions = globalThis.process?.versions; if (versions !== void 0 && Object.hasOwn(versions, "node")) { return; } throw new Error( "failed to detect a server-side environment; do not generate tokens on the frontend in production!\nuse the `force` option to disable environment detection, consult the documentation (Use at your own risk!)" ); } async function generateTenantToken(options) { const optionsWithDefaults = getOptionsWithDefaults(options); if (!optionsWithDefaults.force) { tryDetectEnvironment(); } const encodedPayload = getPayload(optionsWithDefaults); const encodedHeader = getHeader(optionsWithDefaults); const signature = await sign( optionsWithDefaults, encodedPayload, encodedHeader ); return `${encodedHeader}.${encodedPayload}.${signature}`; } exports.generateTenantToken = generateTenantToken; //# sourceMappingURL=token.cjs.map