UNPKG

@atproto/did

Version:

DID resolution and verification library

154 lines 5.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.didSchema = exports.DID_PREFIX = void 0; exports.assertDidMethod = assertDidMethod; exports.extractDidMethod = extractDidMethod; exports.assertDidMsid = assertDidMsid; exports.assertDid = assertDid; exports.isDid = isDid; exports.asDid = asDid; const zod_1 = require("zod"); const did_error_js_1 = require("./did-error.js"); const DID_PREFIX = 'did:'; exports.DID_PREFIX = DID_PREFIX; const DID_PREFIX_LENGTH = DID_PREFIX.length; /** * DID Method-name check function. * * Check if the input is a valid DID method name, at the position between * `start` (inclusive) and `end` (exclusive). */ function assertDidMethod(input, start = 0, end = input.length) { if (!Number.isFinite(end) || !Number.isFinite(start) || end < start || end > input.length) { throw new TypeError('Invalid start or end position'); } if (end === start) { throw new did_error_js_1.InvalidDidError(input, `Empty method name`); } let c; for (let i = start; i < end; i++) { c = input.charCodeAt(i); if ((c < 0x61 || c > 0x7a) && // a-z (c < 0x30 || c > 0x39) // 0-9 ) { throw new did_error_js_1.InvalidDidError(input, `Invalid character at position ${i} in DID method name`); } } } /** * This method assumes the input is a valid Did */ function extractDidMethod(did) { const msidSep = did.indexOf(':', DID_PREFIX_LENGTH); const method = did.slice(DID_PREFIX_LENGTH, msidSep); return method; } /** * DID Method-specific identifier check function. * * Check if the input is a valid DID method-specific identifier, at the position * between `start` (inclusive) and `end` (exclusive). */ function assertDidMsid(input, start = 0, end = input.length) { if (!Number.isFinite(end) || !Number.isFinite(start) || end < start || end > input.length) { throw new TypeError('Invalid start or end position'); } if (end === start) { throw new did_error_js_1.InvalidDidError(input, `DID method-specific id must not be empty`); } let c; for (let i = start; i < end; i++) { c = input.charCodeAt(i); // Check for frequent chars first if ((c < 0x61 || c > 0x7a) && // a-z (c < 0x41 || c > 0x5a) && // A-Z (c < 0x30 || c > 0x39) && // 0-9 c !== 0x2e && // . c !== 0x2d && // - c !== 0x5f // _ ) { // Less frequent chars are checked here // ":" if (c === 0x3a) { if (i === end - 1) { throw new did_error_js_1.InvalidDidError(input, `DID cannot end with ":"`); } continue; } // pct-encoded if (c === 0x25) { c = input.charCodeAt(++i); if ((c < 0x30 || c > 0x39) && (c < 0x41 || c > 0x46)) { throw new did_error_js_1.InvalidDidError(input, `Invalid pct-encoded character at position ${i}`); } c = input.charCodeAt(++i); if ((c < 0x30 || c > 0x39) && (c < 0x41 || c > 0x46)) { throw new did_error_js_1.InvalidDidError(input, `Invalid pct-encoded character at position ${i}`); } // There must always be 2 HEXDIG after a "%" if (i >= end) { throw new did_error_js_1.InvalidDidError(input, `Incomplete pct-encoded character at position ${i - 2}`); } continue; } throw new did_error_js_1.InvalidDidError(input, `Disallowed character in DID at position ${i}`); } } } function assertDid(input) { if (typeof input !== 'string') { throw new did_error_js_1.InvalidDidError(typeof input, `DID must be a string`); } const { length } = input; if (length > 2048) { throw new did_error_js_1.InvalidDidError(input, `DID is too long (2048 chars max)`); } if (!input.startsWith(DID_PREFIX)) { throw new did_error_js_1.InvalidDidError(input, `DID requires "${DID_PREFIX}" prefix`); } const idSep = input.indexOf(':', DID_PREFIX_LENGTH); if (idSep === -1) { throw new did_error_js_1.InvalidDidError(input, `Missing colon after method name`); } assertDidMethod(input, DID_PREFIX_LENGTH, idSep); assertDidMsid(input, idSep + 1, length); } function isDid(input) { try { assertDid(input); return true; } catch (err) { if (err instanceof did_error_js_1.DidError) { return false; } // Unexpected TypeError (should never happen) throw err; } } function asDid(input) { assertDid(input); return input; } exports.didSchema = zod_1.z .string() .superRefine((value, ctx) => { try { assertDid(value); return true; } catch (err) { ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, message: err instanceof Error ? err.message : 'Unexpected error', }); return false; } }); //# sourceMappingURL=did.js.map