"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); // nip98.ts var nip98_exports = {}; __export(nip98_exports, { getToken: () => getToken, unpackEventFromToken: () => unpackEventFromToken, validateEvent: () => validateEvent2, validateToken: () => validateToken }); module.exports = __toCommonJS(nip98_exports); var import_base = require("@scure/base"); // event.ts var import_secp256k1 = require("@noble/curves/secp256k1"); var import_sha256 = require("@noble/hashes/sha256"); var import_utils = require("@noble/hashes/utils"); // utils.ts var utf8Decoder = new TextDecoder("utf-8"); var utf8Encoder = new TextEncoder(); // event.ts var verifiedSymbol = Symbol("verified"); function getBlankEvent(kind = 255 /* Blank */) { return { kind, content: "", tags: [], created_at: 0 }; } function serializeEvent(evt) { if (!validateEvent(evt)) throw new Error("can't serialize event with wrong or missing properties"); return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]); } function getEventHash(event) { let eventHash = (0, import_sha256.sha256)(utf8Encoder.encode(serializeEvent(event))); return (0, import_utils.bytesToHex)(eventHash); } var isRecord = (obj) => obj instanceof Object; function validateEvent(event) { if (!isRecord(event)) return false; if (typeof event.kind !== "number") return false; if (typeof event.content !== "string") return false; if (typeof event.created_at !== "number") return false; if (typeof event.pubkey !== "string") return false; if (!event.pubkey.match(/^[a-f0-9]{64}$/)) return false; if (!Array.isArray(event.tags)) return false; for (let i = 0; i < event.tags.length; i++) { let tag = event.tags[i]; if (!Array.isArray(tag)) return false; for (let j = 0; j < tag.length; j++) { if (typeof tag[j] === "object") return false; } } return true; } function verifySignature(event) { if (typeof event[verifiedSymbol] === "boolean") return event[verifiedSymbol]; const hash = getEventHash(event); if (hash !== event.id) { return event[verifiedSymbol] = false; } try { return event[verifiedSymbol] = import_secp256k1.schnorr.verify(event.sig, hash, event.pubkey); } catch (err) { return event[verifiedSymbol] = false; } } // nip98.ts var _authorizationScheme = "Nostr "; async function getToken(loginUrl, httpMethod, sign, includeAuthorizationScheme = false) { if (!loginUrl || !httpMethod) throw new Error("Missing loginUrl or httpMethod"); const event = getBlankEvent(27235 /* HttpAuth */); event.tags = [ ["u", loginUrl], ["method", httpMethod] ]; event.created_at = Math.round(new Date().getTime() / 1e3); const signedEvent = await sign(event); const authorizationScheme = includeAuthorizationScheme ? _authorizationScheme : ""; return authorizationScheme + import_base.base64.encode(utf8Encoder.encode(JSON.stringify(signedEvent))); } async function validateToken(token, url, method) { const event = await unpackEventFromToken(token).catch((error) => { throw error; }); const valid = await validateEvent2(event, url, method).catch((error) => { throw error; }); return valid; } async function unpackEventFromToken(token) { if (!token) { throw new Error("Missing token"); } token = token.replace(_authorizationScheme, ""); const eventB64 = utf8Decoder.decode(import_base.base64.decode(token)); if (!eventB64 || eventB64.length === 0 || !eventB64.startsWith("{")) { throw new Error("Invalid token"); } const event = JSON.parse(eventB64); return event; } async function validateEvent2(event, url, method) { if (!event) { throw new Error("Invalid nostr event"); } if (!verifySignature(event)) { throw new Error("Invalid nostr event, signature invalid"); } if (event.kind !== 27235 /* HttpAuth */) { throw new Error("Invalid nostr event, kind invalid"); } if (!event.created_at) { throw new Error("Invalid nostr event, created_at invalid"); } if (Math.round(new Date().getTime() / 1e3) - event.created_at > 60) { throw new Error("Invalid nostr event, expired"); } const urlTag = event.tags.find((t) => t[0] === "u"); if (urlTag?.length !== 1 && urlTag?.[1] !== url) { throw new Error("Invalid nostr event, url tag invalid"); } const methodTag = event.tags.find((t) => t[0] === "method"); if (methodTag?.length !== 1 && methodTag?.[1].toLowerCase() !== method.toLowerCase()) { throw new Error("Invalid nostr event, method tag invalid"); } return true; }