@opentdf/sdk 0.4.0-beta.19 → 0.4.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/access.js +1 -16
- package/dist/cjs/src/auth/oidc-refreshtoken-provider.js +1 -15
- package/dist/cjs/src/index.js +2 -4
- package/dist/cjs/src/opentdf.js +12 -64
- package/dist/cjs/src/platform.js +3 -14
- package/dist/cjs/src/seekable.js +1 -32
- package/dist/cjs/src/utils.js +3 -57
- package/dist/types/src/access.d.ts +0 -15
- package/dist/types/src/access.d.ts.map +1 -1
- package/dist/types/src/auth/oidc-refreshtoken-provider.d.ts +0 -14
- package/dist/types/src/auth/oidc-refreshtoken-provider.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/opentdf.d.ts +6 -126
- package/dist/types/src/opentdf.d.ts.map +1 -1
- package/dist/types/src/platform.d.ts +0 -16
- package/dist/types/src/platform.d.ts.map +1 -1
- package/dist/types/src/seekable.d.ts +0 -31
- package/dist/types/src/seekable.d.ts.map +1 -1
- package/dist/types/src/utils.d.ts +2 -56
- package/dist/types/src/utils.d.ts.map +1 -1
- package/dist/web/src/access.js +1 -16
- package/dist/web/src/auth/oidc-refreshtoken-provider.js +1 -15
- package/dist/web/src/index.js +1 -2
- package/dist/web/src/opentdf.js +12 -64
- package/dist/web/src/platform.js +3 -14
- package/dist/web/src/seekable.js +1 -32
- package/dist/web/src/utils.js +3 -57
- package/package.json +3 -5
- package/src/access.ts +0 -15
- package/src/auth/oidc-refreshtoken-provider.ts +0 -14
- package/src/index.ts +0 -1
- package/src/opentdf.ts +71 -147
- package/src/platform.ts +5 -17
- package/src/seekable.ts +0 -31
- package/src/utils.ts +2 -56
package/src/opentdf.ts
CHANGED
|
@@ -50,175 +50,162 @@ export {
|
|
|
50
50
|
isPublicKeyAlgorithm,
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
/** A map of key identifiers to cryptographic keys. */
|
|
54
53
|
export type Keys = {
|
|
55
54
|
[keyID: string]: CryptoKey | CryptoKeyPair;
|
|
56
55
|
};
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
// Options when creating a new TDF object
|
|
58
|
+
// that are shared between all container types.
|
|
59
59
|
export type CreateOptions = {
|
|
60
|
-
|
|
60
|
+
// If the policy service should be used to control creation options
|
|
61
61
|
autoconfigure?: boolean;
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
// List of attributes that will be assigned to the object's policy
|
|
64
64
|
attributes?: string[];
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
* This is helpful for enforcing size limits and preventing DoS attacks.
|
|
69
|
-
*/
|
|
66
|
+
// If set and positive, this represents the maxiumum number of bytes to read from a stream to encrypt.
|
|
67
|
+
// This is helpful for enforcing size limits and preventing DoS attacks.
|
|
70
68
|
byteLimit?: number;
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
// The KAS to use for creation, if none is specified by the attribute service.
|
|
73
71
|
defaultKASEndpoint?: string;
|
|
74
72
|
|
|
75
|
-
|
|
73
|
+
// Private (or shared) keys for signing assertions and bindings
|
|
76
74
|
signers?: Keys;
|
|
77
75
|
|
|
78
|
-
|
|
76
|
+
// Source of plaintext data
|
|
79
77
|
source: Source;
|
|
80
78
|
};
|
|
81
79
|
|
|
82
|
-
/** Options for creating a NanoTDF. */
|
|
83
80
|
export type CreateNanoTDFOptions = CreateOptions & {
|
|
84
|
-
/** The type of binding to use for the NanoTDF. */
|
|
85
81
|
bindingType?: 'ecdsa' | 'gmac';
|
|
86
82
|
|
|
87
|
-
|
|
83
|
+
// When creating a new collection, use ECDSA binding with this key id from the signers,
|
|
84
|
+
// instead of the DEK.
|
|
88
85
|
ecdsaBindingKeyID?: string;
|
|
89
86
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
// When creating a new collection,
|
|
88
|
+
// use the key in the `signers` list with this id
|
|
89
|
+
// to generate a signature for each element.
|
|
90
|
+
// When absent, the nanotdf is unsigned.
|
|
94
91
|
signingKeyID?: string;
|
|
95
92
|
};
|
|
96
93
|
|
|
97
|
-
/** Options for creating a NanoTDF collection. */
|
|
98
94
|
export type CreateNanoTDFCollectionOptions = CreateNanoTDFOptions & {
|
|
99
|
-
/** The platform URL. */
|
|
100
95
|
platformUrl: string;
|
|
101
|
-
|
|
96
|
+
// The maximum number of key iterations to use for a single DEK.
|
|
102
97
|
maxKeyIterations?: number;
|
|
103
98
|
};
|
|
104
99
|
|
|
105
|
-
|
|
100
|
+
// Metadata for a TDF object.
|
|
106
101
|
export type Metadata = object;
|
|
107
102
|
|
|
108
|
-
|
|
103
|
+
// MIME type of the decrypted content.
|
|
109
104
|
export type MimeType = `${string}/${string}`;
|
|
110
105
|
|
|
111
|
-
|
|
106
|
+
// Template for a Key Access Object (KAO) to be filled in during encrypt.
|
|
112
107
|
export type SplitStep = {
|
|
113
|
-
|
|
108
|
+
// Which KAS to use to rewrap this segment of the key
|
|
114
109
|
kas: string;
|
|
115
110
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
* Leave empty to share the key.
|
|
119
|
-
*/
|
|
111
|
+
// An identifier for a key segment.
|
|
112
|
+
// Leave empty to share the key.
|
|
120
113
|
sid?: string;
|
|
121
114
|
};
|
|
122
115
|
|
|
123
|
-
|
|
116
|
+
/// Options specific to the ZTDF container format.
|
|
124
117
|
export type CreateZTDFOptions = CreateOptions & {
|
|
125
|
-
|
|
118
|
+
// Configuration for bound metadata.
|
|
126
119
|
assertionConfigs?: AssertionConfig[];
|
|
127
120
|
|
|
128
|
-
|
|
121
|
+
// Unbound metadata (deprecated)
|
|
129
122
|
metadata?: Metadata;
|
|
130
123
|
|
|
131
|
-
|
|
124
|
+
// MIME type of the decrypted content. Used for display.
|
|
132
125
|
mimeType?: MimeType;
|
|
133
126
|
|
|
134
|
-
|
|
127
|
+
// How to split or share the data encryption key across multiple KASes.
|
|
135
128
|
splitPlan?: SplitStep[];
|
|
136
129
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
* The current default is 1 MiB (2^20 bytes).
|
|
140
|
-
*/
|
|
130
|
+
// The segment size for the content; smaller is slower, but allows faster random access.
|
|
131
|
+
// The current default is 1 MiB (2^20 bytes).
|
|
141
132
|
windowSize?: number;
|
|
142
133
|
|
|
143
|
-
|
|
134
|
+
// Preferred algorithm to use for Key Access Objects.
|
|
144
135
|
wrappingKeyAlgorithm?: KasPublicKeyAlgorithm;
|
|
145
136
|
|
|
146
|
-
|
|
137
|
+
// TDF spec version to target
|
|
147
138
|
tdfSpecVersion?: '4.2.2' | '4.3.0';
|
|
148
139
|
};
|
|
149
140
|
|
|
150
|
-
|
|
141
|
+
// Settings for decrypting any variety of TDF file.
|
|
151
142
|
export type ReadOptions = {
|
|
152
|
-
|
|
143
|
+
// ciphertext
|
|
153
144
|
source: Source;
|
|
154
|
-
|
|
145
|
+
// Platform URL
|
|
155
146
|
platformUrl?: string;
|
|
156
|
-
|
|
147
|
+
// list of KASes that may be contacted for a rewrap
|
|
157
148
|
allowedKASEndpoints?: string[];
|
|
158
|
-
|
|
149
|
+
// Optionally disable checking the allowlist
|
|
159
150
|
ignoreAllowlist?: boolean;
|
|
160
|
-
|
|
151
|
+
// Public (or shared) keys for verifying assertions
|
|
161
152
|
assertionVerificationKeys?: AssertionVerificationKeys;
|
|
162
|
-
|
|
153
|
+
// Optionally disable assertion verification
|
|
163
154
|
noVerify?: boolean;
|
|
164
155
|
|
|
165
|
-
|
|
156
|
+
// If set, prevents more than this number of concurrent requests to the KAS.
|
|
166
157
|
concurrencyLimit?: number;
|
|
167
158
|
|
|
168
|
-
|
|
159
|
+
// Type of key to use for wrapping responses.
|
|
169
160
|
wrappingKeyAlgorithm?: KasPublicKeyAlgorithm;
|
|
170
161
|
};
|
|
171
162
|
|
|
172
|
-
|
|
163
|
+
// Defaults and shared settings that are relevant to creating TDF objects.
|
|
173
164
|
export type OpenTDFOptions = {
|
|
174
|
-
|
|
165
|
+
// Policy service endpoint
|
|
175
166
|
policyEndpoint?: string;
|
|
176
167
|
|
|
177
|
-
|
|
168
|
+
// Platform URL
|
|
178
169
|
platformUrl?: string;
|
|
179
170
|
|
|
180
|
-
|
|
171
|
+
// Auth provider for connections to the policy service and KASes.
|
|
181
172
|
authProvider: AuthProvider;
|
|
182
173
|
|
|
183
|
-
|
|
174
|
+
// Default settings for 'encrypt' type requests.
|
|
184
175
|
defaultCreateOptions?: Omit<CreateOptions, 'source'>;
|
|
185
176
|
|
|
186
|
-
|
|
177
|
+
// Default settings for 'decrypt' type requests.
|
|
187
178
|
defaultReadOptions?: Omit<ReadOptions, 'source'>;
|
|
188
179
|
|
|
189
|
-
|
|
180
|
+
// If we want to *not* send a DPoP token
|
|
190
181
|
disableDPoP?: boolean;
|
|
191
182
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
* which is out of the scope of this library.
|
|
196
|
-
*/
|
|
183
|
+
// Optional keys for DPoP requests to a server.
|
|
184
|
+
// These often must be registered via a DPoP flow with the IdP
|
|
185
|
+
// which is out of the scope of this library.
|
|
197
186
|
dpopKeys?: Promise<CryptoKeyPair>;
|
|
198
187
|
|
|
199
|
-
|
|
188
|
+
// Configuration options for the collection header cache.
|
|
200
189
|
rewrapCacheOptions?: RewrapCacheOptions;
|
|
201
190
|
};
|
|
202
191
|
|
|
203
|
-
/** A decorated readable stream. */
|
|
204
192
|
export type DecoratedStream = ReadableStream<Uint8Array> & {
|
|
205
|
-
|
|
193
|
+
// If the source is a TDF3/ZTDF, and includes metadata, and it has been read.
|
|
206
194
|
metadata?: Promise<unknown>;
|
|
207
|
-
/** The TDF manifest. */
|
|
208
195
|
manifest?: Promise<Manifest>;
|
|
209
|
-
|
|
196
|
+
// If the source is a NanoTDF, this will be set.
|
|
210
197
|
header?: Header;
|
|
211
198
|
};
|
|
212
199
|
|
|
213
|
-
|
|
200
|
+
// Configuration options for the collection header cache.
|
|
214
201
|
export type RewrapCacheOptions = {
|
|
215
|
-
|
|
202
|
+
// If we should disable (bypass) the cache.
|
|
216
203
|
bypass?: boolean;
|
|
217
204
|
|
|
218
|
-
|
|
205
|
+
// Evict keys after this many milliseconds.
|
|
219
206
|
maxAge?: number;
|
|
220
207
|
|
|
221
|
-
|
|
208
|
+
// Check for expired keys once every this many milliseconds.
|
|
222
209
|
pollInterval?: number;
|
|
223
210
|
};
|
|
224
211
|
|
|
@@ -228,11 +215,10 @@ const defaultRewrapCacheOptions: Required<RewrapCacheOptions> = {
|
|
|
228
215
|
pollInterval: 500,
|
|
229
216
|
};
|
|
230
217
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
* */
|
|
218
|
+
// Cache for headers of nanotdf collections.
|
|
219
|
+
// This allows the SDK to quickly open multiple entries of the same collection.
|
|
220
|
+
// It has a demon that removes all keys that have not been accessed in the last 5 minutes.
|
|
221
|
+
// To cancel the demon, and clear the cache, call `close()`.
|
|
236
222
|
export class RewrapCache {
|
|
237
223
|
private cache?: Map<Uint8Array, { lastAccessTime: number; value: CryptoKey }>;
|
|
238
224
|
private closer?: ReturnType<typeof setInterval>;
|
|
@@ -268,7 +254,6 @@ export class RewrapCache {
|
|
|
268
254
|
return undefined;
|
|
269
255
|
}
|
|
270
256
|
|
|
271
|
-
/** Set a key in the cache. */
|
|
272
257
|
set(key: Uint8Array, value: CryptoKey) {
|
|
273
258
|
if (!this.cache) {
|
|
274
259
|
return;
|
|
@@ -276,7 +261,6 @@ export class RewrapCache {
|
|
|
276
261
|
this.cache.set(key, { lastAccessTime: Date.now(), value });
|
|
277
262
|
}
|
|
278
263
|
|
|
279
|
-
/** Close the cache and release any resources. */
|
|
280
264
|
close() {
|
|
281
265
|
if (this.closer !== undefined) {
|
|
282
266
|
clearInterval(this.closer);
|
|
@@ -310,56 +294,19 @@ export type TDFReader = {
|
|
|
310
294
|
attributes: () => Promise<string[]>;
|
|
311
295
|
};
|
|
312
296
|
|
|
313
|
-
|
|
314
|
-
* The main OpenTDF class that provides methods for creating and reading TDF files.
|
|
315
|
-
* It supports both NanoTDF and ZTDF formats.
|
|
316
|
-
* It can be used to create new TDF files and read existing ones.
|
|
317
|
-
* This class is the entry point for using the OpenTDF SDK.
|
|
318
|
-
* It requires an authentication provider to be passed in the constructor.
|
|
319
|
-
* It also requires a platform URL to be set, which is used to fetch key access servers and policies.
|
|
320
|
-
* @example
|
|
321
|
-
* ```
|
|
322
|
-
* import { type Chunker, OpenTDF } from '@opentdf/sdk';
|
|
323
|
-
*
|
|
324
|
-
* const oidcCredentials: RefreshTokenCredentials = {
|
|
325
|
-
* clientId: keycloakClientId,
|
|
326
|
-
* exchange: 'refresh',
|
|
327
|
-
* refreshToken: refreshToken,
|
|
328
|
-
* oidcOrigin: keycloakUrl,
|
|
329
|
-
* };
|
|
330
|
-
* const authProvider = await AuthProviders.refreshAuthProvider(oidcCredentials);
|
|
331
|
-
*
|
|
332
|
-
* const client = new OpenTDF({
|
|
333
|
-
* authProvider,
|
|
334
|
-
* platformUrl: 'https://platform.example.com',
|
|
335
|
-
* });
|
|
336
|
-
*
|
|
337
|
-
* const cipherText = await client.createZTDF({
|
|
338
|
-
* source: { type: 'stream', location: source },
|
|
339
|
-
* autoconfigure: false,
|
|
340
|
-
* });
|
|
341
|
-
*
|
|
342
|
-
* const clearText = await client.read({ type: 'stream', location: cipherText });
|
|
343
|
-
* ```
|
|
344
|
-
*/
|
|
297
|
+
// SDK for dealing with OpenTDF data and policy services.
|
|
345
298
|
export class OpenTDF {
|
|
346
|
-
|
|
299
|
+
// Configuration service and more is at this URL/connectRPC endpoint
|
|
347
300
|
readonly platformUrl: string;
|
|
348
|
-
/** The policy service endpoint */
|
|
349
301
|
readonly policyEndpoint: string;
|
|
350
|
-
/** The auth provider for the OpenTDF instance. */
|
|
351
302
|
readonly authProvider: AuthProvider;
|
|
352
|
-
/** If DPoP is enabled for this instance. */
|
|
353
303
|
readonly dpopEnabled: boolean;
|
|
354
|
-
/** Default options for creating TDF objects. */
|
|
355
304
|
defaultCreateOptions: Omit<CreateOptions, 'source'>;
|
|
356
|
-
/** Default options for reading TDF objects. */
|
|
357
305
|
defaultReadOptions: Omit<ReadOptions, 'source'>;
|
|
358
|
-
/** The DPoP keys for this instance, if any. */
|
|
359
306
|
readonly dpopKeys: Promise<CryptoKeyPair>;
|
|
360
|
-
|
|
307
|
+
|
|
308
|
+
// Header cache for reading nanotdf collections
|
|
361
309
|
private readonly rewrapCache: RewrapCache;
|
|
362
|
-
/** The TDF3 client for encrypting and decrypting ZTDF files. */
|
|
363
310
|
readonly tdf3Client: TDF3Client;
|
|
364
311
|
|
|
365
312
|
constructor({
|
|
@@ -405,7 +352,6 @@ export class OpenTDF {
|
|
|
405
352
|
);
|
|
406
353
|
}
|
|
407
354
|
|
|
408
|
-
/** Creates a new NanoTDF stream. */
|
|
409
355
|
async createNanoTDF(opts: CreateNanoTDFOptions): Promise<DecoratedStream> {
|
|
410
356
|
opts = {
|
|
411
357
|
...this.defaultCreateOptions,
|
|
@@ -424,6 +370,7 @@ export class OpenTDF {
|
|
|
424
370
|
|
|
425
371
|
/**
|
|
426
372
|
* Creates a new collection object, which can be used to encrypt a series of data with the same policy.
|
|
373
|
+
* @returns
|
|
427
374
|
*/
|
|
428
375
|
async createNanoTDFCollection(
|
|
429
376
|
opts: CreateNanoTDFCollectionOptions
|
|
@@ -432,7 +379,6 @@ export class OpenTDF {
|
|
|
432
379
|
return new Collection(this.authProvider, opts);
|
|
433
380
|
}
|
|
434
381
|
|
|
435
|
-
/** Creates a new ZTDF stream. */
|
|
436
382
|
async createZTDF(opts: CreateZTDFOptions): Promise<DecoratedStream> {
|
|
437
383
|
opts = { ...this.defaultCreateOptions, ...opts };
|
|
438
384
|
const oldStream = await this.tdf3Client.encrypt({
|
|
@@ -457,25 +403,26 @@ export class OpenTDF {
|
|
|
457
403
|
return stream;
|
|
458
404
|
}
|
|
459
405
|
|
|
460
|
-
/**
|
|
406
|
+
/**
|
|
407
|
+
* Opens a TDF file for inspection and decryption.
|
|
408
|
+
* @param opts the file to open, and any appropriate configuration options
|
|
409
|
+
* @returns
|
|
410
|
+
*/
|
|
461
411
|
open(opts: ReadOptions): TDFReader {
|
|
462
412
|
opts = { ...this.defaultReadOptions, ...opts };
|
|
463
413
|
return new UnknownTypeReader(this, opts, this.rewrapCache);
|
|
464
414
|
}
|
|
465
415
|
|
|
466
|
-
/** Decrypts a TDF file. */
|
|
467
416
|
async read(opts: ReadOptions): Promise<DecoratedStream> {
|
|
468
417
|
const reader = this.open(opts);
|
|
469
418
|
return reader.decrypt();
|
|
470
419
|
}
|
|
471
420
|
|
|
472
|
-
/** Closes the OpenTDF instance and releases any resources. */
|
|
473
421
|
close() {
|
|
474
422
|
this.rewrapCache.close();
|
|
475
423
|
}
|
|
476
424
|
}
|
|
477
425
|
|
|
478
|
-
/** A TDF reader that can automatically detect the TDF type. */
|
|
479
426
|
class UnknownTypeReader {
|
|
480
427
|
delegate: Promise<TDFReader>;
|
|
481
428
|
state: 'init' | 'resolving' | 'loaded' | 'decrypting' | 'closing' | 'done' | 'error' = 'init';
|
|
@@ -487,7 +434,6 @@ class UnknownTypeReader {
|
|
|
487
434
|
this.delegate = this.resolveType();
|
|
488
435
|
}
|
|
489
436
|
|
|
490
|
-
/** Resolves the TDF type based on the file prefix. */
|
|
491
437
|
async resolveType(): Promise<TDFReader> {
|
|
492
438
|
if (this.state === 'done') {
|
|
493
439
|
throw new ConfigurationError('reader is closed');
|
|
@@ -509,25 +455,21 @@ class UnknownTypeReader {
|
|
|
509
455
|
throw new InvalidFileError(`unsupported format; prefix not recognized ${prefix}`);
|
|
510
456
|
}
|
|
511
457
|
|
|
512
|
-
/** Decrypts the TDF file */
|
|
513
458
|
async decrypt(): Promise<DecoratedStream> {
|
|
514
459
|
const actual = await this.delegate;
|
|
515
460
|
return actual.decrypt();
|
|
516
461
|
}
|
|
517
462
|
|
|
518
|
-
/** Returns the attributes of the TDF file */
|
|
519
463
|
async attributes(): Promise<string[]> {
|
|
520
464
|
const actual = await this.delegate;
|
|
521
465
|
return actual.attributes();
|
|
522
466
|
}
|
|
523
467
|
|
|
524
|
-
/** Returns the manifest of the TDF file */
|
|
525
468
|
async manifest(): Promise<Manifest> {
|
|
526
469
|
const actual = await this.delegate;
|
|
527
470
|
return actual.manifest();
|
|
528
471
|
}
|
|
529
472
|
|
|
530
|
-
/** Closes the TDF reader */
|
|
531
473
|
async close() {
|
|
532
474
|
if (this.state === 'done') {
|
|
533
475
|
return;
|
|
@@ -545,7 +487,6 @@ class UnknownTypeReader {
|
|
|
545
487
|
}
|
|
546
488
|
}
|
|
547
489
|
|
|
548
|
-
/** A TDF reader for NanoTDF files. */
|
|
549
490
|
class NanoTDFReader {
|
|
550
491
|
container: Promise<NanoTDF>;
|
|
551
492
|
constructor(
|
|
@@ -573,7 +514,6 @@ class NanoTDFReader {
|
|
|
573
514
|
});
|
|
574
515
|
}
|
|
575
516
|
|
|
576
|
-
/** Decrypts the NanoTDF file and returns a decorated stream. */
|
|
577
517
|
async decrypt(): Promise<DecoratedStream> {
|
|
578
518
|
const nanotdf = await this.container;
|
|
579
519
|
const cachedDEK = this.rewrapCache.get(nanotdf.header.ephemeralPublicKey);
|
|
@@ -616,12 +556,10 @@ class NanoTDFReader {
|
|
|
616
556
|
|
|
617
557
|
async close() {}
|
|
618
558
|
|
|
619
|
-
/** Returns blank manifest. NanoTDF has no manifest. */
|
|
620
559
|
async manifest(): Promise<Manifest> {
|
|
621
560
|
return {} as Manifest;
|
|
622
561
|
}
|
|
623
562
|
|
|
624
|
-
/** Returns the attributes of the NanoTDF file. */
|
|
625
563
|
async attributes(): Promise<string[]> {
|
|
626
564
|
const nanotdf = await this.container;
|
|
627
565
|
if (!nanotdf.header.policy?.content) {
|
|
@@ -636,7 +574,6 @@ class NanoTDFReader {
|
|
|
636
574
|
}
|
|
637
575
|
}
|
|
638
576
|
|
|
639
|
-
/** A reader for TDF files. */
|
|
640
577
|
class ZTDFReader {
|
|
641
578
|
overview: Promise<InspectedTDFOverview>;
|
|
642
579
|
constructor(
|
|
@@ -647,10 +584,6 @@ class ZTDFReader {
|
|
|
647
584
|
this.overview = loadTDFStream(source);
|
|
648
585
|
}
|
|
649
586
|
|
|
650
|
-
/**
|
|
651
|
-
* Decrypts the TDF file and returns a decorated stream.
|
|
652
|
-
* The stream will have a manifest and metadata attached if available.
|
|
653
|
-
*/
|
|
654
587
|
async decrypt(): Promise<DecoratedStream> {
|
|
655
588
|
const {
|
|
656
589
|
assertionVerificationKeys,
|
|
@@ -708,13 +641,11 @@ class ZTDFReader {
|
|
|
708
641
|
// TODO figure out how to close a chunker, if we want to.
|
|
709
642
|
}
|
|
710
643
|
|
|
711
|
-
/** Returns the manifest of the TDF file. */
|
|
712
644
|
async manifest(): Promise<Manifest> {
|
|
713
645
|
const overview = await this.overview;
|
|
714
646
|
return overview.manifest;
|
|
715
647
|
}
|
|
716
648
|
|
|
717
|
-
/** Returns the attributes of the TDF file. */
|
|
718
649
|
async attributes(): Promise<string[]> {
|
|
719
650
|
const manifest = await this.manifest();
|
|
720
651
|
const policyJSON = base64.decode(manifest.encryptionInformation.policy);
|
|
@@ -735,18 +666,13 @@ async function streamify(ab: Promise<ArrayBuffer>): Promise<ReadableStream<Uint8
|
|
|
735
666
|
return stream;
|
|
736
667
|
}
|
|
737
668
|
|
|
738
|
-
/** A writer for NanoTDF collections. */
|
|
739
669
|
export type NanoTDFCollectionWriter = {
|
|
740
|
-
/** The NanoTDF client used for encrypting data in this collection. */
|
|
741
670
|
encrypt: (source: Source) => Promise<ReadableStream<Uint8Array>>;
|
|
742
|
-
/** Closes the collection and releases any resources. */
|
|
743
671
|
close: () => Promise<void>;
|
|
744
672
|
};
|
|
745
673
|
|
|
746
674
|
class Collection {
|
|
747
|
-
/** The NanoTDF client used for encrypting data in this collection. */
|
|
748
675
|
client?: NanoTDFDatasetClient;
|
|
749
|
-
/** Options for encrypting data in this collection. */
|
|
750
676
|
encryptOptions?: NanoEncryptOptions;
|
|
751
677
|
|
|
752
678
|
constructor(authProvider: AuthProvider, opts: CreateNanoTDFCollectionOptions) {
|
|
@@ -779,7 +705,6 @@ class Collection {
|
|
|
779
705
|
});
|
|
780
706
|
}
|
|
781
707
|
|
|
782
|
-
/** Encrypts a source into a NanoTDF stream. */
|
|
783
708
|
async encrypt(source: Source): Promise<DecoratedStream> {
|
|
784
709
|
if (!this.client) {
|
|
785
710
|
throw new ConfigurationError('Collection is closed');
|
|
@@ -797,7 +722,6 @@ class Collection {
|
|
|
797
722
|
return stream;
|
|
798
723
|
}
|
|
799
724
|
|
|
800
|
-
/** Releases client resources. */
|
|
801
725
|
async close() {
|
|
802
726
|
delete this.client;
|
|
803
727
|
}
|
package/src/platform.ts
CHANGED
|
@@ -33,11 +33,11 @@ export interface PlatformServices {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export interface PlatformClientOptions {
|
|
36
|
-
|
|
36
|
+
// Optional authentication provider for generating auth interceptor.
|
|
37
37
|
authProvider?: AuthProvider;
|
|
38
|
-
|
|
38
|
+
// Array of custom interceptors to apply to rpc requests.
|
|
39
39
|
interceptors?: Interceptor[];
|
|
40
|
-
|
|
40
|
+
// Base URL of the platform API.
|
|
41
41
|
platformUrl: string;
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -50,22 +50,8 @@ export interface PlatformClientOptions {
|
|
|
50
50
|
*
|
|
51
51
|
* This client supports authentication via an `AuthProvider` or custom interceptors, which can
|
|
52
52
|
* be used to add authentication headers or other custom logic to outgoing requests.
|
|
53
|
-
* @example
|
|
54
|
-
* ```
|
|
55
|
-
* import { AuthProviders, OpenTDF } from '@opentdf/sdk';
|
|
56
|
-
* import { PlatformClient } from '@opentdf/sdk/platform';
|
|
57
53
|
*
|
|
58
|
-
* const authProvider: AuthProvider = await AuthProviders.refreshAuthProvider({...});
|
|
59
|
-
* const platform = new PlatformClient({
|
|
60
|
-
* authProvider,
|
|
61
|
-
* platformUrl: 'https://platform.example.com',
|
|
62
|
-
* });
|
|
63
|
-
*
|
|
64
|
-
* const wellKnownResponse = await platform.v1.wellknown.getWellKnownConfiguration({});
|
|
65
|
-
* console.log('Well-known configuration:', wellKnownResponse.configuration);
|
|
66
|
-
* ```
|
|
67
54
|
*/
|
|
68
|
-
|
|
69
55
|
export class PlatformClient {
|
|
70
56
|
readonly v1: PlatformServices;
|
|
71
57
|
|
|
@@ -110,6 +96,8 @@ export class PlatformClient {
|
|
|
110
96
|
* that returns an object containing authentication headers. These headers are then
|
|
111
97
|
* added to the request before it is sent to the server.
|
|
112
98
|
*
|
|
99
|
+
* @param authProvider - An instance of `AuthProvider` used to generate authentication credentials.
|
|
100
|
+
* @returns An `Interceptor` function that modifies requests to include authentication headers.
|
|
113
101
|
*/
|
|
114
102
|
function createAuthInterceptor(authProvider: AuthProvider): Interceptor {
|
|
115
103
|
const authInterceptor: Interceptor = (next) => async (req) => {
|
package/src/seekable.ts
CHANGED
|
@@ -33,30 +33,12 @@ export const fromBrowserFile = (fileRef: Blob): Chunker => {
|
|
|
33
33
|
};
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
/**
|
|
37
|
-
* Creates a seekable object from a buffer.
|
|
38
|
-
* @param source A Uint8Array to read from.
|
|
39
|
-
* If byteStart and byteEnd are not provided, reads the entire array.
|
|
40
|
-
* If byteStart is provided, reads from that index to the end of the array.
|
|
41
|
-
* If byteEnd is provided, reads from byteStart to byteEnd (exclusive).
|
|
42
|
-
* If both byteStart and byteEnd are provided, reads from byteStart to byteEnd (exclusive).
|
|
43
|
-
* @returns A promise that resolves to a Uint8Array containing the requested data.
|
|
44
|
-
*/
|
|
45
36
|
export const fromBuffer = (source: Uint8Array): Chunker => {
|
|
46
37
|
return (byteStart?: number, byteEnd?: number) => {
|
|
47
38
|
return Promise.resolve(source.slice(byteStart, byteEnd));
|
|
48
39
|
};
|
|
49
40
|
};
|
|
50
41
|
|
|
51
|
-
/**
|
|
52
|
-
* Creates a seekable object from a string.
|
|
53
|
-
* @param source A string to read from.
|
|
54
|
-
* If byteStart and byteEnd are not provided, reads the entire string.
|
|
55
|
-
* If byteStart is provided, reads from that index to the end of the string.
|
|
56
|
-
* If byteEnd is provided, reads from byteStart to byteEnd (exclusive).
|
|
57
|
-
* If both byteStart and byteEnd are provided, reads from byteStart to byteEnd (exclusive).
|
|
58
|
-
* @returns A promise that resolves to a Uint8Array containing the requested data.
|
|
59
|
-
*/
|
|
60
42
|
export const fromString = (source: string): Chunker => {
|
|
61
43
|
return fromBuffer(new TextEncoder().encode(source));
|
|
62
44
|
};
|
|
@@ -128,12 +110,6 @@ export const fromUrl = async (location: string): Promise<Chunker> => {
|
|
|
128
110
|
};
|
|
129
111
|
};
|
|
130
112
|
|
|
131
|
-
/**
|
|
132
|
-
* Creates a seekable object from a source.
|
|
133
|
-
* @param source A Source object containing the type and location of the data.
|
|
134
|
-
* @returns A promise that resolves to a Chunker function.
|
|
135
|
-
* @throws ConfigurationError if the source type is not supported or the location is invalid.
|
|
136
|
-
*/
|
|
137
113
|
export const fromSource = async ({ type, location }: Source): Promise<Chunker> => {
|
|
138
114
|
switch (type) {
|
|
139
115
|
case 'buffer':
|
|
@@ -163,13 +139,6 @@ export const fromSource = async ({ type, location }: Source): Promise<Chunker> =
|
|
|
163
139
|
}
|
|
164
140
|
};
|
|
165
141
|
|
|
166
|
-
/**
|
|
167
|
-
* Converts a Source object to a ReadableStream.
|
|
168
|
-
* @param source A Source object containing the type and location of the data.
|
|
169
|
-
* Converts the source to a ReadableStream of Uint8Array.
|
|
170
|
-
* This is useful for streaming data from various sources like files, remote URLs, or chunkers.
|
|
171
|
-
* @returns A ReadableStream of Uint8Array.
|
|
172
|
-
*/
|
|
173
142
|
export async function sourceToStream(source: Source): Promise<ReadableStream<Uint8Array>> {
|
|
174
143
|
switch (source.type) {
|
|
175
144
|
case 'stream':
|