@opentdf/sdk 0.2.0-beta.1758 → 0.2.0-beta.1941
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -38
- package/dist/cjs/src/access.js +47 -11
- package/dist/cjs/src/auth/auth.js +5 -5
- package/dist/cjs/src/auth/oidc-clientcredentials-provider.js +1 -1
- package/dist/cjs/src/auth/oidc-externaljwt-provider.js +1 -1
- package/dist/cjs/src/auth/oidc-refreshtoken-provider.js +1 -1
- package/dist/cjs/src/auth/oidc.js +1 -1
- package/dist/cjs/src/auth/providers.js +1 -1
- package/dist/cjs/src/concurrency.js +3 -4
- package/dist/cjs/src/encodings/base64.js +4 -4
- package/dist/cjs/src/encodings/hex.js +5 -6
- package/dist/cjs/src/encodings/index.js +18 -8
- package/dist/cjs/src/errors.js +1 -1
- package/dist/cjs/src/index.js +28 -318
- package/dist/cjs/src/nanoclients.js +285 -0
- package/dist/cjs/src/nanoindex.js +47 -0
- package/dist/cjs/src/nanotdf/Client.js +18 -8
- package/dist/cjs/src/nanotdf/NanoTDF.js +1 -1
- package/dist/cjs/src/nanotdf/decrypt.js +2 -2
- package/dist/cjs/src/nanotdf/encrypt-dataset.js +2 -2
- package/dist/cjs/src/nanotdf/encrypt.js +2 -2
- package/dist/cjs/src/nanotdf/helpers/calculateByCurve.js +3 -4
- package/dist/cjs/src/nanotdf/helpers/getHkdfSalt.js +2 -2
- package/dist/cjs/src/nanotdf/models/Ciphers.js +3 -3
- package/dist/cjs/src/nanotdf/models/EcCurves.js +3 -3
- package/dist/cjs/src/nanotdf/models/Header.js +1 -1
- package/dist/cjs/src/nanotdf/models/Payload.js +1 -1
- package/dist/cjs/src/nanotdf/models/Policy/AbstractPolicy.js +1 -1
- package/dist/cjs/src/nanotdf/models/Policy/EmbeddedPolicy.js +1 -1
- package/dist/cjs/src/nanotdf/models/Policy/PolicyFactory.js +1 -1
- package/dist/cjs/src/nanotdf/models/ResourceLocator.js +1 -1
- package/dist/cjs/src/nanotdf/models/Signature.js +1 -1
- package/dist/cjs/src/nanotdf-crypto/ciphers.js +1 -1
- package/dist/cjs/src/nanotdf-crypto/decrypt.js +2 -2
- package/dist/cjs/src/nanotdf-crypto/digest.js +2 -2
- package/dist/cjs/src/nanotdf-crypto/ecdsaSignature.js +4 -5
- package/dist/cjs/src/nanotdf-crypto/encrypt.js +2 -2
- package/dist/cjs/src/nanotdf-crypto/exportCryptoKey.js +2 -2
- package/dist/cjs/src/nanotdf-crypto/generateKeyPair.js +2 -2
- package/dist/cjs/src/nanotdf-crypto/generateRandomNumber.js +2 -2
- package/dist/cjs/src/nanotdf-crypto/index.js +21 -13
- package/dist/cjs/src/nanotdf-crypto/keyAgreement.js +10 -8
- package/dist/cjs/src/nanotdf-crypto/pemPublicToCrypto.js +20 -11
- package/dist/cjs/src/opentdf.js +243 -0
- package/dist/cjs/src/policy/api.js +2 -3
- package/dist/cjs/src/policy/granter.js +3 -4
- package/dist/cjs/src/seekable.js +157 -0
- package/dist/cjs/src/tdf/AttributeObject.js +2 -4
- package/dist/cjs/src/tdf/Policy.js +1 -2
- package/dist/cjs/src/utils.js +12 -14
- package/dist/cjs/src/version.js +6 -2
- package/dist/cjs/tdf3/index.js +27 -15
- package/dist/cjs/tdf3/src/assertions.js +25 -11
- package/dist/cjs/tdf3/src/binary.js +1 -1
- package/dist/cjs/tdf3/src/ciphers/aes-gcm-cipher.js +1 -1
- package/dist/cjs/tdf3/src/ciphers/symmetric-cipher-base.js +1 -1
- package/dist/cjs/tdf3/src/client/DecoratedReadableStream.js +7 -74
- package/dist/cjs/tdf3/src/client/builders.js +26 -22
- package/dist/cjs/tdf3/src/client/index.js +88 -61
- package/dist/cjs/tdf3/src/client/validation.js +3 -3
- package/dist/cjs/tdf3/src/crypto/crypto-utils.js +1 -1
- package/dist/cjs/tdf3/src/crypto/index.js +18 -18
- package/dist/cjs/tdf3/src/index.js +22 -11
- package/dist/cjs/tdf3/src/models/attribute-set.js +1 -1
- package/dist/cjs/tdf3/src/models/encryption-information.js +3 -3
- package/dist/cjs/tdf3/src/models/key-access.js +67 -35
- package/dist/cjs/tdf3/src/models/policy.js +3 -3
- package/dist/cjs/tdf3/src/tdf.js +177 -151
- package/dist/cjs/tdf3/src/utils/buffer-crc32.js +2 -3
- package/dist/cjs/tdf3/src/utils/index.js +30 -28
- package/dist/cjs/tdf3/src/utils/keysplit.js +4 -5
- package/dist/cjs/tdf3/src/utils/unwrap.js +21 -0
- package/dist/cjs/tdf3/src/utils/zip-reader.js +4 -4
- package/dist/cjs/tdf3/src/utils/zip-writer.js +4 -4
- package/dist/types/src/access.d.ts +3 -0
- package/dist/types/src/access.d.ts.map +1 -1
- package/dist/types/src/auth/providers.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +5 -136
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/nanoclients.d.ts +107 -0
- package/dist/types/src/nanoclients.d.ts.map +1 -0
- package/dist/types/src/nanoindex.d.ts +5 -0
- package/dist/types/src/nanoindex.d.ts.map +1 -0
- package/dist/types/src/nanotdf/enum/CipherEnum.d.ts +1 -1
- package/dist/types/src/nanotdf/enum/CipherEnum.d.ts.map +1 -1
- package/dist/types/src/nanotdf/enum/PolicyTypeEnum.d.ts +1 -1
- package/dist/types/src/nanotdf/enum/PolicyTypeEnum.d.ts.map +1 -1
- package/dist/types/src/nanotdf/models/DefaultParams.d.ts +1 -1
- package/dist/types/src/nanotdf/models/ResourceLocator.d.ts.map +1 -1
- package/dist/types/src/nanotdf-crypto/generateKeyPair.d.ts +1 -1
- package/dist/types/src/nanotdf-crypto/generateKeyPair.d.ts.map +1 -1
- package/dist/types/src/nanotdf-crypto/generateRandomNumber.d.ts +1 -1
- package/dist/types/src/nanotdf-crypto/generateRandomNumber.d.ts.map +1 -1
- package/dist/types/src/nanotdf-crypto/index.d.ts +2 -3
- package/dist/types/src/nanotdf-crypto/index.d.ts.map +1 -1
- package/dist/types/src/nanotdf-crypto/keyAgreement.d.ts.map +1 -1
- package/dist/types/src/opentdf.d.ts +106 -0
- package/dist/types/src/opentdf.d.ts.map +1 -0
- package/dist/types/src/seekable.d.ts +39 -0
- package/dist/types/src/seekable.d.ts.map +1 -0
- package/dist/types/src/tdf/AttributeObject.d.ts +0 -2
- package/dist/types/src/tdf/AttributeObject.d.ts.map +1 -1
- package/dist/types/src/tdf/NanoTDF/NanoTDF.d.ts +2 -2
- package/dist/types/src/tdf/NanoTDF/NanoTDF.d.ts.map +1 -1
- package/dist/types/src/tdf/Policy.d.ts.map +1 -1
- package/dist/types/src/tdf/PolicyObject.d.ts +0 -1
- package/dist/types/src/tdf/PolicyObject.d.ts.map +1 -1
- package/dist/types/src/utils.d.ts +0 -1
- package/dist/types/src/utils.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +4 -0
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/types/tdf3/index.d.ts +3 -2
- package/dist/types/tdf3/index.d.ts.map +1 -1
- package/dist/types/tdf3/src/assertions.d.ts +3 -3
- package/dist/types/tdf3/src/assertions.d.ts.map +1 -1
- package/dist/types/tdf3/src/client/DecoratedReadableStream.d.ts +1 -13
- package/dist/types/tdf3/src/client/DecoratedReadableStream.d.ts.map +1 -1
- package/dist/types/tdf3/src/client/builders.d.ts +43 -37
- package/dist/types/tdf3/src/client/builders.d.ts.map +1 -1
- package/dist/types/tdf3/src/client/index.d.ts +8 -9
- package/dist/types/tdf3/src/client/index.d.ts.map +1 -1
- package/dist/types/tdf3/src/client/validation.d.ts +3 -3
- package/dist/types/tdf3/src/client/validation.d.ts.map +1 -1
- package/dist/types/tdf3/src/crypto/crypto-utils.d.ts.map +1 -1
- package/dist/types/tdf3/src/index.d.ts +1 -1
- package/dist/types/tdf3/src/index.d.ts.map +1 -1
- package/dist/types/tdf3/src/models/key-access.d.ts +63 -15
- package/dist/types/tdf3/src/models/key-access.d.ts.map +1 -1
- package/dist/types/tdf3/src/models/manifest.d.ts +2 -0
- package/dist/types/tdf3/src/models/manifest.d.ts.map +1 -1
- package/dist/types/tdf3/src/models/policy.d.ts +0 -1
- package/dist/types/tdf3/src/models/policy.d.ts.map +1 -1
- package/dist/types/tdf3/src/tdf.d.ts +20 -24
- package/dist/types/tdf3/src/tdf.d.ts.map +1 -1
- package/dist/types/tdf3/src/utils/index.d.ts +0 -2
- package/dist/types/tdf3/src/utils/index.d.ts.map +1 -1
- package/dist/types/tdf3/src/utils/unwrap.d.ts +2 -0
- package/dist/types/tdf3/src/utils/unwrap.d.ts.map +1 -0
- package/dist/types/tdf3/src/utils/zip-reader.d.ts +1 -1
- package/dist/types/tdf3/src/utils/zip-reader.d.ts.map +1 -1
- package/dist/types/tdf3/src/utils/zip-writer.d.ts +2 -2
- package/dist/web/src/access.js +40 -7
- package/dist/web/src/auth/auth.js +1 -1
- package/dist/web/src/auth/oidc-clientcredentials-provider.js +1 -1
- package/dist/web/src/auth/oidc-externaljwt-provider.js +1 -1
- package/dist/web/src/auth/oidc-refreshtoken-provider.js +1 -1
- package/dist/web/src/auth/oidc.js +1 -1
- package/dist/web/src/auth/providers.js +1 -1
- package/dist/web/src/concurrency.js +1 -1
- package/dist/web/src/encodings/base64.js +1 -1
- package/dist/web/src/encodings/hex.js +1 -1
- package/dist/web/src/errors.js +1 -1
- package/dist/web/src/index.js +6 -310
- package/dist/web/src/nanoclients.js +280 -0
- package/dist/web/src/nanoindex.js +5 -0
- package/dist/web/src/nanotdf/Client.js +1 -1
- package/dist/web/src/nanotdf/NanoTDF.js +1 -1
- package/dist/web/src/nanotdf/encrypt-dataset.js +1 -1
- package/dist/web/src/nanotdf/encrypt.js +1 -1
- package/dist/web/src/nanotdf/models/Ciphers.js +1 -1
- package/dist/web/src/nanotdf/models/EcCurves.js +1 -1
- package/dist/web/src/nanotdf/models/Header.js +1 -1
- package/dist/web/src/nanotdf/models/Payload.js +1 -1
- package/dist/web/src/nanotdf/models/Policy/AbstractPolicy.js +1 -1
- package/dist/web/src/nanotdf/models/Policy/EmbeddedPolicy.js +1 -1
- package/dist/web/src/nanotdf/models/Policy/PolicyFactory.js +1 -1
- package/dist/web/src/nanotdf/models/ResourceLocator.js +1 -1
- package/dist/web/src/nanotdf/models/Signature.js +1 -1
- package/dist/web/src/nanotdf-crypto/ciphers.js +1 -1
- package/dist/web/src/nanotdf-crypto/ecdsaSignature.js +1 -1
- package/dist/web/src/nanotdf-crypto/generateKeyPair.js +2 -2
- package/dist/web/src/nanotdf-crypto/generateRandomNumber.js +2 -2
- package/dist/web/src/nanotdf-crypto/index.js +3 -4
- package/dist/web/src/nanotdf-crypto/keyAgreement.js +9 -6
- package/dist/web/src/nanotdf-crypto/pemPublicToCrypto.js +1 -1
- package/dist/web/src/opentdf.js +234 -0
- package/dist/web/src/policy/api.js +1 -1
- package/dist/web/src/policy/granter.js +1 -1
- package/dist/web/src/seekable.js +148 -0
- package/dist/web/src/tdf/AttributeObject.js +1 -2
- package/dist/web/src/tdf/Policy.js +1 -2
- package/dist/web/src/utils.js +2 -3
- package/dist/web/src/version.js +5 -1
- package/dist/web/tdf3/index.js +3 -2
- package/dist/web/tdf3/src/assertions.js +21 -6
- package/dist/web/tdf3/src/binary.js +1 -1
- package/dist/web/tdf3/src/ciphers/aes-gcm-cipher.js +1 -1
- package/dist/web/tdf3/src/ciphers/symmetric-cipher-base.js +1 -1
- package/dist/web/tdf3/src/client/DecoratedReadableStream.js +4 -68
- package/dist/web/tdf3/src/client/builders.js +26 -22
- package/dist/web/tdf3/src/client/index.js +69 -52
- package/dist/web/tdf3/src/client/validation.js +1 -1
- package/dist/web/tdf3/src/crypto/crypto-utils.js +1 -1
- package/dist/web/tdf3/src/crypto/index.js +1 -1
- package/dist/web/tdf3/src/index.js +2 -2
- package/dist/web/tdf3/src/models/attribute-set.js +1 -1
- package/dist/web/tdf3/src/models/encryption-information.js +3 -3
- package/dist/web/tdf3/src/models/key-access.js +47 -24
- package/dist/web/tdf3/src/models/policy.js +1 -1
- package/dist/web/tdf3/src/tdf.js +149 -130
- package/dist/web/tdf3/src/utils/buffer-crc32.js +1 -1
- package/dist/web/tdf3/src/utils/index.js +1 -5
- package/dist/web/tdf3/src/utils/keysplit.js +1 -1
- package/dist/web/tdf3/src/utils/unwrap.js +18 -0
- package/dist/web/tdf3/src/utils/zip-reader.js +1 -1
- package/dist/web/tdf3/src/utils/zip-writer.js +1 -1
- package/package.json +45 -42
- package/src/access.ts +37 -1
- package/src/index.ts +5 -435
- package/src/nanoclients.ts +405 -0
- package/src/nanoindex.ts +4 -0
- package/src/nanotdf-crypto/generateKeyPair.ts +1 -1
- package/src/nanotdf-crypto/generateRandomNumber.ts +1 -1
- package/src/nanotdf-crypto/index.ts +2 -3
- package/src/nanotdf-crypto/keyAgreement.ts +14 -7
- package/src/opentdf.ts +441 -0
- package/{tdf3/src/utils/chunkers.ts → src/seekable.ts} +69 -20
- package/src/tdf/AttributeObject.ts +0 -3
- package/src/tdf/Policy.ts +0 -1
- package/src/tdf/PolicyObject.ts +0 -1
- package/src/utils.ts +1 -3
- package/src/version.ts +5 -0
- package/tdf3/index.ts +14 -2
- package/tdf3/src/assertions.ts +33 -8
- package/tdf3/src/client/DecoratedReadableStream.ts +2 -78
- package/tdf3/src/client/builders.ts +44 -26
- package/tdf3/src/client/index.ts +101 -86
- package/tdf3/src/index.ts +1 -1
- package/tdf3/src/models/encryption-information.ts +2 -2
- package/tdf3/src/models/key-access.ts +120 -38
- package/tdf3/src/models/manifest.ts +3 -0
- package/tdf3/src/models/policy.ts +0 -1
- package/tdf3/src/tdf.ts +251 -207
- package/tdf3/src/utils/index.ts +0 -5
- package/tdf3/src/utils/unwrap.ts +17 -0
- package/tdf3/src/utils/zip-reader.ts +1 -1
- package/dist/cjs/src/nanotdf-crypto/importRawKey.js +0 -18
- package/dist/cjs/tdf3/src/templates/default.html.js +0 -98
- package/dist/cjs/tdf3/src/templates/escaper.js +0 -15
- package/dist/cjs/tdf3/src/templates/index.js +0 -12
- package/dist/cjs/tdf3/src/utils/chunkers.js +0 -114
- package/dist/cjs/tdf3/src/version.js +0 -6
- package/dist/types/src/nanotdf-crypto/importRawKey.d.ts +0 -13
- package/dist/types/src/nanotdf-crypto/importRawKey.d.ts.map +0 -1
- package/dist/types/tdf3/src/templates/default.html.d.ts +0 -8
- package/dist/types/tdf3/src/templates/default.html.d.ts.map +0 -1
- package/dist/types/tdf3/src/templates/escaper.d.ts +0 -6
- package/dist/types/tdf3/src/templates/escaper.d.ts.map +0 -1
- package/dist/types/tdf3/src/templates/index.d.ts +0 -3
- package/dist/types/tdf3/src/templates/index.d.ts.map +0 -1
- package/dist/types/tdf3/src/utils/chunkers.d.ts +0 -29
- package/dist/types/tdf3/src/utils/chunkers.d.ts.map +0 -1
- package/dist/types/tdf3/src/version.d.ts +0 -3
- package/dist/types/tdf3/src/version.d.ts.map +0 -1
- package/dist/web/src/nanotdf-crypto/importRawKey.js +0 -15
- package/dist/web/tdf3/src/templates/default.html.js +0 -96
- package/dist/web/tdf3/src/templates/escaper.js +0 -10
- package/dist/web/tdf3/src/templates/index.js +0 -3
- package/dist/web/tdf3/src/utils/chunkers.js +0 -107
- package/dist/web/tdf3/src/version.js +0 -3
- package/src/nanotdf-crypto/importRawKey.ts +0 -19
- package/tdf3/src/templates/default.html.ts +0 -105
- package/tdf3/src/templates/escaper.ts +0 -10
- package/tdf3/src/templates/index.ts +0 -2
- package/tdf3/src/version.ts +0 -2
package/src/opentdf.ts
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import { type AuthProvider } from './auth/providers.js';
|
|
2
|
+
import { ConfigurationError, InvalidFileError } from './errors.js';
|
|
3
|
+
import { NanoTDFDatasetClient } from './nanoclients.js';
|
|
4
|
+
export { Client as TDF3Client } from '../tdf3/src/client/index.js';
|
|
5
|
+
import NanoTDF from './nanotdf/NanoTDF.js';
|
|
6
|
+
import decryptNanoTDF from './nanotdf/decrypt.js';
|
|
7
|
+
import Client from './nanotdf/Client.js';
|
|
8
|
+
import Header from './nanotdf/models/Header.js';
|
|
9
|
+
import { fromSource, sourceToStream, type Source } from './seekable.js';
|
|
10
|
+
import { Client as TDF3Client } from '../tdf3/src/client/index.js';
|
|
11
|
+
import { AssertionConfig, AssertionVerificationKeys } from '../tdf3/src/assertions.js';
|
|
12
|
+
import { type KasPublicKeyAlgorithm, OriginAllowList, isPublicKeyAlgorithm } from './access.js';
|
|
13
|
+
import { type Manifest } from '../tdf3/src/models/manifest.js';
|
|
14
|
+
|
|
15
|
+
export { type KasPublicKeyAlgorithm, isPublicKeyAlgorithm };
|
|
16
|
+
|
|
17
|
+
export type Keys = {
|
|
18
|
+
[keyID: string]: CryptoKey | CryptoKeyPair;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Options when creating a new TDF object
|
|
22
|
+
// that are shared between all container types.
|
|
23
|
+
export type CreateOptions = {
|
|
24
|
+
// If the policy service should be used to control creation options
|
|
25
|
+
autoconfigure?: boolean;
|
|
26
|
+
|
|
27
|
+
// List of attributes that will be assigned to the object's policy
|
|
28
|
+
attributes?: string[];
|
|
29
|
+
|
|
30
|
+
// If set and positive, this represents the maxiumum number of bytes to read from a stream to encrypt.
|
|
31
|
+
// This is helpful for enforcing size limits and preventing DoS attacks.
|
|
32
|
+
byteLimit?: number;
|
|
33
|
+
|
|
34
|
+
// The KAS to use for creation, if none is specified by the attribute service.
|
|
35
|
+
defaultKASEndpoint?: string;
|
|
36
|
+
|
|
37
|
+
// Private (or shared) keys for signing assertions and bindings
|
|
38
|
+
signers?: Keys;
|
|
39
|
+
|
|
40
|
+
// Source of plaintext data
|
|
41
|
+
source: Source;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type CreateNanoTDFOptions = CreateOptions & {
|
|
45
|
+
bindingType?: 'ecdsa' | 'gmac';
|
|
46
|
+
|
|
47
|
+
// When creating a new collection, use ECDSA binding with this key id from the signers,
|
|
48
|
+
// instead of the DEK.
|
|
49
|
+
ecdsaBindingKeyID?: string;
|
|
50
|
+
|
|
51
|
+
// When creating a new collection,
|
|
52
|
+
// use the key in the `signers` list with this id
|
|
53
|
+
// to generate a signature for each element.
|
|
54
|
+
// When absent, the nanotdf is unsigned.
|
|
55
|
+
signingKeyID?: string;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type CreateNanoTDFCollectionOptions = CreateNanoTDFOptions & {
|
|
59
|
+
// The maximum number of key iterations to use for a single DEK.
|
|
60
|
+
maxKeyIterations?: number;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Metadata for a TDF object.
|
|
64
|
+
export type Metadata = object;
|
|
65
|
+
|
|
66
|
+
// MIME type of the decrypted content.
|
|
67
|
+
export type MimeType = `${string}/${string}`;
|
|
68
|
+
|
|
69
|
+
// Template for a Key Access Object (KAO) to be filled in during encrypt.
|
|
70
|
+
export type SplitStep = {
|
|
71
|
+
// Which KAS to use to rewrap this segment of the key
|
|
72
|
+
kas: string;
|
|
73
|
+
|
|
74
|
+
// An identifier for a key segment.
|
|
75
|
+
// Leave empty to share the key.
|
|
76
|
+
sid?: string;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/// Options specific to the ZTDF container format.
|
|
80
|
+
export type CreateZTDFOptions = CreateOptions & {
|
|
81
|
+
// Configuration for bound metadata.
|
|
82
|
+
assertionConfigs?: AssertionConfig[];
|
|
83
|
+
|
|
84
|
+
// Unbound metadata (deprecated)
|
|
85
|
+
metadata?: Metadata;
|
|
86
|
+
|
|
87
|
+
// MIME type of the decrypted content. Used for display.
|
|
88
|
+
mimeType?: MimeType;
|
|
89
|
+
|
|
90
|
+
// How to split or share the data encryption key across multiple KASes.
|
|
91
|
+
splitPlan?: SplitStep[];
|
|
92
|
+
|
|
93
|
+
// The segment size for the content; smaller is slower, but allows faster random access.
|
|
94
|
+
// The current default is 1 MiB (2^20 bytes).
|
|
95
|
+
windowSize?: number;
|
|
96
|
+
|
|
97
|
+
// Preferred algorithm to use for Key Access Objects.
|
|
98
|
+
wrappingKeyAlgorithm?: KasPublicKeyAlgorithm;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Settings for decrypting any variety of TDF file.
|
|
102
|
+
export type ReadOptions = {
|
|
103
|
+
// ciphertext
|
|
104
|
+
source: Source;
|
|
105
|
+
// list of KASes that may be contacted for a rewrap
|
|
106
|
+
allowedKASEndpoints?: string[];
|
|
107
|
+
// Optionally disable checking the allowlist
|
|
108
|
+
ignoreAllowlist?: boolean;
|
|
109
|
+
// Public (or shared) keys for verifying assertions
|
|
110
|
+
assertionVerificationKeys?: AssertionVerificationKeys;
|
|
111
|
+
// Optionally disable assertion verification
|
|
112
|
+
noVerify?: boolean;
|
|
113
|
+
|
|
114
|
+
// If set, prevents more than this number of concurrent requests to the KAS.
|
|
115
|
+
concurrencyLimit?: number;
|
|
116
|
+
|
|
117
|
+
// Type of key to use for wrapping responses.
|
|
118
|
+
wrappingKeyAlgorithm?: KasPublicKeyAlgorithm;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// Defaults and shared settings that are relevant to creating TDF objects.
|
|
122
|
+
export type OpenTDFOptions = {
|
|
123
|
+
// Policy service endpoint
|
|
124
|
+
policyEndpoint?: string;
|
|
125
|
+
|
|
126
|
+
// Auth provider for connections to the policy service and KASes.
|
|
127
|
+
authProvider: AuthProvider;
|
|
128
|
+
|
|
129
|
+
// Default settings for 'encrypt' type requests.
|
|
130
|
+
defaultCreateOptions?: Omit<CreateOptions, 'source'>;
|
|
131
|
+
|
|
132
|
+
// Default settings for 'decrypt' type requests.
|
|
133
|
+
defaultReadOptions?: Omit<ReadOptions, 'source'>;
|
|
134
|
+
|
|
135
|
+
// If we want to *not* send a DPoP token
|
|
136
|
+
disableDPoP?: boolean;
|
|
137
|
+
|
|
138
|
+
// Optional keys for DPoP requests to a server.
|
|
139
|
+
// These often must be registered via a DPoP flow with the IdP
|
|
140
|
+
// which is out of the scope of this library.
|
|
141
|
+
dpopKeys?: Promise<CryptoKeyPair>;
|
|
142
|
+
|
|
143
|
+
// Configuration options for the collection header cache.
|
|
144
|
+
rewrapCacheOptions?: RewrapCacheOptions;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export type DecoratedStream = ReadableStream<Uint8Array> & {
|
|
148
|
+
// If the source is a TDF3/ZTDF, and includes metadata, and it has been read.
|
|
149
|
+
metadata?: Promise<unknown>;
|
|
150
|
+
manifest?: Promise<Manifest>;
|
|
151
|
+
// If the source is a NanoTDF, this will be set.
|
|
152
|
+
header?: Header;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// Configuration options for the collection header cache.
|
|
156
|
+
export type RewrapCacheOptions = {
|
|
157
|
+
// If we should disable (bypass) the cache.
|
|
158
|
+
bypass?: boolean;
|
|
159
|
+
|
|
160
|
+
// Evict keys after this many milliseconds.
|
|
161
|
+
maxAge?: number;
|
|
162
|
+
|
|
163
|
+
// Check for expired keys once every this many milliseconds.
|
|
164
|
+
pollInterval?: number;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const defaultRewrapCacheOptions: Required<RewrapCacheOptions> = {
|
|
168
|
+
bypass: false,
|
|
169
|
+
maxAge: 300000,
|
|
170
|
+
pollInterval: 500,
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// Cache for headers of nanotdf collections.
|
|
174
|
+
// This allows the SDK to quickly open multiple entries of the same collection.
|
|
175
|
+
// It has a demon that removes all keys that have not been accessed in the last 5 minutes.
|
|
176
|
+
// To cancel the demon, and clear the cache, call `close()`.
|
|
177
|
+
export class RewrapCache {
|
|
178
|
+
private cache?: Map<Uint8Array, { lastAccessTime: number; value: CryptoKey }>;
|
|
179
|
+
private closer?: ReturnType<typeof setInterval>;
|
|
180
|
+
constructor(opts?: RewrapCacheOptions) {
|
|
181
|
+
const { bypass, maxAge, pollInterval } = { ...defaultRewrapCacheOptions, ...opts };
|
|
182
|
+
if (bypass) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
this.cache = new Map();
|
|
186
|
+
this.closer = setInterval(() => {
|
|
187
|
+
const now = Date.now();
|
|
188
|
+
const c = this.cache;
|
|
189
|
+
if (!c) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
for (const [key, value] of c.entries()) {
|
|
193
|
+
if (now - value.lastAccessTime > maxAge) {
|
|
194
|
+
c.delete(key);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}, pollInterval);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
get(key: Uint8Array): CryptoKey | undefined {
|
|
201
|
+
if (!this.cache) {
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
const entry = this.cache.get(key);
|
|
205
|
+
if (entry) {
|
|
206
|
+
entry.lastAccessTime = Date.now();
|
|
207
|
+
return entry.value;
|
|
208
|
+
}
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
set(key: Uint8Array, value: CryptoKey) {
|
|
213
|
+
if (!this.cache) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
this.cache.set(key, { lastAccessTime: Date.now(), value });
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
close() {
|
|
220
|
+
if (this.closer !== undefined) {
|
|
221
|
+
clearInterval(this.closer);
|
|
222
|
+
delete this.closer;
|
|
223
|
+
delete this.cache;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// SDK for dealing with OpenTDF data and policy services.
|
|
229
|
+
export class OpenTDF {
|
|
230
|
+
// Configuration service and more is at this URL/connectRPC endpoint
|
|
231
|
+
readonly policyEndpoint: string;
|
|
232
|
+
readonly authProvider: AuthProvider;
|
|
233
|
+
readonly dpopEnabled: boolean;
|
|
234
|
+
defaultCreateOptions: Omit<CreateOptions, 'source'>;
|
|
235
|
+
defaultReadOptions: Omit<ReadOptions, 'source'>;
|
|
236
|
+
readonly dpopKeys: Promise<CryptoKeyPair>;
|
|
237
|
+
|
|
238
|
+
// Header cache for reading nanotdf collections
|
|
239
|
+
private readonly rewrapCache: RewrapCache;
|
|
240
|
+
private tdf3Client: TDF3Client;
|
|
241
|
+
|
|
242
|
+
constructor({
|
|
243
|
+
authProvider,
|
|
244
|
+
dpopKeys,
|
|
245
|
+
defaultCreateOptions,
|
|
246
|
+
defaultReadOptions,
|
|
247
|
+
disableDPoP,
|
|
248
|
+
policyEndpoint,
|
|
249
|
+
rewrapCacheOptions,
|
|
250
|
+
}: OpenTDFOptions) {
|
|
251
|
+
this.authProvider = authProvider;
|
|
252
|
+
this.defaultCreateOptions = defaultCreateOptions || {};
|
|
253
|
+
this.defaultReadOptions = defaultReadOptions || {};
|
|
254
|
+
this.dpopEnabled = !!disableDPoP;
|
|
255
|
+
this.policyEndpoint = policyEndpoint || '';
|
|
256
|
+
this.rewrapCache = new RewrapCache(rewrapCacheOptions);
|
|
257
|
+
this.tdf3Client = new TDF3Client({
|
|
258
|
+
authProvider,
|
|
259
|
+
dpopKeys,
|
|
260
|
+
kasEndpoint: 'https://disallow.all.invalid',
|
|
261
|
+
policyEndpoint,
|
|
262
|
+
});
|
|
263
|
+
this.dpopKeys =
|
|
264
|
+
dpopKeys ??
|
|
265
|
+
crypto.subtle.generateKey(
|
|
266
|
+
{
|
|
267
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
268
|
+
hash: 'SHA-256',
|
|
269
|
+
modulusLength: 2048,
|
|
270
|
+
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
|
|
271
|
+
},
|
|
272
|
+
true,
|
|
273
|
+
['sign', 'verify']
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async createNanoTDF(opts: CreateNanoTDFOptions): Promise<DecoratedStream> {
|
|
278
|
+
opts = { ...this.defaultCreateOptions, ...opts };
|
|
279
|
+
const collection = await this.createNanoTDFCollection(opts);
|
|
280
|
+
try {
|
|
281
|
+
return await collection.encrypt(opts.source);
|
|
282
|
+
} finally {
|
|
283
|
+
await collection.close();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Creates a new collection object, which can be used to encrypt a series of data with the same policy.
|
|
289
|
+
* @returns
|
|
290
|
+
*/
|
|
291
|
+
async createNanoTDFCollection(opts: CreateNanoTDFCollectionOptions): Promise<NanoTDFCollection> {
|
|
292
|
+
opts = { ...this.defaultCreateOptions, ...opts };
|
|
293
|
+
return new Collection(this.authProvider, opts);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
async createZTDF(opts: CreateZTDFOptions): Promise<DecoratedStream> {
|
|
297
|
+
opts = { ...this.defaultCreateOptions, ...opts };
|
|
298
|
+
const oldStream = await this.tdf3Client.encrypt({
|
|
299
|
+
source: await sourceToStream(opts.source),
|
|
300
|
+
|
|
301
|
+
assertionConfigs: opts.assertionConfigs,
|
|
302
|
+
autoconfigure: !!opts.autoconfigure,
|
|
303
|
+
defaultKASEndpoint: opts.defaultKASEndpoint,
|
|
304
|
+
byteLimit: opts.byteLimit,
|
|
305
|
+
mimeType: opts.mimeType,
|
|
306
|
+
scope: {
|
|
307
|
+
attributes: opts.attributes,
|
|
308
|
+
},
|
|
309
|
+
splitPlan: opts.splitPlan,
|
|
310
|
+
windowSize: opts.windowSize,
|
|
311
|
+
wrappingKeyAlgorithm: opts.wrappingKeyAlgorithm,
|
|
312
|
+
});
|
|
313
|
+
const stream: DecoratedStream = oldStream.stream;
|
|
314
|
+
stream.manifest = Promise.resolve(oldStream.manifest);
|
|
315
|
+
stream.metadata = Promise.resolve(oldStream.metadata);
|
|
316
|
+
return stream;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Decrypts a nanotdf object. Optionally, stores the collection header and its DEK.
|
|
321
|
+
* @param ciphertext
|
|
322
|
+
*/
|
|
323
|
+
async read(opts: ReadOptions): Promise<DecoratedStream> {
|
|
324
|
+
opts = { ...this.defaultReadOptions, ...opts };
|
|
325
|
+
const chunker = await fromSource(opts.source);
|
|
326
|
+
const prefix = await chunker(0, 3);
|
|
327
|
+
// switch for prefix, if starts with `PK` in ascii, or `L1L` in ascii:
|
|
328
|
+
if (prefix[0] === 0x50 && prefix[1] === 0x4b) {
|
|
329
|
+
const allowList = new OriginAllowList(opts.allowedKASEndpoints ?? [], opts.ignoreAllowlist);
|
|
330
|
+
const oldStream = await this.tdf3Client.decrypt({
|
|
331
|
+
source: opts.source,
|
|
332
|
+
allowList,
|
|
333
|
+
assertionVerificationKeys: opts.assertionVerificationKeys,
|
|
334
|
+
noVerifyAssertions: opts.noVerify,
|
|
335
|
+
wrappingKeyAlgorithm: opts.wrappingKeyAlgorithm,
|
|
336
|
+
});
|
|
337
|
+
const stream: DecoratedStream = oldStream.stream;
|
|
338
|
+
stream.metadata = Promise.resolve(oldStream.metadata);
|
|
339
|
+
return stream;
|
|
340
|
+
} else if (prefix[0] === 0x4c && prefix[1] === 0x31 && prefix[2] === 0x4c) {
|
|
341
|
+
const ciphertext = await chunker();
|
|
342
|
+
const nanotdf = NanoTDF.from(ciphertext);
|
|
343
|
+
const cachedDEK = this.rewrapCache.get(nanotdf.header.ephemeralPublicKey);
|
|
344
|
+
if (cachedDEK) {
|
|
345
|
+
const r: DecoratedStream = await streamify(decryptNanoTDF(cachedDEK, nanotdf));
|
|
346
|
+
r.header = nanotdf.header;
|
|
347
|
+
return r;
|
|
348
|
+
}
|
|
349
|
+
const nc = new Client({
|
|
350
|
+
allowedKases: opts.allowedKASEndpoints,
|
|
351
|
+
authProvider: this.authProvider,
|
|
352
|
+
ignoreAllowList: opts.ignoreAllowlist,
|
|
353
|
+
dpopEnabled: this.dpopEnabled,
|
|
354
|
+
dpopKeys: this.dpopKeys,
|
|
355
|
+
kasEndpoint: opts.allowedKASEndpoints?.[0] || 'https://disallow.all.invalid',
|
|
356
|
+
});
|
|
357
|
+
// TODO: The version number should be fetched from the API
|
|
358
|
+
const version = '0.0.1';
|
|
359
|
+
// Rewrap key on every request
|
|
360
|
+
const dek = await nc.rewrapKey(
|
|
361
|
+
nanotdf.header.toBuffer(),
|
|
362
|
+
nanotdf.header.getKasRewrapUrl(),
|
|
363
|
+
nanotdf.header.magicNumberVersion,
|
|
364
|
+
version
|
|
365
|
+
);
|
|
366
|
+
if (!dek) {
|
|
367
|
+
// These should have thrown already.
|
|
368
|
+
throw new Error('internal: key rewrap failure');
|
|
369
|
+
}
|
|
370
|
+
this.rewrapCache.set(nanotdf.header.ephemeralPublicKey, dek);
|
|
371
|
+
const r: DecoratedStream = await streamify(decryptNanoTDF(dek, nanotdf));
|
|
372
|
+
r.header = nanotdf.header;
|
|
373
|
+
return r;
|
|
374
|
+
}
|
|
375
|
+
throw new InvalidFileError(`unsupported format; prefix not recognized ${prefix}`);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
close() {
|
|
379
|
+
this.rewrapCache.close();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
async function streamify(ab: Promise<ArrayBuffer>): Promise<ReadableStream<Uint8Array>> {
|
|
384
|
+
const stream = new ReadableStream<Uint8Array>({
|
|
385
|
+
start(controller) {
|
|
386
|
+
ab.then((arrayBuffer) => {
|
|
387
|
+
controller.enqueue(new Uint8Array(arrayBuffer));
|
|
388
|
+
controller.close();
|
|
389
|
+
});
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
return stream;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export type NanoTDFCollection = {
|
|
396
|
+
encrypt: (source: Source) => Promise<ReadableStream<Uint8Array>>;
|
|
397
|
+
close: () => Promise<void>;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
class Collection {
|
|
401
|
+
client?: NanoTDFDatasetClient;
|
|
402
|
+
|
|
403
|
+
constructor(authProvider: AuthProvider, opts: CreateNanoTDFCollectionOptions) {
|
|
404
|
+
if (opts.signers || opts.signingKeyID) {
|
|
405
|
+
throw new ConfigurationError('ntdf signing not implemented');
|
|
406
|
+
}
|
|
407
|
+
if (opts.autoconfigure) {
|
|
408
|
+
throw new ConfigurationError('autoconfigure not implemented');
|
|
409
|
+
}
|
|
410
|
+
if (opts.ecdsaBindingKeyID) {
|
|
411
|
+
throw new ConfigurationError('custom binding key not implemented');
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
this.client = new NanoTDFDatasetClient({
|
|
415
|
+
authProvider,
|
|
416
|
+
kasEndpoint: opts.defaultKASEndpoint ?? 'https://disallow.all.invalid',
|
|
417
|
+
maxKeyIterations: opts.maxKeyIterations,
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
async encrypt(source: Source): Promise<DecoratedStream> {
|
|
422
|
+
if (!this.client) {
|
|
423
|
+
throw new ConfigurationError('Collection is closed');
|
|
424
|
+
}
|
|
425
|
+
const chunker = await fromSource(source);
|
|
426
|
+
const cipherChunk = await this.client.encrypt(await chunker());
|
|
427
|
+
const stream: DecoratedStream = new ReadableStream<Uint8Array>({
|
|
428
|
+
start(controller) {
|
|
429
|
+
controller.enqueue(new Uint8Array(cipherChunk));
|
|
430
|
+
controller.close();
|
|
431
|
+
},
|
|
432
|
+
});
|
|
433
|
+
// TODO: client's header object is private
|
|
434
|
+
// stream.header = this.client.header;
|
|
435
|
+
return stream;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
async close() {
|
|
439
|
+
delete this.client;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
@@ -1,30 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type DecoratedReadableStream,
|
|
3
|
-
isDecoratedReadableStream,
|
|
4
|
-
} from '../client/DecoratedReadableStream.js';
|
|
5
|
-
import { ConfigurationError, InvalidFileError, NetworkError } from '../../../src/errors.js';
|
|
1
|
+
import { ConfigurationError, InvalidFileError, NetworkError } from './errors.js';
|
|
6
2
|
|
|
7
3
|
/**
|
|
8
4
|
* Read data from a seekable stream.
|
|
5
|
+
* This is an abstraction for URLs with range queries and local file objects.
|
|
9
6
|
* @param byteStart First byte to read. If negative, reads from the end. If absent, reads everything
|
|
10
7
|
* @param byteEnd Index after last byte to read (exclusive)
|
|
11
8
|
*/
|
|
12
9
|
export type Chunker = (byteStart?: number, byteEnd?: number) => Promise<Uint8Array>;
|
|
13
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Type union for a variety of inputs.
|
|
13
|
+
*/
|
|
14
|
+
export type Source =
|
|
15
|
+
| { type: 'buffer'; location: Uint8Array }
|
|
16
|
+
| { type: 'chunker'; location: Chunker }
|
|
17
|
+
| { type: 'file-browser'; location: Blob }
|
|
18
|
+
| { type: 'remote'; location: string }
|
|
19
|
+
| { type: 'stream'; location: ReadableStream<Uint8Array> };
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Creates a seekable object from a browser file object.
|
|
23
|
+
* @param fileRef the browser file data
|
|
24
|
+
*/
|
|
14
25
|
export const fromBrowserFile = (fileRef: Blob): Chunker => {
|
|
15
26
|
return async (byteStart?: number, byteEnd?: number): Promise<Uint8Array> => {
|
|
27
|
+
if (byteStart === undefined) {
|
|
28
|
+
return new Uint8Array(await fileRef.arrayBuffer());
|
|
29
|
+
}
|
|
16
30
|
const chunkBlob = fileRef.slice(byteStart, byteEnd);
|
|
17
31
|
const arrayBuffer = await new Response(chunkBlob).arrayBuffer();
|
|
18
32
|
return new Uint8Array(arrayBuffer);
|
|
19
33
|
};
|
|
20
34
|
};
|
|
21
35
|
|
|
22
|
-
export const fromBuffer = (source: Uint8Array
|
|
36
|
+
export const fromBuffer = (source: Uint8Array): Chunker => {
|
|
23
37
|
return (byteStart?: number, byteEnd?: number) => {
|
|
24
38
|
return Promise.resolve(source.slice(byteStart, byteEnd));
|
|
25
39
|
};
|
|
26
40
|
};
|
|
27
41
|
|
|
42
|
+
export const fromString = (source: string): Chunker => {
|
|
43
|
+
return fromBuffer(new TextEncoder().encode(source));
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
async function sleep(ms: number) {
|
|
47
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
48
|
+
}
|
|
49
|
+
|
|
28
50
|
async function getRemoteChunk(url: string, range?: string): Promise<Uint8Array> {
|
|
29
51
|
// loop with fetch for three times, with an exponential backoff
|
|
30
52
|
// if the fetch fails with a network error
|
|
@@ -88,14 +110,7 @@ export const fromUrl = async (location: string): Promise<Chunker> => {
|
|
|
88
110
|
};
|
|
89
111
|
};
|
|
90
112
|
|
|
91
|
-
export type
|
|
92
|
-
| { type: 'buffer'; location: Uint8Array }
|
|
93
|
-
| { type: 'chunker'; location: Chunker }
|
|
94
|
-
| { type: 'file-browser'; location: Blob }
|
|
95
|
-
| { type: 'remote'; location: string }
|
|
96
|
-
| { type: 'stream'; location: DecoratedReadableStream };
|
|
97
|
-
|
|
98
|
-
export const fromDataSource = async ({ type, location }: DataSource) => {
|
|
113
|
+
export const fromSource = async ({ type, location }: Source): Promise<Chunker> => {
|
|
99
114
|
switch (type) {
|
|
100
115
|
case 'buffer':
|
|
101
116
|
if (!(location instanceof Uint8Array)) {
|
|
@@ -118,14 +133,48 @@ export const fromDataSource = async ({ type, location }: DataSource) => {
|
|
|
118
133
|
}
|
|
119
134
|
return fromUrl(location);
|
|
120
135
|
case 'stream':
|
|
121
|
-
|
|
122
|
-
throw new ConfigurationError('Invalid data source; must be DecoratedTdfStream');
|
|
123
|
-
}
|
|
124
|
-
return fromBuffer(await location.toBuffer());
|
|
136
|
+
return fromBuffer(new Uint8Array(await new Response(location).arrayBuffer()));
|
|
125
137
|
default:
|
|
126
138
|
throw new ConfigurationError(`Data source type not defined, or not supported: ${type}}`);
|
|
127
139
|
}
|
|
128
140
|
};
|
|
129
|
-
|
|
130
|
-
|
|
141
|
+
|
|
142
|
+
export async function sourceToStream(source: Source): Promise<ReadableStream<Uint8Array>> {
|
|
143
|
+
switch (source.type) {
|
|
144
|
+
case 'stream':
|
|
145
|
+
return source.location;
|
|
146
|
+
case 'file-browser':
|
|
147
|
+
return source.location.stream();
|
|
148
|
+
case 'chunker': {
|
|
149
|
+
const chunkSize = 8 * 1024 * 1024; // 8 megabytes
|
|
150
|
+
let offset = 0;
|
|
151
|
+
return new ReadableStream({
|
|
152
|
+
async pull(controller) {
|
|
153
|
+
const chunk = await source.location(offset, offset + chunkSize);
|
|
154
|
+
if (chunk.length === 0) {
|
|
155
|
+
controller.close();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
controller.enqueue(chunk);
|
|
159
|
+
offset += chunk.length;
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
default: {
|
|
164
|
+
const chunker = await fromSource(source);
|
|
165
|
+
return new ReadableStream({
|
|
166
|
+
async start(controller) {
|
|
167
|
+
const chunk = await chunker();
|
|
168
|
+
controller.enqueue(chunk);
|
|
169
|
+
controller.close();
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
131
174
|
}
|
|
175
|
+
|
|
176
|
+
// Deprected name, prefer `fromSource`
|
|
177
|
+
export const fromDataSource = fromSource;
|
|
178
|
+
|
|
179
|
+
// Deprecated Name; prefer just `Source`
|
|
180
|
+
export type DataSource = Source;
|
|
@@ -7,8 +7,6 @@ export interface AttributeObject {
|
|
|
7
7
|
/** PEM encoded public key */
|
|
8
8
|
readonly pubKey: string;
|
|
9
9
|
readonly kasUrl: string;
|
|
10
|
-
/** The most recent version 1.1.0. */
|
|
11
|
-
readonly schemaVersion?: string;
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
export async function createAttribute(
|
|
@@ -22,6 +20,5 @@ export async function createAttribute(
|
|
|
22
20
|
displayName: '',
|
|
23
21
|
pubKey: pubKey.publicKey,
|
|
24
22
|
kasUrl,
|
|
25
|
-
schemaVersion: '1.1.0',
|
|
26
23
|
};
|
|
27
24
|
}
|
package/src/tdf/Policy.ts
CHANGED
package/src/tdf/PolicyObject.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { exportSPKI, importX509 } from 'jose';
|
|
2
2
|
|
|
3
3
|
import { base64 } from './encodings/index.js';
|
|
4
|
-
import { pemCertToCrypto, pemPublicToCrypto } from './nanotdf-crypto/
|
|
4
|
+
import { pemCertToCrypto, pemPublicToCrypto } from './nanotdf-crypto/pemPublicToCrypto.js';
|
|
5
5
|
import { ConfigurationError } from './errors.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -45,8 +45,6 @@ export function isBrowser() {
|
|
|
45
45
|
return typeof window !== 'undefined'; // eslint-disable-line
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export const isFirefox = (): boolean => isBrowser() && 'InstallTrigger' in window;
|
|
49
|
-
|
|
50
48
|
export const rstrip = (str: string, suffix = ' '): string => {
|
|
51
49
|
while (str && suffix && str.endsWith(suffix)) {
|
|
52
50
|
str = str.slice(0, -suffix.length);
|
package/src/version.ts
CHANGED
|
@@ -7,3 +7,8 @@ export const version = '0.2.0';
|
|
|
7
7
|
* A string name used to label requests as coming from this library client.
|
|
8
8
|
*/
|
|
9
9
|
export const clientType = 'web-sdk';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Version of the opentdf/spec this library is targeting
|
|
13
|
+
*/
|
|
14
|
+
export const tdfSpecVersion = '4.3.0';
|
package/tdf3/index.ts
CHANGED
|
@@ -33,9 +33,9 @@ import {
|
|
|
33
33
|
AuthProviders,
|
|
34
34
|
version,
|
|
35
35
|
clientType,
|
|
36
|
-
} from '../src/
|
|
36
|
+
} from '../src/nanoindex.js';
|
|
37
37
|
import { Algorithms, type AlgorithmName, type AlgorithmUrn } from './src/ciphers/algorithms.js';
|
|
38
|
-
import { type Chunker } from '
|
|
38
|
+
import { type Chunker } from '../src/seekable.js';
|
|
39
39
|
|
|
40
40
|
export type {
|
|
41
41
|
AlgorithmName,
|
|
@@ -82,3 +82,15 @@ export {
|
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
export * as WebCryptoService from './src/crypto/index.js';
|
|
85
|
+
export {
|
|
86
|
+
type CreateNanoTDFCollectionOptions,
|
|
87
|
+
type CreateNanoTDFOptions,
|
|
88
|
+
type CreateOptions,
|
|
89
|
+
type CreateZTDFOptions,
|
|
90
|
+
type DecoratedStream,
|
|
91
|
+
type Keys,
|
|
92
|
+
type OpenTDFOptions,
|
|
93
|
+
type NanoTDFCollection,
|
|
94
|
+
type ReadOptions,
|
|
95
|
+
OpenTDF,
|
|
96
|
+
} from '../src/opentdf.js';
|