@atproto/did
Version:
DID resolution and verification library
128 lines • 4.72 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.didDocumentValidator = exports.didDocumentSchema = void 0;
const zod_1 = require("zod");
const did_js_1 = require("./did.js");
/**
* RFC3968 compliant URI
*
* @see {@link https://www.rfc-editor.org/rfc/rfc3986}
*/
const rfc3968UriSchema = zod_1.z.string().refine((data) => {
try {
new URL(data);
return true;
}
catch {
return false;
}
}, 'RFC3968 compliant URI');
const didControllerSchema = zod_1.z.union([did_js_1.didSchema, zod_1.z.array(did_js_1.didSchema)]);
/**
* @note this schema might be too permissive
*/
const didRelativeUriSchema = zod_1.z.union([
rfc3968UriSchema,
zod_1.z.string().regex(/^#[^#]+$/),
]);
const didVerificationMethodSchema = zod_1.z.object({
id: didRelativeUriSchema,
type: zod_1.z.string().min(1),
controller: didControllerSchema,
publicKeyJwk: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
publicKeyMultibase: zod_1.z.string().optional(),
});
/**
* The value of the id property MUST be a URI conforming to [RFC3986]. A
* conforming producer MUST NOT produce multiple service entries with the same
* id. A conforming consumer MUST produce an error if it detects multiple
* service entries with the same id.
*
* @note Normally, only rfc3968UriSchema should be allowed here. However, the
* did:plc uses relative URI. For this reason, we also allow relative URIs
* here.
*/
const didServiceIdSchema = didRelativeUriSchema;
/**
* The value of the type property MUST be a string or a set of strings. In order
* to maximize interoperability, the service type and its associated properties
* SHOULD be registered in the DID Specification Registries
* [DID-SPEC-REGISTRIES].
*/
const didServiceTypeSchema = zod_1.z.union([zod_1.z.string(), zod_1.z.array(zod_1.z.string())]);
/**
* The value of the serviceEndpoint property MUST be a string, a map, or a set
* composed of one or more strings and/or maps. All string values MUST be valid
* URIs conforming to [RFC3986] and normalized according to the Normalization
* and Comparison rules in RFC3986 and to any normalization rules in its
* applicable URI scheme specification.
*/
const didServiceEndpointSchema = zod_1.z.union([
rfc3968UriSchema,
zod_1.z.record(zod_1.z.string(), rfc3968UriSchema),
zod_1.z
.array(zod_1.z.union([rfc3968UriSchema, zod_1.z.record(zod_1.z.string(), rfc3968UriSchema)]))
.nonempty(),
]);
/**
* Each service map MUST contain id, type, and serviceEndpoint properties.
* @see {@link https://www.w3.org/TR/did-core/#services}
*/
const didServiceSchema = zod_1.z.object({
id: didServiceIdSchema,
type: didServiceTypeSchema,
serviceEndpoint: didServiceEndpointSchema,
});
const didAuthenticationSchema = zod_1.z.union([
//
didRelativeUriSchema,
didVerificationMethodSchema,
]);
/**
* @note This schema is incomplete
* @see {@link https://www.w3.org/TR/did-core/#production-0}
*/
exports.didDocumentSchema = zod_1.z.object({
'@context': zod_1.z.union([
zod_1.z.literal('https://www.w3.org/ns/did/v1'),
zod_1.z
.array(zod_1.z.string().url())
.nonempty()
.refine((data) => data[0] === 'https://www.w3.org/ns/did/v1', {
message: 'First @context must be https://www.w3.org/ns/did/v1',
}),
]),
id: did_js_1.didSchema,
controller: didControllerSchema.optional(),
alsoKnownAs: zod_1.z.array(rfc3968UriSchema).optional(),
service: zod_1.z.array(didServiceSchema).optional(),
authentication: zod_1.z.array(didAuthenticationSchema).optional(),
verificationMethod: zod_1.z
.array(zod_1.z.union([didVerificationMethodSchema, didRelativeUriSchema]))
.optional(),
});
// @TODO: add other refinements ?
exports.didDocumentValidator = exports.didDocumentSchema
// Ensure that every service id is unique
.superRefine(({ id: did, service }, ctx) => {
if (service) {
const visited = new Set();
for (let i = 0; i < service.length; i++) {
const current = service[i];
const serviceId = current.id.startsWith('#')
? `${did}${current.id}`
: current.id;
if (!visited.has(serviceId)) {
visited.add(serviceId);
}
else {
ctx.addIssue({
code: zod_1.z.ZodIssueCode.custom,
message: `Duplicate service id (${current.id}) found in the document`,
path: ['service', i, 'id'],
});
}
}
}
});
//# sourceMappingURL=did-document.js.map