@pcircle/evidencemcp-server 0.1.1 → 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/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/crypto/decrypt.d.ts +11 -0
- package/dist/lib/crypto/decrypt.d.ts.map +1 -0
- package/dist/lib/crypto/decrypt.js +30 -0
- package/dist/lib/crypto/decrypt.js.map +1 -0
- package/dist/lib/crypto/encrypt.d.ts +13 -0
- package/dist/lib/crypto/encrypt.d.ts.map +1 -0
- package/dist/lib/crypto/encrypt.js +24 -0
- package/dist/lib/crypto/encrypt.js.map +1 -0
- package/dist/lib/crypto/index.d.ts +6 -0
- package/dist/lib/crypto/index.d.ts.map +1 -0
- package/dist/lib/crypto/index.js +5 -0
- package/dist/lib/crypto/index.js.map +1 -0
- package/dist/lib/crypto/key-derivation.d.ts +30 -0
- package/dist/lib/crypto/key-derivation.d.ts.map +1 -0
- package/dist/lib/crypto/key-derivation.js +63 -0
- package/dist/lib/crypto/key-derivation.js.map +1 -0
- package/dist/lib/crypto/types.d.ts +22 -0
- package/dist/lib/crypto/types.d.ts.map +1 -0
- package/dist/lib/crypto/types.js +10 -0
- package/dist/lib/crypto/types.js.map +1 -0
- package/dist/lib/storage/database.d.ts +66 -0
- package/dist/lib/storage/database.d.ts.map +1 -0
- package/dist/lib/storage/database.js +195 -0
- package/dist/lib/storage/database.js.map +1 -0
- package/dist/lib/storage/export.d.ts +26 -0
- package/dist/lib/storage/export.d.ts.map +1 -0
- package/dist/lib/storage/export.js +113 -0
- package/dist/lib/storage/export.js.map +1 -0
- package/dist/lib/storage/git.d.ts +16 -0
- package/dist/lib/storage/git.d.ts.map +1 -0
- package/dist/lib/storage/git.js +55 -0
- package/dist/lib/storage/git.js.map +1 -0
- package/dist/lib/storage/index.d.ts +6 -0
- package/dist/lib/storage/index.d.ts.map +1 -0
- package/dist/lib/storage/index.js +5 -0
- package/dist/lib/storage/index.js.map +1 -0
- package/dist/lib/storage/schema.d.ts +17 -0
- package/dist/lib/storage/schema.d.ts.map +1 -0
- package/dist/lib/storage/schema.js +103 -0
- package/dist/lib/storage/schema.js.map +1 -0
- package/dist/lib/storage/types.d.ts +26 -0
- package/dist/lib/storage/types.d.ts.map +1 -0
- package/dist/lib/storage/types.js +2 -0
- package/dist/lib/storage/types.js.map +1 -0
- package/package.json +7 -3
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
-
import { EvidenceDatabase, getCurrentCommit } from '
|
|
5
|
-
import { deriveKey, encrypt, decrypt } from '
|
|
4
|
+
import { EvidenceDatabase, getCurrentCommit } from './lib/storage/index.js';
|
|
5
|
+
import { deriveKey, encrypt, decrypt } from './lib/crypto/index.js';
|
|
6
6
|
import * as z from 'zod';
|
|
7
7
|
import * as crypto from 'crypto';
|
|
8
8
|
function getErrorMessage(error) {
|
|
@@ -153,7 +153,7 @@ export class EvidenceMCPServer {
|
|
|
153
153
|
}
|
|
154
154
|
}, async (params) => {
|
|
155
155
|
try {
|
|
156
|
-
const { exportEvidences } = await import('
|
|
156
|
+
const { exportEvidences } = await import('./lib/storage/index.js');
|
|
157
157
|
const fs = await import('fs');
|
|
158
158
|
const result = await exportEvidences(this.db, {
|
|
159
159
|
evidenceIds: params.evidenceIds,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAGjC,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IACpB,MAAM,CAAY;IAClB,MAAM,CAAe;IACrB,EAAE,CAAmB;IACrB,UAAU,GAAsB,IAAI,CAAC;IAE7C,YAAY,MAAoB;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,kCAAkC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC;YAC1B,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,gBAAgB;YACrC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO;SACnC,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACrD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC;QAC/B,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAEO,aAAa;QACnB,IAAI,CAAC,MAAM,CAAC,YAAY,CACtB,kBAAkB,EAClB;YACE,KAAK,EAAE,kBAAkB;YACzB,WAAW,EAAE,kDAAkD;YAC/D,WAAW,EAAE;gBACX,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;gBACtD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;gBAC/E,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;gBACnF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;gBACxE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;aACxE;YACD,YAAY,EAAE;gBACZ,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;gBACd,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;gBACrB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBACpC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;aACrB;SACF,EACD,KAAK,EAAE,MAA6B,EAAE,EAAE;YACtC,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1D,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;gBAC7C,CAAC;gBACD,IAAI,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,CAAC;oBAC7B,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBACpD,CAAC;gBAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvC,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACrD,MAAM,OAAO,GAAG,MAAM,gBAAgB,EAAE,CAAC;gBACzC,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAErF,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;oBACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACnC,cAAc,EAAE,MAAM,CAAC,cAAc;oBACrC,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,gBAAgB,EAAE,SAAS,CAAC,UAAU;oBACtC,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,WAAW;oBACX,YAAY,EAAE,MAAM,CAAC,YAAY;oBACjC,aAAa,EAAE,OAAO,EAAE,UAAU,IAAI,IAAI;oBAC1C,YAAY,EAAE,OAAO,EAAE,SAAS,IAAI,IAAI;oBACxC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI;iBAC1B,CAAC,CAAC;gBAEH,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,uCAAuC,EAAE,EAAE,EAAE,CAAC;oBAC9E,iBAAiB,EAAE;wBACjB,EAAE;wBACF,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBACnC,aAAa,EAAE,OAAO,EAAE,UAAU,IAAI,IAAI;wBAC1C,OAAO,EAAE,IAAI;qBACd;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,4BAA4B,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,YAAY,CACtB,gBAAgB,EAChB;YACE,KAAK,EAAE,gBAAgB;YACvB,WAAW,EAAE,4CAA4C;YACzD,WAAW,EAAE;gBACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;gBACzE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;aACzE;YACD,YAAY,EAAE;gBACZ,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;oBAC1B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;oBACd,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;oBACrB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;oBAC1B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;oBACvB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;oBACxB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;iBAC5B,CAAC,CAAC;gBACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;aAClB;SACF,EACD,KAAK,EAAE,MAA2C,EAAE,EAAE;YACpD,IAAI,CAAC;gBACH,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;oBACpD,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;gBAC5C,CAAC;gBACD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACrD,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;gBAC/C,CAAC;gBAED,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC/E,MAAM,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBAC1C,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,SAAS,EAAE,CAAC,CAAC,SAAS;oBACtB,cAAc,EAAE,CAAC,CAAC,cAAc;oBAChC,WAAW,EAAE,CAAC,CAAC,WAAW;oBAC1B,YAAY,EAAE,CAAC,CAAC,YAAY;oBAC5B,IAAI,EAAE,CAAC,CAAC,IAAI;iBACb,CAAC,CAAC,CAAC;gBAEJ,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,SAAS,CAAC,MAAM,cAAc,EAAE,CAAC;oBAC1E,iBAAiB,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE;iBAC3E,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,YAAY,CACtB,kBAAkB,EAClB;YACE,KAAK,EAAE,kBAAkB;YACzB,WAAW,EAAE,2CAA2C;YACxD,WAAW,EAAE;gBACX,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;gBAClF,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;aAC1E;YACD,YAAY,EAAE;gBACZ,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;gBACpB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;gBACpB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;gBACzB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;aACrB;SACF,EACD,KAAK,EAAE,MAA4D,EAAE,EAAE;YACrE,IAAI,CAAC;gBACH,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;gBACnE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;gBAE9B,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE;oBAC5C,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,KAAK;iBAC/C,CAAC,CAAC;gBAEH,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;gBAElD,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,MAAM,CAAC,aAAa,mBAAmB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;oBACvG,iBAAiB,EAAE;wBACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;wBACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;wBACzB,aAAa,EAAE,MAAM,CAAC,aAAa;wBACnC,OAAO,EAAE,IAAI;qBACd;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,4BAA4B,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,YAAY,CACtB,cAAc,EACd;YACE,KAAK,EAAE,cAAc;YACrB,WAAW,EAAE,8CAA8C;YAC3D,WAAW,EAAE;gBACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;aACvC;YACD,YAAY,EAAE;gBACZ,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;gBACd,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;gBACrB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;gBAC1B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;gBACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;gBACnB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;gBACxB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;oBAChB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;oBACtB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;iBACtB,CAAC,CAAC,QAAQ,EAAE;gBACb,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;aAC5B;SACF,EACD,KAAK,EAAE,MAAsB,EAAE,EAAE;YAC/B,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtD,CAAC;gBAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvC,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBAE1E,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa;oBACpC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,aAAa,EAAE,SAAS,EAAE,QAAQ,CAAC,YAAa,EAAE;oBAC3E,CAAC,CAAC,IAAI,CAAC;gBAET,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,QAAQ,CAAC,EAAE,cAAc,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;oBAC5G,iBAAiB,EAAE;wBACjB,EAAE,EAAE,QAAQ,CAAC,EAAE;wBACf,SAAS,EAAE,QAAQ,CAAC,SAAS;wBAC7B,cAAc,EAAE,QAAQ,CAAC,cAAc;wBACvC,WAAW,EAAE,QAAQ,CAAC,WAAW;wBACjC,OAAO,EAAE,SAAS;wBAClB,YAAY,EAAE,QAAQ,CAAC,YAAY;wBACnC,OAAO;wBACP,IAAI,EAAE,QAAQ,CAAC,IAAI;qBACpB;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,wBAAwB,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACpE,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;IAEO,iBAAiB;QACvB,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAC1B,UAAU,EACV,IAAI,gBAAgB,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAC5D;YACE,KAAK,EAAE,kBAAkB;YACzB,WAAW,EAAE,wCAAwC;YACrD,QAAQ,EAAE,YAAY;SACvB,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;YACpB,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAY,CAAC,CAAC;gBAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,MAAM,IAAI,KAAK,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAAC;gBACtD,CAAC;gBAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvC,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBAE1E,OAAO;oBACL,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;iBACvE,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,uCAAuC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACnF,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;CACF;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAiB;QAC3B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,eAAe;QAC1D,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE;KACjD,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decrypt ciphertext using XChaCha20-Poly1305 AEAD
|
|
3
|
+
*
|
|
4
|
+
* @param ciphertext - Encrypted data
|
|
5
|
+
* @param nonce - 24-byte nonce used during encryption
|
|
6
|
+
* @param key - 32-byte encryption key
|
|
7
|
+
* @returns Decrypted plaintext
|
|
8
|
+
* @throws Error if authentication fails or key is wrong
|
|
9
|
+
*/
|
|
10
|
+
export declare function decrypt(ciphertext: Uint8Array, nonce: Uint8Array, key: Uint8Array): string;
|
|
11
|
+
//# sourceMappingURL=decrypt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decrypt.d.ts","sourceRoot":"","sources":["../../../src/lib/crypto/decrypt.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CACrB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,UAAU,GACd,MAAM,CAqBR"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { xchacha20poly1305 } from '@noble/ciphers/chacha';
|
|
2
|
+
/**
|
|
3
|
+
* Decrypt ciphertext using XChaCha20-Poly1305 AEAD
|
|
4
|
+
*
|
|
5
|
+
* @param ciphertext - Encrypted data
|
|
6
|
+
* @param nonce - 24-byte nonce used during encryption
|
|
7
|
+
* @param key - 32-byte encryption key
|
|
8
|
+
* @returns Decrypted plaintext
|
|
9
|
+
* @throws Error if authentication fails or key is wrong
|
|
10
|
+
*/
|
|
11
|
+
export function decrypt(ciphertext, nonce, key) {
|
|
12
|
+
if (key.length !== 32) {
|
|
13
|
+
throw new Error('Key must be 32 bytes');
|
|
14
|
+
}
|
|
15
|
+
if (nonce.length !== 24) {
|
|
16
|
+
throw new Error('Nonce must be 24 bytes');
|
|
17
|
+
}
|
|
18
|
+
// Create cipher instance
|
|
19
|
+
const cipher = xchacha20poly1305(key, nonce);
|
|
20
|
+
try {
|
|
21
|
+
// Decrypt and verify authentication tag
|
|
22
|
+
const plaintextBytes = cipher.decrypt(ciphertext);
|
|
23
|
+
// Convert bytes back to string
|
|
24
|
+
return new TextDecoder().decode(plaintextBytes);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw new Error('Decryption failed: invalid key or tampered data');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=decrypt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decrypt.js","sourceRoot":"","sources":["../../../src/lib/crypto/decrypt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CACrB,UAAsB,EACtB,KAAiB,EACjB,GAAe;IAEf,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IAED,yBAAyB;IACzB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE7C,IAAI,CAAC;QACH,wCAAwC;QACxC,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAElD,+BAA+B;QAC/B,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface EncryptedData {
|
|
2
|
+
ciphertext: Uint8Array;
|
|
3
|
+
nonce: Uint8Array;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Encrypt plaintext using XChaCha20-Poly1305 AEAD
|
|
7
|
+
*
|
|
8
|
+
* @param plaintext - Text to encrypt
|
|
9
|
+
* @param key - 32-byte encryption key
|
|
10
|
+
* @returns Encrypted data with nonce
|
|
11
|
+
*/
|
|
12
|
+
export declare function encrypt(plaintext: string, key: Uint8Array): EncryptedData;
|
|
13
|
+
//# sourceMappingURL=encrypt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encrypt.d.ts","sourceRoot":"","sources":["../../../src/lib/crypto/encrypt.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,aAAa,CAkBzE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { xchacha20poly1305 } from '@noble/ciphers/chacha';
|
|
2
|
+
import { randomBytes } from '@noble/hashes/utils';
|
|
3
|
+
/**
|
|
4
|
+
* Encrypt plaintext using XChaCha20-Poly1305 AEAD
|
|
5
|
+
*
|
|
6
|
+
* @param plaintext - Text to encrypt
|
|
7
|
+
* @param key - 32-byte encryption key
|
|
8
|
+
* @returns Encrypted data with nonce
|
|
9
|
+
*/
|
|
10
|
+
export function encrypt(plaintext, key) {
|
|
11
|
+
if (key.length !== 32) {
|
|
12
|
+
throw new Error('Key must be 32 bytes');
|
|
13
|
+
}
|
|
14
|
+
// Generate random 24-byte nonce (XChaCha20 extended nonce)
|
|
15
|
+
const nonce = randomBytes(24);
|
|
16
|
+
// Convert plaintext to bytes
|
|
17
|
+
const plaintextBytes = new TextEncoder().encode(plaintext);
|
|
18
|
+
// Create cipher instance
|
|
19
|
+
const cipher = xchacha20poly1305(key, nonce);
|
|
20
|
+
// Encrypt with authentication
|
|
21
|
+
const ciphertext = cipher.encrypt(plaintextBytes);
|
|
22
|
+
return { ciphertext, nonce };
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=encrypt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encrypt.js","sourceRoot":"","sources":["../../../src/lib/crypto/encrypt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOlD;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,SAAiB,EAAE,GAAe;IACxD,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,2DAA2D;IAC3D,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAE9B,6BAA6B;IAC7B,MAAM,cAAc,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAE3D,yBAAyB;IACzB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE7C,8BAA8B;IAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAElD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { deriveKey, verifyKey } from './key-derivation.js';
|
|
2
|
+
export { encrypt } from './encrypt.js';
|
|
3
|
+
export { decrypt } from './decrypt.js';
|
|
4
|
+
export type { DerivedKey, KeyDerivationParams, EncryptedData } from './types.js';
|
|
5
|
+
export { DEFAULT_KDF_PARAMS } from './types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DerivedKey, KeyDerivationParams } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Derive encryption key from password using Argon2id
|
|
4
|
+
*
|
|
5
|
+
* @param password - User password (must not be empty)
|
|
6
|
+
* @param params - Optional KDF parameters (uses OWASP defaults)
|
|
7
|
+
* @returns Derived key and salt
|
|
8
|
+
*
|
|
9
|
+
* @security When comparing derived keys for authentication,
|
|
10
|
+
* use constant-time comparison to prevent timing attacks:
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { timingSafeEqual } from 'node:crypto';
|
|
14
|
+
*
|
|
15
|
+
* const derived = await deriveKey('password');
|
|
16
|
+
* // SECURE - constant-time comparison
|
|
17
|
+
* const match = timingSafeEqual(derived.key, storedKey);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function deriveKey(password: string, params?: Partial<KeyDerivationParams>): Promise<DerivedKey>;
|
|
21
|
+
/**
|
|
22
|
+
* Re-derive key from password and existing salt (for verification)
|
|
23
|
+
*
|
|
24
|
+
* @param password - User password
|
|
25
|
+
* @param salt - Existing salt (from previous derivation)
|
|
26
|
+
* @param params - Optional KDF parameters
|
|
27
|
+
* @returns Derived key with same salt
|
|
28
|
+
*/
|
|
29
|
+
export declare function verifyKey(password: string, salt: Uint8Array, params?: Partial<KeyDerivationParams>): Promise<DerivedKey>;
|
|
30
|
+
//# sourceMappingURL=key-derivation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-derivation.d.ts","sourceRoot":"","sources":["../../../src/lib/crypto/key-derivation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGlE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACxC,OAAO,CAAC,UAAU,CAAC,CAuBrB;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACxC,OAAO,CAAC,UAAU,CAAC,CAwBrB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { argon2id } from '@noble/hashes/argon2';
|
|
2
|
+
import { randomBytes } from '@noble/hashes/utils';
|
|
3
|
+
import { DEFAULT_KDF_PARAMS } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Derive encryption key from password using Argon2id
|
|
6
|
+
*
|
|
7
|
+
* @param password - User password (must not be empty)
|
|
8
|
+
* @param params - Optional KDF parameters (uses OWASP defaults)
|
|
9
|
+
* @returns Derived key and salt
|
|
10
|
+
*
|
|
11
|
+
* @security When comparing derived keys for authentication,
|
|
12
|
+
* use constant-time comparison to prevent timing attacks:
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { timingSafeEqual } from 'node:crypto';
|
|
16
|
+
*
|
|
17
|
+
* const derived = await deriveKey('password');
|
|
18
|
+
* // SECURE - constant-time comparison
|
|
19
|
+
* const match = timingSafeEqual(derived.key, storedKey);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export async function deriveKey(password, params = {}) {
|
|
23
|
+
if (!password || password.length === 0) {
|
|
24
|
+
throw new Error('Password cannot be empty');
|
|
25
|
+
}
|
|
26
|
+
const kdfParams = { ...DEFAULT_KDF_PARAMS, ...params };
|
|
27
|
+
// Generate random salt (16 bytes)
|
|
28
|
+
const salt = randomBytes(16);
|
|
29
|
+
// Derive key using Argon2id
|
|
30
|
+
const key = argon2id(password, salt, {
|
|
31
|
+
m: kdfParams.memory,
|
|
32
|
+
t: kdfParams.iterations,
|
|
33
|
+
p: kdfParams.parallelism,
|
|
34
|
+
dkLen: kdfParams.keyLength,
|
|
35
|
+
});
|
|
36
|
+
return { key, salt };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Re-derive key from password and existing salt (for verification)
|
|
40
|
+
*
|
|
41
|
+
* @param password - User password
|
|
42
|
+
* @param salt - Existing salt (from previous derivation)
|
|
43
|
+
* @param params - Optional KDF parameters
|
|
44
|
+
* @returns Derived key with same salt
|
|
45
|
+
*/
|
|
46
|
+
export async function verifyKey(password, salt, params = {}) {
|
|
47
|
+
if (!password || password.length === 0) {
|
|
48
|
+
throw new Error('Password cannot be empty');
|
|
49
|
+
}
|
|
50
|
+
const kdfParams = { ...DEFAULT_KDF_PARAMS, ...params };
|
|
51
|
+
if (salt.length !== 16) {
|
|
52
|
+
throw new Error('Salt must be 16 bytes');
|
|
53
|
+
}
|
|
54
|
+
// Re-derive key using same salt
|
|
55
|
+
const key = argon2id(password, salt, {
|
|
56
|
+
m: kdfParams.memory,
|
|
57
|
+
t: kdfParams.iterations,
|
|
58
|
+
p: kdfParams.parallelism,
|
|
59
|
+
dkLen: kdfParams.keyLength,
|
|
60
|
+
});
|
|
61
|
+
return { key, salt };
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=key-derivation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-derivation.js","sourceRoot":"","sources":["../../../src/lib/crypto/key-derivation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,QAAgB,EAChB,SAAuC,EAAE;IAEzC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,SAAS,GAAG,EAAE,GAAG,kBAAkB,EAAE,GAAG,MAAM,EAAE,CAAC;IAEvD,kCAAkC;IAClC,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAE7B,4BAA4B;IAC5B,MAAM,GAAG,GAAG,QAAQ,CAClB,QAAQ,EACR,IAAI,EACJ;QACE,CAAC,EAAE,SAAS,CAAC,MAAM;QACnB,CAAC,EAAE,SAAS,CAAC,UAAU;QACvB,CAAC,EAAE,SAAS,CAAC,WAAW;QACxB,KAAK,EAAE,SAAS,CAAC,SAAS;KAC3B,CACF,CAAC;IAEF,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,QAAgB,EAChB,IAAgB,EAChB,SAAuC,EAAE;IAEzC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,SAAS,GAAG,EAAE,GAAG,kBAAkB,EAAE,GAAG,MAAM,EAAE,CAAC;IAEvD,IAAI,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,gCAAgC;IAChC,MAAM,GAAG,GAAG,QAAQ,CAClB,QAAQ,EACR,IAAI,EACJ;QACE,CAAC,EAAE,SAAS,CAAC,MAAM;QACnB,CAAC,EAAE,SAAS,CAAC,UAAU;QACvB,CAAC,EAAE,SAAS,CAAC,WAAW;QACxB,KAAK,EAAE,SAAS,CAAC,SAAS;KAC3B,CACF,CAAC;IAEF,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encryption key derived from user password
|
|
3
|
+
*/
|
|
4
|
+
export interface DerivedKey {
|
|
5
|
+
key: Uint8Array;
|
|
6
|
+
salt: Uint8Array;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Parameters for Argon2 key derivation
|
|
10
|
+
*/
|
|
11
|
+
export interface KeyDerivationParams {
|
|
12
|
+
memory: number;
|
|
13
|
+
iterations: number;
|
|
14
|
+
parallelism: number;
|
|
15
|
+
keyLength: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Default Argon2id parameters (OWASP recommended)
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEFAULT_KDF_PARAMS: KeyDerivationParams;
|
|
21
|
+
export type { EncryptedData } from './encrypt.js';
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/crypto/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,UAAU,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,mBAKhC,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/crypto/types.ts"],"names":[],"mappings":"AAkBA;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAwB;IACrD,MAAM,EAAE,KAAK,EAAO,QAAQ;IAC5B,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,CAAC;IACd,SAAS,EAAE,EAAE;CACd,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Evidence } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Evidence database with CRUD operations
|
|
4
|
+
* Manages encrypted evidence storage with SQLite backend
|
|
5
|
+
*/
|
|
6
|
+
export declare class EvidenceDatabase {
|
|
7
|
+
private db;
|
|
8
|
+
/**
|
|
9
|
+
* Creates or opens an evidence database
|
|
10
|
+
* @param dbPath - Path to SQLite database file
|
|
11
|
+
*/
|
|
12
|
+
constructor(dbPath: string);
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new evidence record
|
|
15
|
+
* @param evidence - Evidence data without id, createdAt, updatedAt
|
|
16
|
+
* @returns UUID of created evidence
|
|
17
|
+
*/
|
|
18
|
+
create(evidence: Omit<Evidence, 'id' | 'createdAt' | 'updatedAt'>): string;
|
|
19
|
+
/**
|
|
20
|
+
* Finds evidence by ID
|
|
21
|
+
* @param id - Evidence UUID
|
|
22
|
+
* @returns Evidence or null if not found
|
|
23
|
+
*/
|
|
24
|
+
findById(id: string): Evidence | null;
|
|
25
|
+
/**
|
|
26
|
+
* Finds all evidences for a conversation
|
|
27
|
+
* @param conversationId - Conversation identifier
|
|
28
|
+
* @returns Array of evidences (empty if none found)
|
|
29
|
+
*/
|
|
30
|
+
findByConversationId(conversationId: string): Evidence[];
|
|
31
|
+
/**
|
|
32
|
+
* Lists evidences with pagination
|
|
33
|
+
* @param options - Pagination options (limit, offset)
|
|
34
|
+
* @returns Array of evidences
|
|
35
|
+
*/
|
|
36
|
+
list(options?: {
|
|
37
|
+
limit?: number;
|
|
38
|
+
offset?: number;
|
|
39
|
+
}): Evidence[];
|
|
40
|
+
/**
|
|
41
|
+
* Updates git commit information for an evidence
|
|
42
|
+
* @param id - Evidence UUID
|
|
43
|
+
* @param gitCommitHash - Git commit hash
|
|
44
|
+
* @param gitTimestamp - Git commit timestamp (ISO 8601)
|
|
45
|
+
*/
|
|
46
|
+
updateGitInfo(id: string, gitCommitHash: string, gitTimestamp: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Adds tags to an evidence (appends to existing tags)
|
|
49
|
+
* @param id - Evidence UUID
|
|
50
|
+
* @param tags - Array of tags to add
|
|
51
|
+
*/
|
|
52
|
+
addTags(id: string, tags: string[]): void;
|
|
53
|
+
/**
|
|
54
|
+
* Closes the database connection
|
|
55
|
+
* Should be called when done with the database
|
|
56
|
+
*/
|
|
57
|
+
close(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Converts database row to Evidence object
|
|
60
|
+
* Handles BLOB to Uint8Array conversion
|
|
61
|
+
* @param row - Raw database row
|
|
62
|
+
* @returns Evidence object
|
|
63
|
+
*/
|
|
64
|
+
private rowToEvidence;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/database.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAqB3C;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,EAAE,CAAoB;IAE9B;;;OAGG;gBACS,MAAM,EAAE,MAAM;IAK1B;;;;OAIG;IACH,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG,MAAM;IAmC1E;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAkBrC;;;;OAIG;IACH,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,QAAQ,EAAE;IAiBxD;;;;OAIG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,QAAQ,EAAE;IA4B/D;;;;;OAKG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAoB5E;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IA4BzC;;;OAGG;IACH,KAAK,IAAI,IAAI;IAIb;;;;;OAKG;IACH,OAAO,CAAC,aAAa;CAiBtB"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { createSchema } from './schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Evidence database with CRUD operations
|
|
5
|
+
* Manages encrypted evidence storage with SQLite backend
|
|
6
|
+
*/
|
|
7
|
+
export class EvidenceDatabase {
|
|
8
|
+
db;
|
|
9
|
+
/**
|
|
10
|
+
* Creates or opens an evidence database
|
|
11
|
+
* @param dbPath - Path to SQLite database file
|
|
12
|
+
*/
|
|
13
|
+
constructor(dbPath) {
|
|
14
|
+
this.db = new Database(dbPath);
|
|
15
|
+
createSchema(this.db);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new evidence record
|
|
19
|
+
* @param evidence - Evidence data without id, createdAt, updatedAt
|
|
20
|
+
* @returns UUID of created evidence
|
|
21
|
+
*/
|
|
22
|
+
create(evidence) {
|
|
23
|
+
const id = crypto.randomUUID();
|
|
24
|
+
const now = new Date().toISOString();
|
|
25
|
+
try {
|
|
26
|
+
const stmt = this.db.prepare(`
|
|
27
|
+
INSERT INTO evidences (
|
|
28
|
+
id, timestamp, conversationId, llmProvider,
|
|
29
|
+
encryptedContent, nonce, contentHash, messageCount,
|
|
30
|
+
gitCommitHash, gitTimestamp, tags, createdAt, updatedAt
|
|
31
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
32
|
+
`);
|
|
33
|
+
stmt.run(id, evidence.timestamp, evidence.conversationId, evidence.llmProvider, Buffer.from(evidence.encryptedContent), Buffer.from(evidence.nonce), evidence.contentHash, evidence.messageCount, evidence.gitCommitHash, evidence.gitTimestamp, evidence.tags, now, now);
|
|
34
|
+
return id;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw new Error(`Failed to create evidence: ${error instanceof Error ? error.message : String(error)}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Finds evidence by ID
|
|
42
|
+
* @param id - Evidence UUID
|
|
43
|
+
* @returns Evidence or null if not found
|
|
44
|
+
*/
|
|
45
|
+
findById(id) {
|
|
46
|
+
try {
|
|
47
|
+
const stmt = this.db.prepare(`
|
|
48
|
+
SELECT * FROM evidences WHERE id = ?
|
|
49
|
+
`);
|
|
50
|
+
const row = stmt.get(id);
|
|
51
|
+
if (!row) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
return this.rowToEvidence(row);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
// Don't swallow database errors - re-throw with context
|
|
58
|
+
throw new Error(`Failed to find evidence by ID: ${error instanceof Error ? error.message : String(error)}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Finds all evidences for a conversation
|
|
63
|
+
* @param conversationId - Conversation identifier
|
|
64
|
+
* @returns Array of evidences (empty if none found)
|
|
65
|
+
*/
|
|
66
|
+
findByConversationId(conversationId) {
|
|
67
|
+
try {
|
|
68
|
+
const stmt = this.db.prepare(`
|
|
69
|
+
SELECT * FROM evidences
|
|
70
|
+
WHERE conversationId = ?
|
|
71
|
+
ORDER BY timestamp ASC
|
|
72
|
+
`);
|
|
73
|
+
const rows = stmt.all(conversationId);
|
|
74
|
+
return rows.map((row) => this.rowToEvidence(row));
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
throw new Error(`Failed to find evidences by conversationId: ${error instanceof Error ? error.message : String(error)}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Lists evidences with pagination
|
|
82
|
+
* @param options - Pagination options (limit, offset)
|
|
83
|
+
* @returns Array of evidences
|
|
84
|
+
*/
|
|
85
|
+
list(options) {
|
|
86
|
+
try {
|
|
87
|
+
const limit = options?.limit;
|
|
88
|
+
const offset = options?.offset ?? 0;
|
|
89
|
+
let query = 'SELECT * FROM evidences ORDER BY timestamp DESC';
|
|
90
|
+
const params = [];
|
|
91
|
+
if (limit !== undefined) {
|
|
92
|
+
query += ' LIMIT ?';
|
|
93
|
+
params.push(limit);
|
|
94
|
+
if (offset > 0) {
|
|
95
|
+
query += ' OFFSET ?';
|
|
96
|
+
params.push(offset);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (offset > 0) {
|
|
100
|
+
query += ' LIMIT -1 OFFSET ?';
|
|
101
|
+
params.push(offset);
|
|
102
|
+
}
|
|
103
|
+
const stmt = this.db.prepare(query);
|
|
104
|
+
const rows = stmt.all(...params);
|
|
105
|
+
return rows.map((row) => this.rowToEvidence(row));
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
throw new Error(`Failed to list evidences: ${error instanceof Error ? error.message : String(error)}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Updates git commit information for an evidence
|
|
113
|
+
* @param id - Evidence UUID
|
|
114
|
+
* @param gitCommitHash - Git commit hash
|
|
115
|
+
* @param gitTimestamp - Git commit timestamp (ISO 8601)
|
|
116
|
+
*/
|
|
117
|
+
updateGitInfo(id, gitCommitHash, gitTimestamp) {
|
|
118
|
+
try {
|
|
119
|
+
const stmt = this.db.prepare(`
|
|
120
|
+
UPDATE evidences
|
|
121
|
+
SET gitCommitHash = ?,
|
|
122
|
+
gitTimestamp = ?,
|
|
123
|
+
updatedAt = ?
|
|
124
|
+
WHERE id = ?
|
|
125
|
+
`);
|
|
126
|
+
const result = stmt.run(gitCommitHash, gitTimestamp, new Date().toISOString(), id);
|
|
127
|
+
if (result.changes === 0) {
|
|
128
|
+
throw new Error(`Evidence with id ${id} not found`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw new Error(`Failed to update git info: ${error instanceof Error ? error.message : String(error)}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Adds tags to an evidence (appends to existing tags)
|
|
137
|
+
* @param id - Evidence UUID
|
|
138
|
+
* @param tags - Array of tags to add
|
|
139
|
+
*/
|
|
140
|
+
addTags(id, tags) {
|
|
141
|
+
try {
|
|
142
|
+
// First, get existing tags
|
|
143
|
+
const evidence = this.findById(id);
|
|
144
|
+
if (!evidence) {
|
|
145
|
+
throw new Error(`Evidence with id ${id} not found`);
|
|
146
|
+
}
|
|
147
|
+
// Parse existing tags or create empty array
|
|
148
|
+
const existingTags = evidence.tags ? JSON.parse(evidence.tags) : [];
|
|
149
|
+
// Merge tags
|
|
150
|
+
const mergedTags = [...existingTags, ...tags];
|
|
151
|
+
// Update database
|
|
152
|
+
const stmt = this.db.prepare(`
|
|
153
|
+
UPDATE evidences
|
|
154
|
+
SET tags = ?,
|
|
155
|
+
updatedAt = ?
|
|
156
|
+
WHERE id = ?
|
|
157
|
+
`);
|
|
158
|
+
stmt.run(JSON.stringify(mergedTags), new Date().toISOString(), id);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
throw new Error(`Failed to add tags: ${error instanceof Error ? error.message : String(error)}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Closes the database connection
|
|
166
|
+
* Should be called when done with the database
|
|
167
|
+
*/
|
|
168
|
+
close() {
|
|
169
|
+
this.db.close();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Converts database row to Evidence object
|
|
173
|
+
* Handles BLOB to Uint8Array conversion
|
|
174
|
+
* @param row - Raw database row
|
|
175
|
+
* @returns Evidence object
|
|
176
|
+
*/
|
|
177
|
+
rowToEvidence(row) {
|
|
178
|
+
return {
|
|
179
|
+
id: row.id,
|
|
180
|
+
timestamp: row.timestamp,
|
|
181
|
+
conversationId: row.conversationId,
|
|
182
|
+
llmProvider: row.llmProvider,
|
|
183
|
+
encryptedContent: new Uint8Array(row.encryptedContent),
|
|
184
|
+
nonce: new Uint8Array(row.nonce),
|
|
185
|
+
contentHash: row.contentHash,
|
|
186
|
+
messageCount: row.messageCount,
|
|
187
|
+
gitCommitHash: row.gitCommitHash,
|
|
188
|
+
gitTimestamp: row.gitTimestamp,
|
|
189
|
+
tags: row.tags,
|
|
190
|
+
createdAt: row.createdAt,
|
|
191
|
+
updatedAt: row.updatedAt
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/lib/storage/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { EvidenceDatabase } from './database.js';
|
|
2
|
+
export interface ExportOptions {
|
|
3
|
+
evidenceIds?: string[];
|
|
4
|
+
includeGitInfo?: boolean;
|
|
5
|
+
password?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ExportResult {
|
|
8
|
+
filename: string;
|
|
9
|
+
zipData: Uint8Array;
|
|
10
|
+
checksum: string;
|
|
11
|
+
evidenceCount: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Export evidences to a ZIP archive with encrypted data and metadata.
|
|
15
|
+
*
|
|
16
|
+
* ⚠️ **Memory Warning**: Entire ZIP is generated in-memory. For large exports
|
|
17
|
+
* (>1000 evidences or >100MB encrypted data), consider exporting in batches
|
|
18
|
+
* to avoid memory exhaustion.
|
|
19
|
+
*
|
|
20
|
+
* @param db - EvidenceDatabase instance
|
|
21
|
+
* @param options - Export options
|
|
22
|
+
* @returns Export result with ZIP data and metadata
|
|
23
|
+
* @throws Error if database operations fail, IDs not found, or ZIP generation fails
|
|
24
|
+
*/
|
|
25
|
+
export declare function exportEvidences(db: EvidenceDatabase, options?: ExportOptions): Promise<ExportResult>;
|
|
26
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/export.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAYD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,gBAAgB,EACpB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAiHvB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
// Export format version constant
|
|
4
|
+
const EXPORT_FORMAT_VERSION = '1.0.0';
|
|
5
|
+
/**
|
|
6
|
+
* Export evidences to a ZIP archive with encrypted data and metadata.
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ **Memory Warning**: Entire ZIP is generated in-memory. For large exports
|
|
9
|
+
* (>1000 evidences or >100MB encrypted data), consider exporting in batches
|
|
10
|
+
* to avoid memory exhaustion.
|
|
11
|
+
*
|
|
12
|
+
* @param db - EvidenceDatabase instance
|
|
13
|
+
* @param options - Export options
|
|
14
|
+
* @returns Export result with ZIP data and metadata
|
|
15
|
+
* @throws Error if database operations fail, IDs not found, or ZIP generation fails
|
|
16
|
+
*/
|
|
17
|
+
export async function exportEvidences(db, options = {}) {
|
|
18
|
+
try {
|
|
19
|
+
const { evidenceIds, includeGitInfo = false } = options;
|
|
20
|
+
// Get evidences to export - validate IDs if specified
|
|
21
|
+
let evidences;
|
|
22
|
+
if (evidenceIds) {
|
|
23
|
+
// Validate all IDs exist first
|
|
24
|
+
const notFound = evidenceIds.filter(id => !db.findById(id));
|
|
25
|
+
if (notFound.length > 0) {
|
|
26
|
+
throw new Error(`Evidence IDs not found: ${notFound.join(', ')}`);
|
|
27
|
+
}
|
|
28
|
+
evidences = evidenceIds.map(id => db.findById(id));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
evidences = db.list();
|
|
32
|
+
}
|
|
33
|
+
// Create ZIP archive
|
|
34
|
+
const zip = new JSZip();
|
|
35
|
+
// Add manifest.json
|
|
36
|
+
const manifest = {
|
|
37
|
+
version: EXPORT_FORMAT_VERSION,
|
|
38
|
+
exportDate: new Date().toISOString(),
|
|
39
|
+
evidenceCount: evidences.length,
|
|
40
|
+
includeGitInfo,
|
|
41
|
+
};
|
|
42
|
+
zip.file('manifest.json', JSON.stringify(manifest, null, 2));
|
|
43
|
+
// Add each evidence
|
|
44
|
+
const checksumEntries = [];
|
|
45
|
+
for (const evidence of evidences) {
|
|
46
|
+
const evidenceFolder = `evidences/${evidence.id}`;
|
|
47
|
+
// Add encrypted-data
|
|
48
|
+
zip.file(`${evidenceFolder}/encrypted-data`, evidence.encryptedContent);
|
|
49
|
+
// Calculate checksum for encrypted data
|
|
50
|
+
const dataChecksum = createHash('sha256')
|
|
51
|
+
.update(evidence.encryptedContent)
|
|
52
|
+
.digest('hex');
|
|
53
|
+
checksumEntries.push(`${dataChecksum} ${evidenceFolder}/encrypted-data`);
|
|
54
|
+
// Add metadata.json
|
|
55
|
+
const metadata = {
|
|
56
|
+
id: evidence.id,
|
|
57
|
+
timestamp: evidence.timestamp,
|
|
58
|
+
conversationId: evidence.conversationId,
|
|
59
|
+
llmProvider: evidence.llmProvider,
|
|
60
|
+
contentHash: evidence.contentHash,
|
|
61
|
+
messageCount: evidence.messageCount,
|
|
62
|
+
tags: evidence.tags,
|
|
63
|
+
nonce: Array.from(evidence.nonce), // Convert Uint8Array to array for JSON
|
|
64
|
+
};
|
|
65
|
+
const metadataJson = JSON.stringify(metadata, null, 2);
|
|
66
|
+
zip.file(`${evidenceFolder}/metadata.json`, metadataJson);
|
|
67
|
+
const metadataChecksum = createHash('sha256')
|
|
68
|
+
.update(metadataJson)
|
|
69
|
+
.digest('hex');
|
|
70
|
+
checksumEntries.push(`${metadataChecksum} ${evidenceFolder}/metadata.json`);
|
|
71
|
+
// Add git-info.json if requested and available
|
|
72
|
+
if (includeGitInfo && evidence.gitCommitHash && evidence.gitTimestamp) {
|
|
73
|
+
const gitInfo = {
|
|
74
|
+
gitCommitHash: evidence.gitCommitHash,
|
|
75
|
+
gitTimestamp: evidence.gitTimestamp,
|
|
76
|
+
};
|
|
77
|
+
const gitInfoJson = JSON.stringify(gitInfo, null, 2);
|
|
78
|
+
zip.file(`${evidenceFolder}/git-info.json`, gitInfoJson);
|
|
79
|
+
const gitChecksum = createHash('sha256').update(gitInfoJson).digest('hex');
|
|
80
|
+
checksumEntries.push(`${gitChecksum} ${evidenceFolder}/git-info.json`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Add checksum.txt
|
|
84
|
+
const checksumContent = [
|
|
85
|
+
'SHA-256 Checksums',
|
|
86
|
+
'=================',
|
|
87
|
+
'',
|
|
88
|
+
...checksumEntries,
|
|
89
|
+
].join('\n');
|
|
90
|
+
zip.file('checksum.txt', checksumContent);
|
|
91
|
+
// Generate ZIP data
|
|
92
|
+
const zipData = await zip.generateAsync({
|
|
93
|
+
type: 'uint8array',
|
|
94
|
+
compression: 'DEFLATE',
|
|
95
|
+
compressionOptions: { level: 9 },
|
|
96
|
+
});
|
|
97
|
+
// Calculate ZIP checksum
|
|
98
|
+
const zipChecksum = createHash('sha256').update(zipData).digest('hex');
|
|
99
|
+
// Generate filename
|
|
100
|
+
const timestamp = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
|
|
101
|
+
const filename = `evidence-export-${timestamp}.zip`;
|
|
102
|
+
return {
|
|
103
|
+
filename,
|
|
104
|
+
zipData,
|
|
105
|
+
checksum: zipChecksum,
|
|
106
|
+
evidenceCount: evidences.length,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
throw new Error(`Failed to export evidences: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../../src/lib/storage/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git commit information
|
|
3
|
+
*/
|
|
4
|
+
export interface GitInfo {
|
|
5
|
+
commitHash: string;
|
|
6
|
+
timestamp: string;
|
|
7
|
+
message?: string;
|
|
8
|
+
author?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Get current Git commit information
|
|
12
|
+
* @param dir - Directory path (defaults to process.cwd())
|
|
13
|
+
* @returns GitInfo or null if not a git repository
|
|
14
|
+
*/
|
|
15
|
+
export declare function getCurrentCommit(dir?: string): Promise<GitInfo | null>;
|
|
16
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/git.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAsBD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CA+BzB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import git from 'isomorphic-git';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
/**
|
|
5
|
+
* Find git root directory by walking up the directory tree
|
|
6
|
+
* @param startDir - Starting directory
|
|
7
|
+
* @returns Git root directory or null if not found
|
|
8
|
+
*/
|
|
9
|
+
async function findGitRoot(startDir) {
|
|
10
|
+
let currentDir = path.resolve(startDir);
|
|
11
|
+
const root = path.parse(currentDir).root;
|
|
12
|
+
while (currentDir !== root) {
|
|
13
|
+
const gitDir = path.join(currentDir, '.git');
|
|
14
|
+
if (fs.existsSync(gitDir)) {
|
|
15
|
+
return currentDir;
|
|
16
|
+
}
|
|
17
|
+
currentDir = path.dirname(currentDir);
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get current Git commit information
|
|
23
|
+
* @param dir - Directory path (defaults to process.cwd())
|
|
24
|
+
* @returns GitInfo or null if not a git repository
|
|
25
|
+
*/
|
|
26
|
+
export async function getCurrentCommit(dir = process.cwd()) {
|
|
27
|
+
try {
|
|
28
|
+
// Find git root directory
|
|
29
|
+
const gitRoot = await findGitRoot(dir);
|
|
30
|
+
if (!gitRoot) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
// Get current commit SHA
|
|
34
|
+
const commits = await git.log({
|
|
35
|
+
fs,
|
|
36
|
+
dir: gitRoot,
|
|
37
|
+
depth: 1,
|
|
38
|
+
});
|
|
39
|
+
if (commits.length === 0) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const commit = commits[0];
|
|
43
|
+
return {
|
|
44
|
+
commitHash: commit.oid,
|
|
45
|
+
timestamp: new Date(commit.commit.committer.timestamp * 1000).toISOString(),
|
|
46
|
+
message: commit.commit.message,
|
|
47
|
+
author: commit.commit.author.name,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
// Not a git repository or other git error
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/lib/storage/git.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,gBAAgB,CAAC;AACjC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAYxB;;;;GAIG;AACH,KAAK,UAAU,WAAW,CAAC,QAAgB;IACzC,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;IAEzC,OAAO,UAAU,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC7C,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,OAAO,CAAC,GAAG,EAAE;IAE3B,IAAI,CAAC;QACH,0BAA0B;QAC1B,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QAED,yBAAyB;QACzB,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC;YAC5B,EAAE;YACF,GAAG,EAAE,OAAO;YACZ,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAE1B,OAAO;YACL,UAAU,EAAE,MAAM,CAAC,GAAG;YACtB,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;YAC3E,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO;YAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI;SAClC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0CAA0C;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createSchema, verifySchema } from './schema.js';
|
|
2
|
+
export { EvidenceDatabase } from './database.js';
|
|
3
|
+
export type { Evidence, Metadata } from './types.js';
|
|
4
|
+
export { getCurrentCommit, type GitInfo } from './git.js';
|
|
5
|
+
export { exportEvidences, type ExportOptions, type ExportResult } from './export.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAgB,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAyC,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the database schema (tables and indexes)
|
|
4
|
+
* This function is idempotent - safe to run multiple times
|
|
5
|
+
*
|
|
6
|
+
* @param db - SQLite database instance
|
|
7
|
+
*/
|
|
8
|
+
export declare function createSchema(db: Database.Database): void;
|
|
9
|
+
/**
|
|
10
|
+
* Verifies that the database schema is valid
|
|
11
|
+
* Checks for existence of required tables
|
|
12
|
+
*
|
|
13
|
+
* @param db - SQLite database instance
|
|
14
|
+
* @returns true if schema is valid, false otherwise
|
|
15
|
+
*/
|
|
16
|
+
export declare function verifySchema(db: Database.Database): boolean;
|
|
17
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAO3C;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAqDxD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAqC3D"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Current schema version
|
|
3
|
+
*/
|
|
4
|
+
const SCHEMA_VERSION = '1';
|
|
5
|
+
/**
|
|
6
|
+
* Creates the database schema (tables and indexes)
|
|
7
|
+
* This function is idempotent - safe to run multiple times
|
|
8
|
+
*
|
|
9
|
+
* @param db - SQLite database instance
|
|
10
|
+
*/
|
|
11
|
+
export function createSchema(db) {
|
|
12
|
+
try {
|
|
13
|
+
// Create evidences table
|
|
14
|
+
db.exec(`
|
|
15
|
+
CREATE TABLE IF NOT EXISTS evidences (
|
|
16
|
+
id TEXT PRIMARY KEY,
|
|
17
|
+
timestamp TEXT NOT NULL,
|
|
18
|
+
conversationId TEXT NOT NULL,
|
|
19
|
+
llmProvider TEXT NOT NULL,
|
|
20
|
+
encryptedContent BLOB NOT NULL,
|
|
21
|
+
nonce BLOB NOT NULL,
|
|
22
|
+
contentHash TEXT NOT NULL,
|
|
23
|
+
messageCount INTEGER NOT NULL DEFAULT 0,
|
|
24
|
+
gitCommitHash TEXT,
|
|
25
|
+
gitTimestamp TEXT,
|
|
26
|
+
tags TEXT,
|
|
27
|
+
createdAt TEXT NOT NULL DEFAULT (datetime('now')),
|
|
28
|
+
updatedAt TEXT NOT NULL DEFAULT (datetime('now'))
|
|
29
|
+
);
|
|
30
|
+
`);
|
|
31
|
+
// Create metadata table for schema versioning
|
|
32
|
+
db.exec(`
|
|
33
|
+
CREATE TABLE IF NOT EXISTS metadata (
|
|
34
|
+
key TEXT PRIMARY KEY,
|
|
35
|
+
value TEXT NOT NULL
|
|
36
|
+
);
|
|
37
|
+
`);
|
|
38
|
+
// Create indexes for common queries
|
|
39
|
+
db.exec(`
|
|
40
|
+
CREATE INDEX IF NOT EXISTS idx_timestamp ON evidences(timestamp);
|
|
41
|
+
`);
|
|
42
|
+
db.exec(`
|
|
43
|
+
CREATE INDEX IF NOT EXISTS idx_conversation_id ON evidences(conversationId);
|
|
44
|
+
`);
|
|
45
|
+
db.exec(`
|
|
46
|
+
CREATE INDEX IF NOT EXISTS idx_content_hash ON evidences(contentHash);
|
|
47
|
+
`);
|
|
48
|
+
// Set schema version (use INSERT OR IGNORE to make it idempotent)
|
|
49
|
+
const stmt = db.prepare(`
|
|
50
|
+
INSERT OR IGNORE INTO metadata (key, value)
|
|
51
|
+
VALUES ('schema_version', ?)
|
|
52
|
+
`);
|
|
53
|
+
stmt.run(SCHEMA_VERSION);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
// Clean up database connection on failure to prevent resource leaks
|
|
57
|
+
db.close();
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Verifies that the database schema is valid
|
|
63
|
+
* Checks for existence of required tables
|
|
64
|
+
*
|
|
65
|
+
* @param db - SQLite database instance
|
|
66
|
+
* @returns true if schema is valid, false otherwise
|
|
67
|
+
*/
|
|
68
|
+
export function verifySchema(db) {
|
|
69
|
+
try {
|
|
70
|
+
// Check if evidences table exists
|
|
71
|
+
const evidencesTableInfo = db.pragma('table_info(evidences)');
|
|
72
|
+
if (!evidencesTableInfo || evidencesTableInfo.length === 0) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
// Check if metadata table exists
|
|
76
|
+
const metadataTableInfo = db.pragma('table_info(metadata)');
|
|
77
|
+
if (!metadataTableInfo || metadataTableInfo.length === 0) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
// Verify required columns exist in evidences table
|
|
81
|
+
const evidencesColumns = evidencesTableInfo.map((col) => col.name);
|
|
82
|
+
const requiredColumns = [
|
|
83
|
+
'id',
|
|
84
|
+
'timestamp',
|
|
85
|
+
'encryptedContent',
|
|
86
|
+
'nonce',
|
|
87
|
+
'contentHash',
|
|
88
|
+
'messageCount',
|
|
89
|
+
'createdAt',
|
|
90
|
+
'updatedAt'
|
|
91
|
+
];
|
|
92
|
+
for (const col of requiredColumns) {
|
|
93
|
+
if (!evidencesColumns.includes(col)) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/lib/storage/schema.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,EAAqB;IAChD,IAAI,CAAC;QACH,yBAAyB;QACzB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;KAgBP,CAAC,CAAC;QAEH,8CAA8C;QAC9C,EAAE,CAAC,IAAI,CAAC;;;;;KAKP,CAAC,CAAC;QAEH,oCAAoC;QACpC,EAAE,CAAC,IAAI,CAAC;;KAEP,CAAC,CAAC;QAEH,EAAE,CAAC,IAAI,CAAC;;KAEP,CAAC,CAAC;QAEH,EAAE,CAAC,IAAI,CAAC;;KAEP,CAAC,CAAC;QAEH,kEAAkE;QAClE,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;KAGvB,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,oEAAoE;QACpE,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,EAAqB;IAChD,IAAI,CAAC;QACH,kCAAkC;QAClC,MAAM,kBAAkB,GAAG,EAAE,CAAC,MAAM,CAAC,uBAAuB,CAA0C,CAAC;QACvG,IAAI,CAAC,kBAAkB,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,iCAAiC;QACjC,MAAM,iBAAiB,GAAG,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAA0C,CAAC;QACrG,IAAI,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,mDAAmD;QACnD,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnE,MAAM,eAAe,GAAG;YACtB,IAAI;YACJ,WAAW;YACX,kBAAkB;YAClB,OAAO;YACP,aAAa;YACb,cAAc;YACd,WAAW;YACX,WAAW;SACZ,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YAClC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpC,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence record stored in the database
|
|
3
|
+
*/
|
|
4
|
+
export interface Evidence {
|
|
5
|
+
id: string;
|
|
6
|
+
timestamp: string;
|
|
7
|
+
conversationId: string | null;
|
|
8
|
+
llmProvider: string | null;
|
|
9
|
+
encryptedContent: Uint8Array;
|
|
10
|
+
nonce: Uint8Array;
|
|
11
|
+
contentHash: string;
|
|
12
|
+
messageCount: number;
|
|
13
|
+
gitCommitHash: string | null;
|
|
14
|
+
gitTimestamp: string | null;
|
|
15
|
+
tags: string | null;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
updatedAt: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Metadata key-value pairs for schema versioning and other system data
|
|
21
|
+
*/
|
|
22
|
+
export interface Metadata {
|
|
23
|
+
key: string;
|
|
24
|
+
value: string;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,EAAE,UAAU,CAAC;IAC7B,KAAK,EAAE,UAAU,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/storage/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pcircle/evidencemcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server for EvidenceMCP - automatically capture and encrypt LLM conversations as legal evidence with Git timestamps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -46,11 +46,15 @@
|
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
49
|
+
"@noble/ciphers": "^0.5.2",
|
|
50
|
+
"@noble/hashes": "^1.3.3",
|
|
51
|
+
"better-sqlite3": "^12.6.2",
|
|
52
|
+
"isomorphic-git": "^1.36.2",
|
|
53
|
+
"jszip": "^3.10.1",
|
|
51
54
|
"zod": "^3.23.8"
|
|
52
55
|
},
|
|
53
56
|
"devDependencies": {
|
|
57
|
+
"@types/better-sqlite3": "^7.6.9",
|
|
54
58
|
"@types/node": "^22.10.5",
|
|
55
59
|
"tsx": "^4.21.0",
|
|
56
60
|
"typescript": "^5.9.3",
|