digiid-ts
Version:
A modern TypeScript implementation of the DigiID authentication protocol.
98 lines (97 loc) • 3.12 kB
JavaScript
import { randomBytes as f } from "crypto";
import * as m from "bitcoinjs-message";
class e extends Error {
constructor(r) {
super(r), this.name = "DigiIDError";
}
}
async function U(t, r, i) {
const c = `DigiByte Signed Message:
`;
try {
return !!m.verify(
t,
// The message that was signed (the DigiID URI)
r,
// The DigiByte address (D..., S..., or dgb1...)
i,
// The signature string (Base64 encoded)
c,
// The DigiByte specific message prefix
!0
// Set checkSegwitAlways to true to handle all address types correctly
);
} catch (a) {
const s = a instanceof Error ? a.message : String(a);
throw new e(`Signature verification failed: ${s}`);
}
}
function b(t = 16) {
return f(t).toString("hex");
}
function k(t) {
if (!t.callbackUrl)
throw new e("Callback URL is required.");
let r;
try {
r = new URL(t.callbackUrl);
} catch (o) {
throw new e(`Invalid callback URL: ${o.message}`);
}
const i = r.host + r.pathname, c = t.nonce || b(), a = t.unsecure ? "1" : "0";
if (t.unsecure && r.protocol !== "http:")
throw new e("Unsecure flag is true, but callback URL does not use http protocol.");
if (!t.unsecure && r.protocol !== "https:")
throw new e("Callback URL must use https protocol unless unsecure flag is set to true.");
return `digiid://${i}?x=${c}&u=${a}`;
}
async function R(t, r) {
const { address: i, uri: c, signature: a } = t, { expectedCallbackUrl: s, expectedNonce: o } = r;
if (!i || !c || !a)
throw new e("Missing required callback data: address, uri, or signature.");
let l;
try {
const n = c.replace(/^digiid:/, "http:");
l = new URL(n);
} catch (n) {
throw new e(`Invalid URI received in callback: ${n.message}`);
}
const u = l.searchParams.get("x"), h = l.searchParams.get("u"), g = l.host + l.pathname;
if (u === null || h === null)
throw new e("URI missing nonce (x) or unsecure (u) parameter.");
let d;
try {
d = typeof s == "string" ? new URL(s) : s;
} catch (n) {
throw new e(`Invalid expectedCallbackUrl provided: ${n.message}`);
}
const p = d.host + d.pathname;
if (g !== p)
throw new e(`Callback URL mismatch: URI contained "${g}", expected "${p}"`);
const w = d.protocol;
if (h === "1" && w !== "http:")
throw new e("URI indicates unsecure (u=1), but expectedCallbackUrl is not http.");
if (h === "0" && w !== "https:")
throw new e("URI indicates secure (u=0), but expectedCallbackUrl is not https.");
if (o && u !== o)
throw new e(`Nonce mismatch: URI contained "${u}", expected "${o}". Possible replay attack.`);
try {
if (!await U(c, i, a))
throw new e("Invalid signature.");
} catch (n) {
throw n instanceof e ? n : new e(`Unexpected error during signature verification: ${n.message}`);
}
return {
isValid: !0,
address: i,
nonce: u
// Return the nonce from the URI
};
}
export {
e as DigiIDError,
U as _internalVerifySignature,
k as generateDigiIDUri,
R as verifyDigiIDCallback
};
//# sourceMappingURL=digiid-ts.es.js.map