UNPKG

anon-identity

Version:

Decentralized identity framework with DIDs, Verifiable Credentials, and privacy-preserving selective disclosure

326 lines 12.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.FileStorageProvider = void 0; const uuid_1 = require("uuid"); // Lazy-loaded Node.js dependencies let fsModule; let pathModule; let cryptoModule; class FileStorageProvider { constructor(filePath, encryption = true, passphrase) { this.encryption = encryption; this.passphrase = passphrase; this.data = { dids: new Map(), credentials: new Map(), revocations: new Map(), keyPairs: new Map(), schemas: new Map(), }; this.initialized = false; this.initPromise = null; this.filePath = filePath; if (encryption && passphrase) { this.encryptionKey = passphrase; } } async initialize() { if (this.initialized) return; if (this.initPromise) return this.initPromise; this.initPromise = this.doInitialize(); await this.initPromise; this.initialized = true; } async doInitialize() { try { // Dynamic import of Node.js modules [fsModule, pathModule, cryptoModule] = await Promise.all([ Promise.resolve().then(() => __importStar(require('fs'))).then(m => m.promises), Promise.resolve().then(() => __importStar(require('path'))), Promise.resolve().then(() => __importStar(require('crypto'))), ]); await this.load(); } catch (error) { throw new Error(`Failed to initialize file storage: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async ensureDirectoryExists(filePath) { const dir = pathModule.dirname(filePath); try { await fsModule.access(dir); } catch { await fsModule.mkdir(dir, { recursive: true }); } } encrypt(data) { if (!this.encryptionKey) return data; const algorithm = 'aes-256-gcm'; const salt = cryptoModule.randomBytes(16); const key = cryptoModule.pbkdf2Sync(this.encryptionKey, salt, 100000, 32, 'sha256'); const iv = cryptoModule.randomBytes(16); const cipher = cryptoModule.createCipheriv(algorithm, key, iv); let encrypted = cipher.update(data, 'utf8', 'hex'); encrypted += cipher.final('hex'); const authTag = cipher.getAuthTag(); return JSON.stringify({ encrypted, salt: salt.toString('hex'), iv: iv.toString('hex'), authTag: authTag.toString('hex'), }); } decrypt(encryptedData) { if (!this.encryptionKey) return encryptedData; try { const { encrypted, salt, iv, authTag } = JSON.parse(encryptedData); const algorithm = 'aes-256-gcm'; const key = cryptoModule.pbkdf2Sync(this.encryptionKey, Buffer.from(salt, 'hex'), 100000, 32, 'sha256'); const decipher = cryptoModule.createDecipheriv(algorithm, key, Buffer.from(iv, 'hex')); decipher.setAuthTag(Buffer.from(authTag, 'hex')); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } catch (error) { // If decryption fails, assume data is not encrypted return encryptedData; } } async save() { await this.ensureDirectoryExists(this.filePath); const dataToSave = { dids: Array.from(this.data.dids.entries()), credentials: Array.from(this.data.credentials.entries()), revocations: Array.from(this.data.revocations.entries()), keyPairs: Array.from(this.data.keyPairs.entries()), schemas: Array.from(this.data.schemas.entries()), }; const jsonData = JSON.stringify(dataToSave, null, 2); const dataToWrite = this.encrypt(jsonData); await fsModule.writeFile(this.filePath, dataToWrite, 'utf8'); } async load() { try { await this.ensureDirectoryExists(this.filePath); const encryptedData = await fsModule.readFile(this.filePath, 'utf8'); const jsonData = this.decrypt(encryptedData); const loadedData = JSON.parse(jsonData); this.data.dids = new Map(loadedData.dids || []); this.data.credentials = new Map(loadedData.credentials || []); this.data.revocations = new Map(loadedData.revocations || []); this.data.keyPairs = new Map(loadedData.keyPairs || []); this.data.schemas = new Map(loadedData.schemas || []); } catch (error) { // File doesn't exist or is corrupt, start fresh this.data = { dids: new Map(), credentials: new Map(), revocations: new Map(), keyPairs: new Map(), schemas: new Map(), }; } } // DID Operations async storeDID(did, document) { await this.initialize(); this.data.dids.set(did, document); await this.save(); } async resolveDID(did) { await this.initialize(); return this.data.dids.get(did) || null; } async listDIDs(owner) { await this.initialize(); if (!owner) { return Array.from(this.data.dids.keys()); } const dids = []; for (const [did, document] of this.data.dids) { if (document.verificationMethod?.some(vm => vm.controller === owner)) { dids.push(did); } } return dids; } // Credential Operations async storeCredential(credential) { await this.initialize(); this.data.credentials.set(credential.id, credential); await this.save(); } async getCredential(id) { await this.initialize(); return this.data.credentials.get(id) || null; } async listCredentials(holder) { await this.initialize(); const credentials = []; for (const credential of this.data.credentials.values()) { if (credential.credentialSubject.id === holder) { credentials.push(credential); } } return credentials; } async deleteCredential(id) { await this.initialize(); this.data.credentials.delete(id); await this.save(); } // Revocation Operations async publishRevocation(issuerDID, revocationList) { await this.initialize(); this.data.revocations.set(issuerDID, revocationList); await this.save(); } async checkRevocation(issuerDID, credentialId) { await this.initialize(); const revocationList = this.data.revocations.get(issuerDID); if (!revocationList) return false; return revocationList.revokedCredentialIds.includes(credentialId); } async getRevocationList(issuerDID) { await this.initialize(); return this.data.revocations.get(issuerDID) || null; } // Key Management async storeKeyPair(identifier, encryptedKeyPair) { await this.initialize(); this.data.keyPairs.set(identifier, encryptedKeyPair); await this.save(); } async retrieveKeyPair(identifier) { await this.initialize(); return this.data.keyPairs.get(identifier) || null; } async deleteKeyPair(identifier) { await this.initialize(); this.data.keyPairs.delete(identifier); await this.save(); } // Schema Operations async registerSchema(schema) { await this.initialize(); const schemaId = schema.id || `schema:${(0, uuid_1.v4)()}`; const schemaWithId = { ...schema, id: schemaId }; this.data.schemas.set(schemaId, schemaWithId); await this.save(); return schemaId; } async getSchema(schemaId) { await this.initialize(); return this.data.schemas.get(schemaId) || null; } async listSchemas(issuerDID) { await this.initialize(); if (!issuerDID) { return Array.from(this.data.schemas.values()); } return Array.from(this.data.schemas.values()).filter(schema => schema.issuerDID === issuerDID); } // General operations async clear() { await this.initialize(); this.data = { dids: new Map(), credentials: new Map(), revocations: new Map(), keyPairs: new Map(), schemas: new Map(), }; await this.save(); } // Phone Number Operations async storePhoneNumber(userDID, phoneNumber) { throw new Error('Phone number storage not implemented in file provider lazy loader'); } async getPhoneNumber(userDID, phoneId) { throw new Error('Phone number retrieval not implemented in file provider lazy loader'); } async listPhoneNumbers(userDID) { throw new Error('Phone number listing not implemented in file provider lazy loader'); } async updatePhoneNumber(userDID, phoneId, phoneNumber) { throw new Error('Phone number update not implemented in file provider lazy loader'); } async deletePhoneNumber(userDID, phoneId) { throw new Error('Phone number deletion not implemented in file provider lazy loader'); } // Address Operations async storeAddress(userDID, address) { throw new Error('Address storage not implemented in file provider lazy loader'); } async getAddress(userDID, addressId) { throw new Error('Address retrieval not implemented in file provider lazy loader'); } async listAddresses(userDID) { throw new Error('Address listing not implemented in file provider lazy loader'); } async updateAddress(userDID, addressId, address) { throw new Error('Address update not implemented in file provider lazy loader'); } async deleteAddress(userDID, addressId) { throw new Error('Address deletion not implemented in file provider lazy loader'); } // Email Address Operations async storeEmailAddress(userDID, emailAddress) { throw new Error('Email address storage not implemented in file provider lazy loader'); } async getEmailAddress(userDID, emailId) { throw new Error('Email address storage not implemented in file provider lazy loader'); } async listEmailAddresses(userDID) { throw new Error('Email address storage not implemented in file provider lazy loader'); } async updateEmailAddress(userDID, emailId, emailAddress) { throw new Error('Email address storage not implemented in file provider lazy loader'); } async deleteEmailAddress(userDID, emailId) { throw new Error('Email address storage not implemented in file provider lazy loader'); } } exports.FileStorageProvider = FileStorageProvider; //# sourceMappingURL=file-storage-provider-lazy.js.map