@pcircle/footprint 1.1.1 → 1.2.1
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 +165 -12
- package/SKILL.md +72 -15
- package/dist/src/analyzers/content-analyzer.d.ts +20 -0
- package/dist/src/analyzers/content-analyzer.d.ts.map +1 -0
- package/dist/src/analyzers/content-analyzer.js +169 -0
- package/dist/src/analyzers/content-analyzer.js.map +1 -0
- package/dist/src/index.d.ts +38 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +243 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib/crypto/decrypt.d.ts.map +1 -0
- package/dist/{lib → src/lib}/crypto/decrypt.js +4 -0
- package/dist/src/lib/crypto/decrypt.js.map +1 -0
- package/dist/src/lib/crypto/encrypt.d.ts.map +1 -0
- package/dist/src/lib/crypto/encrypt.js.map +1 -0
- package/dist/{lib → src/lib}/crypto/index.d.ts +1 -1
- package/dist/src/lib/crypto/index.d.ts.map +1 -0
- package/dist/{lib → src/lib}/crypto/index.js +1 -1
- package/dist/src/lib/crypto/index.js.map +1 -0
- package/dist/{lib → src/lib}/crypto/key-derivation.d.ts +17 -3
- package/dist/src/lib/crypto/key-derivation.d.ts.map +1 -0
- package/dist/{lib → src/lib}/crypto/key-derivation.js +44 -3
- package/dist/src/lib/crypto/key-derivation.js.map +1 -0
- package/dist/src/lib/crypto/types.d.ts.map +1 -0
- package/dist/src/lib/crypto/types.js.map +1 -0
- package/dist/src/lib/errors/base-error.d.ts +15 -0
- package/dist/src/lib/errors/base-error.d.ts.map +1 -0
- package/dist/src/lib/errors/base-error.js +34 -0
- package/dist/src/lib/errors/base-error.js.map +1 -0
- package/dist/src/lib/errors/crypto-error.d.ts +29 -0
- package/dist/src/lib/errors/crypto-error.d.ts.map +1 -0
- package/dist/src/lib/errors/crypto-error.js +43 -0
- package/dist/src/lib/errors/crypto-error.js.map +1 -0
- package/dist/src/lib/errors/index.d.ts +26 -0
- package/dist/src/lib/errors/index.d.ts.map +1 -0
- package/dist/src/lib/errors/index.js +26 -0
- package/dist/src/lib/errors/index.js.map +1 -0
- package/dist/src/lib/errors/storage-error.d.ts +25 -0
- package/dist/src/lib/errors/storage-error.d.ts.map +1 -0
- package/dist/src/lib/errors/storage-error.js +38 -0
- package/dist/src/lib/errors/storage-error.js.map +1 -0
- package/dist/src/lib/errors/validation-error.d.ts +21 -0
- package/dist/src/lib/errors/validation-error.d.ts.map +1 -0
- package/dist/src/lib/errors/validation-error.js +29 -0
- package/dist/src/lib/errors/validation-error.js.map +1 -0
- package/dist/{lib → src/lib}/storage/database.d.ts +14 -2
- package/dist/src/lib/storage/database.d.ts.map +1 -0
- package/dist/{lib → src/lib}/storage/database.js +65 -29
- package/dist/src/lib/storage/database.js.map +1 -0
- package/dist/src/lib/storage/export.d.ts.map +1 -0
- package/dist/{lib → src/lib}/storage/export.js +16 -1
- package/dist/src/lib/storage/export.js.map +1 -0
- package/dist/{lib → src/lib}/storage/git.d.ts +1 -1
- package/dist/src/lib/storage/git.d.ts.map +1 -0
- package/dist/{lib → src/lib}/storage/git.js +5 -2
- package/dist/src/lib/storage/git.js.map +1 -0
- package/dist/{lib → src/lib}/storage/index.d.ts +1 -0
- package/dist/src/lib/storage/index.d.ts.map +1 -0
- package/dist/{lib → src/lib}/storage/index.js +1 -0
- package/dist/src/lib/storage/index.js.map +1 -0
- package/dist/src/lib/storage/salt-storage.d.ts +25 -0
- package/dist/src/lib/storage/salt-storage.d.ts.map +1 -0
- package/dist/src/lib/storage/salt-storage.js +66 -0
- package/dist/src/lib/storage/salt-storage.js.map +1 -0
- package/dist/src/lib/storage/schema.d.ts.map +1 -0
- package/dist/{lib → src/lib}/storage/schema.js +22 -1
- package/dist/src/lib/storage/schema.js.map +1 -0
- package/dist/src/lib/storage/types.d.ts.map +1 -0
- package/dist/src/lib/storage/types.js.map +1 -0
- package/dist/src/lib/tool-response.d.ts +84 -0
- package/dist/src/lib/tool-response.d.ts.map +1 -0
- package/dist/src/lib/tool-response.js +91 -0
- package/dist/src/lib/tool-response.js.map +1 -0
- package/dist/src/lib/tool-wrapper.d.ts +45 -0
- package/dist/src/lib/tool-wrapper.d.ts.map +1 -0
- package/dist/src/lib/tool-wrapper.js +73 -0
- package/dist/src/lib/tool-wrapper.js.map +1 -0
- package/dist/{test-helpers.d.ts → src/test-helpers.d.ts} +4 -4
- package/dist/src/test-helpers.d.ts.map +1 -0
- package/dist/{test-helpers.js → src/test-helpers.js} +2 -2
- package/dist/src/test-helpers.js.map +1 -0
- package/dist/src/tools/capture-footprint.d.ts +29 -0
- package/dist/src/tools/capture-footprint.d.ts.map +1 -0
- package/dist/src/tools/capture-footprint.js +94 -0
- package/dist/src/tools/capture-footprint.js.map +1 -0
- package/dist/src/tools/delete-footprints.d.ts +22 -0
- package/dist/src/tools/delete-footprints.d.ts.map +1 -0
- package/dist/src/tools/delete-footprints.js +33 -0
- package/dist/src/tools/delete-footprints.js.map +1 -0
- package/dist/src/tools/export-footprints.d.ts +33 -0
- package/dist/src/tools/export-footprints.d.ts.map +1 -0
- package/dist/src/tools/export-footprints.js +50 -0
- package/dist/src/tools/export-footprints.js.map +1 -0
- package/dist/src/tools/get-footprint.d.ts +51 -0
- package/dist/src/tools/get-footprint.d.ts.map +1 -0
- package/dist/src/tools/get-footprint.js +66 -0
- package/dist/src/tools/get-footprint.js.map +1 -0
- package/dist/src/tools/get-tag-stats.d.ts +30 -0
- package/dist/src/tools/get-tag-stats.d.ts.map +1 -0
- package/dist/src/tools/get-tag-stats.js +33 -0
- package/dist/src/tools/get-tag-stats.js.map +1 -0
- package/dist/src/tools/index.d.ts +16 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +16 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/list-footprints.d.ts +57 -0
- package/dist/src/tools/list-footprints.d.ts.map +1 -0
- package/dist/src/tools/list-footprints.js +57 -0
- package/dist/src/tools/list-footprints.js.map +1 -0
- package/dist/src/tools/remove-tag.d.ts +22 -0
- package/dist/src/tools/remove-tag.d.ts.map +1 -0
- package/dist/src/tools/remove-tag.js +30 -0
- package/dist/src/tools/remove-tag.js.map +1 -0
- package/dist/src/tools/rename-tag.d.ts +24 -0
- package/dist/src/tools/rename-tag.d.ts.map +1 -0
- package/dist/src/tools/rename-tag.js +34 -0
- package/dist/src/tools/rename-tag.js.map +1 -0
- package/dist/src/tools/search-footprints.d.ts +60 -0
- package/dist/src/tools/search-footprints.d.ts.map +1 -0
- package/dist/src/tools/search-footprints.js +78 -0
- package/dist/src/tools/search-footprints.js.map +1 -0
- package/dist/src/tools/suggest-capture.d.ts +21 -0
- package/dist/src/tools/suggest-capture.d.ts.map +1 -0
- package/dist/src/tools/suggest-capture.js +37 -0
- package/dist/src/tools/suggest-capture.js.map +1 -0
- package/dist/src/tools/verify-footprint.d.ts +104 -0
- package/dist/src/tools/verify-footprint.d.ts.map +1 -0
- package/dist/src/tools/verify-footprint.js +102 -0
- package/dist/src/tools/verify-footprint.js.map +1 -0
- package/dist/{types.d.ts → src/types.d.ts} +1 -1
- package/dist/src/types.d.ts.map +1 -0
- package/dist/{lib/storage → src}/types.js.map +1 -1
- package/dist/src/ui/register.d.ts.map +1 -0
- package/dist/src/ui/register.js +94 -0
- package/dist/src/ui/register.js.map +1 -0
- package/dist/tests/error-handling.test.d.ts +2 -0
- package/dist/tests/error-handling.test.d.ts.map +1 -0
- package/dist/tests/error-handling.test.js +114 -0
- package/dist/tests/error-handling.test.js.map +1 -0
- package/dist/tests/fixtures.d.ts +87 -0
- package/dist/tests/fixtures.d.ts.map +1 -0
- package/dist/tests/fixtures.js +130 -0
- package/dist/tests/fixtures.js.map +1 -0
- package/dist/tests/integration.test.d.ts +2 -0
- package/dist/tests/integration.test.d.ts.map +1 -0
- package/dist/tests/integration.test.js +115 -0
- package/dist/tests/integration.test.js.map +1 -0
- package/dist/tests/resources.test.d.ts +2 -0
- package/dist/tests/resources.test.d.ts.map +1 -0
- package/dist/tests/resources.test.js +73 -0
- package/dist/tests/resources.test.js.map +1 -0
- package/dist/tests/setup.d.ts +8 -0
- package/dist/tests/setup.d.ts.map +1 -0
- package/dist/tests/setup.js +8 -0
- package/dist/tests/setup.js.map +1 -0
- package/dist/tests/tools.test.d.ts +2 -0
- package/dist/tests/tools.test.d.ts.map +1 -0
- package/dist/tests/tools.test.js +224 -0
- package/dist/tests/tools.test.js.map +1 -0
- package/dist/ui/dashboard.html +1 -1
- package/dist/ui/detail.html +1 -1
- package/dist/ui/export.html +1 -1
- package/dist/ui-tmp/ui/export.html +1 -1
- package/package.json +8 -8
- package/dist/index.d.ts +0 -19
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -694
- package/dist/index.js.map +0 -1
- package/dist/lib/crypto/decrypt.d.ts.map +0 -1
- package/dist/lib/crypto/decrypt.js.map +0 -1
- package/dist/lib/crypto/encrypt.d.ts.map +0 -1
- package/dist/lib/crypto/encrypt.js.map +0 -1
- package/dist/lib/crypto/index.d.ts.map +0 -1
- package/dist/lib/crypto/index.js.map +0 -1
- package/dist/lib/crypto/key-derivation.d.ts.map +0 -1
- package/dist/lib/crypto/key-derivation.js.map +0 -1
- package/dist/lib/crypto/types.d.ts.map +0 -1
- package/dist/lib/crypto/types.js.map +0 -1
- package/dist/lib/storage/database.d.ts.map +0 -1
- package/dist/lib/storage/database.js.map +0 -1
- package/dist/lib/storage/export.d.ts.map +0 -1
- package/dist/lib/storage/export.js.map +0 -1
- package/dist/lib/storage/git.d.ts.map +0 -1
- package/dist/lib/storage/git.js.map +0 -1
- package/dist/lib/storage/index.d.ts.map +0 -1
- package/dist/lib/storage/index.js.map +0 -1
- package/dist/lib/storage/schema.d.ts.map +0 -1
- package/dist/lib/storage/schema.js.map +0 -1
- package/dist/lib/storage/types.d.ts.map +0 -1
- package/dist/test-helpers.d.ts.map +0 -1
- package/dist/test-helpers.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/ui/register.d.ts.map +0 -1
- package/dist/ui/register.js +0 -154
- package/dist/ui/register.js.map +0 -1
- /package/dist/{lib → src/lib}/crypto/decrypt.d.ts +0 -0
- /package/dist/{lib → src/lib}/crypto/encrypt.d.ts +0 -0
- /package/dist/{lib → src/lib}/crypto/encrypt.js +0 -0
- /package/dist/{lib → src/lib}/crypto/types.d.ts +0 -0
- /package/dist/{lib → src/lib}/crypto/types.js +0 -0
- /package/dist/{lib → src/lib}/storage/export.d.ts +0 -0
- /package/dist/{lib → src/lib}/storage/schema.d.ts +0 -0
- /package/dist/{lib → src/lib}/storage/types.d.ts +0 -0
- /package/dist/{lib → src/lib}/storage/types.js +0 -0
- /package/dist/{types.js → src/types.js} +0 -0
- /package/dist/{ui → src/ui}/register.d.ts +0 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer, ResourceTemplate, } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { EvidenceDatabase, storeSalt, retrieveSalt, } from "./lib/storage/index.js";
|
|
5
|
+
import { deriveKey, rederiveKey } from "./lib/crypto/index.js";
|
|
6
|
+
import { registerUIResources } from "./ui/register.js";
|
|
7
|
+
import { getErrorMessage } from "./lib/tool-wrapper.js";
|
|
8
|
+
import { decrypt } from "./lib/crypto/index.js";
|
|
9
|
+
// Import all tool handlers
|
|
10
|
+
import { captureFootprintSchema, captureFootprintMetadata, createCaptureFootprintHandler, listFootprintsSchema, listFootprintsMetadata, createListFootprintsHandler, exportFootprintsSchema, exportFootprintsMetadata, createExportFootprintsHandler, getFootprintSchema, getFootprintMetadata, createGetFootprintHandler, searchFootprintsSchema, searchFootprintsMetadata, createSearchFootprintsHandler, verifyFootprintSchema, verifyFootprintMetadata, createVerifyFootprintHandler, suggestCaptureSchema, suggestCaptureMetadata, createSuggestCaptureHandler, deleteFootprintsSchema, deleteFootprintsMetadata, createDeleteFootprintsHandler, renameTagSchema, renameTagMetadata, createRenameTagHandler, removeTagSchema, removeTagMetadata, createRemoveTagHandler, getTagStatsSchema, getTagStatsMetadata, createGetTagStatsHandler, } from "./tools/index.js";
|
|
11
|
+
/**
|
|
12
|
+
* Footprint Server - Captures LLM conversations as encrypted evidence
|
|
13
|
+
* with Git timestamps and export capabilities.
|
|
14
|
+
*/
|
|
15
|
+
export class FootprintServer {
|
|
16
|
+
server;
|
|
17
|
+
config;
|
|
18
|
+
db;
|
|
19
|
+
derivedKey = null;
|
|
20
|
+
keyDerivationPromise = null;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.config = config;
|
|
23
|
+
try {
|
|
24
|
+
this.db = new EvidenceDatabase(config.dbPath);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw new Error(`Failed to initialize database: ${getErrorMessage(error)}`);
|
|
28
|
+
}
|
|
29
|
+
this.server = new McpServer({
|
|
30
|
+
name: config.name || "traceguard-mcp",
|
|
31
|
+
version: config.version || "0.1.0",
|
|
32
|
+
});
|
|
33
|
+
// Register UI resources for MCP Apps
|
|
34
|
+
registerUIResources(this.server);
|
|
35
|
+
this.registerTools();
|
|
36
|
+
this.registerResources();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get or derive encryption key using stored salt (thread-safe)
|
|
40
|
+
* Caches key in memory for performance, with cleanup on shutdown
|
|
41
|
+
* Handles concurrent calls by ensuring only one derivation happens at a time
|
|
42
|
+
*
|
|
43
|
+
* @returns 32-byte encryption key
|
|
44
|
+
* @throws Error if salt storage fails
|
|
45
|
+
*/
|
|
46
|
+
async getDerivedKey() {
|
|
47
|
+
// Fast path: key already derived
|
|
48
|
+
if (this.derivedKey) {
|
|
49
|
+
return this.derivedKey;
|
|
50
|
+
}
|
|
51
|
+
// If derivation is in progress, wait for it to complete
|
|
52
|
+
if (this.keyDerivationPromise) {
|
|
53
|
+
return this.keyDerivationPromise;
|
|
54
|
+
}
|
|
55
|
+
// Start derivation (only one caller proceeds here)
|
|
56
|
+
this.keyDerivationPromise = (async () => {
|
|
57
|
+
try {
|
|
58
|
+
// Check if salt exists in database
|
|
59
|
+
const existingSalt = retrieveSalt(this.db.getDb());
|
|
60
|
+
let result;
|
|
61
|
+
if (existingSalt) {
|
|
62
|
+
// Re-derive key using stored salt
|
|
63
|
+
result = await rederiveKey(this.config.password, existingSalt);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// First-time: generate new key and store salt
|
|
67
|
+
result = await deriveKey(this.config.password);
|
|
68
|
+
storeSalt(this.db.getDb(), result.salt);
|
|
69
|
+
}
|
|
70
|
+
this.derivedKey = result.key;
|
|
71
|
+
return result.key;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
// Clear promise after derivation completes (success or failure)
|
|
75
|
+
this.keyDerivationPromise = null;
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
78
|
+
return this.keyDerivationPromise;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Securely clear derived key from memory
|
|
82
|
+
* Should be called on server shutdown
|
|
83
|
+
*/
|
|
84
|
+
clearDerivedKey() {
|
|
85
|
+
if (this.derivedKey) {
|
|
86
|
+
// Zero out key in memory
|
|
87
|
+
this.derivedKey.fill(0);
|
|
88
|
+
this.derivedKey = null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
registerTools() {
|
|
92
|
+
// Capture footprint tool
|
|
93
|
+
this.server.registerTool("capture-footprint", {
|
|
94
|
+
...captureFootprintMetadata,
|
|
95
|
+
inputSchema: captureFootprintSchema.inputSchema,
|
|
96
|
+
outputSchema: captureFootprintSchema.outputSchema,
|
|
97
|
+
}, createCaptureFootprintHandler(this.db, this.getDerivedKey.bind(this)));
|
|
98
|
+
// List footprints tool
|
|
99
|
+
this.server.registerTool("list-footprints", {
|
|
100
|
+
...listFootprintsMetadata,
|
|
101
|
+
inputSchema: listFootprintsSchema.inputSchema,
|
|
102
|
+
outputSchema: listFootprintsSchema.outputSchema,
|
|
103
|
+
}, createListFootprintsHandler(this.db));
|
|
104
|
+
// Export footprints tool
|
|
105
|
+
this.server.registerTool("export-footprints", {
|
|
106
|
+
...exportFootprintsMetadata,
|
|
107
|
+
inputSchema: exportFootprintsSchema.inputSchema,
|
|
108
|
+
outputSchema: exportFootprintsSchema.outputSchema,
|
|
109
|
+
}, createExportFootprintsHandler(this.db));
|
|
110
|
+
// Get footprint tool
|
|
111
|
+
this.server.registerTool("get-footprint", {
|
|
112
|
+
...getFootprintMetadata,
|
|
113
|
+
inputSchema: getFootprintSchema.inputSchema,
|
|
114
|
+
outputSchema: getFootprintSchema.outputSchema,
|
|
115
|
+
}, createGetFootprintHandler(this.db, this.getDerivedKey.bind(this)));
|
|
116
|
+
// Search footprints tool
|
|
117
|
+
this.server.registerTool("search-footprints", {
|
|
118
|
+
...searchFootprintsMetadata,
|
|
119
|
+
inputSchema: searchFootprintsSchema.inputSchema,
|
|
120
|
+
outputSchema: searchFootprintsSchema.outputSchema,
|
|
121
|
+
}, createSearchFootprintsHandler(this.db));
|
|
122
|
+
// Verify footprint tool
|
|
123
|
+
this.server.registerTool("verify-footprint", {
|
|
124
|
+
...verifyFootprintMetadata,
|
|
125
|
+
inputSchema: verifyFootprintSchema.inputSchema,
|
|
126
|
+
outputSchema: verifyFootprintSchema.outputSchema,
|
|
127
|
+
}, createVerifyFootprintHandler(this.db, this.getDerivedKey.bind(this)));
|
|
128
|
+
// Suggest capture tool
|
|
129
|
+
this.server.registerTool("suggest-capture", {
|
|
130
|
+
...suggestCaptureMetadata,
|
|
131
|
+
inputSchema: suggestCaptureSchema.inputSchema,
|
|
132
|
+
outputSchema: suggestCaptureSchema.outputSchema,
|
|
133
|
+
}, createSuggestCaptureHandler());
|
|
134
|
+
// Delete footprints tool
|
|
135
|
+
this.server.registerTool("delete-footprints", {
|
|
136
|
+
...deleteFootprintsMetadata,
|
|
137
|
+
inputSchema: deleteFootprintsSchema.inputSchema,
|
|
138
|
+
outputSchema: deleteFootprintsSchema.outputSchema,
|
|
139
|
+
}, createDeleteFootprintsHandler(this.db));
|
|
140
|
+
// Rename tag tool
|
|
141
|
+
this.server.registerTool("rename-tag", {
|
|
142
|
+
...renameTagMetadata,
|
|
143
|
+
inputSchema: renameTagSchema.inputSchema,
|
|
144
|
+
outputSchema: renameTagSchema.outputSchema,
|
|
145
|
+
}, createRenameTagHandler(this.db));
|
|
146
|
+
// Remove tag tool
|
|
147
|
+
this.server.registerTool("remove-tag", {
|
|
148
|
+
...removeTagMetadata,
|
|
149
|
+
inputSchema: removeTagSchema.inputSchema,
|
|
150
|
+
outputSchema: removeTagSchema.outputSchema,
|
|
151
|
+
}, createRemoveTagHandler(this.db));
|
|
152
|
+
// Get tag statistics tool
|
|
153
|
+
this.server.registerTool("get-tag-stats", {
|
|
154
|
+
...getTagStatsMetadata,
|
|
155
|
+
inputSchema: getTagStatsSchema.inputSchema,
|
|
156
|
+
outputSchema: getTagStatsSchema.outputSchema,
|
|
157
|
+
}, createGetTagStatsHandler(this.db));
|
|
158
|
+
}
|
|
159
|
+
registerResources() {
|
|
160
|
+
this.server.registerResource("evidence", new ResourceTemplate("evidence://{id}", { list: undefined }), {
|
|
161
|
+
title: "Evidence Content",
|
|
162
|
+
description: "Access encrypted footprint record by ID",
|
|
163
|
+
mimeType: "text/plain",
|
|
164
|
+
}, async (uri, { id }) => {
|
|
165
|
+
try {
|
|
166
|
+
const evidence = this.db.findById(id);
|
|
167
|
+
if (!evidence) {
|
|
168
|
+
throw new Error(`Evidence with ID ${id} not found`);
|
|
169
|
+
}
|
|
170
|
+
const key = await this.getDerivedKey();
|
|
171
|
+
const decrypted = decrypt(evidence.encryptedContent, evidence.nonce, key);
|
|
172
|
+
return {
|
|
173
|
+
contents: [
|
|
174
|
+
{ uri: uri.href, mimeType: "text/plain", text: decrypted },
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
throw new Error(`Failed to access evidence resource: ${getErrorMessage(error)}`);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async start() {
|
|
184
|
+
const transport = new StdioServerTransport();
|
|
185
|
+
await this.server.connect(transport);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Cleanup server resources
|
|
189
|
+
* Clears derived key from memory and closes database
|
|
190
|
+
*/
|
|
191
|
+
close() {
|
|
192
|
+
this.clearDerivedKey();
|
|
193
|
+
this.db.close();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async function main() {
|
|
197
|
+
const config = {
|
|
198
|
+
dbPath: process.env.FOOTPRINT_DB_PATH || "./evidence.db",
|
|
199
|
+
password: process.env.FOOTPRINT_PASSWORD || "",
|
|
200
|
+
};
|
|
201
|
+
if (!config.password) {
|
|
202
|
+
console.error("Error: FOOTPRINT_PASSWORD environment variable required");
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
const server = new FootprintServer(config);
|
|
206
|
+
// Setup cleanup handlers for graceful shutdown
|
|
207
|
+
const cleanup = () => {
|
|
208
|
+
server.close();
|
|
209
|
+
};
|
|
210
|
+
// Handle uncaught exceptions and promise rejections
|
|
211
|
+
process.on("uncaughtException", (error) => {
|
|
212
|
+
console.error("Uncaught exception:", error);
|
|
213
|
+
cleanup();
|
|
214
|
+
process.exit(1);
|
|
215
|
+
});
|
|
216
|
+
process.on("unhandledRejection", (reason) => {
|
|
217
|
+
console.error("Unhandled rejection:", reason);
|
|
218
|
+
cleanup();
|
|
219
|
+
process.exit(1);
|
|
220
|
+
});
|
|
221
|
+
process.on("SIGINT", () => {
|
|
222
|
+
cleanup();
|
|
223
|
+
process.exit(0);
|
|
224
|
+
});
|
|
225
|
+
process.on("SIGTERM", () => {
|
|
226
|
+
cleanup();
|
|
227
|
+
process.exit(0);
|
|
228
|
+
});
|
|
229
|
+
process.on("exit", cleanup);
|
|
230
|
+
await server.start();
|
|
231
|
+
}
|
|
232
|
+
// Handle both direct execution and symlink execution
|
|
233
|
+
const isMainModule = import.meta.url === `file://${process.argv[1]}` ||
|
|
234
|
+
process.argv[1]?.endsWith("/footprint") ||
|
|
235
|
+
process.argv[1]?.endsWith("/dist/index.js");
|
|
236
|
+
if (isMainModule) {
|
|
237
|
+
main().catch((error) => {
|
|
238
|
+
console.error("Server error:", error);
|
|
239
|
+
process.exit(1);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
export { FootprintTestHelpers } from "./test-helpers.js";
|
|
243
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -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,CA0BR"}
|
|
@@ -24,6 +24,10 @@ export function decrypt(ciphertext, nonce, key) {
|
|
|
24
24
|
return new TextDecoder().decode(plaintextBytes);
|
|
25
25
|
}
|
|
26
26
|
catch (error) {
|
|
27
|
+
// Log detailed error for debugging (server-side only, never exposed to client)
|
|
28
|
+
const originalError = error instanceof Error ? error.message : String(error);
|
|
29
|
+
console.error('[Decrypt] Decryption failed:', originalError);
|
|
30
|
+
// User-facing error remains generic (security best practice)
|
|
27
31
|
throw new Error('Decryption failed: invalid key or tampered data');
|
|
28
32
|
}
|
|
29
33
|
}
|
|
@@ -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,+EAA+E;QAC/E,MAAM,aAAa,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7E,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,aAAa,CAAC,CAAC;QAE7D,6DAA6D;QAC7D,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;AACH,CAAC"}
|
|
@@ -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 @@
|
|
|
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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { deriveKey, verifyKey } from './key-derivation.js';
|
|
1
|
+
export { deriveKey, rederiveKey, verifyKey } from './key-derivation.js';
|
|
2
2
|
export { encrypt } from './encrypt.js';
|
|
3
3
|
export { decrypt } from './decrypt.js';
|
|
4
4
|
export type { DerivedKey, KeyDerivationParams, EncryptedData } from './types.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxE,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,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -19,12 +19,26 @@ import type { DerivedKey, KeyDerivationParams } from './types.js';
|
|
|
19
19
|
*/
|
|
20
20
|
export declare function deriveKey(password: string, params?: Partial<KeyDerivationParams>): Promise<DerivedKey>;
|
|
21
21
|
/**
|
|
22
|
-
* Re-derive key from password and existing salt
|
|
22
|
+
* Re-derive key from password and existing salt
|
|
23
|
+
* Use this for subsequent encryptions/decryptions with stored salt
|
|
23
24
|
*
|
|
24
25
|
* @param password - User password
|
|
25
|
-
* @param salt - Existing salt (from
|
|
26
|
+
* @param salt - Existing salt (from database)
|
|
26
27
|
* @param params - Optional KDF parameters
|
|
27
28
|
* @returns Derived key with same salt
|
|
28
29
|
*/
|
|
29
|
-
export declare function
|
|
30
|
+
export declare function rederiveKey(password: string, salt: Uint8Array, params?: Partial<KeyDerivationParams>): Promise<DerivedKey>;
|
|
31
|
+
/**
|
|
32
|
+
* Verify password by comparing derived key with expected key
|
|
33
|
+
* Uses constant-time comparison to prevent timing attacks
|
|
34
|
+
*
|
|
35
|
+
* @param password - User password to verify
|
|
36
|
+
* @param salt - Existing salt (from database)
|
|
37
|
+
* @param expectedKey - Expected key (from previous derivation)
|
|
38
|
+
* @param params - Optional KDF parameters
|
|
39
|
+
* @returns true if password is correct, false otherwise
|
|
40
|
+
*
|
|
41
|
+
* @security Uses timingSafeEqual to prevent timing attacks
|
|
42
|
+
*/
|
|
43
|
+
export declare function verifyKey(password: string, salt: Uint8Array, expectedKey: Uint8Array, params?: Partial<KeyDerivationParams>): Promise<boolean>;
|
|
30
44
|
//# 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":"AAGA,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;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACxC,OAAO,CAAC,UAAU,CAAC,CAwBrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,UAAU,EACvB,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACxC,OAAO,CAAC,OAAO,CAAC,CAkClB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { argon2id } from '@noble/hashes/argon2';
|
|
2
2
|
import { randomBytes } from '@noble/hashes/utils';
|
|
3
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
3
4
|
import { DEFAULT_KDF_PARAMS } from './types.js';
|
|
4
5
|
/**
|
|
5
6
|
* Derive encryption key from password using Argon2id
|
|
@@ -36,14 +37,15 @@ export async function deriveKey(password, params = {}) {
|
|
|
36
37
|
return { key, salt };
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
|
-
* Re-derive key from password and existing salt
|
|
40
|
+
* Re-derive key from password and existing salt
|
|
41
|
+
* Use this for subsequent encryptions/decryptions with stored salt
|
|
40
42
|
*
|
|
41
43
|
* @param password - User password
|
|
42
|
-
* @param salt - Existing salt (from
|
|
44
|
+
* @param salt - Existing salt (from database)
|
|
43
45
|
* @param params - Optional KDF parameters
|
|
44
46
|
* @returns Derived key with same salt
|
|
45
47
|
*/
|
|
46
|
-
export async function
|
|
48
|
+
export async function rederiveKey(password, salt, params = {}) {
|
|
47
49
|
if (!password || password.length === 0) {
|
|
48
50
|
throw new Error('Password cannot be empty');
|
|
49
51
|
}
|
|
@@ -60,4 +62,43 @@ export async function verifyKey(password, salt, params = {}) {
|
|
|
60
62
|
});
|
|
61
63
|
return { key, salt };
|
|
62
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Verify password by comparing derived key with expected key
|
|
67
|
+
* Uses constant-time comparison to prevent timing attacks
|
|
68
|
+
*
|
|
69
|
+
* @param password - User password to verify
|
|
70
|
+
* @param salt - Existing salt (from database)
|
|
71
|
+
* @param expectedKey - Expected key (from previous derivation)
|
|
72
|
+
* @param params - Optional KDF parameters
|
|
73
|
+
* @returns true if password is correct, false otherwise
|
|
74
|
+
*
|
|
75
|
+
* @security Uses timingSafeEqual to prevent timing attacks
|
|
76
|
+
*/
|
|
77
|
+
export async function verifyKey(password, salt, expectedKey, params = {}) {
|
|
78
|
+
if (!password || password.length === 0) {
|
|
79
|
+
throw new Error('Password cannot be empty');
|
|
80
|
+
}
|
|
81
|
+
if (salt.length !== 16) {
|
|
82
|
+
throw new Error('Salt must be 16 bytes');
|
|
83
|
+
}
|
|
84
|
+
if (expectedKey.length !== 32) {
|
|
85
|
+
throw new Error('Expected key must be 32 bytes');
|
|
86
|
+
}
|
|
87
|
+
const kdfParams = { ...DEFAULT_KDF_PARAMS, ...params };
|
|
88
|
+
// Re-derive key using same salt
|
|
89
|
+
const derivedKey = argon2id(password, salt, {
|
|
90
|
+
m: kdfParams.memory,
|
|
91
|
+
t: kdfParams.iterations,
|
|
92
|
+
p: kdfParams.parallelism,
|
|
93
|
+
dkLen: kdfParams.keyLength,
|
|
94
|
+
});
|
|
95
|
+
// Constant-time comparison to prevent timing attacks
|
|
96
|
+
try {
|
|
97
|
+
return timingSafeEqual(Buffer.from(derivedKey), Buffer.from(expectedKey));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// timingSafeEqual throws if lengths don't match
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
63
104
|
//# 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":"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"}
|
|
@@ -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,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all Footprint errors
|
|
3
|
+
* Provides structured error information with error codes and HTTP-like status codes
|
|
4
|
+
*/
|
|
5
|
+
export declare abstract class FootprintError extends Error {
|
|
6
|
+
readonly code: string;
|
|
7
|
+
readonly statusCode: number;
|
|
8
|
+
readonly context?: Record<string, unknown> | undefined;
|
|
9
|
+
constructor(message: string, code: string, statusCode: number, context?: Record<string, unknown> | undefined);
|
|
10
|
+
/**
|
|
11
|
+
* Convert error to JSON format for logging or API responses
|
|
12
|
+
*/
|
|
13
|
+
toJSON(): Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=base-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-error.d.ts","sourceRoot":"","sources":["../../../../src/lib/errors/base-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,8BAAsB,cAAe,SAAQ,KAAK;aAG9B,IAAI,EAAE,MAAM;aACZ,UAAU,EAAE,MAAM;aAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAHjD,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA;IAWnD;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAUlC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all Footprint errors
|
|
3
|
+
* Provides structured error information with error codes and HTTP-like status codes
|
|
4
|
+
*/
|
|
5
|
+
export class FootprintError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
statusCode;
|
|
8
|
+
context;
|
|
9
|
+
constructor(message, code, statusCode, context) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.statusCode = statusCode;
|
|
13
|
+
this.context = context;
|
|
14
|
+
this.name = this.constructor.name;
|
|
15
|
+
// Maintains proper stack trace for where error was thrown (V8 only)
|
|
16
|
+
if (Error.captureStackTrace) {
|
|
17
|
+
Error.captureStackTrace(this, this.constructor);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Convert error to JSON format for logging or API responses
|
|
22
|
+
*/
|
|
23
|
+
toJSON() {
|
|
24
|
+
return {
|
|
25
|
+
name: this.name,
|
|
26
|
+
message: this.message,
|
|
27
|
+
code: this.code,
|
|
28
|
+
statusCode: this.statusCode,
|
|
29
|
+
context: this.context,
|
|
30
|
+
stack: this.stack
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=base-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-error.js","sourceRoot":"","sources":["../../../../src/lib/errors/base-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAgB,cAAe,SAAQ,KAAK;IAG9B;IACA;IACA;IAJlB,YACE,OAAe,EACC,IAAY,EACZ,UAAkB,EAClB,OAAiC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAQ;QAClB,YAAO,GAAP,OAAO,CAA0B;QAGjD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAElC,oEAAoE;QACpE,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FootprintError } from './base-error.js';
|
|
2
|
+
/**
|
|
3
|
+
* Cryptography error for encryption, decryption, and key operations
|
|
4
|
+
* HTTP status code: 500 (Internal Server Error)
|
|
5
|
+
*/
|
|
6
|
+
export declare class CryptoError extends FootprintError {
|
|
7
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
8
|
+
/**
|
|
9
|
+
* Create a crypto error for encryption failures
|
|
10
|
+
*/
|
|
11
|
+
static encryptionFailed(originalError: Error): CryptoError;
|
|
12
|
+
/**
|
|
13
|
+
* Create a crypto error for decryption failures
|
|
14
|
+
*/
|
|
15
|
+
static decryptionFailed(reason?: string): CryptoError;
|
|
16
|
+
/**
|
|
17
|
+
* Create a crypto error for key derivation failures
|
|
18
|
+
*/
|
|
19
|
+
static keyDerivationFailed(originalError: Error): CryptoError;
|
|
20
|
+
/**
|
|
21
|
+
* Create a crypto error for invalid key
|
|
22
|
+
*/
|
|
23
|
+
static invalidKey(reason: string): CryptoError;
|
|
24
|
+
/**
|
|
25
|
+
* Create a crypto error for invalid nonce
|
|
26
|
+
*/
|
|
27
|
+
static invalidNonce(reason: string): CryptoError;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=crypto-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto-error.d.ts","sourceRoot":"","sources":["../../../../src/lib/errors/crypto-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;GAGG;AACH,qBAAa,WAAY,SAAQ,cAAc;gBACjC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI9D;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,KAAK,GAAG,WAAW;IAO1D;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW;IASrD;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,KAAK,GAAG,WAAW;IAO7D;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;IAI9C;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;CAGjD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { FootprintError } from './base-error.js';
|
|
2
|
+
/**
|
|
3
|
+
* Cryptography error for encryption, decryption, and key operations
|
|
4
|
+
* HTTP status code: 500 (Internal Server Error)
|
|
5
|
+
*/
|
|
6
|
+
export class CryptoError extends FootprintError {
|
|
7
|
+
constructor(message, context) {
|
|
8
|
+
super(message, 'CRYPTO_ERROR', 500, context);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Create a crypto error for encryption failures
|
|
12
|
+
*/
|
|
13
|
+
static encryptionFailed(originalError) {
|
|
14
|
+
return new CryptoError(`Encryption failed: ${originalError.message}`, { originalError: originalError.message });
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create a crypto error for decryption failures
|
|
18
|
+
*/
|
|
19
|
+
static decryptionFailed(reason) {
|
|
20
|
+
return new CryptoError(reason
|
|
21
|
+
? `Decryption failed: ${reason}`
|
|
22
|
+
: 'Decryption failed: invalid key or tampered data', { reason });
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create a crypto error for key derivation failures
|
|
26
|
+
*/
|
|
27
|
+
static keyDerivationFailed(originalError) {
|
|
28
|
+
return new CryptoError(`Key derivation failed: ${originalError.message}`, { originalError: originalError.message });
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create a crypto error for invalid key
|
|
32
|
+
*/
|
|
33
|
+
static invalidKey(reason) {
|
|
34
|
+
return new CryptoError(`Invalid key: ${reason}`, { reason });
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create a crypto error for invalid nonce
|
|
38
|
+
*/
|
|
39
|
+
static invalidNonce(reason) {
|
|
40
|
+
return new CryptoError(`Invalid nonce: ${reason}`, { reason });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=crypto-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto-error.js","sourceRoot":"","sources":["../../../../src/lib/errors/crypto-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,cAAc;IAC7C,YAAY,OAAe,EAAE,OAAiC;QAC5D,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,aAAoB;QAC1C,OAAO,IAAI,WAAW,CACpB,sBAAsB,aAAa,CAAC,OAAO,EAAE,EAC7C,EAAE,aAAa,EAAE,aAAa,CAAC,OAAO,EAAE,CACzC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAe;QACrC,OAAO,IAAI,WAAW,CACpB,MAAM;YACJ,CAAC,CAAC,sBAAsB,MAAM,EAAE;YAChC,CAAC,CAAC,iDAAiD,EACrD,EAAE,MAAM,EAAE,CACX,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,aAAoB;QAC7C,OAAO,IAAI,WAAW,CACpB,0BAA0B,aAAa,CAAC,OAAO,EAAE,EACjD,EAAE,aAAa,EAAE,aAAa,CAAC,OAAO,EAAE,CACzC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAc;QAC9B,OAAO,IAAI,WAAW,CAAC,gBAAgB,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,MAAc;QAChC,OAAO,IAAI,WAAW,CAAC,kBAAkB,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured error hierarchy for Footprint MCP server
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { ValidationError, StorageError, CryptoError } from './lib/errors/index.js';
|
|
7
|
+
*
|
|
8
|
+
* // Validation errors (HTTP 400)
|
|
9
|
+
* throw ValidationError.required('conversationId');
|
|
10
|
+
* throw ValidationError.invalidFormat('tags', 'comma-separated string');
|
|
11
|
+
* throw new ValidationError('Content cannot be empty', { field: 'content' });
|
|
12
|
+
*
|
|
13
|
+
* // Storage errors (HTTP 500)
|
|
14
|
+
* throw StorageError.notFound('Evidence', id);
|
|
15
|
+
* throw StorageError.databaseOperation('insert', error);
|
|
16
|
+
*
|
|
17
|
+
* // Crypto errors (HTTP 500)
|
|
18
|
+
* throw CryptoError.decryptionFailed();
|
|
19
|
+
* throw CryptoError.invalidKey('Key must be 32 bytes');
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export { FootprintError } from './base-error.js';
|
|
23
|
+
export { ValidationError } from './validation-error.js';
|
|
24
|
+
export { StorageError } from './storage-error.js';
|
|
25
|
+
export { CryptoError } from './crypto-error.js';
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/errors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured error hierarchy for Footprint MCP server
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { ValidationError, StorageError, CryptoError } from './lib/errors/index.js';
|
|
7
|
+
*
|
|
8
|
+
* // Validation errors (HTTP 400)
|
|
9
|
+
* throw ValidationError.required('conversationId');
|
|
10
|
+
* throw ValidationError.invalidFormat('tags', 'comma-separated string');
|
|
11
|
+
* throw new ValidationError('Content cannot be empty', { field: 'content' });
|
|
12
|
+
*
|
|
13
|
+
* // Storage errors (HTTP 500)
|
|
14
|
+
* throw StorageError.notFound('Evidence', id);
|
|
15
|
+
* throw StorageError.databaseOperation('insert', error);
|
|
16
|
+
*
|
|
17
|
+
* // Crypto errors (HTTP 500)
|
|
18
|
+
* throw CryptoError.decryptionFailed();
|
|
19
|
+
* throw CryptoError.invalidKey('Key must be 32 bytes');
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export { FootprintError } from './base-error.js';
|
|
23
|
+
export { ValidationError } from './validation-error.js';
|
|
24
|
+
export { StorageError } from './storage-error.js';
|
|
25
|
+
export { CryptoError } from './crypto-error.js';
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/errors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|