@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 @@
|
|
|
1
|
+
{"version":3,"file":"retry-executor.d.ts","sourceRoot":"","sources":["../../src/internal/retry-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAA0B,KAAK,iBAAiB,EAA0B,MAAM,mBAAmB,CAAC;AAE3G;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AA4DD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAwB;gBAE1B,MAAM,GAAE,WAAgB;IAIpC;;OAEG;IACG,OAAO,CAAC,CAAC,EACb,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GACxC,OAAO,CAAC,CAAC,CAAC;IAkCb;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IA0DvE;;OAEG;IACH,OAAO,CAAC,cAAc;CAmDvB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,aAAa,CAEvE"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified retry executor - eliminates retry logic duplication
|
|
3
|
+
* @file capsara.sdk/typescript/src/internal/retry-executor.ts
|
|
4
|
+
*
|
|
5
|
+
* This module provides a unified retry mechanism that can be used for:
|
|
6
|
+
* - Axios HTTP requests (via interceptor in http-factory)
|
|
7
|
+
* - Raw HTTP/HTTPS requests (for multipart uploads)
|
|
8
|
+
* - Generic async operations
|
|
9
|
+
*/
|
|
10
|
+
import * as http from 'http';
|
|
11
|
+
import * as https from 'https';
|
|
12
|
+
import { URL } from 'url';
|
|
13
|
+
import { createAgentForProtocol, DEFAULT_TIMEOUT_CONFIG } from './http-factory.js';
|
|
14
|
+
/**
|
|
15
|
+
* Default retry configuration
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_RETRY_CONFIG = {
|
|
18
|
+
maxRetries: 3,
|
|
19
|
+
baseDelay: 1000,
|
|
20
|
+
maxDelay: 30000,
|
|
21
|
+
enableLogging: false,
|
|
22
|
+
// eslint-disable-next-line no-console
|
|
23
|
+
logger: { log: (msg) => console.log(msg) },
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Calculate exponential backoff delay with jitter
|
|
27
|
+
*/
|
|
28
|
+
function calculateBackoff(attempt, baseDelay, maxDelay) {
|
|
29
|
+
const exponentialDelay = baseDelay * Math.pow(2, attempt);
|
|
30
|
+
const jitter = Math.random() * 0.3 * exponentialDelay;
|
|
31
|
+
return Math.min(Math.floor(exponentialDelay + jitter), maxDelay);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Sleep for specified duration
|
|
35
|
+
*/
|
|
36
|
+
function sleep(ms) {
|
|
37
|
+
return new Promise(resolve => globalThis.setTimeout(resolve, ms));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if HTTP status is retryable
|
|
41
|
+
*/
|
|
42
|
+
function isRetryableStatus(status) {
|
|
43
|
+
return status === 503 || status === 429;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse retry delay from response headers
|
|
47
|
+
*/
|
|
48
|
+
function parseRetryDelay(headers) {
|
|
49
|
+
const retryAfter = headers['retry-after'];
|
|
50
|
+
if (!retryAfter || typeof retryAfter !== 'string') {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const seconds = parseInt(retryAfter, 10);
|
|
54
|
+
if (!isNaN(seconds)) {
|
|
55
|
+
return seconds * 1000;
|
|
56
|
+
}
|
|
57
|
+
const date = new Date(retryAfter);
|
|
58
|
+
if (!isNaN(date.getTime())) {
|
|
59
|
+
const delay = date.getTime() - Date.now();
|
|
60
|
+
return delay > 0 ? delay : 0;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Unified retry executor for both axios and raw HTTP requests
|
|
66
|
+
*/
|
|
67
|
+
export class RetryExecutor {
|
|
68
|
+
config;
|
|
69
|
+
constructor(config = {}) {
|
|
70
|
+
this.config = { ...DEFAULT_RETRY_CONFIG, ...config };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Execute a generic async operation with retry
|
|
74
|
+
*/
|
|
75
|
+
async execute(operation, isRetryable) {
|
|
76
|
+
let lastError;
|
|
77
|
+
for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
|
|
78
|
+
try {
|
|
79
|
+
return await operation();
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
lastError = error;
|
|
83
|
+
// Check if we should retry
|
|
84
|
+
if (attempt >= this.config.maxRetries) {
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
// Default: retry on any error; custom function can override
|
|
88
|
+
const shouldRetry = isRetryable ? isRetryable(error) : true;
|
|
89
|
+
if (!shouldRetry) {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
const delay = calculateBackoff(attempt, this.config.baseDelay, this.config.maxDelay);
|
|
93
|
+
if (this.config.enableLogging) {
|
|
94
|
+
this.config.logger.log(`[Capsara SDK] Retry ${attempt + 1}/${this.config.maxRetries} - waiting ${delay}ms`);
|
|
95
|
+
}
|
|
96
|
+
await sleep(delay);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
throw lastError;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Execute a raw HTTP request with retry (for multipart uploads)
|
|
103
|
+
*
|
|
104
|
+
* This replaces the duplicated retry logic in:
|
|
105
|
+
* - CapsaraClient#sendCapsasWithRetry (121 lines)
|
|
106
|
+
* - CapsaraClient#downloadFileWithRetry (54 lines)
|
|
107
|
+
*/
|
|
108
|
+
async executeRawHttp(options) {
|
|
109
|
+
let lastError;
|
|
110
|
+
let lastResponse = null;
|
|
111
|
+
for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
|
|
112
|
+
try {
|
|
113
|
+
const response = await this.makeRawRequest(options);
|
|
114
|
+
lastResponse = response;
|
|
115
|
+
// Check if response indicates a retryable error
|
|
116
|
+
if (isRetryableStatus(response.statusCode)) {
|
|
117
|
+
if (attempt >= this.config.maxRetries) {
|
|
118
|
+
// Return the response even on error (caller can check statusCode)
|
|
119
|
+
return response;
|
|
120
|
+
}
|
|
121
|
+
// Get delay from server or use backoff
|
|
122
|
+
const serverDelay = parseRetryDelay(response.headers);
|
|
123
|
+
const delay = serverDelay !== null
|
|
124
|
+
? Math.min(serverDelay, this.config.maxDelay)
|
|
125
|
+
: calculateBackoff(attempt, this.config.baseDelay, this.config.maxDelay);
|
|
126
|
+
if (this.config.enableLogging) {
|
|
127
|
+
this.config.logger.log(`[Capsara SDK] Retry ${attempt + 1}/${this.config.maxRetries} for ${response.statusCode} - waiting ${delay}ms`);
|
|
128
|
+
}
|
|
129
|
+
await sleep(delay);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
return response;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
lastError = error;
|
|
136
|
+
if (attempt >= this.config.maxRetries) {
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
const delay = calculateBackoff(attempt, this.config.baseDelay, this.config.maxDelay);
|
|
140
|
+
if (this.config.enableLogging) {
|
|
141
|
+
this.config.logger.log(`[Capsara SDK] Retry ${attempt + 1}/${this.config.maxRetries} (network error) - waiting ${delay}ms`);
|
|
142
|
+
}
|
|
143
|
+
await sleep(delay);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Return last response if we have one, otherwise throw
|
|
147
|
+
if (lastResponse) {
|
|
148
|
+
return lastResponse;
|
|
149
|
+
}
|
|
150
|
+
throw lastError;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Make a single raw HTTP request
|
|
154
|
+
*/
|
|
155
|
+
makeRawRequest(options) {
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
const url = new URL(options.url);
|
|
158
|
+
const timeout = options.timeout ?? DEFAULT_TIMEOUT_CONFIG.uploadTimeout;
|
|
159
|
+
const timeoutConfig = options.timeoutConfig ?? DEFAULT_TIMEOUT_CONFIG;
|
|
160
|
+
const requestModule = url.protocol === 'https:' ? https : http;
|
|
161
|
+
const agent = createAgentForProtocol(url.protocol, timeout, timeoutConfig);
|
|
162
|
+
const requestOptions = {
|
|
163
|
+
hostname: url.hostname,
|
|
164
|
+
port: url.port || (url.protocol === 'https:' ? 443 : 80),
|
|
165
|
+
path: url.pathname + url.search,
|
|
166
|
+
method: options.method,
|
|
167
|
+
headers: options.headers,
|
|
168
|
+
agent,
|
|
169
|
+
timeout,
|
|
170
|
+
};
|
|
171
|
+
const req = requestModule.request(requestOptions, (res) => {
|
|
172
|
+
const chunks = [];
|
|
173
|
+
res.on('data', (chunk) => {
|
|
174
|
+
chunks.push(chunk);
|
|
175
|
+
});
|
|
176
|
+
res.on('end', () => {
|
|
177
|
+
resolve({
|
|
178
|
+
statusCode: res.statusCode ?? 0,
|
|
179
|
+
headers: res.headers,
|
|
180
|
+
body: Buffer.concat(chunks),
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
req.on('error', (error) => {
|
|
185
|
+
reject(error);
|
|
186
|
+
});
|
|
187
|
+
req.on('timeout', () => {
|
|
188
|
+
req.destroy();
|
|
189
|
+
reject(new Error(`Request timeout after ${timeout}ms`));
|
|
190
|
+
});
|
|
191
|
+
if (options.body) {
|
|
192
|
+
req.write(options.body);
|
|
193
|
+
}
|
|
194
|
+
req.end();
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Create a retry executor with default or custom configuration
|
|
200
|
+
*/
|
|
201
|
+
export function createRetryExecutor(config) {
|
|
202
|
+
return new RetryExecutor(config);
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=retry-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-executor.js","sourceRoot":"","sources":["../../src/internal/retry-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** Account management client for key rotation and account operations. */
|
|
2
|
+
import { type GeneratedKeyPair } from '../crypto/key-generator.js';
|
|
3
|
+
import { type HttpTimeoutConfig } from '../config/http-client.js';
|
|
4
|
+
import type { RetryConfig } from '../config/retry-interceptor.js';
|
|
5
|
+
export interface PublicKeyInfo {
|
|
6
|
+
publicKey: string;
|
|
7
|
+
keyFingerprint: string;
|
|
8
|
+
createdAt: string;
|
|
9
|
+
isActive: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface KeyHistoryEntry {
|
|
12
|
+
publicKey: string;
|
|
13
|
+
keyFingerprint: string;
|
|
14
|
+
createdAt: string;
|
|
15
|
+
revokedAt?: string;
|
|
16
|
+
isActive: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare class AccountClient {
|
|
19
|
+
private axiosInstance;
|
|
20
|
+
constructor(baseUrl: string, getToken: () => string | null, timeout?: Partial<HttpTimeoutConfig>, retry?: RetryConfig);
|
|
21
|
+
/**
|
|
22
|
+
* Get current active public key
|
|
23
|
+
* @returns Current public key info or null if not set
|
|
24
|
+
*/
|
|
25
|
+
getCurrentPublicKey(): Promise<PublicKeyInfo | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Add new public key (auto-rotates: moves current to history)
|
|
28
|
+
*
|
|
29
|
+
* When a new public key is added, the API automatically:
|
|
30
|
+
* - Moves current active key to history
|
|
31
|
+
* - Sets new key as active
|
|
32
|
+
*
|
|
33
|
+
* @param publicKey - New public key in PEM format
|
|
34
|
+
* @param fingerprint - SHA-256 fingerprint of the public key
|
|
35
|
+
* @param reason - Optional reason for key rotation
|
|
36
|
+
* @returns Updated public key info
|
|
37
|
+
* @throws {CapsaraAccountError} If validation error or unauthorized
|
|
38
|
+
*/
|
|
39
|
+
addPublicKey(publicKey: string, fingerprint: string, reason?: string): Promise<PublicKeyInfo>;
|
|
40
|
+
/**
|
|
41
|
+
* Get key history (all previous keys)
|
|
42
|
+
* @returns Array of historical keys (including current active key)
|
|
43
|
+
*/
|
|
44
|
+
getKeyHistory(): Promise<KeyHistoryEntry[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Rotate key: generate new key pair and update on server.
|
|
47
|
+
* Application must store the returned private key securely.
|
|
48
|
+
* The private key is never sent to the server.
|
|
49
|
+
* @returns New key pair and updated server info
|
|
50
|
+
*/
|
|
51
|
+
rotateKey(): Promise<{
|
|
52
|
+
keyPair: GeneratedKeyPair;
|
|
53
|
+
serverInfo: PublicKeyInfo;
|
|
54
|
+
}>;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=account-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-service.d.ts","sourceRoot":"","sources":["../../../src/internal/services/account-service.ts"],"names":[],"mappings":"AAAA,yEAAyE;AAGzE,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEpF,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAElE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAAgB;gBAEzB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,EAAE,WAAW;IAwBrH;;;OAGG;IACG,mBAAmB,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAuB1D;;;;;;;;;;;;OAYG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA0BnG;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IA2BjD;;;;;OAKG;IACG,SAAS,IAAI,OAAO,CAAC;QACzB,OAAO,EAAE,gBAAgB,CAAC;QAC1B,UAAU,EAAE,aAAa,CAAC;KAC3B,CAAC;CASH"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/** Account management client for key rotation and account operations. */
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { generateKeyPair } from '../crypto/key-generator.js';
|
|
4
|
+
import { CapsaraAccountError } from '../../errors/account-error.js';
|
|
5
|
+
import { createAxiosConfig, configureRetryInterceptor, DEFAULT_TIMEOUT_CONFIG, } from '../config/http-client.js';
|
|
6
|
+
export class AccountClient {
|
|
7
|
+
axiosInstance;
|
|
8
|
+
constructor(baseUrl, getToken, timeout, retry) {
|
|
9
|
+
const timeoutConfig = {
|
|
10
|
+
...DEFAULT_TIMEOUT_CONFIG,
|
|
11
|
+
...timeout,
|
|
12
|
+
};
|
|
13
|
+
const axiosConfig = createAxiosConfig(baseUrl, timeoutConfig.apiTimeout, timeoutConfig);
|
|
14
|
+
this.axiosInstance = axios.create(axiosConfig);
|
|
15
|
+
configureRetryInterceptor(this.axiosInstance, retry);
|
|
16
|
+
this.axiosInstance.interceptors.request.use((config) => {
|
|
17
|
+
const token = getToken();
|
|
18
|
+
if (token) {
|
|
19
|
+
config.headers.Authorization = `Bearer ${token}`;
|
|
20
|
+
}
|
|
21
|
+
return config;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get current active public key
|
|
26
|
+
* @returns Current public key info or null if not set
|
|
27
|
+
*/
|
|
28
|
+
async getCurrentPublicKey() {
|
|
29
|
+
try {
|
|
30
|
+
const response = await this.axiosInstance.get('/api/account/key');
|
|
31
|
+
// API returns null fields when no key is configured
|
|
32
|
+
if (!response.data.publicKey)
|
|
33
|
+
return null;
|
|
34
|
+
return {
|
|
35
|
+
publicKey: response.data.publicKey,
|
|
36
|
+
keyFingerprint: response.data.publicKeyFingerprint ?? '',
|
|
37
|
+
createdAt: '', // API does not return this
|
|
38
|
+
isActive: true,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
// eslint-disable-next-line no-console
|
|
43
|
+
console.warn('Failed to get current public key:', error);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Add new public key (auto-rotates: moves current to history)
|
|
49
|
+
*
|
|
50
|
+
* When a new public key is added, the API automatically:
|
|
51
|
+
* - Moves current active key to history
|
|
52
|
+
* - Sets new key as active
|
|
53
|
+
*
|
|
54
|
+
* @param publicKey - New public key in PEM format
|
|
55
|
+
* @param fingerprint - SHA-256 fingerprint of the public key
|
|
56
|
+
* @param reason - Optional reason for key rotation
|
|
57
|
+
* @returns Updated public key info
|
|
58
|
+
* @throws {CapsaraAccountError} If validation error or unauthorized
|
|
59
|
+
*/
|
|
60
|
+
async addPublicKey(publicKey, fingerprint, reason) {
|
|
61
|
+
try {
|
|
62
|
+
const response = await this.axiosInstance.post('/api/account/key', {
|
|
63
|
+
publicKey,
|
|
64
|
+
publicKeyFingerprint: fingerprint,
|
|
65
|
+
...(reason && { reason })
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
publicKey: response.data.publicKey,
|
|
69
|
+
keyFingerprint: response.data.publicKeyFingerprint,
|
|
70
|
+
createdAt: new Date().toISOString(), // API doesn't return this, use current time
|
|
71
|
+
isActive: true, // Newly added keys are always active
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
throw CapsaraAccountError.fromApiError(error);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get key history (all previous keys)
|
|
80
|
+
* @returns Array of historical keys (including current active key)
|
|
81
|
+
*/
|
|
82
|
+
async getKeyHistory() {
|
|
83
|
+
try {
|
|
84
|
+
const response = await this.axiosInstance.get('/api/account/key/history');
|
|
85
|
+
return (response.data.keyHistory ?? []).map(e => ({
|
|
86
|
+
publicKey: '', // API does not return public key in history
|
|
87
|
+
keyFingerprint: e.keyFingerprint,
|
|
88
|
+
createdAt: e.rotatedAt, // Best approximation: when the key was rotated out
|
|
89
|
+
revokedAt: e.rotatedAt,
|
|
90
|
+
isActive: false,
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
// eslint-disable-next-line no-console
|
|
95
|
+
console.warn('Failed to get key history:', error);
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Rotate key: generate new key pair and update on server.
|
|
101
|
+
* Application must store the returned private key securely.
|
|
102
|
+
* The private key is never sent to the server.
|
|
103
|
+
* @returns New key pair and updated server info
|
|
104
|
+
*/
|
|
105
|
+
async rotateKey() {
|
|
106
|
+
const keyPair = await generateKeyPair();
|
|
107
|
+
const serverInfo = await this.addPublicKey(keyPair.publicKey, keyPair.publicKeyFingerprint);
|
|
108
|
+
return {
|
|
109
|
+
keyPair,
|
|
110
|
+
serverInfo,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=account-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-service.js","sourceRoot":"","sources":["../../../src/internal/services/account-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Audit trail service for capsa audit entry operations. */
|
|
2
|
+
import type { AxiosInstance } from 'axios';
|
|
3
|
+
import type { GetAuditEntriesFilters, GetAuditEntriesResponse, CreateAuditEntryRequest, CreateAuditEntryResponse } from '../../types/index.js';
|
|
4
|
+
export interface AuditServiceOptions {
|
|
5
|
+
axiosInstance: AxiosInstance;
|
|
6
|
+
}
|
|
7
|
+
export declare class AuditService {
|
|
8
|
+
private http;
|
|
9
|
+
constructor(options: AuditServiceOptions);
|
|
10
|
+
/**
|
|
11
|
+
* Get audit trail for a capsa
|
|
12
|
+
* @param capsaId - Capsa ID
|
|
13
|
+
* @param filters - Optional filters
|
|
14
|
+
* @returns Paginated audit entries
|
|
15
|
+
*/
|
|
16
|
+
getAuditEntries(capsaId: string, filters?: GetAuditEntriesFilters): Promise<GetAuditEntriesResponse>;
|
|
17
|
+
/**
|
|
18
|
+
* Create audit entry for a capsa
|
|
19
|
+
* @param capsaId - Capsa ID
|
|
20
|
+
* @param entry - Audit entry request
|
|
21
|
+
* @returns Success response
|
|
22
|
+
*/
|
|
23
|
+
createAuditEntry(capsaId: string, entry: CreateAuditEntryRequest): Promise<CreateAuditEntryResponse>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=audit-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-service.d.ts","sourceRoot":"","sources":["../../../src/internal/services/audit-service.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAgB;gBAEhB,OAAO,EAAE,mBAAmB;IAIxC;;;;;OAKG;IACG,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,uBAAuB,CAAC;IAYnC;;;;;OAKG;IACG,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,wBAAwB,CAAC;CAgBrC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Audit trail service for capsa audit entry operations. */
|
|
2
|
+
import { CapsaraAuditError } from '../../errors/audit-error.js';
|
|
3
|
+
export class AuditService {
|
|
4
|
+
http;
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.http = options.axiosInstance;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Get audit trail for a capsa
|
|
10
|
+
* @param capsaId - Capsa ID
|
|
11
|
+
* @param filters - Optional filters
|
|
12
|
+
* @returns Paginated audit entries
|
|
13
|
+
*/
|
|
14
|
+
async getAuditEntries(capsaId, filters) {
|
|
15
|
+
try {
|
|
16
|
+
const response = await this.http.get(`/api/capsas/${capsaId}/audit`, { params: filters });
|
|
17
|
+
return response.data;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
throw CapsaraAuditError.fromApiError(error);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create audit entry for a capsa
|
|
25
|
+
* @param capsaId - Capsa ID
|
|
26
|
+
* @param entry - Audit entry request
|
|
27
|
+
* @returns Success response
|
|
28
|
+
*/
|
|
29
|
+
async createAuditEntry(capsaId, entry) {
|
|
30
|
+
// Client-side validation: 'log' action requires details
|
|
31
|
+
if (entry.action === 'log' && (!entry.details || Object.keys(entry.details).length === 0)) {
|
|
32
|
+
throw CapsaraAuditError.missingDetails();
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const response = await this.http.post(`/api/capsas/${capsaId}/audit`, entry);
|
|
36
|
+
return response.data;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw CapsaraAuditError.fromApiError(error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=audit-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-service.js","sourceRoot":"","sources":["../../../src/internal/services/audit-service.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAG5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAahE,MAAM,OAAO,YAAY;IACf,IAAI,CAAgB;IAE5B,YAAY,OAA4B;QACtC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IACpC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,eAAe,CACnB,OAAe,EACf,OAAgC;QAEhC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAClC,eAAe,OAAO,QAAQ,EAC9B,EAAE,MAAM,EAAE,OAAkC,EAAE,CAC/C,CAAC;YACF,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,iBAAiB,CAAC,YAAY,CAAC,KAAuB,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,gBAAgB,CACpB,OAAe,EACf,KAA8B;QAE9B,wDAAwD;QACxD,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;YAC1F,MAAM,iBAAiB,CAAC,cAAc,EAAE,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CACnC,eAAe,OAAO,QAAQ,EAC9B,KAAK,CACN,CAAC;YACF,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,iBAAiB,CAAC,YAAY,CAAC,KAAuB,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Authentication service for managing access tokens and refresh tokens. */
|
|
2
|
+
import type { AuthCredentials, AuthResponse } from '../../types/index.js';
|
|
3
|
+
import { type HttpTimeoutConfig } from '../http-factory.js';
|
|
4
|
+
import type { RetryConfig } from '../config/retry-interceptor.js';
|
|
5
|
+
export type AuthStateChangeCallback = (state: {
|
|
6
|
+
isAuthenticated: boolean;
|
|
7
|
+
event: 'login' | 'logout' | 'refresh' | 'expired';
|
|
8
|
+
}) => void;
|
|
9
|
+
export interface AuthServiceOptions {
|
|
10
|
+
expectedIssuer?: string;
|
|
11
|
+
expectedAudience?: string;
|
|
12
|
+
timeout?: Partial<HttpTimeoutConfig>;
|
|
13
|
+
retry?: RetryConfig;
|
|
14
|
+
userAgent?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class AuthService {
|
|
17
|
+
private accessToken;
|
|
18
|
+
private refreshToken;
|
|
19
|
+
private tokenExpiresAt;
|
|
20
|
+
private http;
|
|
21
|
+
private authStateCallbacks;
|
|
22
|
+
private expectedIssuer;
|
|
23
|
+
private expectedAudience;
|
|
24
|
+
private lastRefreshError;
|
|
25
|
+
constructor(baseUrl: string, options?: AuthServiceOptions);
|
|
26
|
+
onAuthChange(callback: AuthStateChangeCallback): void;
|
|
27
|
+
offAuthChange(callback: AuthStateChangeCallback): void;
|
|
28
|
+
private emitAuthChange;
|
|
29
|
+
private decodeJWT;
|
|
30
|
+
private validateAndExtractExpiry;
|
|
31
|
+
isTokenExpired(bufferSeconds?: number): boolean;
|
|
32
|
+
login(credentials: AuthCredentials): Promise<AuthResponse>;
|
|
33
|
+
refresh(): Promise<boolean>;
|
|
34
|
+
getLastRefreshError(): Error | null;
|
|
35
|
+
getToken(): string | null;
|
|
36
|
+
getRefreshToken(): string | null;
|
|
37
|
+
isAuthenticated(): boolean;
|
|
38
|
+
canRefresh(): boolean;
|
|
39
|
+
logout(): Promise<boolean>;
|
|
40
|
+
setToken(token: string): void;
|
|
41
|
+
setRefreshToken(token: string): void;
|
|
42
|
+
setTokens(accessToken: string, refreshToken: string): void;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=auth-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../../../src/internal/services/auth-service.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAG5E,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAG1E,OAAO,EAAoB,KAAK,iBAAiB,EAA0B,MAAM,oBAAoB,CAAC;AACtG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAElE,MAAM,MAAM,uBAAuB,GAAG,CAAC,KAAK,EAAE;IAC5C,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;CACnD,KAAK,IAAI,CAAC;AASX,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,kBAAkB,CAA2C;IACrE,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,gBAAgB,CAAsB;gBAElC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB;IAYzD,YAAY,CAAC,QAAQ,EAAE,uBAAuB,GAAG,IAAI;IAIrD,aAAa,CAAC,QAAQ,EAAE,uBAAuB,GAAG,IAAI;IAItD,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,wBAAwB;IAgBhC,cAAc,CAAC,aAAa,SAAK,GAAG,OAAO;IAKrC,KAAK,CAAC,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC;IAmB1D,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IA4BjC,mBAAmB,IAAI,KAAK,GAAG,IAAI;IAInC,QAAQ,IAAI,MAAM,GAAG,IAAI;IAIzB,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC,eAAe,IAAI,OAAO;IAI1B,UAAU,IAAI,OAAO;IAIf,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IA6BhC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIpC,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;CAK3D"}
|