@capsara/sdk 1.0.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/LICENSE +74 -0
- package/README.md +230 -0
- package/dist/builder/capsa-builder.d.ts +167 -0
- package/dist/builder/capsa-builder.d.ts.map +1 -0
- package/dist/builder/capsa-builder.js +489 -0
- package/dist/builder/capsa-builder.js.map +1 -0
- package/dist/client/capsara-client.d.ts +96 -0
- package/dist/client/capsara-client.d.ts.map +1 -0
- package/dist/client/capsara-client.js +266 -0
- package/dist/client/capsara-client.js.map +1 -0
- package/dist/errors/account-error.d.ts +73 -0
- package/dist/errors/account-error.d.ts.map +1 -0
- package/dist/errors/account-error.js +155 -0
- package/dist/errors/account-error.js.map +1 -0
- package/dist/errors/audit-error.d.ts +34 -0
- package/dist/errors/audit-error.d.ts.map +1 -0
- package/dist/errors/audit-error.js +93 -0
- package/dist/errors/audit-error.js.map +1 -0
- package/dist/errors/auth-error.d.ts +38 -0
- package/dist/errors/auth-error.d.ts.map +1 -0
- package/dist/errors/auth-error.js +87 -0
- package/dist/errors/auth-error.js.map +1 -0
- package/dist/errors/capsa-error.d.ts +64 -0
- package/dist/errors/capsa-error.d.ts.map +1 -0
- package/dist/errors/capsa-error.js +172 -0
- package/dist/errors/capsa-error.js.map +1 -0
- package/dist/errors/capsara-error.d.ts +52 -0
- package/dist/errors/capsara-error.d.ts.map +1 -0
- package/dist/errors/capsara-error.js +83 -0
- package/dist/errors/capsara-error.js.map +1 -0
- package/dist/errors/index.d.ts +8 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +7 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/capsa-cache.d.ts +49 -0
- package/dist/internal/capsa-cache.d.ts.map +1 -0
- package/dist/internal/capsa-cache.js +118 -0
- package/dist/internal/capsa-cache.js.map +1 -0
- package/dist/internal/config/http-client.d.ts +37 -0
- package/dist/internal/config/http-client.d.ts.map +1 -0
- package/dist/internal/config/http-client.js +63 -0
- package/dist/internal/config/http-client.js.map +1 -0
- package/dist/internal/config/retry-interceptor.d.ts +18 -0
- package/dist/internal/config/retry-interceptor.d.ts.map +1 -0
- package/dist/internal/config/retry-interceptor.js +103 -0
- package/dist/internal/config/retry-interceptor.js.map +1 -0
- package/dist/internal/crypto/compression.d.ts +15 -0
- package/dist/internal/crypto/compression.d.ts.map +1 -0
- package/dist/internal/crypto/compression.js +34 -0
- package/dist/internal/crypto/compression.js.map +1 -0
- package/dist/internal/crypto/key-generator.d.ts +23 -0
- package/dist/internal/crypto/key-generator.d.ts.map +1 -0
- package/dist/internal/crypto/key-generator.js +65 -0
- package/dist/internal/crypto/key-generator.js.map +1 -0
- package/dist/internal/crypto/primitives.d.ts +67 -0
- package/dist/internal/crypto/primitives.d.ts.map +1 -0
- package/dist/internal/crypto/primitives.js +230 -0
- package/dist/internal/crypto/primitives.js.map +1 -0
- package/dist/internal/crypto/signatures.d.ts +30 -0
- package/dist/internal/crypto/signatures.d.ts.map +1 -0
- package/dist/internal/crypto/signatures.js +153 -0
- package/dist/internal/crypto/signatures.js.map +1 -0
- package/dist/internal/decryptor/capsa-decryptor.d.ts +89 -0
- package/dist/internal/decryptor/capsa-decryptor.d.ts.map +1 -0
- package/dist/internal/decryptor/capsa-decryptor.js +263 -0
- package/dist/internal/decryptor/capsa-decryptor.js.map +1 -0
- package/dist/internal/http-factory.d.ts +78 -0
- package/dist/internal/http-factory.d.ts.map +1 -0
- package/dist/internal/http-factory.js +201 -0
- package/dist/internal/http-factory.js.map +1 -0
- package/dist/internal/index.d.ts +5 -0
- package/dist/internal/index.d.ts.map +1 -0
- package/dist/internal/index.js +5 -0
- package/dist/internal/index.js.map +1 -0
- package/dist/internal/retry-executor.d.ts +74 -0
- package/dist/internal/retry-executor.d.ts.map +1 -0
- package/dist/internal/retry-executor.js +204 -0
- package/dist/internal/retry-executor.js.map +1 -0
- package/dist/internal/services/account-service.d.ts +56 -0
- package/dist/internal/services/account-service.d.ts.map +1 -0
- package/dist/internal/services/account-service.js +114 -0
- package/dist/internal/services/account-service.js.map +1 -0
- package/dist/internal/services/audit-service.d.ts +25 -0
- package/dist/internal/services/audit-service.d.ts.map +1 -0
- package/dist/internal/services/audit-service.js +43 -0
- package/dist/internal/services/audit-service.js.map +1 -0
- package/dist/internal/services/auth-service.d.ts +44 -0
- package/dist/internal/services/auth-service.d.ts.map +1 -0
- package/dist/internal/services/auth-service.js +170 -0
- package/dist/internal/services/auth-service.js.map +1 -0
- package/dist/internal/services/capsa-service.d.ts +40 -0
- package/dist/internal/services/capsa-service.d.ts.map +1 -0
- package/dist/internal/services/capsa-service.js +82 -0
- package/dist/internal/services/capsa-service.js.map +1 -0
- package/dist/internal/services/download-service.d.ts +62 -0
- package/dist/internal/services/download-service.d.ts.map +1 -0
- package/dist/internal/services/download-service.js +114 -0
- package/dist/internal/services/download-service.js.map +1 -0
- package/dist/internal/services/key-service.d.ts +28 -0
- package/dist/internal/services/key-service.d.ts.map +1 -0
- package/dist/internal/services/key-service.js +45 -0
- package/dist/internal/services/key-service.js.map +1 -0
- package/dist/internal/services/limits-service.d.ts +30 -0
- package/dist/internal/services/limits-service.d.ts.map +1 -0
- package/dist/internal/services/limits-service.js +73 -0
- package/dist/internal/services/limits-service.js.map +1 -0
- package/dist/internal/services/upload-service.d.ts +61 -0
- package/dist/internal/services/upload-service.d.ts.map +1 -0
- package/dist/internal/services/upload-service.js +258 -0
- package/dist/internal/services/upload-service.js.map +1 -0
- package/dist/internal/types.d.ts +74 -0
- package/dist/internal/types.d.ts.map +1 -0
- package/dist/internal/types.js +3 -0
- package/dist/internal/types.js.map +1 -0
- package/dist/internal/upload/multipart-builder.d.ts +57 -0
- package/dist/internal/upload/multipart-builder.d.ts.map +1 -0
- package/dist/internal/upload/multipart-builder.js +139 -0
- package/dist/internal/upload/multipart-builder.js.map +1 -0
- package/dist/internal/utils/id-generator.d.ts +8 -0
- package/dist/internal/utils/id-generator.d.ts.map +1 -0
- package/dist/internal/utils/id-generator.js +20 -0
- package/dist/internal/utils/id-generator.js.map +1 -0
- package/dist/internal/utils/mimetype-lookup.d.ts +8 -0
- package/dist/internal/utils/mimetype-lookup.d.ts.map +1 -0
- package/dist/internal/utils/mimetype-lookup.js +118 -0
- package/dist/internal/utils/mimetype-lookup.js.map +1 -0
- package/dist/internal/version.d.ts +20 -0
- package/dist/internal/version.d.ts.map +1 -0
- package/dist/internal/version.js +25 -0
- package/dist/internal/version.js.map +1 -0
- package/dist/types/index.d.ts +143 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +20 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
/** Fluent capsa builder for creating encrypted capsas. */
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { generateId } from '../internal/utils/id-generator.js';
|
|
5
|
+
import { lookupMimeType } from '../internal/utils/mimetype-lookup.js';
|
|
6
|
+
import { generateMasterKey, generateIV, encryptAES, encryptAESRaw, encryptMasterKeyForParty, computeHash, } from '../internal/crypto/primitives.js';
|
|
7
|
+
import { buildCanonicalString, createCapsaSignature, } from '../internal/crypto/signatures.js';
|
|
8
|
+
import { compressData, shouldCompress, } from '../internal/crypto/compression.js';
|
|
9
|
+
/** Server-aligned validation constants. */
|
|
10
|
+
export const SERVER_LIMITS = {
|
|
11
|
+
/** Maximum keychain entries (recipients + creator + delegates) */
|
|
12
|
+
MAX_KEYCHAIN_KEYS: 100,
|
|
13
|
+
/** Maximum base64url-encoded encrypted subject length */
|
|
14
|
+
MAX_ENCRYPTED_SUBJECT: 65_536,
|
|
15
|
+
/** Maximum base64url-encoded encrypted body length */
|
|
16
|
+
MAX_ENCRYPTED_BODY: 1_048_576,
|
|
17
|
+
/** Maximum base64url-encoded encrypted structured data length */
|
|
18
|
+
MAX_ENCRYPTED_STRUCTURED: 1_048_576,
|
|
19
|
+
/** Maximum metadata label length */
|
|
20
|
+
MAX_METADATA_LABEL: 512,
|
|
21
|
+
/** Maximum tags per envelope */
|
|
22
|
+
MAX_METADATA_TAGS: 100,
|
|
23
|
+
/** Maximum characters per tag */
|
|
24
|
+
MAX_TAG_LENGTH: 100,
|
|
25
|
+
/** Maximum metadata notes length */
|
|
26
|
+
MAX_METADATA_NOTES: 10_240,
|
|
27
|
+
/** Maximum related packages */
|
|
28
|
+
MAX_RELATED_PACKAGES: 50,
|
|
29
|
+
/** Maximum party ID length */
|
|
30
|
+
MAX_PARTY_ID_LENGTH: 100,
|
|
31
|
+
/** Maximum base64url-encoded encrypted filename length */
|
|
32
|
+
MAX_ENCRYPTED_FILENAME: 2_048,
|
|
33
|
+
/** Maximum base64url-encoded signature payload length */
|
|
34
|
+
MAX_SIGNATURE_PAYLOAD: 65_536,
|
|
35
|
+
/** Maximum parties a delegate can act for */
|
|
36
|
+
MAX_ACTING_FOR: 10,
|
|
37
|
+
};
|
|
38
|
+
export class CapsaBuilder {
|
|
39
|
+
subject;
|
|
40
|
+
body;
|
|
41
|
+
structured = {};
|
|
42
|
+
/** Unencrypted metadata */
|
|
43
|
+
metadata = {};
|
|
44
|
+
/** Expiration date (UTC, rounded to minute) */
|
|
45
|
+
get expiresAt() {
|
|
46
|
+
return this.#expiresAt ? new Date(this.#expiresAt) : undefined;
|
|
47
|
+
}
|
|
48
|
+
set expiresAt(value) {
|
|
49
|
+
if (value === undefined) {
|
|
50
|
+
this.#expiresAt = undefined;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const dateObj = typeof value === 'string' ? new Date(value) : value;
|
|
54
|
+
dateObj.setSeconds(0, 0);
|
|
55
|
+
this.#expiresAt = dateObj.toISOString();
|
|
56
|
+
}
|
|
57
|
+
#masterKey;
|
|
58
|
+
#creatorId;
|
|
59
|
+
#recipients = [];
|
|
60
|
+
#files = [];
|
|
61
|
+
#creatorPrivateKey;
|
|
62
|
+
#limits;
|
|
63
|
+
#expiresAt;
|
|
64
|
+
constructor(creatorId, creatorPrivateKey, limits) {
|
|
65
|
+
this.#masterKey = generateMasterKey();
|
|
66
|
+
this.#creatorId = creatorId;
|
|
67
|
+
this.#creatorPrivateKey = creatorPrivateKey;
|
|
68
|
+
this.#limits = limits;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Add a recipient to the capsa
|
|
72
|
+
* @param partyId - Party ID
|
|
73
|
+
*/
|
|
74
|
+
addRecipient(partyId) {
|
|
75
|
+
if (!partyId || partyId.length === 0) {
|
|
76
|
+
throw new Error('Party ID cannot be empty.');
|
|
77
|
+
}
|
|
78
|
+
if (partyId.length > SERVER_LIMITS.MAX_PARTY_ID_LENGTH) {
|
|
79
|
+
throw new Error(`Party ID (${partyId.length} chars) exceeds server limit of ${SERVER_LIMITS.MAX_PARTY_ID_LENGTH} chars.`);
|
|
80
|
+
}
|
|
81
|
+
// +1 for the creator who also gets a keychain entry
|
|
82
|
+
if (this.#recipients.length + 1 >= SERVER_LIMITS.MAX_KEYCHAIN_KEYS) {
|
|
83
|
+
throw new Error(`Cannot add recipient: keychain would exceed ${SERVER_LIMITS.MAX_KEYCHAIN_KEYS} entries (including creator). Server will reject this capsa.`);
|
|
84
|
+
}
|
|
85
|
+
this.#recipients.push({ partyId, permissions: ['read'] });
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Add multiple recipients to the capsa
|
|
90
|
+
* @param partyIds - Party IDs
|
|
91
|
+
*/
|
|
92
|
+
addRecipients(...partyIds) {
|
|
93
|
+
for (const partyId of partyIds) {
|
|
94
|
+
if (!partyId || partyId.length === 0) {
|
|
95
|
+
throw new Error('Party ID cannot be empty.');
|
|
96
|
+
}
|
|
97
|
+
if (partyId.length > SERVER_LIMITS.MAX_PARTY_ID_LENGTH) {
|
|
98
|
+
throw new Error(`Party ID (${partyId.length} chars) exceeds server limit of ${SERVER_LIMITS.MAX_PARTY_ID_LENGTH} chars.`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// +1 for the creator who also gets a keychain entry
|
|
102
|
+
if (this.#recipients.length + partyIds.length + 1 > SERVER_LIMITS.MAX_KEYCHAIN_KEYS) {
|
|
103
|
+
throw new Error(`Cannot add ${partyIds.length} recipients: keychain would have ${this.#recipients.length + partyIds.length + 1} entries (max ${SERVER_LIMITS.MAX_KEYCHAIN_KEYS}). Server will reject this capsa.`);
|
|
104
|
+
}
|
|
105
|
+
for (const partyId of partyIds) {
|
|
106
|
+
this.#recipients.push({ partyId, permissions: ['read'] });
|
|
107
|
+
}
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Add a file to the capsa
|
|
112
|
+
* @param input - File input (path or buffer with filename)
|
|
113
|
+
* @throws Error if file exceeds size limit or too many files
|
|
114
|
+
*/
|
|
115
|
+
addFile(input) {
|
|
116
|
+
if (this.#files.length >= this.#limits.maxFilesPerCapsa) {
|
|
117
|
+
throw new Error(`Cannot add file: capsa already has ${this.#files.length} files (max: ${this.#limits.maxFilesPerCapsa})`);
|
|
118
|
+
}
|
|
119
|
+
let fileSize;
|
|
120
|
+
if (input.buffer) {
|
|
121
|
+
fileSize = input.buffer.length;
|
|
122
|
+
}
|
|
123
|
+
else if (input.path) {
|
|
124
|
+
fileSize = fs.statSync(input.path).size;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
throw new Error('File input must have either path or buffer');
|
|
128
|
+
}
|
|
129
|
+
if (fileSize > this.#limits.maxFileSize) {
|
|
130
|
+
throw new Error(`File "${input.filename}" exceeds maximum size of ${Math.floor(this.#limits.maxFileSize / 1024 / 1024)}MB (${fileSize} bytes)`);
|
|
131
|
+
}
|
|
132
|
+
this.#files.push({ input });
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Add a file from a file path
|
|
137
|
+
* @param filePath - File path on disk
|
|
138
|
+
* @param filename - Filename override (defaults to basename)
|
|
139
|
+
* @param mimetype - MIME type (auto-detected if not specified)
|
|
140
|
+
*/
|
|
141
|
+
addFileFromPath(filePath, filename, mimetype) {
|
|
142
|
+
const resolvedFilename = filename ?? path.basename(filePath);
|
|
143
|
+
return this.addFile({ path: filePath, filename: resolvedFilename, mimetype });
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Add a file from a Buffer
|
|
147
|
+
* @param buffer - File content
|
|
148
|
+
* @param filename - Filename
|
|
149
|
+
* @param mimetype - MIME type (auto-detected if not specified)
|
|
150
|
+
*/
|
|
151
|
+
addFileFromBuffer(buffer, filename, mimetype) {
|
|
152
|
+
return this.addFile({ buffer, filename, mimetype });
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Add multiple files from file paths
|
|
156
|
+
* @param paths - File paths on disk
|
|
157
|
+
*/
|
|
158
|
+
addFiles(...paths) {
|
|
159
|
+
for (const path of paths) {
|
|
160
|
+
this.addFileFromPath(path);
|
|
161
|
+
}
|
|
162
|
+
return this;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Add multiple files from FileInput objects
|
|
166
|
+
* @param files - File inputs
|
|
167
|
+
*/
|
|
168
|
+
addFilesFromInputs(...files) {
|
|
169
|
+
for (const file of files) {
|
|
170
|
+
this.addFile(file);
|
|
171
|
+
}
|
|
172
|
+
return this;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Add a text file from string content
|
|
176
|
+
* @param filename - Filename
|
|
177
|
+
* @param content - Text content
|
|
178
|
+
*/
|
|
179
|
+
addTextFile(filename, content) {
|
|
180
|
+
const buffer = Buffer.from(content, 'utf-8');
|
|
181
|
+
return this.addFile({ buffer, filename, mimetype: 'text/plain' });
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Add a JSON file from an object
|
|
185
|
+
* @param filename - Filename
|
|
186
|
+
* @param data - Object to serialize as JSON
|
|
187
|
+
*/
|
|
188
|
+
addJsonFile(filename, data) {
|
|
189
|
+
const json = JSON.stringify(data);
|
|
190
|
+
const buffer = Buffer.from(json, 'utf-8');
|
|
191
|
+
return this.addFile({ buffer, filename, mimetype: 'application/json' });
|
|
192
|
+
}
|
|
193
|
+
withStructured(keyOrData, value) {
|
|
194
|
+
if (typeof keyOrData === 'string') {
|
|
195
|
+
this.structured[keyOrData] = value;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
Object.assign(this.structured, keyOrData);
|
|
199
|
+
}
|
|
200
|
+
return this;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Set the subject
|
|
204
|
+
* @param subject - Subject text
|
|
205
|
+
*/
|
|
206
|
+
withSubject(subject) {
|
|
207
|
+
this.subject = subject;
|
|
208
|
+
return this;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Set the body
|
|
212
|
+
* @param body - Body text
|
|
213
|
+
*/
|
|
214
|
+
withBody(body) {
|
|
215
|
+
this.body = body;
|
|
216
|
+
return this;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Set the expiration
|
|
220
|
+
* @param expiresAt - Expiration date/time
|
|
221
|
+
*/
|
|
222
|
+
withExpiration(expiresAt) {
|
|
223
|
+
this.expiresAt = expiresAt;
|
|
224
|
+
return this;
|
|
225
|
+
}
|
|
226
|
+
async #encryptFile(input) {
|
|
227
|
+
let fileData;
|
|
228
|
+
if (input.buffer) {
|
|
229
|
+
fileData = input.buffer;
|
|
230
|
+
}
|
|
231
|
+
else if (input.path) {
|
|
232
|
+
fileData = fs.readFileSync(input.path);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
throw new Error('File input must have either path or buffer');
|
|
236
|
+
}
|
|
237
|
+
const originalSize = fileData.length;
|
|
238
|
+
const shouldCompressFile = input.compress !== false && shouldCompress(originalSize);
|
|
239
|
+
let dataToEncrypt = fileData;
|
|
240
|
+
let compressed = false;
|
|
241
|
+
let compressionAlgorithm;
|
|
242
|
+
if (shouldCompressFile) {
|
|
243
|
+
const compressionResult = await compressData(fileData);
|
|
244
|
+
dataToEncrypt = compressionResult.compressedData;
|
|
245
|
+
compressed = true;
|
|
246
|
+
compressionAlgorithm = 'gzip';
|
|
247
|
+
}
|
|
248
|
+
const raw = encryptAESRaw(dataToEncrypt, this.#masterKey);
|
|
249
|
+
const hash = computeHash(raw.encryptedData);
|
|
250
|
+
const contentIV = raw.iv.toString('base64url');
|
|
251
|
+
const authTag = raw.authTag.toString('base64url');
|
|
252
|
+
const mimetype = input.mimetype || (input.path && lookupMimeType(input.path)) || 'application/octet-stream';
|
|
253
|
+
return {
|
|
254
|
+
encryptedData: raw.encryptedData,
|
|
255
|
+
iv: contentIV,
|
|
256
|
+
authTag,
|
|
257
|
+
hash,
|
|
258
|
+
size: raw.encryptedData.length,
|
|
259
|
+
mimetype,
|
|
260
|
+
...(compressed && { compressed }),
|
|
261
|
+
...(compressionAlgorithm && { compressionAlgorithm }),
|
|
262
|
+
...(compressed && { originalSize }),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
getRecipientIds() {
|
|
266
|
+
return this.#recipients.map((r) => r.partyId);
|
|
267
|
+
}
|
|
268
|
+
getFileCount() {
|
|
269
|
+
return this.#files.length;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Build the capsa with encryption and signature.
|
|
273
|
+
* @param partyKeys - Public keys for all recipients
|
|
274
|
+
*/
|
|
275
|
+
async build(partyKeys) {
|
|
276
|
+
// No-content guard: server requires files OR a message (subject/body)
|
|
277
|
+
const hasContent = this.#files.length > 0 || this.subject || this.body;
|
|
278
|
+
if (!hasContent) {
|
|
279
|
+
throw new Error('Capsa must contain either files or a message (subject/body). Server will reject empty capsas.');
|
|
280
|
+
}
|
|
281
|
+
const packageId = `capsa_${generateId(22)}`;
|
|
282
|
+
const encryptedFiles = [];
|
|
283
|
+
let totalSize = 0;
|
|
284
|
+
for (const file of this.#files) {
|
|
285
|
+
const encrypted = await this.#encryptFile(file.input);
|
|
286
|
+
const { encryptedData: encryptedFilename, iv: filenameIV, authTag: filenameAuthTag } = encryptAES(Buffer.from(file.input.filename, 'utf-8'), this.#masterKey);
|
|
287
|
+
if (encryptedFilename.length > SERVER_LIMITS.MAX_ENCRYPTED_FILENAME) {
|
|
288
|
+
throw new Error(`Encrypted filename for "${file.input.filename.slice(0, 30)}..." (${encryptedFilename.length} chars) exceeds server limit of ${SERVER_LIMITS.MAX_ENCRYPTED_FILENAME} chars. Use a shorter filename.`);
|
|
289
|
+
}
|
|
290
|
+
let normalizedFileExpiresAt;
|
|
291
|
+
if (file.input.expiresAt !== undefined) {
|
|
292
|
+
const dateObj = typeof file.input.expiresAt === 'string' ? new Date(file.input.expiresAt) : file.input.expiresAt;
|
|
293
|
+
dateObj.setSeconds(0, 0);
|
|
294
|
+
normalizedFileExpiresAt = dateObj.toISOString();
|
|
295
|
+
}
|
|
296
|
+
const fileMetadata = {
|
|
297
|
+
fileId: `file_${generateId(16)}.enc`,
|
|
298
|
+
encryptedFilename,
|
|
299
|
+
filenameIV,
|
|
300
|
+
filenameAuthTag,
|
|
301
|
+
iv: encrypted.iv,
|
|
302
|
+
authTag: encrypted.authTag,
|
|
303
|
+
mimetype: encrypted.mimetype,
|
|
304
|
+
size: encrypted.size,
|
|
305
|
+
hash: encrypted.hash,
|
|
306
|
+
hashAlgorithm: 'SHA-256',
|
|
307
|
+
...(encrypted.compressed !== undefined && { compressed: encrypted.compressed }),
|
|
308
|
+
...(encrypted.compressionAlgorithm && { compressionAlgorithm: encrypted.compressionAlgorithm }),
|
|
309
|
+
...(encrypted.originalSize !== undefined && { originalSize: encrypted.originalSize }),
|
|
310
|
+
...(normalizedFileExpiresAt !== undefined && { expiresAt: normalizedFileExpiresAt }),
|
|
311
|
+
...(file.input.transform && { transform: file.input.transform }),
|
|
312
|
+
};
|
|
313
|
+
encryptedFiles.push({
|
|
314
|
+
metadata: fileMetadata,
|
|
315
|
+
data: encrypted.encryptedData,
|
|
316
|
+
});
|
|
317
|
+
totalSize += encrypted.size;
|
|
318
|
+
}
|
|
319
|
+
if (totalSize > this.#limits.maxTotalSize) {
|
|
320
|
+
throw new Error(`Total capsa size ${totalSize} bytes exceeds maximum of ${Math.floor(this.#limits.maxTotalSize / 1024 / 1024)}MB`);
|
|
321
|
+
}
|
|
322
|
+
let encryptedSubject;
|
|
323
|
+
let subjectIV;
|
|
324
|
+
let subjectAuthTag;
|
|
325
|
+
let encryptedBody;
|
|
326
|
+
let bodyIV;
|
|
327
|
+
let bodyAuthTag;
|
|
328
|
+
let encryptedStructured;
|
|
329
|
+
let structuredIV;
|
|
330
|
+
let structuredAuthTag;
|
|
331
|
+
if (this.subject) {
|
|
332
|
+
const result = encryptAES(Buffer.from(this.subject, 'utf-8'), this.#masterKey);
|
|
333
|
+
encryptedSubject = result.encryptedData;
|
|
334
|
+
subjectIV = result.iv;
|
|
335
|
+
subjectAuthTag = result.authTag;
|
|
336
|
+
if (encryptedSubject.length > SERVER_LIMITS.MAX_ENCRYPTED_SUBJECT) {
|
|
337
|
+
throw new Error(`Encrypted subject (${encryptedSubject.length} chars) exceeds server limit of ${SERVER_LIMITS.MAX_ENCRYPTED_SUBJECT} chars. Reduce subject length.`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
if (this.body) {
|
|
341
|
+
const result = encryptAES(Buffer.from(this.body, 'utf-8'), this.#masterKey);
|
|
342
|
+
encryptedBody = result.encryptedData;
|
|
343
|
+
bodyIV = result.iv;
|
|
344
|
+
bodyAuthTag = result.authTag;
|
|
345
|
+
if (encryptedBody.length > SERVER_LIMITS.MAX_ENCRYPTED_BODY) {
|
|
346
|
+
throw new Error(`Encrypted body (${encryptedBody.length} chars) exceeds server limit of ${SERVER_LIMITS.MAX_ENCRYPTED_BODY} chars. Reduce body length.`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
const hasStructured = Object.keys(this.structured).length > 0;
|
|
350
|
+
if (hasStructured) {
|
|
351
|
+
const result = encryptAES(Buffer.from(JSON.stringify(this.structured), 'utf-8'), this.#masterKey);
|
|
352
|
+
encryptedStructured = result.encryptedData;
|
|
353
|
+
structuredIV = result.iv;
|
|
354
|
+
structuredAuthTag = result.authTag;
|
|
355
|
+
if (encryptedStructured.length > SERVER_LIMITS.MAX_ENCRYPTED_STRUCTURED) {
|
|
356
|
+
throw new Error(`Encrypted structured data (${encryptedStructured.length} chars) exceeds server limit of ${SERVER_LIMITS.MAX_ENCRYPTED_STRUCTURED} chars. Reduce structured data size.`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
const keychain = [];
|
|
360
|
+
for (const partyKey of partyKeys) {
|
|
361
|
+
const recipient = this.#recipients.find((r) => r.partyId === partyKey.id);
|
|
362
|
+
const isCreator = partyKey.id === this.#creatorId;
|
|
363
|
+
let permissions = [];
|
|
364
|
+
let actingFor;
|
|
365
|
+
if (partyKey.isDelegate && Array.isArray(partyKey.isDelegate)) {
|
|
366
|
+
const recipientIds = this.#recipients.map(r => r.partyId);
|
|
367
|
+
const relevantActingFor = partyKey.isDelegate.filter(id => recipientIds.includes(id));
|
|
368
|
+
if (relevantActingFor.length === 0) {
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
if (relevantActingFor.length > SERVER_LIMITS.MAX_ACTING_FOR) {
|
|
372
|
+
throw new Error(`Delegate "${partyKey.id}" acting for ${relevantActingFor.length} parties exceeds server limit of ${SERVER_LIMITS.MAX_ACTING_FOR}.`);
|
|
373
|
+
}
|
|
374
|
+
permissions = ['delegate'];
|
|
375
|
+
actingFor = relevantActingFor;
|
|
376
|
+
}
|
|
377
|
+
else if (isCreator) {
|
|
378
|
+
permissions = [];
|
|
379
|
+
}
|
|
380
|
+
else if (recipient) {
|
|
381
|
+
permissions = recipient.permissions;
|
|
382
|
+
actingFor = recipient.actingFor;
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
const isDelegatedRecipient = permissions.length === 0 && !isCreator;
|
|
388
|
+
const keyIV = generateIV();
|
|
389
|
+
keychain.push({
|
|
390
|
+
party: partyKey.id,
|
|
391
|
+
encryptedKey: isDelegatedRecipient
|
|
392
|
+
? ''
|
|
393
|
+
: encryptMasterKeyForParty(this.#masterKey, partyKey.publicKey),
|
|
394
|
+
iv: keyIV,
|
|
395
|
+
fingerprint: partyKey.fingerprint,
|
|
396
|
+
permissions,
|
|
397
|
+
actingFor,
|
|
398
|
+
revoked: false,
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
const canonicalString = buildCanonicalString({
|
|
402
|
+
packageId,
|
|
403
|
+
totalSize,
|
|
404
|
+
algorithm: 'AES-256-GCM',
|
|
405
|
+
files: encryptedFiles.map((f) => f.metadata),
|
|
406
|
+
structuredIV,
|
|
407
|
+
subjectIV,
|
|
408
|
+
bodyIV,
|
|
409
|
+
});
|
|
410
|
+
const signature = createCapsaSignature(canonicalString, this.#creatorPrivateKey);
|
|
411
|
+
if (signature.payload.length > SERVER_LIMITS.MAX_SIGNATURE_PAYLOAD) {
|
|
412
|
+
throw new Error(`Signature payload (${signature.payload.length} chars) exceeds server limit of ${SERVER_LIMITS.MAX_SIGNATURE_PAYLOAD} chars.`);
|
|
413
|
+
}
|
|
414
|
+
const capsa = {
|
|
415
|
+
packageId,
|
|
416
|
+
keychain: {
|
|
417
|
+
algorithm: 'AES-256-GCM',
|
|
418
|
+
keys: keychain,
|
|
419
|
+
},
|
|
420
|
+
signature,
|
|
421
|
+
files: encryptedFiles.map((f) => f.metadata),
|
|
422
|
+
accessControl: {
|
|
423
|
+
expiresAt: this.#expiresAt,
|
|
424
|
+
},
|
|
425
|
+
deliveryPriority: 'normal',
|
|
426
|
+
};
|
|
427
|
+
const hasMetadata = this.metadata.label || this.metadata.tags?.length || this.metadata.notes || this.metadata.relatedPackages?.length;
|
|
428
|
+
if (hasMetadata) {
|
|
429
|
+
if (this.metadata.label && this.metadata.label.length > SERVER_LIMITS.MAX_METADATA_LABEL) {
|
|
430
|
+
throw new Error(`Metadata label (${this.metadata.label.length} chars) exceeds server limit of ${SERVER_LIMITS.MAX_METADATA_LABEL} chars.`);
|
|
431
|
+
}
|
|
432
|
+
if (this.metadata.tags && this.metadata.tags.length > SERVER_LIMITS.MAX_METADATA_TAGS) {
|
|
433
|
+
throw new Error(`Metadata tags count (${this.metadata.tags.length}) exceeds server limit of ${SERVER_LIMITS.MAX_METADATA_TAGS}.`);
|
|
434
|
+
}
|
|
435
|
+
if (this.metadata.tags) {
|
|
436
|
+
for (const tag of this.metadata.tags) {
|
|
437
|
+
if (tag.length > SERVER_LIMITS.MAX_TAG_LENGTH) {
|
|
438
|
+
throw new Error(`Metadata tag "${tag.slice(0, 20)}..." (${tag.length} chars) exceeds server limit of ${SERVER_LIMITS.MAX_TAG_LENGTH} chars.`);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
if (this.metadata.notes && this.metadata.notes.length > SERVER_LIMITS.MAX_METADATA_NOTES) {
|
|
443
|
+
throw new Error(`Metadata notes (${this.metadata.notes.length} chars) exceeds server limit of ${SERVER_LIMITS.MAX_METADATA_NOTES} chars.`);
|
|
444
|
+
}
|
|
445
|
+
if (this.metadata.relatedPackages && this.metadata.relatedPackages.length > SERVER_LIMITS.MAX_RELATED_PACKAGES) {
|
|
446
|
+
throw new Error(`Related packages count (${this.metadata.relatedPackages.length}) exceeds server limit of ${SERVER_LIMITS.MAX_RELATED_PACKAGES}.`);
|
|
447
|
+
}
|
|
448
|
+
capsa.metadata = this.metadata;
|
|
449
|
+
}
|
|
450
|
+
if (encryptedSubject) {
|
|
451
|
+
capsa.encryptedSubject = encryptedSubject;
|
|
452
|
+
capsa.subjectIV = subjectIV;
|
|
453
|
+
capsa.subjectAuthTag = subjectAuthTag;
|
|
454
|
+
}
|
|
455
|
+
if (encryptedBody) {
|
|
456
|
+
capsa.encryptedBody = encryptedBody;
|
|
457
|
+
capsa.bodyIV = bodyIV;
|
|
458
|
+
capsa.bodyAuthTag = bodyAuthTag;
|
|
459
|
+
}
|
|
460
|
+
if (encryptedStructured) {
|
|
461
|
+
capsa.encryptedStructured = encryptedStructured;
|
|
462
|
+
capsa.structuredIV = structuredIV;
|
|
463
|
+
capsa.structuredAuthTag = structuredAuthTag;
|
|
464
|
+
}
|
|
465
|
+
// Defense-in-depth: detect duplicate IVs across all fields.
|
|
466
|
+
// Server performs the same check and will reject duplicates.
|
|
467
|
+
const allIVs = [];
|
|
468
|
+
if (subjectIV)
|
|
469
|
+
allIVs.push(subjectIV);
|
|
470
|
+
if (bodyIV)
|
|
471
|
+
allIVs.push(bodyIV);
|
|
472
|
+
if (structuredIV)
|
|
473
|
+
allIVs.push(structuredIV);
|
|
474
|
+
for (const entry of keychain) {
|
|
475
|
+
if (entry.iv)
|
|
476
|
+
allIVs.push(entry.iv);
|
|
477
|
+
}
|
|
478
|
+
for (const file of encryptedFiles) {
|
|
479
|
+
allIVs.push(file.metadata.iv);
|
|
480
|
+
allIVs.push(file.metadata.filenameIV);
|
|
481
|
+
}
|
|
482
|
+
const ivSet = new Set(allIVs);
|
|
483
|
+
if (ivSet.size !== allIVs.length) {
|
|
484
|
+
throw new Error('Duplicate IV detected across capsa fields. This indicates a CSPRNG failure. Do not send this capsa.');
|
|
485
|
+
}
|
|
486
|
+
return { capsa, files: encryptedFiles };
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
//# sourceMappingURL=capsa-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capsa-builder.js","sourceRoot":"","sources":["../../src/builder/capsa-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/** Primary interface for zero-knowledge encrypted file sharing. */
|
|
2
|
+
import { type PublicKeyInfo, type KeyHistoryEntry } from '../internal/services/account-service.js';
|
|
3
|
+
import { type GeneratedKeyPair } from '../internal/crypto/key-generator.js';
|
|
4
|
+
import { CapsaBuilder } from '../builder/capsa-builder.js';
|
|
5
|
+
import { type DecryptedCapsa } from '../internal/decryptor/capsa-decryptor.js';
|
|
6
|
+
import { type HttpTimeoutConfig } from '../internal/config/http-client.js';
|
|
7
|
+
import type { RetryConfig } from '../internal/config/retry-interceptor.js';
|
|
8
|
+
import type { AuthCredentials, AuthResponse, Capsa, SystemLimits, CapsaListFilters, CapsaListResponse, GetAuditEntriesFilters, GetAuditEntriesResponse, CreateAuditEntryRequest, CreateAuditEntryResponse } from '../types/index.js';
|
|
9
|
+
export interface CapsaraClientOptions {
|
|
10
|
+
credentials?: AuthCredentials;
|
|
11
|
+
accessToken?: string;
|
|
12
|
+
expectedIssuer?: string;
|
|
13
|
+
expectedAudience?: string;
|
|
14
|
+
timeout?: Partial<HttpTimeoutConfig>;
|
|
15
|
+
retry?: RetryConfig;
|
|
16
|
+
maxBatchSize?: number;
|
|
17
|
+
cacheTTL?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Custom user agent string to append to the default SDK user agent.
|
|
20
|
+
* Default: "Capsara-SDK/1.0.0 (Node.js v20.x.x)"
|
|
21
|
+
* If provided, becomes: "Capsara-SDK/1.0.0 (Node.js v20.x.x) YourCustomAgent"
|
|
22
|
+
*/
|
|
23
|
+
userAgent?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare class CapsaraClient {
|
|
26
|
+
private creatorId;
|
|
27
|
+
private creatorPrivateKey;
|
|
28
|
+
private authService;
|
|
29
|
+
private keyManager;
|
|
30
|
+
private limitsManager;
|
|
31
|
+
private accountClient;
|
|
32
|
+
private capsaService;
|
|
33
|
+
private downloadService;
|
|
34
|
+
private uploadService;
|
|
35
|
+
private auditService;
|
|
36
|
+
private capsaCache;
|
|
37
|
+
private axiosInstance;
|
|
38
|
+
private blobClient;
|
|
39
|
+
private timeoutConfig;
|
|
40
|
+
private retryConfig;
|
|
41
|
+
private maxBatchSize;
|
|
42
|
+
private logger;
|
|
43
|
+
private refreshPromise;
|
|
44
|
+
private inFlightCapsaFetches;
|
|
45
|
+
constructor(baseUrl: string, options?: CapsaraClientOptions);
|
|
46
|
+
login(credentials: AuthCredentials): Promise<AuthResponse>;
|
|
47
|
+
logout(): Promise<boolean>;
|
|
48
|
+
isAuthenticated(): boolean;
|
|
49
|
+
setPrivateKey(privateKey: string): void;
|
|
50
|
+
createCapsaBuilder(): Promise<CapsaBuilder>;
|
|
51
|
+
sendCapsas(builders: CapsaBuilder[]): Promise<{
|
|
52
|
+
batchId: string;
|
|
53
|
+
successful: number;
|
|
54
|
+
failed: number;
|
|
55
|
+
partialSuccess?: boolean;
|
|
56
|
+
created: Array<{
|
|
57
|
+
packageId: string;
|
|
58
|
+
index: number;
|
|
59
|
+
}>;
|
|
60
|
+
errors?: Array<{
|
|
61
|
+
index: number;
|
|
62
|
+
packageId: string;
|
|
63
|
+
error: string;
|
|
64
|
+
}>;
|
|
65
|
+
}>;
|
|
66
|
+
getCapsa(capsaId: string): Promise<DecryptedCapsa>;
|
|
67
|
+
getCapsa(capsaId: string, options: {
|
|
68
|
+
decrypt: false;
|
|
69
|
+
}): Promise<Capsa>;
|
|
70
|
+
getCapsa(capsaId: string, options: {
|
|
71
|
+
verifySignature?: boolean;
|
|
72
|
+
}): Promise<DecryptedCapsa>;
|
|
73
|
+
private getOrCreateCapsaFetch;
|
|
74
|
+
private fetchAndDecryptCapsa;
|
|
75
|
+
listCapsas(filters?: CapsaListFilters): Promise<CapsaListResponse>;
|
|
76
|
+
deleteCapsa(capsaId: string): Promise<void>;
|
|
77
|
+
downloadFile(capsaId: string, fileId: string): Promise<{
|
|
78
|
+
data: Buffer;
|
|
79
|
+
filename: string;
|
|
80
|
+
}>;
|
|
81
|
+
getAuditEntries(capsaId: string, filters?: GetAuditEntriesFilters): Promise<GetAuditEntriesResponse>;
|
|
82
|
+
createAuditEntry(capsaId: string, entry: CreateAuditEntryRequest): Promise<CreateAuditEntryResponse>;
|
|
83
|
+
getCurrentPublicKey(): Promise<PublicKeyInfo | null>;
|
|
84
|
+
addPublicKey(publicKey: string, fingerprint: string, reason?: string): Promise<PublicKeyInfo>;
|
|
85
|
+
getKeyHistory(): Promise<KeyHistoryEntry[]>;
|
|
86
|
+
rotateKey(): Promise<{
|
|
87
|
+
keyPair: GeneratedKeyPair;
|
|
88
|
+
serverInfo: PublicKeyInfo;
|
|
89
|
+
}>;
|
|
90
|
+
getLimits(): Promise<SystemLimits>;
|
|
91
|
+
static generateKeyPair(): Promise<GeneratedKeyPair>;
|
|
92
|
+
clearCache(): void;
|
|
93
|
+
/** Release all resources and securely clear cached keys. */
|
|
94
|
+
destroy(): Promise<void>;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=capsara-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capsara-client.d.ts","sourceRoot":"","sources":["../../src/client/capsara-client.ts"],"names":[],"mappings":"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"}
|