@web5/credentials
Version:
Verifiable Credentials
81 lines • 3.97 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { Validator as JsonSchemaValidator } from 'jsonschema';
import { DEFAULT_VC_CONTEXT, DEFAULT_VC_TYPE } from './verifiable-credential.js';
import { isValidRFC3339Timestamp, isValidXmlSchema112Timestamp } from './utils.js';
import { DEFAULT_VP_TYPE } from './verifiable-presentation.js';
const jsonSchemaValidator = new JsonSchemaValidator();
export class SsiValidator {
static validateCredentialPayload(vc) {
this.validateContext(vc.vcDataModel['@context']);
this.validateVcType(vc.type);
this.validateCredentialSubject(vc.vcDataModel.credentialSubject);
if (vc.vcDataModel.issuanceDate)
this.validateTimestamp(vc.vcDataModel.issuanceDate);
if (vc.vcDataModel.expirationDate)
this.validateTimestamp(vc.vcDataModel.expirationDate);
}
static validateContext(value) {
const input = this.asArray(value);
if (input.length < 1 || input.indexOf(DEFAULT_VC_CONTEXT) === -1) {
throw new Error(`@context is missing default context "${DEFAULT_VC_CONTEXT}"`);
}
}
static validateVcType(value) {
const input = this.asArray(value);
if (input.length < 1 || input.indexOf(DEFAULT_VC_TYPE) === -1) {
throw new Error(`type is missing default "${DEFAULT_VC_TYPE}"`);
}
}
static validateVpType(value) {
const input = this.asArray(value);
if (input.length < 1 || input.indexOf(DEFAULT_VP_TYPE) === -1) {
throw new Error(`type is missing default "${DEFAULT_VP_TYPE}"`);
}
}
static validateCredentialSubject(value) {
if (Object.keys(value).length === 0) {
throw new Error(`credentialSubject must not be empty`);
}
}
static validateTimestamp(timestamp) {
if (!isValidXmlSchema112Timestamp(timestamp) && !isValidRFC3339Timestamp(timestamp)) {
throw new Error(`timestamp is not valid xml schema 112 timestamp`);
}
}
static validateCredentialSchema(vcDataModel) {
return __awaiter(this, void 0, void 0, function* () {
const credentialSchema = vcDataModel.credentialSchema;
if (!credentialSchema || (Array.isArray(credentialSchema) && credentialSchema.length === 0)) {
throw new Error('Credential schema is missing or empty');
}
const schemaId = Array.isArray(credentialSchema) ? credentialSchema[0].id : credentialSchema.id;
let jsonSchema;
try {
const response = yield fetch(schemaId);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
jsonSchema = yield response.json();
}
catch (error) {
throw new Error(`Failed to fetch schema from ${schemaId}: ${error.message}`);
}
const validationResult = jsonSchemaValidator.validate(vcDataModel, jsonSchema);
if (!validationResult.valid) {
throw new Error(`Schema Validation Errors: ${JSON.stringify(validationResult.errors)}`);
}
});
}
static asArray(arg) {
return Array.isArray(arg) ? arg : [arg];
}
}
//# sourceMappingURL=validators.js.map