@enbox/dwn-sdk-js 0.4.7 → 0.4.9

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.
Files changed (121) hide show
  1. package/dist/browser.mjs +1 -1
  2. package/dist/browser.mjs.map +4 -4
  3. package/dist/esm/generated/precompiled-validators.js +319 -0
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/dwn-error.js +1 -0
  6. package/dist/esm/src/core/dwn-error.js.map +1 -1
  7. package/dist/esm/src/index.js +1 -1
  8. package/dist/esm/src/index.js.map +1 -1
  9. package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
  10. package/dist/esm/src/protocols/encryption.js +38 -6
  11. package/dist/esm/src/protocols/encryption.js.map +1 -1
  12. package/dist/esm/src/store/index-level-compound.js.map +1 -1
  13. package/dist/esm/src/store/level-wrapper.js +6 -2
  14. package/dist/esm/src/store/level-wrapper.js.map +1 -1
  15. package/dist/esm/src/utils/jws.js.map +1 -1
  16. package/dist/esm/tests/dwn.spec.js +5 -5
  17. package/dist/esm/tests/dwn.spec.js.map +1 -1
  18. package/dist/esm/tests/features/author-delegated-grant.spec.js +16 -16
  19. package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
  20. package/dist/esm/tests/features/owner-delegated-grant.spec.js +7 -7
  21. package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
  22. package/dist/esm/tests/features/permissions.spec.js +8 -8
  23. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  24. package/dist/esm/tests/features/protocol-composition.spec.js +3 -3
  25. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  26. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js +5 -5
  27. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js.map +1 -1
  28. package/dist/esm/tests/features/records-prune.spec.js +15 -15
  29. package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
  30. package/dist/esm/tests/features/records-squash.spec.js +9 -9
  31. package/dist/esm/tests/features/records-squash.spec.js.map +1 -1
  32. package/dist/esm/tests/features/records-tags.spec.js +28 -28
  33. package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
  34. package/dist/esm/tests/features/resumable-tasks.spec.js +3 -3
  35. package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
  36. package/dist/esm/tests/fuzz/data-stream.fuzz.spec.js +2 -2
  37. package/dist/esm/tests/fuzz/data-stream.fuzz.spec.js.map +1 -1
  38. package/dist/esm/tests/fuzz/filter.fuzz.spec.js +1 -1
  39. package/dist/esm/tests/fuzz/filter.fuzz.spec.js.map +1 -1
  40. package/dist/esm/tests/fuzz/records-utils.fuzz.spec.js +2 -2
  41. package/dist/esm/tests/fuzz/records-utils.fuzz.spec.js.map +1 -1
  42. package/dist/esm/tests/fuzz/resumable-task-store.fuzz.spec.js +4 -4
  43. package/dist/esm/tests/fuzz/resumable-task-store.fuzz.spec.js.map +1 -1
  44. package/dist/esm/tests/handlers/messages-subscribe.spec.js +16 -16
  45. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  46. package/dist/esm/tests/handlers/protocols-configure.spec.js +5 -5
  47. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  48. package/dist/esm/tests/handlers/protocols-query.spec.js +11 -11
  49. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  50. package/dist/esm/tests/handlers/records-delete.spec.js +22 -22
  51. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  52. package/dist/esm/tests/handlers/records-query.spec.js +120 -120
  53. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  54. package/dist/esm/tests/handlers/records-read.spec.js +1 -1
  55. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  56. package/dist/esm/tests/handlers/records-subscribe.spec.js +10 -10
  57. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  58. package/dist/esm/tests/handlers/records-write.spec.js +31 -31
  59. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  60. package/dist/esm/tests/interfaces/protocols-configure.spec.js +4 -4
  61. package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
  62. package/dist/esm/tests/jose/jws/general.spec.js +4 -4
  63. package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
  64. package/dist/esm/tests/protocols/encryption.spec.js +94 -3
  65. package/dist/esm/tests/protocols/encryption.spec.js.map +1 -1
  66. package/dist/esm/tests/scenarios/nested-roles.spec.js +1 -1
  67. package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
  68. package/dist/esm/tests/scenarios/subscriptions.spec.js +28 -28
  69. package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
  70. package/dist/esm/tests/store/blockstore-mock.spec.js +1 -1
  71. package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
  72. package/dist/esm/tests/store/data-store-level.spec.js +3 -3
  73. package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
  74. package/dist/esm/tests/store/index-level.spec.js +83 -83
  75. package/dist/esm/tests/store/index-level.spec.js.map +1 -1
  76. package/dist/esm/tests/store/message-store-level.spec.js +2 -2
  77. package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
  78. package/dist/esm/tests/store/message-store.spec.js +30 -30
  79. package/dist/esm/tests/store/message-store.spec.js.map +1 -1
  80. package/dist/esm/tests/store-dependent-tests.spec.js +5 -0
  81. package/dist/esm/tests/store-dependent-tests.spec.js.map +1 -1
  82. package/dist/esm/tests/utils/data-stream.spec.js +15 -15
  83. package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
  84. package/dist/esm/tests/utils/encryption.spec.js +1 -1
  85. package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
  86. package/dist/esm/tests/utils/messages.spec.js +8 -8
  87. package/dist/esm/tests/utils/messages.spec.js.map +1 -1
  88. package/dist/esm/tests/utils/secp256k1.spec.js +2 -2
  89. package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
  90. package/dist/esm/tests/utils/secp256r1.spec.js +1 -1
  91. package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
  92. package/dist/esm/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.js +43 -0
  93. package/dist/esm/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.js.map +1 -0
  94. package/dist/types/generated/precompiled-validators.d.ts +16 -0
  95. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  96. package/dist/types/src/core/dwn-error.d.ts +1 -0
  97. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  98. package/dist/types/src/index.d.ts +2 -1
  99. package/dist/types/src/index.d.ts.map +1 -1
  100. package/dist/types/src/interfaces/messages-subscribe.d.ts +1 -2
  101. package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
  102. package/dist/types/src/protocols/encryption.d.ts +15 -2
  103. package/dist/types/src/protocols/encryption.d.ts.map +1 -1
  104. package/dist/types/src/store/index-level-compound.d.ts +2 -4
  105. package/dist/types/src/store/index-level-compound.d.ts.map +1 -1
  106. package/dist/types/src/store/level-wrapper.d.ts.map +1 -1
  107. package/dist/types/src/types/protocols-types.d.ts +1 -1
  108. package/dist/types/src/types/protocols-types.d.ts.map +1 -1
  109. package/dist/types/src/utils/jws.d.ts +1 -2
  110. package/dist/types/src/utils/jws.d.ts.map +1 -1
  111. package/dist/types/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.d.ts +2 -0
  112. package/dist/types/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.d.ts.map +1 -0
  113. package/package.json +4 -4
  114. package/src/core/dwn-error.ts +1 -0
  115. package/src/index.ts +2 -1
  116. package/src/interfaces/messages-subscribe.ts +1 -2
  117. package/src/protocols/encryption.ts +59 -6
  118. package/src/store/index-level-compound.ts +2 -5
  119. package/src/store/level-wrapper.ts +6 -2
  120. package/src/types/protocols-types.ts +2 -1
  121. package/src/utils/jws.ts +1 -2
@@ -6,14 +6,42 @@ import type { PermissionScope } from '../types/permission-types.js';
6
6
  import type { ProtocolDefinition } from '../types/protocols-types.js';
7
7
  import type { RecordsWriteMessage } from '../types/records-types.js';
8
8
  import type { ValidationStateReader } from '../types/validation-state-reader.js';
9
+ import type { ContentEncryptionAlgorithm, X25519KeyEncryptionBase } from '../utils/encryption.js';
9
10
 
11
+ import { DwnConstant } from '../core/dwn-constant.js';
12
+ import { Encoder } from '../utils/encoder.js';
10
13
  import { ENCRYPTION_PROTOCOL_URI } from '../core/constants.js';
11
14
  import { FilterUtility } from '../utils/filter.js';
12
15
  import { Message } from '../core/message.js';
13
16
  import { Records } from '../utils/records.js';
17
+ import { validateJsonSchema } from '../schema-validator.js';
14
18
  import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
15
19
  import { grantKeyScopeCoversDeliveredScope, isGrantKeyEligibleRecordsScope, isGrantKeyRecordsScope } from '../utils/grant-key-coverage.js';
16
20
 
21
+ export const WRAPPED_GRANT_KEY_FORMAT = 'enbox/wrapped-grant-key@1';
22
+
23
+ export type WrappedGrantKeyEnvelope = {
24
+ format: typeof WRAPPED_GRANT_KEY_FORMAT;
25
+ keyEncryption: X25519KeyEncryptionBase;
26
+ contentEncryption: {
27
+ algorithm: typeof ContentEncryptionAlgorithm.A256CTR;
28
+ initializationVector: string;
29
+ };
30
+ ciphertext: string;
31
+ };
32
+
33
+ export function assertWrappedGrantKeyEnvelope(envelope: unknown): asserts envelope is WrappedGrantKeyEnvelope {
34
+ try {
35
+ validateJsonSchema('WrappedGrantKeyEnvelope', envelope);
36
+ } catch (error) {
37
+ const detail = error instanceof Error ? error.message : String(error);
38
+ throw new DwnError(
39
+ DwnErrorCode.EncryptionProtocolValidateGrantKeyWrappedDeliveryInvalid,
40
+ `wrapped grantKey envelope is invalid: ${detail}`
41
+ );
42
+ }
43
+ }
44
+
17
45
  export class EncryptionProtocol implements CoreProtocol {
18
46
  public static readonly uri = ENCRYPTION_PROTOCOL_URI;
19
47
  public static readonly grantKeyPath = 'grantKey';
@@ -64,9 +92,9 @@ export class EncryptionProtocol implements CoreProtocol {
64
92
  }
65
93
  }
66
94
 
67
- public async validateRecord(message: RecordsWriteMessage, _dataBytes: Uint8Array): Promise<void> {
95
+ public async validateRecord(message: RecordsWriteMessage, dataBytes: Uint8Array): Promise<void> {
68
96
  if (message.descriptor.protocolPath === EncryptionProtocol.grantKeyPath) {
69
- EncryptionProtocol.verifyEncryptedDelivery(message);
97
+ EncryptionProtocol.verifyGrantKeyDelivery(message, dataBytes);
70
98
  return;
71
99
  }
72
100
 
@@ -81,7 +109,7 @@ export class EncryptionProtocol implements CoreProtocol {
81
109
  message: RecordsWriteMessage,
82
110
  validationStateReader: ValidationStateReader,
83
111
  ): Promise<void> {
84
- EncryptionProtocol.verifyEncryptedDelivery(message);
112
+ EncryptionProtocol.verifyInlineWrappedGrantKeyDelivery(message);
85
113
 
86
114
  const grantId = EncryptionProtocol.getRequiredStringTag(message, 'grantId');
87
115
  const protocol = EncryptionProtocol.getRequiredStringTag(message, 'protocol');
@@ -102,11 +130,36 @@ export class EncryptionProtocol implements CoreProtocol {
102
130
  });
103
131
  }
104
132
 
105
- private static verifyEncryptedDelivery(message: RecordsWriteMessage): void {
106
- if (message.encryption === undefined) {
133
+ private static verifyInlineWrappedGrantKeyDelivery(message: RecordsWriteMessage): void {
134
+ if (message.encryption !== undefined) {
135
+ return;
136
+ }
137
+
138
+ if (message.descriptor.dataSize > DwnConstant.maxDataSizeAllowedToBeEncoded) {
139
+ throw new DwnError(
140
+ DwnErrorCode.EncryptionProtocolValidateEncryptedDeliveryMissingEncryption,
141
+ 'plaintext grantKey records must carry an inline wrapped grantKey envelope.'
142
+ );
143
+ }
144
+ }
145
+
146
+ private static verifyGrantKeyDelivery(message: RecordsWriteMessage, dataBytes: Uint8Array): void {
147
+ if (message.encryption !== undefined) {
148
+ return;
149
+ }
150
+
151
+ try {
152
+ const envelope = Encoder.bytesToObject(dataBytes);
153
+ assertWrappedGrantKeyEnvelope(envelope);
154
+ } catch (error) {
155
+ if (error instanceof DwnError) {
156
+ throw error;
157
+ }
158
+
159
+ const detail = error instanceof Error ? error.message : String(error);
107
160
  throw new DwnError(
108
161
  DwnErrorCode.EncryptionProtocolValidateEncryptedDeliveryMissingEncryption,
109
- `${message.descriptor.protocolPath} records must be encrypted.`
162
+ `${message.descriptor.protocolPath} records must be encrypted or carry a valid wrapped grantKey envelope: ${detail}`
110
163
  );
111
164
  }
112
165
  }
@@ -1,9 +1,6 @@
1
+ import type { CompoundIndexDefinition, IndexedItem, IndexLevelOptions } from './index-level.js';
1
2
  import type { Filter, KeyValues, QueryOptions } from '../types/query-types.js';
2
- import type { IndexedItem, IndexLevelOptions } from './index-level.js';
3
- import type { LevelWrapperBatchOperation, LevelWrapperIteratorOptions } from './level-wrapper.js';
4
-
5
- import type { CompoundIndexDefinition } from './index-level.js';
6
- import type { LevelWrapper } from './level-wrapper.js';
3
+ import type { LevelWrapper, LevelWrapperBatchOperation, LevelWrapperIteratorOptions } from './level-wrapper.js';
7
4
 
8
5
  import { FilterUtility } from '../utils/filter.js';
9
6
  import { SortDirection } from '../types/query-types.js';
@@ -251,8 +251,12 @@ export class LevelWrapper<V> {
251
251
  }
252
252
 
253
253
  // derive an exclusive `maxKey` by changing the last prefix character to the immediate succeeding character in unicode
254
- // (which matches how `abstract-level` creates a `boundary`)
255
- const maxKey = prefix.slice(0, -1) + String.fromCharCode(prefix.charCodeAt(prefix.length - 1) + 1);
254
+ // (which matches how `abstract-level` creates a `boundary`).
255
+ //
256
+ // This MUST stay UTF-16 code-unit based (`charCodeAt`/`fromCharCode`) to match `abstract-level`'s
257
+ // boundary semantics: `fromCharCode` wraps at 0xFFFF whereas `fromCodePoint` would emit an astral
258
+ // surrogate pair, producing a different — and incorrect — key range. NOSONAR (typescript:S7758).
259
+ const maxKey = prefix.slice(0, -1) + String.fromCharCode(prefix.charCodeAt(prefix.length - 1) + 1); // NOSONAR
256
260
  const minKey = prefix;
257
261
 
258
262
  return [minKey, maxKey];
@@ -237,7 +237,8 @@ type ProtocolRuleSetValue =
237
237
  | ProtocolTagsDefinition
238
238
  | ProtocolSizeDefinition
239
239
  | ProtocolRecordLimitDefinition
240
- | ProtocolDeliveryStrategy
240
+ // `ProtocolDeliveryStrategy` ('direct' | 'subscribe') is intentionally omitted here: its
241
+ // values are already covered by the `string` member below (see the `$delivery` field typing).
241
242
  | boolean
242
243
  | string
243
244
  | undefined;
package/src/utils/jws.ts CHANGED
@@ -1,6 +1,5 @@
1
- import type { GeneralJws } from '../types/jws-types.js';
2
1
  import type { MessageSigner } from '../types/signer.js';
3
- import type { SignatureEntry } from '../types/jws-types.js';
2
+ import type { GeneralJws, SignatureEntry } from '../types/jws-types.js';
4
3
  import type { KeyMaterial, PublicKeyJwk } from '../types/jose-types.js';
5
4
 
6
5
  import { Encoder } from './encoder.js';