/** * Credential lifecycle management operations */ import { query } from './client'; // Note: CredentialTemplate operations are now in credential-templates.ts // This file focuses on lifecycle operations (status history, revocation, audit) // Credential Status History operations export async function addCredentialStatusHistory(history) { const result = await query(`INSERT INTO credential_status_history (credential_id, status, reason, changed_by, metadata) VALUES ($1, $2, $3, $4, $5) RETURNING *`, [ history.credential_id, history.status, history.reason || null, history.changed_by || null, history.metadata ? JSON.stringify(history.metadata) : null, ]); return result.rows[0]; } export async function getCredentialStatusHistory(credentialId) { const result = await query(`SELECT * FROM credential_status_history WHERE credential_id = $1 ORDER BY changed_at DESC`, [credentialId]); return result.rows; } // Credential Revocation operations export async function revokeCredential(revocation) { // First, update the credential as revoked await query(`UPDATE verifiable_credentials SET revoked = TRUE, updated_at = NOW() WHERE credential_id = $1`, [revocation.credential_id]); // Get the next revocation list index const indexResult = await query(`SELECT MAX(revocation_list_index) as max_index FROM credential_revocation_registry WHERE issuer_did = $1`, [revocation.issuer_did]); const nextIndex = (indexResult.rows[0]?.max_index ?? -1) + 1; // Add to revocation registry const result = await query(`INSERT INTO credential_revocation_registry (credential_id, issuer_did, revocation_reason, revoked_by, revocation_list_index) VALUES ($1, $2, $3, $4, $5) RETURNING *`, [ revocation.credential_id, revocation.issuer_did, revocation.revocation_reason || null, revocation.revoked_by || null, nextIndex, ]); return result.rows[0]; } export async function isCredentialRevoked(credentialId) { const result = await query(`SELECT revoked FROM verifiable_credentials WHERE credential_id = $1`, [credentialId]); return result.rows[0]?.revoked ?? false; } export async function getRevocationRegistry(issuerDid, limit = 100, offset = 0) { const result = await query(`SELECT * FROM credential_revocation_registry WHERE issuer_did = $1 ORDER BY revocation_list_index DESC LIMIT $2 OFFSET $3`, [issuerDid, limit, offset]); return result.rows; } // Credential Audit Log operations export async function logCredentialAction(audit) { const result = await query(`INSERT INTO credential_issuance_audit (credential_id, issuer_did, subject_did, credential_type, action, performed_by, metadata, ip_address, user_agent) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING *`, [ audit.credential_id, audit.issuer_did, audit.subject_did, audit.credential_type, audit.action, audit.performed_by || null, audit.metadata ? JSON.stringify(audit.metadata) : null, audit.ip_address || null, audit.user_agent || null, ]); return result.rows[0]; } export async function getCredentialAuditLog(credentialId, limit = 100) { const result = await query(`SELECT * FROM credential_issuance_audit WHERE credential_id = $1 ORDER BY performed_at DESC LIMIT $2`, [credentialId, limit]); return result.rows; } export async function getExpiringCredentials(daysAhead, limit = 100) { const result = await query(`SELECT credential_id, expiration_date, subject_did, issuer_did, credential_type, credential_subject FROM verifiable_credentials WHERE expiration_date IS NOT NULL AND expiration_date > NOW() AND expiration_date < NOW() + INTERVAL '${daysAhead} days' AND revoked = FALSE ORDER BY expiration_date ASC LIMIT $1`, [limit]); return result.rows; } //# sourceMappingURL=credential-lifecycle.js.map