@openeudi/core 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +249 -64
- package/dist/index.cjs +532 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +352 -57
- package/dist/index.d.ts +352 -57
- package/dist/index.js +530 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/verification.ts","../src/errors.ts","../src/storage/memory.store.ts","../src/modes/demo.mode.ts","../src/modes/mock.mode.ts","../src/verification.service.ts","../src/index.ts"],"names":["VerificationType","VerificationStatus","EventEmitter","uuidv4"],"mappings":";;;;;;AAGO,IAAK,gBAAA,qBAAAA,iBAAAA,KAAL;AAEH,EAAAA,kBAAA,KAAA,CAAA,GAAM,KAAA;AAEN,EAAAA,kBAAA,SAAA,CAAA,GAAU,SAAA;AAEV,EAAAA,kBAAA,MAAA,CAAA,GAAO,MAAA;AANC,EAAA,OAAAA,iBAAAA;AAAA,CAAA,EAAA,gBAAA,IAAA,EAAA;AAYL,IAAK,kBAAA,qBAAAC,mBAAAA,KAAL;AAEH,EAAAA,oBAAA,SAAA,CAAA,GAAU,SAAA;AAEV,EAAAA,oBAAA,SAAA,CAAA,GAAU,SAAA;AAEV,EAAAA,oBAAA,UAAA,CAAA,GAAW,UAAA;AAEX,EAAAA,oBAAA,UAAA,CAAA,GAAW,UAAA;AAEX,EAAAA,oBAAA,SAAA,CAAA,GAAU,SAAA;AAVF,EAAA,OAAAA,mBAAAA;AAAA,CAAA,EAAA,kBAAA,IAAA,EAAA;;;ACZL,IAAM,oBAAA,GAAN,cAAmC,KAAA,CAAM;AAAA,EAC5C,YAAY,SAAA,EAAmB;AAC3B,IAAA,KAAA,CAAM,CAAA,mBAAA,EAAsB,SAAS,CAAA,CAAE,CAAA;AACvC,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EACpD;AACJ;AAKO,IAAM,mBAAA,GAAN,cAAkC,KAAA,CAAM;AAAA,EAC3C,YAAY,SAAA,EAAmB;AAC3B,IAAA,KAAA,CAAM,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAE,CAAA;AACrC,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EACpD;AACJ;;;ACXO,IAAM,uBAAN,MAAoD;AAAA,EAC/C,QAAA,uBAAe,GAAA,EAAiC;AAAA,EAExD,MAAM,IAAI,EAAA,EAAiD;AACvD,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA,IAAK,IAAA;AAAA,EACpC;AAAA,EAEA,MAAM,IAAI,OAAA,EAA6C;AACnD,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,EAAA,EAAI,OAAO,CAAA;AAAA,EACzC;AAAA,EAEA,MAAM,OAAO,EAAA,EAA2B;AACpC,IAAA,IAAA,CAAK,QAAA,CAAS,OAAO,EAAE,CAAA;AAAA,EAC3B;AACJ;;;AClBA,IAAM,YAAA,GAAe;AAAA,EACjB,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA;AACJ,CAAA;AAWO,IAAM,WAAN,MAA4C;AAAA,EACtC,IAAA,GAAO,MAAA;AAAA,EACR,OAAA;AAAA,EAER,WAAA,CAAY,MAAA,GAAyB,EAAC,EAAG;AACrC,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,GAAA;AAAA,EACrC;AAAA,EAEA,MAAM,eAAA,CAAgB,OAAA,EAA8B,eAAA,EAAuD;AACvG,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,WAAA,CAAY,OAAA,CAAQ,gBAAgB,CAAA;AACzD,IAAA,OAAO,IAAA,CAAK,WAAA,CAAY,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA;AAAA,EACjD;AAAA,EAEA,MAAM,mBAAmB,OAAA,EAA2D;AAChF,IAAA,MAAM,IAAI,QAAQ,CAAC,OAAA,KAAY,WAAW,OAAA,EAAS,IAAA,CAAK,OAAO,CAAC,CAAA;AAChE,IAAA,OAAO,IAAA,CAAK,eAAA,CAAgB,OAAA,EAAS,EAAE,CAAA;AAAA,EAC3C;AAAA,EAEQ,YAAY,SAAA,EAA8B;AAC9C,IAAA,MAAM,IAAA,GAAO,SAAA,IAAa,SAAA,CAAU,MAAA,GAAS,IAAI,SAAA,GAAY,YAAA;AAC7D,IAAA,OAAO,IAAA,CAAK,KAAK,KAAA,CAAM,IAAA,CAAK,QAAO,GAAI,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,EACvD;AAAA,EAEQ,WAAA,CAAY,MAAwB,OAAA,EAAqC;AAC7E,IAAA,MAAM,aAAa,IAAA,KAAA,KAAA,cAAiC,IAAA,KAAA,MAAA;AACpD,IAAA,MAAM,iBAAiB,IAAA,KAAA,SAAA,kBAAqC,IAAA,KAAA,MAAA;AAE5D,IAAA,OAAO;AAAA,MACH,QAAA,EAAU,IAAA;AAAA,MACV,OAAA;AAAA,MACA,WAAA,EAAa,aAAa,IAAA,GAAO,MAAA;AAAA,MACjC,eAAA,EAAiB,iBAAiB,IAAA,GAAO;AAAA,KAC7C;AAAA,EACJ;AACJ;;;ACnEA,IAAM,cAAA,GAAqC;AAAA,EACvC,QAAA,EAAU,IAAA;AAAA,EACV,OAAA,EAAS,IAAA;AAAA,EACT,WAAA,EAAa,IAAA;AAAA,EACb,eAAA,EAAiB;AACrB,CAAA;AAMO,IAAM,WAAN,MAA4C;AAAA,EACtC,IAAA,GAAO,MAAA;AAAA,EACR,aAAA;AAAA,EACA,OAAA;AAAA,EACA,gBAAA,uBAAuB,GAAA,EAAgC;AAAA,EAE/D,WAAA,CAAY,MAAA,GAAyB,EAAC,EAAG;AACrC,IAAA,IAAA,CAAK,aAAA,GAAgB,MAAA,CAAO,aAAA,IAAiB,EAAE,GAAG,cAAA,EAAe;AACjE,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,CAAA;AAAA,EACrC;AAAA;AAAA,EAGA,gBAAA,CAAiB,WAAmB,MAAA,EAAkC;AAClE,IAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,SAAA,EAAW,MAAM,CAAA;AAAA,EAC/C;AAAA;AAAA,EAGA,mBAAmB,SAAA,EAAyB;AACxC,IAAA,IAAA,CAAK,gBAAA,CAAiB,OAAO,SAAS,CAAA;AAAA,EAC1C;AAAA,EAEA,MAAM,eAAA,CAAgB,OAAA,EAA8B,eAAA,EAAuD;AACvG,IAAA,IAAI,IAAA,CAAK,UAAU,CAAA,EAAG;AAClB,MAAA,MAAM,IAAI,QAAQ,CAAC,OAAA,KAAY,WAAW,OAAA,EAAS,IAAA,CAAK,OAAO,CAAC,CAAA;AAAA,IACpE;AACA,IAAA,OAAO,IAAA,CAAK,iBAAiB,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA,IAAK,EAAE,GAAG,IAAA,CAAK,aAAA,EAAc;AAAA,EAC5E;AAAA,EAEA,MAAM,mBAAmB,OAAA,EAA2D;AAChF,IAAA,OAAO,IAAA,CAAK,eAAA,CAAgB,OAAA,EAAS,EAAE,CAAA;AAAA,EAC3C;AACJ;ACzCA,IAAM,cAAA,GAAiB,GAAA;AACvB,IAAM,uBAAA,GAA0B,oBAAA;AAUzB,IAAM,mBAAA,GAAN,cAAkCC,mBAAA,CAAa;AAAA,EAC1C,KAAA;AAAA,EACA,IAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA;AAAA,EAEA,UAAA,uBAAiB,GAAA,EAAY;AAAA,EAErC,YAAY,MAAA,EAAmC;AAC3C,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,OAAO,MAAA,CAAO,IAAA;AACnB,IAAA,IAAA,CAAK,KAAA,GAAQ,MAAA,CAAO,KAAA,IAAS,IAAI,oBAAA,EAAqB;AACtD,IAAA,IAAA,CAAK,YAAA,GAAe,OAAO,YAAA,IAAgB,cAAA;AAC3C,IAAA,IAAA,CAAK,aAAA,GAAgB,OAAO,aAAA,IAAiB,uBAAA;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,KAAA,EAAyD;AACzE,IAAA,MAAM,KAAKC,OAAA,EAAO;AAClB,IAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AAErB,IAAA,MAAM,OAAA,GAA+B;AAAA,MACjC,EAAA;AAAA,MACA,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,MAAA,EAAA,SAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA;AAAA,MACX,kBAAkB,KAAA,CAAM,gBAAA;AAAA,MACxB,kBAAkB,KAAA,CAAM,gBAAA;AAAA,MACxB,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,UAAU,KAAA,CAAM,QAAA;AAAA,MAChB,SAAA,EAAW,GAAA;AAAA,MACX,WAAW,IAAI,IAAA,CAAK,IAAI,OAAA,EAAQ,GAAI,KAAK,YAAY;AAAA,KACzD;AAEA,IAAA,OAAA,CAAQ,SAAA,GAAY,IAAA,CAAK,IAAA,CAAK,cAAA,GACxB,MAAM,IAAA,CAAK,IAAA,CAAK,cAAA,CAAe,EAAA,EAAI,KAAK,CAAA,GACxC,CAAA,EAAG,IAAA,CAAK,aAAa,YAAY,EAAE,CAAA,CAAA;AAEzC,IAAA,MAAM,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AAC5B,IAAA,IAAA,CAAK,UAAA,CAAW,IAAI,EAAE,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,CAAK,mBAAmB,OAAO,CAAA;AAGpC,IAAA,IAAI,IAAA,CAAK,KAAK,kBAAA,EAAoB;AAC9B,MAAA,IAAA,CAAK,KACA,kBAAA,CAAmB,OAAO,CAAA,CAC1B,IAAA,CAAK,OAAO,MAAA,KAAW;AAEpB,QAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,KAAA,CAAM,IAAI,EAAE,CAAA;AACvC,QAAA,IAAI,OAAA,IAAW,QAAQ,MAAA,KAAA,SAAA,gBAAuC;AAC1D,UAAA,MAAM,IAAA,CAAK,eAAA,CAAgB,OAAA,EAAS,MAAM,CAAA;AAAA,QAC9C;AAAA,MACJ,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,MAEb,CAAC,CAAA;AAAA,IACT;AAEA,IAAA,OAAO,OAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,EAAA,EAA0C;AACvD,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,KAAA,CAAM,IAAI,EAAE,CAAA;AACvC,IAAA,IAAI,CAAC,OAAA,EAAS;AACV,MAAA,MAAM,IAAI,qBAAqB,EAAE,CAAA;AAAA,IACrC;AACA,IAAA,OAAO,OAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cAAA,CAAe,SAAA,EAAmB,cAAA,EAAsD;AAC1F,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,KAAA,CAAM,IAAI,SAAS,CAAA;AAC9C,IAAA,IAAI,CAAC,OAAA,EAAS;AACV,MAAA,MAAM,IAAI,qBAAqB,SAAS,CAAA;AAAA,IAC5C;AACA,IAAA,oBAAI,IAAI,IAAA,EAAK,GAAI,OAAA,CAAQ,SAAA,EAAW;AAChC,MAAA,MAAM,IAAI,oBAAoB,SAAS,CAAA;AAAA,IAC3C;AAEA,IAAA,MAAM,SAAS,MAAM,IAAA,CAAK,IAAA,CAAK,eAAA,CAAgB,SAAS,cAAc,CAAA;AACtE,IAAA,MAAM,IAAA,CAAK,eAAA,CAAgB,OAAA,EAAS,MAAM,CAAA;AAC1C,IAAA,OAAO,MAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAAA,GAAkC;AACpC,IAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,IAAA,IAAI,KAAA,GAAQ,CAAA;AAEZ,IAAA,KAAA,MAAW,EAAA,IAAM,KAAK,UAAA,EAAY;AAC9B,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,KAAA,CAAM,IAAI,EAAE,CAAA;AACvC,MAAA,IAAI,CAAC,OAAA,EAAS;AACV,QAAA,IAAA,CAAK,UAAA,CAAW,OAAO,EAAE,CAAA;AACzB,QAAA;AAAA,MACJ;AACA,MAAA,IAAI,GAAA,GAAM,OAAA,CAAQ,SAAA,IAAa,OAAA,CAAQ,MAAA,KAAA,SAAA,gBAAuC;AAC1E,QAAA,MAAM,OAAA,GAAU,EAAE,GAAG,OAAA,EAAS,MAAA,EAAA,SAAA,gBAAmC;AACjE,QAAA,MAAM,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AAC5B,QAAA,MAAM,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,EAAE,CAAA;AAC1B,QAAA,IAAA,CAAK,UAAA,CAAW,OAAO,EAAE,CAAA;AACzB,QAAA,IAAA,CAAK,IAAA,CAAK,mBAAmB,OAAO,CAAA;AACpC,QAAA,KAAA,EAAA;AAAA,MACJ;AAAA,IACJ;AAEA,IAAA,OAAO,KAAA;AAAA,EACX;AAAA,EAEA,MAAc,eAAA,CAAgB,OAAA,EAA8B,MAAA,EAA2C;AACnG,IAAA,MAAM,SAAS,MAAA,CAAO,QAAA,GAAA,UAAA,kBAAA,UAAA;AACtB,IAAA,MAAM,OAAA,GAA+B;AAAA,MACjC,GAAG,OAAA;AAAA,MACH,MAAA;AAAA,MACA,WAAA,sBAAiB,IAAA,EAAK;AAAA,MACtB;AAAA,KACJ;AAEA,IAAA,MAAM,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AAE5B,IAAA,IAAI,OAAO,QAAA,EAAU;AACjB,MAAA,IAAA,CAAK,IAAA,CAAK,kBAAA,EAAoB,OAAA,EAAS,MAAM,CAAA;AAAA,IACjD,CAAA,MAAO;AACH,MAAA,IAAA,CAAK,IAAA,CAAK,kBAAA,EAAoB,OAAA,EAAS,MAAA,CAAO,eAAe,CAAA;AAAA,IACjE;AAAA,EACJ;AACJ;;;AChKO,IAAM,OAAA,GAAU","file":"index.cjs","sourcesContent":["/**\n * Type of verification to perform\n */\nexport enum VerificationType {\n /** Verify age (over_18 attribute) */\n AGE = 'AGE',\n /** Verify country of residence */\n COUNTRY = 'COUNTRY',\n /** Verify both age and country */\n BOTH = 'BOTH',\n}\n\n/**\n * Status of a verification session\n */\nexport enum VerificationStatus {\n /** Session created, waiting for wallet scan */\n PENDING = 'PENDING',\n /** QR code scanned, credential exchange in progress */\n SCANNED = 'SCANNED',\n /** Verification completed successfully */\n VERIFIED = 'VERIFIED',\n /** Verification rejected (age, country, or policy) */\n REJECTED = 'REJECTED',\n /** Session expired before completion */\n EXPIRED = 'EXPIRED',\n}\n","/**\n * Thrown when a session ID is not found in the store\n */\nexport class SessionNotFoundError extends Error {\n constructor(sessionId: string) {\n super(`Session not found: ${sessionId}`);\n this.name = 'SessionNotFoundError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when an operation is attempted on an expired session\n */\nexport class SessionExpiredError extends Error {\n constructor(sessionId: string) {\n super(`Session expired: ${sessionId}`);\n this.name = 'SessionExpiredError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import type { VerificationSession } from '../types/session.js';\n\nimport type { ISessionStore } from './store.interface.js';\n\n/**\n * In-memory session store using a Map.\n * Suitable for development, testing, and single-process deployments.\n * Sessions are lost on process restart.\n */\nexport class InMemorySessionStore implements ISessionStore {\n private sessions = new Map<string, VerificationSession>();\n\n async get(id: string): Promise<VerificationSession | null> {\n return this.sessions.get(id) ?? null;\n }\n\n async set(session: VerificationSession): Promise<void> {\n this.sessions.set(session.id, session);\n }\n\n async delete(id: string): Promise<void> {\n this.sessions.delete(id);\n }\n}\n","import type { VerificationSession, VerificationResult } from '../types/session.js';\nimport { VerificationType } from '../types/verification.js';\n\nimport type { IVerificationMode } from './mode.interface.js';\n\nconst EU_COUNTRIES = [\n 'AT',\n 'BE',\n 'BG',\n 'HR',\n 'CY',\n 'CZ',\n 'DK',\n 'EE',\n 'FI',\n 'FR',\n 'DE',\n 'GR',\n 'HU',\n 'IE',\n 'IT',\n 'LV',\n 'LT',\n 'LU',\n 'MT',\n 'NL',\n 'PL',\n 'PT',\n 'RO',\n 'SK',\n 'SI',\n 'ES',\n 'SE',\n];\n\nexport interface DemoModeConfig {\n /** Delay in ms before auto-completion (default: 3000) */\n delayMs?: number;\n}\n\n/**\n * Demo mode — auto-completes verification with randomized EU data.\n * Used for product demos and landing page previews.\n */\nexport class DemoMode implements IVerificationMode {\n readonly name = 'demo';\n private delayMs: number;\n\n constructor(config: DemoModeConfig = {}) {\n this.delayMs = config.delayMs ?? 3000;\n }\n\n async processCallback(session: VerificationSession, _walletResponse: unknown): Promise<VerificationResult> {\n const country = this.pickCountry(session.countryWhitelist);\n return this.buildResult(session.type, country);\n }\n\n async simulateCompletion(session: VerificationSession): Promise<VerificationResult> {\n await new Promise((resolve) => setTimeout(resolve, this.delayMs));\n return this.processCallback(session, {});\n }\n\n private pickCountry(whitelist?: string[]): string {\n const pool = whitelist && whitelist.length > 0 ? whitelist : EU_COUNTRIES;\n return pool[Math.floor(Math.random() * pool.length)];\n }\n\n private buildResult(type: VerificationType, country: string): VerificationResult {\n const includeAge = type === VerificationType.AGE || type === VerificationType.BOTH;\n const includeCountry = type === VerificationType.COUNTRY || type === VerificationType.BOTH;\n\n return {\n verified: true,\n country,\n ageVerified: includeAge ? true : undefined,\n countryVerified: includeCountry ? true : undefined,\n };\n }\n}\n","import type { VerificationSession, VerificationResult } from '../types/session.js';\n\nimport type { IVerificationMode } from './mode.interface.js';\n\nexport interface MockModeConfig {\n /** Default result returned for all sessions (default: verified with DE) */\n defaultResult?: VerificationResult;\n /** Delay in ms before returning result (default: 0) */\n delayMs?: number;\n}\n\nconst DEFAULT_RESULT: VerificationResult = {\n verified: true,\n country: 'DE',\n ageVerified: true,\n countryVerified: true,\n};\n\n/**\n * Mock mode — configurable responses for integration testing.\n * Supports global defaults and per-session overrides.\n */\nexport class MockMode implements IVerificationMode {\n readonly name = 'mock';\n private defaultResult: VerificationResult;\n private delayMs: number;\n private sessionOverrides = new Map<string, VerificationResult>();\n\n constructor(config: MockModeConfig = {}) {\n this.defaultResult = config.defaultResult ?? { ...DEFAULT_RESULT };\n this.delayMs = config.delayMs ?? 0;\n }\n\n /** Set a per-session result override */\n setSessionResult(sessionId: string, result: VerificationResult): void {\n this.sessionOverrides.set(sessionId, result);\n }\n\n /** Clear a per-session result override */\n clearSessionResult(sessionId: string): void {\n this.sessionOverrides.delete(sessionId);\n }\n\n async processCallback(session: VerificationSession, _walletResponse: unknown): Promise<VerificationResult> {\n if (this.delayMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, this.delayMs));\n }\n return this.sessionOverrides.get(session.id) ?? { ...this.defaultResult };\n }\n\n async simulateCompletion(session: VerificationSession): Promise<VerificationResult> {\n return this.processCallback(session, {});\n }\n}\n","import { EventEmitter } from 'node:events';\n\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { SessionNotFoundError, SessionExpiredError } from './errors.js';\nimport type { IVerificationMode } from './modes/mode.interface.js';\nimport { InMemorySessionStore } from './storage/memory.store.js';\nimport type { ISessionStore } from './storage/store.interface.js';\nimport type { VerificationServiceConfig } from './types/config.js';\nimport type { VerificationSession, VerificationResult, CreateSessionInput } from './types/session.js';\nimport { VerificationStatus } from './types/verification.js';\n\nconst DEFAULT_TTL_MS = 300_000; // 5 minutes\nconst DEFAULT_WALLET_BASE_URL = 'openid4vp://verify';\n\n/**\n * EUDI Wallet verification session orchestrator.\n *\n * Manages the lifecycle of verification sessions: creation, status tracking,\n * wallet callback handling, expiration, and event emission.\n *\n * Transport-agnostic — consumers wire events to SSE, WebSocket, polling, etc.\n */\nexport class VerificationService extends EventEmitter {\n private store: ISessionStore;\n private mode: IVerificationMode;\n private sessionTtlMs: number;\n private walletBaseUrl: string;\n /** Track session IDs for cleanup (store interface has no list method) */\n private sessionIds = new Set<string>();\n\n constructor(config: VerificationServiceConfig) {\n super();\n this.mode = config.mode;\n this.store = config.store ?? new InMemorySessionStore();\n this.sessionTtlMs = config.sessionTtlMs ?? DEFAULT_TTL_MS;\n this.walletBaseUrl = config.walletBaseUrl ?? DEFAULT_WALLET_BASE_URL;\n }\n\n /**\n * Create a new verification session\n */\n async createSession(input: CreateSessionInput): Promise<VerificationSession> {\n const id = uuidv4();\n const now = new Date();\n\n const session: VerificationSession = {\n id,\n type: input.type,\n status: VerificationStatus.PENDING,\n walletUrl: '', // set below, may be async from mode\n countryWhitelist: input.countryWhitelist,\n countryBlacklist: input.countryBlacklist,\n redirectUrl: input.redirectUrl,\n metadata: input.metadata,\n createdAt: now,\n expiresAt: new Date(now.getTime() + this.sessionTtlMs),\n };\n\n session.walletUrl = this.mode.buildWalletUrl\n ? await this.mode.buildWalletUrl(id, input)\n : `${this.walletBaseUrl}?session=${id}`;\n\n await this.store.set(session);\n this.sessionIds.add(id);\n this.emit('session:created', session);\n\n // If mode supports auto-completion (DemoMode), trigger it in background\n if (this.mode.simulateCompletion) {\n this.mode\n .simulateCompletion(session)\n .then(async (result) => {\n // Only auto-complete if session is still pending\n const current = await this.store.get(id);\n if (current && current.status === VerificationStatus.PENDING) {\n await this.completeSession(current, result);\n }\n })\n .catch(() => {\n // Ignore simulation errors (session may have been completed manually)\n });\n }\n\n return session;\n }\n\n /**\n * Get a session by ID\n * @throws SessionNotFoundError\n */\n async getSession(id: string): Promise<VerificationSession> {\n const session = await this.store.get(id);\n if (!session) {\n throw new SessionNotFoundError(id);\n }\n return session;\n }\n\n /**\n * Handle a callback from the wallet\n * @throws SessionNotFoundError\n * @throws SessionExpiredError\n */\n async handleCallback(sessionId: string, walletResponse: unknown): Promise<VerificationResult> {\n const session = await this.store.get(sessionId);\n if (!session) {\n throw new SessionNotFoundError(sessionId);\n }\n if (new Date() > session.expiresAt) {\n throw new SessionExpiredError(sessionId);\n }\n\n const result = await this.mode.processCallback(session, walletResponse);\n await this.completeSession(session, result);\n return result;\n }\n\n /**\n * Remove expired sessions from the store\n * @returns Number of sessions cleaned up\n */\n async cleanupExpired(): Promise<number> {\n const now = new Date();\n let count = 0;\n\n for (const id of this.sessionIds) {\n const session = await this.store.get(id);\n if (!session) {\n this.sessionIds.delete(id);\n continue;\n }\n if (now > session.expiresAt && session.status === VerificationStatus.PENDING) {\n const expired = { ...session, status: VerificationStatus.EXPIRED };\n await this.store.set(expired);\n await this.store.delete(id);\n this.sessionIds.delete(id);\n this.emit('session:expired', expired);\n count++;\n }\n }\n\n return count;\n }\n\n private async completeSession(session: VerificationSession, result: VerificationResult): Promise<void> {\n const status = result.verified ? VerificationStatus.VERIFIED : VerificationStatus.REJECTED;\n const updated: VerificationSession = {\n ...session,\n status,\n completedAt: new Date(),\n result,\n };\n\n await this.store.set(updated);\n\n if (result.verified) {\n this.emit('session:verified', updated, result);\n } else {\n this.emit('session:rejected', updated, result.rejectionReason);\n }\n }\n}\n","// @openeudi/core — EUDI Wallet verification protocol engine\nexport const VERSION = '0.1.0';\n\n// Types\nexport { VerificationType, VerificationStatus } from './types/index.js';\n\nexport type {\n VerificationSession,\n VerificationResult,\n CreateSessionInput,\n VerificationServiceConfig,\n} from './types/index.js';\n\n// Errors\nexport { SessionNotFoundError, SessionExpiredError } from './errors.js';\n\n// Storage\nexport type { ISessionStore } from './storage/store.interface.js';\nexport { InMemorySessionStore } from './storage/memory.store.js';\n\n// Modes\nexport type { IVerificationMode } from './modes/mode.interface.js';\nexport { DemoMode } from './modes/demo.mode.js';\nexport type { DemoModeConfig } from './modes/demo.mode.js';\nexport { MockMode } from './modes/mock.mode.js';\nexport type { MockModeConfig } from './modes/mock.mode.js';\n\n// Service\nexport { VerificationService } from './verification.service.js';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/verification.ts","../src/errors.ts","../src/storage/memory.store.ts","../src/modes/demo.mode.ts","../src/modes/mock.mode.ts","../src/validation.ts","../src/verification.service.ts","../src/index.ts"],"names":["VerificationType","VerificationStatus","EventEmitter","uuidv4"],"mappings":"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A,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EAAM,IAAA;AAAA,EACtD,IAAA;AA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","file":"index.cjs","sourcesContent":["/**\n * Type of verification to perform\n */\nexport enum VerificationType {\n /** Verify age (over_18 attribute) */\n AGE = 'AGE',\n /** Verify country of residence */\n COUNTRY = 'COUNTRY',\n /** Verify both age and country */\n BOTH = 'BOTH',\n}\n\n/**\n * Status of a verification session.\n * SCANNED has been removed — the in-flight credential exchange state\n * is an internal wallet concern, not a session lifecycle stage.\n */\nexport enum VerificationStatus {\n /** Session created, waiting for wallet to initiate the flow */\n PENDING = 'PENDING',\n /** Verification completed successfully */\n VERIFIED = 'VERIFIED',\n /** Verification rejected (age, country, or policy failure) */\n REJECTED = 'REJECTED',\n /** Session expired before completion */\n EXPIRED = 'EXPIRED',\n}\n","/**\n * Thrown when a session ID is not found in the store\n */\nexport class SessionNotFoundError extends Error {\n constructor(sessionId: string) {\n super(`Session not found: ${sessionId}`);\n this.name = 'SessionNotFoundError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when an operation is attempted on an expired session\n */\nexport class SessionExpiredError extends Error {\n constructor(sessionId: string) {\n super(`Session expired: ${sessionId}`);\n this.name = 'SessionExpiredError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when an operation requires a session to be in PENDING status\n * but it is in a different status (e.g., cancelling an already-completed session).\n */\nexport class SessionNotPendingError extends Error {\n /** The session ID that was not in PENDING status */\n readonly sessionId: string;\n /** The status the session was actually in */\n readonly currentStatus: string;\n\n constructor(sessionId: string, currentStatus: string) {\n super(`Session ${sessionId} is not pending (current status: ${currentStatus})`);\n this.name = 'SessionNotPendingError';\n this.sessionId = sessionId;\n this.currentStatus = currentStatus;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when any method is called on a {@link VerificationService} instance\n * after {@link VerificationService.destroy} has been invoked.\n */\nexport class ServiceDestroyedError extends Error {\n constructor() {\n super('VerificationService has been destroyed and cannot accept new operations');\n this.name = 'ServiceDestroyedError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import type { VerificationSession } from '../types/session.js';\n\nimport type { ISessionStore } from './store.interface.js';\n\n/**\n * In-memory session store using a Map.\n * Suitable for development, testing, and single-process deployments.\n * Sessions are lost on process restart.\n */\nexport class InMemorySessionStore implements ISessionStore {\n private sessions = new Map<string, VerificationSession>();\n\n async get(id: string): Promise<VerificationSession | null> {\n return this.sessions.get(id) ?? null;\n }\n\n async set(session: VerificationSession): Promise<void> {\n this.sessions.set(session.id, session);\n }\n\n async delete(id: string): Promise<void> {\n this.sessions.delete(id);\n }\n}\n","import type { BaseSession, VerificationResult } from '../types/session.js';\nimport { VerificationType } from '../types/verification.js';\n\nimport type { IVerificationMode } from './mode.interface.js';\n\nconst EU_COUNTRIES = [\n 'AT',\n 'BE',\n 'BG',\n 'HR',\n 'CY',\n 'CZ',\n 'DK',\n 'EE',\n 'FI',\n 'FR',\n 'DE',\n 'GR',\n 'HU',\n 'IE',\n 'IT',\n 'LV',\n 'LT',\n 'LU',\n 'MT',\n 'NL',\n 'PL',\n 'PT',\n 'RO',\n 'SK',\n 'SI',\n 'ES',\n 'SE',\n];\n\nexport interface DemoModeConfig {\n /** Delay in ms before auto-completion (default: 3000) */\n delayMs?: number;\n}\n\n/**\n * Demo mode -- auto-completes verification with randomized EU data.\n * Used for product demos and landing page previews.\n */\nexport class DemoMode implements IVerificationMode {\n readonly name = 'demo';\n private delayMs: number;\n\n constructor(config: DemoModeConfig = {}) {\n this.delayMs = config.delayMs ?? 3000;\n }\n\n async processCallback(session: BaseSession, _walletResponse: unknown): Promise<VerificationResult> {\n const country = this.pickCountry(session.countryWhitelist);\n return this.buildResult(session.type, country);\n }\n\n async simulateCompletion(session: BaseSession): Promise<VerificationResult> {\n await new Promise((resolve) => setTimeout(resolve, this.delayMs));\n return this.processCallback(session, {});\n }\n\n private pickCountry(whitelist?: string[]): string {\n const pool = whitelist && whitelist.length > 0 ? whitelist : EU_COUNTRIES;\n return pool[Math.floor(Math.random() * pool.length)];\n }\n\n private buildResult(type: VerificationType, country: string): VerificationResult {\n const includeAge = type === VerificationType.AGE || type === VerificationType.BOTH;\n const includeCountry = type === VerificationType.COUNTRY || type === VerificationType.BOTH;\n\n return {\n verified: true,\n country,\n ageVerified: includeAge ? true : undefined,\n countryVerified: includeCountry ? true : undefined,\n };\n }\n}\n","import type { BaseSession, VerificationResult } from '../types/session.js';\n\nimport type { IVerificationMode } from './mode.interface.js';\n\nexport interface MockModeConfig {\n /** Default result returned for all sessions (default: verified with DE) */\n defaultResult?: VerificationResult;\n /** Delay in ms before returning result (default: 0) */\n delayMs?: number;\n}\n\nconst DEFAULT_RESULT: VerificationResult = {\n verified: true,\n country: 'DE',\n ageVerified: true,\n countryVerified: true,\n};\n\n/**\n * Mock mode -- configurable responses for integration testing.\n * Supports global defaults and per-session overrides.\n */\nexport class MockMode implements IVerificationMode {\n readonly name = 'mock';\n private defaultResult: VerificationResult;\n private delayMs: number;\n private sessionOverrides = new Map<string, VerificationResult>();\n\n constructor(config: MockModeConfig = {}) {\n this.defaultResult = config.defaultResult ?? { ...DEFAULT_RESULT };\n this.delayMs = config.delayMs ?? 0;\n }\n\n /** Set a per-session result override */\n setSessionResult(sessionId: string, result: VerificationResult): void {\n this.sessionOverrides.set(sessionId, result);\n }\n\n /** Clear a per-session result override */\n clearSessionResult(sessionId: string): void {\n this.sessionOverrides.delete(sessionId);\n }\n\n async processCallback(session: BaseSession, _walletResponse: unknown): Promise<VerificationResult> {\n if (this.delayMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, this.delayMs));\n }\n return this.sessionOverrides.get(session.id) ?? { ...this.defaultResult };\n }\n\n async simulateCompletion(session: BaseSession): Promise<VerificationResult> {\n return this.processCallback(session, {});\n }\n}\n","import type { VerificationServiceConfig } from './types/config.js';\nimport type { CreateSessionInput } from './types/session.js';\n\n/**\n * Complete set of ISO 3166-1 alpha-2 country codes (249 entries).\n * Used to validate country codes supplied in session inputs.\n *\n * Source: ISO 3166 Maintenance Agency\n * @see https://www.iso.org/iso-3166-country-codes.html\n */\nconst ISO_3166_1_ALPHA2: ReadonlySet<string> = new Set([\n 'AF', 'AX', 'AL', 'DZ', 'AS', 'AD', 'AO', 'AI', 'AQ', 'AG',\n 'AR', 'AM', 'AW', 'AU', 'AT', 'AZ', 'BS', 'BH', 'BD', 'BB',\n 'BY', 'BE', 'BZ', 'BJ', 'BM', 'BT', 'BO', 'BQ', 'BA', 'BW',\n 'BV', 'BR', 'IO', 'BN', 'BG', 'BF', 'BI', 'CV', 'KH', 'CM',\n 'CA', 'KY', 'CF', 'TD', 'CL', 'CN', 'CX', 'CC', 'CO', 'KM',\n 'CG', 'CD', 'CK', 'CR', 'CI', 'HR', 'CU', 'CW', 'CY', 'CZ',\n 'DK', 'DJ', 'DM', 'DO', 'EC', 'EG', 'SV', 'GQ', 'ER', 'EE',\n 'SZ', 'ET', 'FK', 'FO', 'FJ', 'FI', 'FR', 'GF', 'PF', 'TF',\n 'GA', 'GM', 'GE', 'DE', 'GH', 'GI', 'GR', 'GL', 'GD', 'GP',\n 'GU', 'GT', 'GG', 'GN', 'GW', 'GY', 'HT', 'HM', 'VA', 'HN',\n 'HK', 'HU', 'IS', 'IN', 'ID', 'IR', 'IQ', 'IE', 'IM', 'IL',\n 'IT', 'JM', 'JP', 'JE', 'JO', 'KZ', 'KE', 'KI', 'KP', 'KR',\n 'KW', 'KG', 'LA', 'LV', 'LB', 'LS', 'LR', 'LY', 'LI', 'LT',\n 'LU', 'MO', 'MG', 'MW', 'MY', 'MV', 'ML', 'MT', 'MH', 'MQ',\n 'MR', 'MU', 'YT', 'MX', 'FM', 'MD', 'MC', 'MN', 'ME', 'MS',\n 'MA', 'MZ', 'MM', 'NA', 'NR', 'NP', 'NL', 'NC', 'NZ', 'NI',\n 'NE', 'NG', 'NU', 'NF', 'MK', 'MP', 'NO', 'OM', 'PK', 'PW',\n 'PS', 'PA', 'PG', 'PY', 'PE', 'PH', 'PN', 'PL', 'PT', 'PR',\n 'QA', 'RE', 'RO', 'RU', 'RW', 'BL', 'SH', 'KN', 'LC', 'MF',\n 'PM', 'VC', 'WS', 'SM', 'ST', 'SA', 'SN', 'RS', 'SC', 'SL',\n 'SG', 'SX', 'SK', 'SI', 'SB', 'SO', 'ZA', 'GS', 'SS', 'ES',\n 'LK', 'SD', 'SR', 'SJ', 'SE', 'CH', 'SY', 'TW', 'TJ', 'TZ',\n 'TH', 'TL', 'TG', 'TK', 'TO', 'TT', 'TN', 'TR', 'TM', 'TC',\n 'TV', 'UG', 'UA', 'AE', 'GB', 'US', 'UM', 'UY', 'UZ', 'VU',\n 'VE', 'VN', 'VG', 'VI', 'WF', 'EH', 'YE', 'ZM', 'ZW',\n]);\n\n/**\n * Check whether a value is a valid ISO 3166-1 alpha-2 country code.\n *\n * The check is case-sensitive: codes must be uppercase two-letter strings\n * (e.g. `'DE'`, `'FR'`). Lowercase variants (`'de'`), three-letter codes\n * (`'DEU'`), empty strings, and unknown codes all return `false`.\n *\n * @param code - The string to validate\n * @returns `true` if `code` is a recognised ISO 3166-1 alpha-2 code\n *\n * @example\n * ```typescript\n * isValidCountryCode('DE'); // true\n * isValidCountryCode('de'); // false — must be uppercase\n * isValidCountryCode('DEU'); // false — alpha-3, not alpha-2\n * isValidCountryCode('XX'); // false — not a real country\n * ```\n */\nexport function isValidCountryCode(code: string): boolean {\n return ISO_3166_1_ALPHA2.has(code);\n}\n\n/**\n * Validate a {@link VerificationServiceConfig} object.\n *\n * Checks:\n * - `sessionTtlMs` must be a positive integer (if provided)\n * - `walletBaseUrl` must be a non-empty string (if provided)\n *\n * @param config - The configuration object to validate\n * @throws {Error} With a descriptive message if validation fails\n *\n * @example\n * ```typescript\n * validateConfig({ mode: demoMode, sessionTtlMs: -1 }); // throws\n * validateConfig({ mode: demoMode, sessionTtlMs: 60_000 }); // ok\n * ```\n */\nexport function validateConfig(config: Pick<VerificationServiceConfig, 'sessionTtlMs' | 'walletBaseUrl'>): void {\n if (config.sessionTtlMs !== undefined) {\n if (config.sessionTtlMs <= 0) {\n throw new Error(\n `sessionTtlMs must be a positive number, received: ${config.sessionTtlMs}`,\n );\n }\n }\n\n if (config.walletBaseUrl !== undefined) {\n if (config.walletBaseUrl.trim().length === 0) {\n throw new Error('walletBaseUrl must be a non-empty string');\n }\n }\n}\n\n/**\n * Validate a {@link CreateSessionInput} object before creating a session.\n *\n * Checks:\n * - `countryWhitelist` and `countryBlacklist` cannot both be provided\n * - All codes in `countryWhitelist` must be valid ISO 3166-1 alpha-2 codes\n * - All codes in `countryBlacklist` must be valid ISO 3166-1 alpha-2 codes\n *\n * @param input - The session creation input to validate\n * @throws {Error} With a descriptive message if validation fails\n *\n * @example\n * ```typescript\n * // Throws — cannot combine whitelist and blacklist\n * validateSessionInput({\n * type: VerificationType.AGE,\n * countryWhitelist: ['DE'],\n * countryBlacklist: ['FR'],\n * });\n *\n * // Throws — 'de' is not a valid alpha-2 code\n * validateSessionInput({ type: VerificationType.AGE, countryWhitelist: ['de'] });\n * ```\n */\nexport function validateSessionInput(input: CreateSessionInput): void {\n if (input.countryWhitelist !== undefined && input.countryBlacklist !== undefined) {\n throw new Error(\n 'countryWhitelist and countryBlacklist cannot both be provided; use one or the other',\n );\n }\n\n if (input.countryWhitelist !== undefined) {\n const invalid = input.countryWhitelist.filter((code) => !isValidCountryCode(code));\n if (invalid.length > 0) {\n throw new Error(\n `countryWhitelist contains invalid ISO 3166-1 alpha-2 codes: ${invalid.join(', ')}`,\n );\n }\n }\n\n if (input.countryBlacklist !== undefined) {\n const invalid = input.countryBlacklist.filter((code) => !isValidCountryCode(code));\n if (invalid.length > 0) {\n throw new Error(\n `countryBlacklist contains invalid ISO 3166-1 alpha-2 codes: ${invalid.join(', ')}`,\n );\n }\n }\n}\n","import { EventEmitter } from 'node:events';\n\nimport { v4 as uuidv4 } from 'uuid';\n\nimport {\n SessionNotFoundError,\n SessionExpiredError,\n SessionNotPendingError,\n ServiceDestroyedError,\n} from './errors.js';\nimport type { IVerificationMode } from './modes/mode.interface.js';\nimport { InMemorySessionStore } from './storage/memory.store.js';\nimport type { ISessionStore } from './storage/store.interface.js';\nimport type { VerificationServiceConfig } from './types/config.js';\nimport type { VerificationEvents } from './types/events.js';\nimport type {\n VerificationSession,\n VerificationResult,\n CreateSessionInput,\n PendingSession,\n CompletedSession,\n ExpiredSession,\n} from './types/session.js';\nimport { VerificationStatus } from './types/verification.js';\nimport { validateConfig, validateSessionInput } from './validation.js';\n\nconst DEFAULT_TTL_MS = 300_000; // 5 minutes\nconst DEFAULT_WALLET_BASE_URL = 'openid4vp://verify';\n\n/**\n * EUDI Wallet verification session orchestrator.\n *\n * Manages the lifecycle of verification sessions: creation, status tracking,\n * wallet callback handling, cancellation, expiration, and event emission.\n *\n * Transport-agnostic -- consumers wire events to SSE, WebSocket, polling, etc.\n *\n * @example\n * ```typescript\n * const service = new VerificationService({\n * mode: new DemoMode({ delayMs: 2000 }),\n * sessionTtlMs: 60_000,\n * });\n *\n * service.on('session:verified', (session, result) => {\n * console.log('Verified:', session.id, result.country);\n * });\n *\n * const session = await service.createSession({ type: VerificationType.AGE });\n * ```\n */\nexport class VerificationService extends EventEmitter {\n private store: ISessionStore;\n private mode: IVerificationMode;\n private sessionTtlMs: number;\n private walletBaseUrl: string;\n /** Track session IDs for cleanup (store interface has no list method) */\n private sessionIds = new Set<string>();\n /** Whether {@link destroy} has been called */\n private destroyed = false;\n\n /**\n * Create a new VerificationService instance.\n *\n * @param config - Service configuration including mode, store, TTL, and wallet URL\n * @throws {Error} If config.sessionTtlMs is not positive or config.walletBaseUrl is empty\n *\n * @example\n * ```typescript\n * const service = new VerificationService({\n * mode: new DemoMode(),\n * store: new InMemorySessionStore(),\n * sessionTtlMs: 300_000,\n * walletBaseUrl: 'openid4vp://verify',\n * });\n * ```\n */\n constructor(config: VerificationServiceConfig) {\n super();\n validateConfig(config);\n this.mode = config.mode;\n this.store = config.store ?? new InMemorySessionStore();\n this.sessionTtlMs = config.sessionTtlMs ?? DEFAULT_TTL_MS;\n this.walletBaseUrl = config.walletBaseUrl ?? DEFAULT_WALLET_BASE_URL;\n }\n\n // -----------------------------------------------------------------------\n // Typed EventEmitter overrides\n // -----------------------------------------------------------------------\n\n /**\n * Register a listener for a typed event.\n *\n * @param event - Event name from {@link VerificationEvents}\n * @param listener - Callback receiving the event's typed arguments\n * @returns this (for chaining)\n */\n on<K extends keyof VerificationEvents>(\n event: K,\n listener: (...args: VerificationEvents[K]) => void,\n ): this {\n return super.on(event, listener as (...args: unknown[]) => void);\n }\n\n /**\n * Register a one-time listener for a typed event.\n *\n * @param event - Event name from {@link VerificationEvents}\n * @param listener - Callback receiving the event's typed arguments (called at most once)\n * @returns this (for chaining)\n */\n once<K extends keyof VerificationEvents>(\n event: K,\n listener: (...args: VerificationEvents[K]) => void,\n ): this {\n return super.once(event, listener as (...args: unknown[]) => void);\n }\n\n /**\n * Remove a previously registered listener for a typed event.\n *\n * @param event - Event name from {@link VerificationEvents}\n * @param listener - The exact function reference that was registered\n * @returns this (for chaining)\n */\n off<K extends keyof VerificationEvents>(\n event: K,\n listener: (...args: VerificationEvents[K]) => void,\n ): this {\n return super.off(event, listener as (...args: unknown[]) => void);\n }\n\n /**\n * Emit a typed event.\n *\n * @param event - Event name from {@link VerificationEvents}\n * @param args - Arguments matching the event's type signature\n * @returns true if the event had listeners, false otherwise\n */\n emit<K extends keyof VerificationEvents>(\n event: K,\n ...args: VerificationEvents[K]\n ): boolean {\n return super.emit(event, ...args);\n }\n\n // -----------------------------------------------------------------------\n // Public API\n // -----------------------------------------------------------------------\n\n /**\n * Create a new verification session.\n *\n * Builds the wallet URL, persists the session, emits `session:created`,\n * and (if the mode supports it) kicks off background auto-completion.\n *\n * @param input - Session creation parameters (type, country filters, metadata)\n * @returns The newly created pending session with a populated walletUrl\n * @throws {ServiceDestroyedError} If the service has been destroyed\n * @throws {Error} If input validation fails (e.g. invalid country codes)\n * @emits session:created When the session is persisted\n *\n * @example\n * ```typescript\n * const session = await service.createSession({\n * type: VerificationType.AGE,\n * countryWhitelist: ['DE', 'FR'],\n * });\n * console.log(session.walletUrl); // 'openid4vp://verify?session=...'\n * ```\n */\n async createSession(input: CreateSessionInput): Promise<PendingSession> {\n this.assertNotDestroyed();\n validateSessionInput(input);\n\n const id = uuidv4();\n const now = new Date();\n\n // Build walletUrl BEFORE constructing the session object so\n // the session:created event always carries a non-empty walletUrl.\n const walletUrl = this.mode.buildWalletUrl\n ? await this.mode.buildWalletUrl(id, input)\n : `${this.walletBaseUrl}?session=${id}`;\n\n const session: PendingSession = {\n id,\n type: input.type,\n status: VerificationStatus.PENDING,\n walletUrl,\n countryWhitelist: input.countryWhitelist,\n countryBlacklist: input.countryBlacklist,\n redirectUrl: input.redirectUrl,\n metadata: input.metadata,\n createdAt: now,\n expiresAt: new Date(now.getTime() + this.sessionTtlMs),\n };\n\n await this.store.set(session);\n this.sessionIds.add(id);\n this.emit('session:created', session);\n\n // If mode supports auto-completion (DemoMode), trigger it in background\n if (this.mode.simulateCompletion) {\n this.mode\n .simulateCompletion(session)\n .then(async (result) => {\n // Only auto-complete if session is still pending\n const current = await this.store.get(id);\n if (current && current.status === VerificationStatus.PENDING) {\n await this.completeSession(current, result);\n }\n })\n .catch((error: unknown) => {\n // Emit error event instead of silently swallowing\n this.emit('error', error instanceof Error ? error : new Error(String(error)), id);\n });\n }\n\n return session;\n }\n\n /**\n * Retrieve a session by its ID.\n *\n * @param id - The session UUID to look up\n * @returns The session in its current state\n * @throws {ServiceDestroyedError} If the service has been destroyed\n * @throws {SessionNotFoundError} If no session exists with the given ID\n *\n * @example\n * ```typescript\n * const session = await service.getSession('550e8400-e29b-41d4-a716-446655440000');\n * if (session.status === VerificationStatus.VERIFIED) {\n * console.log('Already verified:', session.result);\n * }\n * ```\n */\n async getSession(id: string): Promise<VerificationSession> {\n this.assertNotDestroyed();\n const session = await this.store.get(id);\n if (!session) {\n throw new SessionNotFoundError(id);\n }\n return session;\n }\n\n /**\n * Handle a callback from the wallet containing credential data.\n *\n * Delegates to the mode's `processCallback` to evaluate the wallet response,\n * then transitions the session to VERIFIED or REJECTED.\n *\n * @param sessionId - The session UUID the callback belongs to\n * @param walletResponse - Raw credential data from the wallet\n * @returns The verification result\n * @throws {ServiceDestroyedError} If the service has been destroyed\n * @throws {SessionNotFoundError} If no session exists with the given ID\n * @throws {SessionExpiredError} If the session has passed its TTL\n * @emits session:verified When verification succeeds\n * @emits session:rejected When verification fails\n *\n * @example\n * ```typescript\n * const result = await service.handleCallback(sessionId, walletData);\n * if (result.verified) {\n * grantAccess(result.country);\n * }\n * ```\n */\n async handleCallback(sessionId: string, walletResponse: unknown): Promise<VerificationResult> {\n this.assertNotDestroyed();\n const session = await this.store.get(sessionId);\n if (!session) {\n throw new SessionNotFoundError(sessionId);\n }\n if (new Date() > session.expiresAt) {\n throw new SessionExpiredError(sessionId);\n }\n\n const result = await this.mode.processCallback(session, walletResponse);\n await this.completeSession(session, result);\n return result;\n }\n\n /**\n * Cancel a pending verification session.\n *\n * Only sessions in PENDING status can be cancelled. Completed or expired\n * sessions will cause a {@link SessionNotPendingError}.\n *\n * @param id - The session UUID to cancel\n * @throws {ServiceDestroyedError} If the service has been destroyed\n * @throws {SessionNotFoundError} If no session exists with the given ID\n * @throws {SessionNotPendingError} If the session is not in PENDING status\n * @emits session:cancelled When the session is removed\n *\n * @example\n * ```typescript\n * await service.cancelSession(session.id);\n * // session is now deleted from the store\n * ```\n */\n async cancelSession(id: string): Promise<void> {\n this.assertNotDestroyed();\n const session = await this.store.get(id);\n if (!session) {\n throw new SessionNotFoundError(id);\n }\n if (session.status !== VerificationStatus.PENDING) {\n throw new SessionNotPendingError(id, session.status);\n }\n\n await this.store.delete(id);\n this.sessionIds.delete(id);\n this.emit('session:cancelled', session);\n }\n\n /**\n * Remove expired sessions from the store.\n *\n * Iterates all tracked session IDs and transitions any pending session\n * whose TTL has elapsed to EXPIRED status before deleting it.\n *\n * @returns Number of sessions that were expired and removed\n * @throws {ServiceDestroyedError} If the service has been destroyed\n * @emits session:expired For each session that is expired\n *\n * @example\n * ```typescript\n * // Run periodically (e.g. every 60 seconds)\n * const count = await service.cleanupExpired();\n * console.log(`Cleaned up ${count} expired sessions`);\n * ```\n */\n async cleanupExpired(): Promise<number> {\n this.assertNotDestroyed();\n const now = new Date();\n let count = 0;\n\n for (const id of this.sessionIds) {\n const session = await this.store.get(id);\n if (!session) {\n this.sessionIds.delete(id);\n continue;\n }\n if (now > session.expiresAt && session.status === VerificationStatus.PENDING) {\n const expired: ExpiredSession = {\n ...session,\n status: VerificationStatus.EXPIRED,\n completedAt: now,\n };\n await this.store.set(expired);\n await this.store.delete(id);\n this.sessionIds.delete(id);\n this.emit('session:expired', expired);\n count++;\n }\n }\n\n return count;\n }\n\n /**\n * Permanently destroy this service instance.\n *\n * Removes all event listeners, clears tracked session IDs, and marks\n * the instance as destroyed. All subsequent public method calls will\n * throw {@link ServiceDestroyedError}.\n *\n * @example\n * ```typescript\n * service.destroy();\n * // Any further call throws ServiceDestroyedError\n * await service.createSession({ type: VerificationType.AGE }); // throws\n * ```\n */\n destroy(): void {\n this.removeAllListeners();\n this.sessionIds.clear();\n this.destroyed = true;\n }\n\n // -----------------------------------------------------------------------\n // Private helpers\n // -----------------------------------------------------------------------\n\n /**\n * Guard that throws if the service has been destroyed.\n * Called at the top of every public method.\n */\n private assertNotDestroyed(): void {\n if (this.destroyed) {\n throw new ServiceDestroyedError();\n }\n }\n\n /**\n * Transition a session to VERIFIED or REJECTED and emit the appropriate event.\n */\n private async completeSession(session: VerificationSession, result: VerificationResult): Promise<void> {\n const status = result.verified ? VerificationStatus.VERIFIED : VerificationStatus.REJECTED;\n const updated: CompletedSession = {\n ...session,\n status,\n completedAt: new Date(),\n result,\n };\n\n await this.store.set(updated);\n this.sessionIds.delete(session.id);\n\n if (result.verified) {\n this.emit('session:verified', updated, result);\n } else {\n this.emit('session:rejected', updated, result.rejectionReason ?? '');\n }\n }\n}\n","// @openeudi/core -- EUDI Wallet verification protocol engine\nexport const VERSION = '0.2.0';\n\n// Types\nexport { VerificationType, VerificationStatus } from './types/index.js';\nexport type {\n VerificationSession,\n VerificationResult,\n CreateSessionInput,\n VerificationServiceConfig,\n BaseSession,\n PendingSession,\n CompletedSession,\n ExpiredSession,\n VerificationEvents,\n} from './types/index.js';\n\n// Errors\nexport {\n SessionNotFoundError,\n SessionExpiredError,\n SessionNotPendingError,\n ServiceDestroyedError,\n} from './errors.js';\n\n// Storage\nexport type { ISessionStore } from './storage/store.interface.js';\nexport { InMemorySessionStore } from './storage/memory.store.js';\n\n// Modes\nexport type { IVerificationMode } from './modes/mode.interface.js';\nexport { DemoMode } from './modes/demo.mode.js';\nexport type { DemoModeConfig } from './modes/demo.mode.js';\nexport { MockMode } from './modes/mock.mode.js';\nexport type { MockModeConfig } from './modes/mock.mode.js';\n\n// Validation\nexport { isValidCountryCode } from './validation.js';\n\n// Service\nexport { VerificationService } from './verification.service.js';\n"]}
|