@mdbase-dev/connect-protocol 0.1.0-beta.56 → 0.1.0-beta.58
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/application-authorization.d.ts +3 -3
- package/dist/application-authorization.js +27 -3
- package/dist/compatibility.d.ts +13 -2
- package/dist/compatibility.js +33 -4
- package/dist/connect-problems.generated.d.ts +11 -0
- package/dist/connect-problems.generated.js +1 -0
- package/dist/index.d.ts +18 -8
- package/dist/index.js +4 -1
- package/package.json +1 -1
- package/schemas/catalog.json +1 -0
- package/schemas/connect-problem.v1.schema.json +40 -0
- package/schemas/connect-problems.v1.catalog.json +1 -0
- package/schemas/encrypted-relay.v2.schema.json +63 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ApplicationFileRequirement } from "./files.js";
|
|
2
|
-
import type
|
|
3
|
-
import type { ConnectContractRequirements } from "./compatibility.js";
|
|
2
|
+
import { type CollectionOperation } from "./operations.js";
|
|
3
|
+
import type { AuthorizationBindingProtocolVersion, ConnectContractRequirements } from "./compatibility.js";
|
|
4
4
|
export type ApplicationAuthorizationFlow = "authorization_code" | "device_code";
|
|
5
5
|
export interface ApplicationAuthorizationBinding {
|
|
6
|
-
protocol_version:
|
|
6
|
+
protocol_version: AuthorizationBindingProtocolVersion;
|
|
7
7
|
authorization_id: string;
|
|
8
8
|
application_id: string;
|
|
9
9
|
application_declaration_id: string;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { isMutatingOperation } from "./operations.js";
|
|
2
|
+
import { AUTHORIZATION_BINDING_PROTOCOL_VERSION, LEGACY_AUTHORIZATION_BINDING_PROTOCOL_VERSION, OPERATION_TRANSPORT_PROTOCOL_VERSION, isSupportedAuthorizationBinding, isSupportedOperationTransport } from "./compatibility.js";
|
|
1
3
|
const INSTALLATION_ID_DOMAIN = new TextEncoder().encode("mdbase-connect application installation id v2\0");
|
|
2
|
-
const
|
|
4
|
+
const AUTHORIZATION_PROOF_V4_DOMAIN = new TextEncoder().encode("mdbase-connect application authorization proof v4\0");
|
|
5
|
+
const AUTHORIZATION_PROOF_V5_DOMAIN = new TextEncoder().encode("mdbase-connect application authorization proof v5\0");
|
|
3
6
|
export async function applicationInstallationIdFromPublicKey(signingPublicKey) {
|
|
4
7
|
const signing = publicKey(signingPublicKey);
|
|
5
8
|
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", concat([INSTALLATION_ID_DOMAIN, field(signing)])));
|
|
@@ -26,7 +29,10 @@ export function authorizationSigningMessage(binding) {
|
|
|
26
29
|
const nonce = canonicalBase64(binding.authorization_nonce);
|
|
27
30
|
const challenge = canonicalBase64(binding.code_challenge);
|
|
28
31
|
const contracts = binding.contracts;
|
|
29
|
-
|
|
32
|
+
const recovery = contracts.operation_transport_recovery ?? [];
|
|
33
|
+
const requiresDurableMutation = binding.requested_operations.some((operation) => isMutatingOperation(operation, { action: "mutate" }))
|
|
34
|
+
|| binding.requested_files?.actions.some((action) => !["list", "read"].includes(action)) === true;
|
|
35
|
+
if (!isSupportedAuthorizationBinding(binding.protocol_version)
|
|
30
36
|
|| nonce.byteLength !== 32
|
|
31
37
|
|| !/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)+$/u.test(binding.application_declaration_id)
|
|
32
38
|
|| !/^[0-9a-f]{64}$/u.test(binding.application_manifest_digest)
|
|
@@ -39,6 +45,19 @@ export function authorizationSigningMessage(binding) {
|
|
|
39
45
|
contracts.semantic_capabilities,
|
|
40
46
|
contracts.durable_mutation ?? 1
|
|
41
47
|
].every((version) => Number.isInteger(version) && version > 0)
|
|
48
|
+
|| contracts.authorization_binding !== binding.protocol_version
|
|
49
|
+
|| !isSupportedOperationTransport(contracts.operation_transport)
|
|
50
|
+
|| (binding.protocol_version === AUTHORIZATION_BINDING_PROTOCOL_VERSION
|
|
51
|
+
&& contracts.operation_transport !== OPERATION_TRANSPORT_PROTOCOL_VERSION)
|
|
52
|
+
|| recovery.some((version) => !isSupportedOperationTransport(version)
|
|
53
|
+
|| version === contracts.operation_transport)
|
|
54
|
+
|| new Set(recovery).size !== recovery.length
|
|
55
|
+
|| (binding.protocol_version === LEGACY_AUTHORIZATION_BINDING_PROTOCOL_VERSION
|
|
56
|
+
&& recovery.length > 0)
|
|
57
|
+
|| (recovery.length > 0 && !requiresDurableMutation)
|
|
58
|
+
|| (requiresDurableMutation
|
|
59
|
+
? contracts.durable_mutation !== 1
|
|
60
|
+
: contracts.durable_mutation !== undefined)
|
|
42
61
|
|| (binding.requested_operations.length === 0 && binding.requested_files === undefined)
|
|
43
62
|
|| new Set(binding.requested_operations).size !== binding.requested_operations.length
|
|
44
63
|
|| binding.requested_operations.some((operation) => !operation || operation.includes("\0"))
|
|
@@ -52,7 +71,9 @@ export function authorizationSigningMessage(binding) {
|
|
|
52
71
|
validateRequestedFiles(binding.requested_files);
|
|
53
72
|
const operationFields = binding.requested_operations.map((operation) => field(new TextEncoder().encode(operation)));
|
|
54
73
|
return concat([
|
|
55
|
-
|
|
74
|
+
binding.protocol_version === AUTHORIZATION_BINDING_PROTOCOL_VERSION
|
|
75
|
+
? AUTHORIZATION_PROOF_V5_DOMAIN
|
|
76
|
+
: AUTHORIZATION_PROOF_V4_DOMAIN,
|
|
56
77
|
u32(binding.protocol_version),
|
|
57
78
|
field(uuidBytes(binding.application_id)),
|
|
58
79
|
field(uuidBytes(binding.authorization_id)),
|
|
@@ -68,6 +89,9 @@ export function authorizationSigningMessage(binding) {
|
|
|
68
89
|
optionalString(binding.state),
|
|
69
90
|
field(new TextEncoder().encode(binding.code_challenge)),
|
|
70
91
|
u32(contracts.operation_transport),
|
|
92
|
+
...(binding.protocol_version === AUTHORIZATION_BINDING_PROTOCOL_VERSION
|
|
93
|
+
? [u32(recovery.length), ...recovery.map(u32)]
|
|
94
|
+
: []),
|
|
71
95
|
u32(contracts.authorization_binding),
|
|
72
96
|
u32(contracts.semantic_capabilities),
|
|
73
97
|
optionalU32(contracts.durable_mutation),
|
package/dist/compatibility.d.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import type { ApplicationFileRequirement } from "./files.js";
|
|
2
2
|
import { type CollectionOperation } from "./operations.js";
|
|
3
3
|
export declare const OPERATION_TRANSPORT_PROTOCOL_VERSION: 3;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const LEGACY_OPERATION_TRANSPORT_PROTOCOL_VERSION: 2;
|
|
5
|
+
export declare const SUPPORTED_OPERATION_TRANSPORT_PROTOCOL_VERSIONS: readonly [3, 2];
|
|
6
|
+
export type OperationTransportProtocolVersion = typeof SUPPORTED_OPERATION_TRANSPORT_PROTOCOL_VERSIONS[number];
|
|
7
|
+
export declare const AUTHORIZATION_BINDING_PROTOCOL_VERSION: 5;
|
|
8
|
+
export declare const LEGACY_AUTHORIZATION_BINDING_PROTOCOL_VERSION: 4;
|
|
9
|
+
export declare const SUPPORTED_AUTHORIZATION_BINDING_PROTOCOL_VERSIONS: readonly [5, 4];
|
|
10
|
+
export type AuthorizationBindingProtocolVersion = typeof SUPPORTED_AUTHORIZATION_BINDING_PROTOCOL_VERSIONS[number];
|
|
5
11
|
export declare const SEMANTIC_CAPABILITY_CONTRACT_VERSION: 1;
|
|
6
12
|
export declare const DURABLE_MUTATION_CONTRACT_VERSION: 1;
|
|
7
13
|
export interface ConnectContractRequirements {
|
|
8
14
|
operation_transport: number;
|
|
15
|
+
/** Signed, mutation-only transports retained solely for exact outcome recovery. */
|
|
16
|
+
operation_transport_recovery?: number[];
|
|
9
17
|
authorization_binding: number;
|
|
10
18
|
semantic_capabilities: number;
|
|
11
19
|
/** Required only by operations that can durably mutate authority state. */
|
|
@@ -22,5 +30,8 @@ export declare const CONNECT_CONTRACT_SUPPORT: ConnectContractSupport;
|
|
|
22
30
|
* Produce the exact contract ceiling signed during authorization. `sync` is
|
|
23
31
|
* conservatively mutation-capable because its action is selected per request.
|
|
24
32
|
*/
|
|
25
|
-
export declare function authorizationContractRequirements(operations: readonly CollectionOperation[], files?: ApplicationFileRequirement): ConnectContractRequirements;
|
|
33
|
+
export declare function authorizationContractRequirements(operations: readonly CollectionOperation[], files?: ApplicationFileRequirement, operationTransportRecovery?: readonly OperationTransportProtocolVersion[]): ConnectContractRequirements;
|
|
26
34
|
export declare function supportsContractRequirements(required: ConnectContractRequirements, supported: ConnectContractSupport, durableMutation: boolean): boolean;
|
|
35
|
+
export declare function isSupportedOperationTransport(version: number): version is OperationTransportProtocolVersion;
|
|
36
|
+
export declare function isSupportedAuthorizationBinding(version: number): version is AuthorizationBindingProtocolVersion;
|
|
37
|
+
export declare function permitsOperationTransport(contracts: ConnectContractRequirements, version: number, recoveryOnly?: boolean): boolean;
|
package/dist/compatibility.js
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { isMutatingOperation } from "./operations.js";
|
|
2
2
|
export const OPERATION_TRANSPORT_PROTOCOL_VERSION = 3;
|
|
3
|
-
export const
|
|
3
|
+
export const LEGACY_OPERATION_TRANSPORT_PROTOCOL_VERSION = 2;
|
|
4
|
+
export const SUPPORTED_OPERATION_TRANSPORT_PROTOCOL_VERSIONS = [
|
|
5
|
+
OPERATION_TRANSPORT_PROTOCOL_VERSION,
|
|
6
|
+
LEGACY_OPERATION_TRANSPORT_PROTOCOL_VERSION
|
|
7
|
+
];
|
|
8
|
+
export const AUTHORIZATION_BINDING_PROTOCOL_VERSION = 5;
|
|
9
|
+
export const LEGACY_AUTHORIZATION_BINDING_PROTOCOL_VERSION = 4;
|
|
10
|
+
export const SUPPORTED_AUTHORIZATION_BINDING_PROTOCOL_VERSIONS = [
|
|
11
|
+
AUTHORIZATION_BINDING_PROTOCOL_VERSION,
|
|
12
|
+
LEGACY_AUTHORIZATION_BINDING_PROTOCOL_VERSION
|
|
13
|
+
];
|
|
4
14
|
export const SEMANTIC_CAPABILITY_CONTRACT_VERSION = 1;
|
|
5
15
|
export const DURABLE_MUTATION_CONTRACT_VERSION = 1;
|
|
6
16
|
export const CONNECT_CONTRACT_SUPPORT = {
|
|
7
|
-
operation_transport: [
|
|
8
|
-
authorization_binding: [
|
|
17
|
+
operation_transport: [...SUPPORTED_OPERATION_TRANSPORT_PROTOCOL_VERSIONS],
|
|
18
|
+
authorization_binding: [...SUPPORTED_AUTHORIZATION_BINDING_PROTOCOL_VERSIONS],
|
|
9
19
|
semantic_capabilities: [SEMANTIC_CAPABILITY_CONTRACT_VERSION],
|
|
10
20
|
durable_mutation: [DURABLE_MUTATION_CONTRACT_VERSION]
|
|
11
21
|
};
|
|
@@ -13,12 +23,17 @@ export const CONNECT_CONTRACT_SUPPORT = {
|
|
|
13
23
|
* Produce the exact contract ceiling signed during authorization. `sync` is
|
|
14
24
|
* conservatively mutation-capable because its action is selected per request.
|
|
15
25
|
*/
|
|
16
|
-
export function authorizationContractRequirements(operations, files) {
|
|
26
|
+
export function authorizationContractRequirements(operations, files, operationTransportRecovery = []) {
|
|
17
27
|
const requirements = {
|
|
18
28
|
operation_transport: OPERATION_TRANSPORT_PROTOCOL_VERSION,
|
|
19
29
|
authorization_binding: AUTHORIZATION_BINDING_PROTOCOL_VERSION,
|
|
20
30
|
semantic_capabilities: 1
|
|
21
31
|
};
|
|
32
|
+
const recovery = [...new Set(operationTransportRecovery)]
|
|
33
|
+
.filter((version) => version !== OPERATION_TRANSPORT_PROTOCOL_VERSION)
|
|
34
|
+
.sort((left, right) => right - left);
|
|
35
|
+
if (recovery.length > 0)
|
|
36
|
+
requirements.operation_transport_recovery = recovery;
|
|
22
37
|
if (operations.some((operation) => isMutatingOperation(operation, { action: "mutate" }))
|
|
23
38
|
|| files?.actions.some((action) => action !== "list" && action !== "read") === true) {
|
|
24
39
|
requirements.durable_mutation = 1;
|
|
@@ -27,9 +42,23 @@ export function authorizationContractRequirements(operations, files) {
|
|
|
27
42
|
}
|
|
28
43
|
export function supportsContractRequirements(required, supported, durableMutation) {
|
|
29
44
|
return supported.operation_transport.includes(required.operation_transport)
|
|
45
|
+
&& (required.operation_transport_recovery ?? []).every((version) => supported.operation_transport.includes(version))
|
|
30
46
|
&& supported.authorization_binding.includes(required.authorization_binding)
|
|
31
47
|
&& supported.semantic_capabilities.includes(required.semantic_capabilities)
|
|
32
48
|
&& (!durableMutation
|
|
33
49
|
|| (required.durable_mutation !== undefined
|
|
34
50
|
&& supported.durable_mutation.includes(required.durable_mutation)));
|
|
35
51
|
}
|
|
52
|
+
export function isSupportedOperationTransport(version) {
|
|
53
|
+
return SUPPORTED_OPERATION_TRANSPORT_PROTOCOL_VERSIONS
|
|
54
|
+
.includes(version);
|
|
55
|
+
}
|
|
56
|
+
export function isSupportedAuthorizationBinding(version) {
|
|
57
|
+
return SUPPORTED_AUTHORIZATION_BINDING_PROTOCOL_VERSIONS
|
|
58
|
+
.includes(version);
|
|
59
|
+
}
|
|
60
|
+
export function permitsOperationTransport(contracts, version, recoveryOnly = false) {
|
|
61
|
+
return contracts.operation_transport === version
|
|
62
|
+
|| (recoveryOnly
|
|
63
|
+
&& (contracts.operation_transport_recovery ?? []).includes(version));
|
|
64
|
+
}
|
|
@@ -156,6 +156,10 @@ export declare const CONNECT_PROBLEM_CATALOG: {
|
|
|
156
156
|
readonly category: "conflict";
|
|
157
157
|
readonly recovery: "refresh";
|
|
158
158
|
};
|
|
159
|
+
readonly file_index_warming: {
|
|
160
|
+
readonly category: "availability";
|
|
161
|
+
readonly recovery: "retry";
|
|
162
|
+
};
|
|
159
163
|
readonly file_move_failed: {
|
|
160
164
|
readonly category: "internal";
|
|
161
165
|
readonly recovery: "contact_support";
|
|
@@ -525,6 +529,7 @@ export interface ConnectProblemDetailsByCode {
|
|
|
525
529
|
"expired_token": undefined;
|
|
526
530
|
"file_changed_during_move": undefined;
|
|
527
531
|
"file_changed_during_read": undefined;
|
|
532
|
+
"file_index_warming": undefined;
|
|
528
533
|
"file_move_failed": undefined;
|
|
529
534
|
"file_mutation_conflict": undefined;
|
|
530
535
|
"file_not_found": undefined;
|
|
@@ -856,6 +861,12 @@ export interface ConnectProblemByCode {
|
|
|
856
861
|
recovery: "refresh";
|
|
857
862
|
details?: never;
|
|
858
863
|
};
|
|
864
|
+
"file_index_warming": ConnectProblemBase & {
|
|
865
|
+
code: "file_index_warming";
|
|
866
|
+
category: "availability";
|
|
867
|
+
recovery: "retry";
|
|
868
|
+
details?: never;
|
|
869
|
+
};
|
|
859
870
|
"file_move_failed": ConnectProblemBase & {
|
|
860
871
|
code: "file_move_failed";
|
|
861
872
|
category: "internal";
|
|
@@ -40,6 +40,7 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
40
40
|
"expired_token": { category: "authorization", recovery: "reauthorize" },
|
|
41
41
|
"file_changed_during_move": { category: "conflict", recovery: "refresh" },
|
|
42
42
|
"file_changed_during_read": { category: "conflict", recovery: "refresh" },
|
|
43
|
+
"file_index_warming": { category: "availability", recovery: "retry" },
|
|
43
44
|
"file_move_failed": { category: "internal", recovery: "contact_support" },
|
|
44
45
|
"file_mutation_conflict": { category: "conflict", recovery: "resolve_conflict" },
|
|
45
46
|
"file_not_found": { category: "conflict", recovery: "refresh" },
|
package/dist/index.d.ts
CHANGED
|
@@ -23,11 +23,12 @@ export declare const GRANT_ENCRYPTION_PROTOCOL_VERSION: 1;
|
|
|
23
23
|
export declare const SYNC_PROTOCOL_VERSION: 1;
|
|
24
24
|
export declare const CONTRACT_SETUP_CAPABILITY: "contract-setup-v1";
|
|
25
25
|
export declare const FILE_RELAY_CAPABILITY: "file-relay-v1";
|
|
26
|
+
export declare const PROTOCOL_USAGE_REPORT_CAPABILITY: "protocol-usage-report-v1";
|
|
26
27
|
export declare const RELAY_REQUIRED_CAPABILITIES: readonly ["application-authorization-v4", "authorization-activation", "encrypted-relay", "policy-ack"];
|
|
27
28
|
export declare const MINIMUM_CONNECTOR_VERSION: "0.1.0-beta.33";
|
|
28
29
|
export declare const HOSTED_PROVIDER_REQUIRED_CAPABILITIES: readonly ["durable-mutation-journal-v1", "durable-file-lifecycle-v1"];
|
|
29
30
|
export declare const HOSTED_PROVIDER_CAPABILITIES: readonly ["durable-mutation-journal-v1", "durable-file-lifecycle-v1", "mutation-replay-after-credential-retirement-v1"];
|
|
30
|
-
export declare const RELAY_CAPABILITIES: readonly ["application-authorization-v4", "authorization-activation", "encrypted-relay", "policy-ack", "contract-setup-v1", "file-relay-v1"];
|
|
31
|
+
export declare const RELAY_CAPABILITIES: readonly ["application-authorization-v4", "authorization-activation", "encrypted-relay", "policy-ack", "application-authorization-v5", "contract-setup-v1", "file-relay-v1", "protocol-usage-report-v1"];
|
|
31
32
|
export declare const AUTHORITY_PROOF_VERSION: 1;
|
|
32
33
|
export declare const AUTHORITY_PROOF_ALGORITHM: "P256-SHA256";
|
|
33
34
|
export declare const AUTHORITY_PROOF_DOMAIN: "mdbase-authority-request-proof-v1";
|
|
@@ -182,7 +183,7 @@ export interface GrantScope {
|
|
|
182
183
|
}
|
|
183
184
|
export interface RelayOperationRequest {
|
|
184
185
|
type: "operation_request";
|
|
185
|
-
protocol_version:
|
|
186
|
+
protocol_version: import("./compatibility.js").OperationTransportProtocolVersion;
|
|
186
187
|
request_id: string;
|
|
187
188
|
grant_id: string;
|
|
188
189
|
collection_id: string;
|
|
@@ -192,29 +193,29 @@ export interface RelayOperationRequest {
|
|
|
192
193
|
}
|
|
193
194
|
export type RelayOperationResponse = {
|
|
194
195
|
type: "operation_response";
|
|
195
|
-
protocol_version:
|
|
196
|
+
protocol_version: import("./compatibility.js").OperationTransportProtocolVersion;
|
|
196
197
|
request_id: string;
|
|
197
198
|
ok: true;
|
|
198
199
|
result: unknown;
|
|
199
200
|
} | {
|
|
200
201
|
type: "operation_response";
|
|
201
|
-
protocol_version:
|
|
202
|
+
protocol_version: import("./compatibility.js").OperationTransportProtocolVersion;
|
|
202
203
|
request_id: string;
|
|
203
204
|
ok: false;
|
|
204
205
|
problem: ConnectProblem;
|
|
205
206
|
};
|
|
206
207
|
export interface MdbaseOperationRequest<Input = unknown> {
|
|
207
|
-
protocol_version:
|
|
208
|
+
protocol_version: import("./compatibility.js").OperationTransportProtocolVersion;
|
|
208
209
|
request_id: string;
|
|
209
210
|
input: Input;
|
|
210
211
|
}
|
|
211
212
|
export type MdbaseOperationResponse<Result = unknown> = {
|
|
212
|
-
protocol_version:
|
|
213
|
+
protocol_version: import("./compatibility.js").OperationTransportProtocolVersion;
|
|
213
214
|
request_id: string;
|
|
214
215
|
ok: true;
|
|
215
216
|
result: Result;
|
|
216
217
|
} | {
|
|
217
|
-
protocol_version:
|
|
218
|
+
protocol_version: import("./compatibility.js").OperationTransportProtocolVersion;
|
|
218
219
|
request_id: string;
|
|
219
220
|
ok: false;
|
|
220
221
|
problem: ConnectProblem;
|
|
@@ -261,7 +262,7 @@ export interface GrantEncryption {
|
|
|
261
262
|
connector_agreement_public_key: string;
|
|
262
263
|
}
|
|
263
264
|
export interface EncryptedRelayEnvelope {
|
|
264
|
-
protocol_version:
|
|
265
|
+
protocol_version: import("./compatibility.js").OperationTransportProtocolVersion;
|
|
265
266
|
suite: typeof RELAY_ENCRYPTION_SUITE;
|
|
266
267
|
request_id: string;
|
|
267
268
|
grant_id: string;
|
|
@@ -549,6 +550,15 @@ export interface RelayPolicyApplied {
|
|
|
549
550
|
details?: unknown;
|
|
550
551
|
};
|
|
551
552
|
}
|
|
553
|
+
export interface ProtocolUsageReport {
|
|
554
|
+
type: "protocol_usage_report";
|
|
555
|
+
protocol_version: 1;
|
|
556
|
+
entries: Array<{
|
|
557
|
+
axis: "operation_transport";
|
|
558
|
+
version: number;
|
|
559
|
+
count: number;
|
|
560
|
+
}>;
|
|
561
|
+
}
|
|
552
562
|
export interface AuthorizationCollectionOffer {
|
|
553
563
|
collection_id: string;
|
|
554
564
|
display_name: string;
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export const GRANT_ENCRYPTION_PROTOCOL_VERSION = 1;
|
|
|
16
16
|
export const SYNC_PROTOCOL_VERSION = 1;
|
|
17
17
|
export const CONTRACT_SETUP_CAPABILITY = "contract-setup-v1";
|
|
18
18
|
export const FILE_RELAY_CAPABILITY = "file-relay-v1";
|
|
19
|
+
export const PROTOCOL_USAGE_REPORT_CAPABILITY = "protocol-usage-report-v1";
|
|
19
20
|
export const RELAY_REQUIRED_CAPABILITIES = [
|
|
20
21
|
"application-authorization-v4",
|
|
21
22
|
"authorization-activation",
|
|
@@ -33,8 +34,10 @@ export const HOSTED_PROVIDER_CAPABILITIES = [
|
|
|
33
34
|
];
|
|
34
35
|
export const RELAY_CAPABILITIES = [
|
|
35
36
|
...RELAY_REQUIRED_CAPABILITIES,
|
|
37
|
+
"application-authorization-v5",
|
|
36
38
|
CONTRACT_SETUP_CAPABILITY,
|
|
37
|
-
FILE_RELAY_CAPABILITY
|
|
39
|
+
FILE_RELAY_CAPABILITY,
|
|
40
|
+
PROTOCOL_USAGE_REPORT_CAPABILITY
|
|
38
41
|
];
|
|
39
42
|
export const AUTHORITY_PROOF_VERSION = 1;
|
|
40
43
|
export const AUTHORITY_PROOF_ALGORITHM = "P256-SHA256";
|
package/package.json
CHANGED
package/schemas/catalog.json
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"connect_problem_catalog": "./connect-problems.v1.catalog.json",
|
|
10
10
|
"mdbase_query_v0_3": "./mdbase-query.v0.3.schema.json",
|
|
11
11
|
"encrypted_relay": "./encrypted-relay.v3.schema.json",
|
|
12
|
+
"encrypted_relay_legacy_v2": "./encrypted-relay.v2.schema.json",
|
|
12
13
|
"files": "./files.v1.schema.json",
|
|
13
14
|
"notification_webhook": "./notification-webhook.v1.schema.json",
|
|
14
15
|
"sync": "./sync.v1.schema.json"
|
|
@@ -1808,6 +1808,46 @@
|
|
|
1808
1808
|
}
|
|
1809
1809
|
}
|
|
1810
1810
|
},
|
|
1811
|
+
{
|
|
1812
|
+
"type": "object",
|
|
1813
|
+
"additionalProperties": false,
|
|
1814
|
+
"required": [
|
|
1815
|
+
"problem_version",
|
|
1816
|
+
"code",
|
|
1817
|
+
"category",
|
|
1818
|
+
"recovery",
|
|
1819
|
+
"message"
|
|
1820
|
+
],
|
|
1821
|
+
"properties": {
|
|
1822
|
+
"problem_version": {
|
|
1823
|
+
"const": 1
|
|
1824
|
+
},
|
|
1825
|
+
"code": {
|
|
1826
|
+
"const": "file_index_warming"
|
|
1827
|
+
},
|
|
1828
|
+
"category": {
|
|
1829
|
+
"const": "availability"
|
|
1830
|
+
},
|
|
1831
|
+
"recovery": {
|
|
1832
|
+
"const": "retry"
|
|
1833
|
+
},
|
|
1834
|
+
"message": {
|
|
1835
|
+
"type": "string",
|
|
1836
|
+
"minLength": 1
|
|
1837
|
+
},
|
|
1838
|
+
"operation_outcome": {
|
|
1839
|
+
"enum": [
|
|
1840
|
+
"not_sent",
|
|
1841
|
+
"rejected",
|
|
1842
|
+
"unknown"
|
|
1843
|
+
]
|
|
1844
|
+
},
|
|
1845
|
+
"trace_id": {
|
|
1846
|
+
"type": "string",
|
|
1847
|
+
"minLength": 1
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
},
|
|
1811
1851
|
{
|
|
1812
1852
|
"type": "object",
|
|
1813
1853
|
"additionalProperties": false,
|
|
@@ -191,6 +191,7 @@
|
|
|
191
191
|
"expired_token": { "category": "authorization", "recovery": "reauthorize" },
|
|
192
192
|
"file_changed_during_move": { "category": "conflict", "recovery": "refresh" },
|
|
193
193
|
"file_changed_during_read": { "category": "conflict", "recovery": "refresh" },
|
|
194
|
+
"file_index_warming": { "category": "availability", "recovery": "retry" },
|
|
194
195
|
"file_move_failed": { "category": "internal", "recovery": "contact_support" },
|
|
195
196
|
"file_mutation_conflict": { "category": "conflict", "recovery": "resolve_conflict" },
|
|
196
197
|
"file_not_found": { "category": "conflict", "recovery": "refresh" },
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://mdbase.dev/connect/schemas/encrypted-relay.v2.json",
|
|
4
|
+
"title": "mdbase connect encrypted operation transport 2",
|
|
5
|
+
"description": "Opaque authenticated operation envelopes routed between an application and authority.",
|
|
6
|
+
"oneOf": [
|
|
7
|
+
{ "$ref": "#/$defs/request" },
|
|
8
|
+
{ "$ref": "#/$defs/response" },
|
|
9
|
+
{ "$ref": "#/$defs/rejected" }
|
|
10
|
+
],
|
|
11
|
+
"$defs": {
|
|
12
|
+
"uuid": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
|
|
15
|
+
},
|
|
16
|
+
"operation": {
|
|
17
|
+
"enum": ["describe", "changes", "read", "query", "list_views", "execute_view", "read_view_source", "create_view_source", "update_view_source", "delete_view_source", "validate", "create", "update", "delete", "rename", "read_type", "create_type", "update_type", "assess_type_pack", "apply_type_pack", "assess_collection_setup", "apply_collection_setup", "list_timers", "put_timer", "cancel_timer", "reconcile_timers", "sync", "file_control"]
|
|
18
|
+
},
|
|
19
|
+
"envelope": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"additionalProperties": false,
|
|
22
|
+
"required": ["type", "protocol_version", "suite", "request_id", "grant_id", "application_id", "connector_id", "collection_id", "operation", "scope_epoch", "key_id", "counter", "ciphertext"],
|
|
23
|
+
"properties": {
|
|
24
|
+
"type": { "enum": ["encrypted_operation_request", "encrypted_operation_response"] },
|
|
25
|
+
"protocol_version": { "const": 2 },
|
|
26
|
+
"suite": { "const": "P256-HKDF-SHA256-AES256GCM" },
|
|
27
|
+
"request_id": { "$ref": "#/$defs/uuid" },
|
|
28
|
+
"grant_id": { "$ref": "#/$defs/uuid" },
|
|
29
|
+
"application_id": { "$ref": "#/$defs/uuid" },
|
|
30
|
+
"connector_id": { "$ref": "#/$defs/uuid" },
|
|
31
|
+
"collection_id": { "$ref": "#/$defs/uuid" },
|
|
32
|
+
"operation": { "$ref": "#/$defs/operation" },
|
|
33
|
+
"scope_epoch": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
|
|
34
|
+
"key_id": { "type": "string", "minLength": 1, "maxLength": 200 },
|
|
35
|
+
"counter": { "type": "string", "pattern": "^[1-9][0-9]{0,19}$" },
|
|
36
|
+
"ciphertext": { "type": "string", "minLength": 1, "maxLength": 2800000, "pattern": "^[A-Za-z0-9_-]+$" }
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"request": {
|
|
40
|
+
"allOf": [
|
|
41
|
+
{ "$ref": "#/$defs/envelope" },
|
|
42
|
+
{ "type": "object", "properties": { "type": { "const": "encrypted_operation_request" } } }
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
"response": {
|
|
46
|
+
"allOf": [
|
|
47
|
+
{ "$ref": "#/$defs/envelope" },
|
|
48
|
+
{ "type": "object", "properties": { "type": { "const": "encrypted_operation_response" } } }
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
"rejected": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"additionalProperties": false,
|
|
54
|
+
"required": ["type", "protocol_version", "request_id", "problem"],
|
|
55
|
+
"properties": {
|
|
56
|
+
"type": { "const": "encrypted_operation_rejected" },
|
|
57
|
+
"protocol_version": { "const": 2 },
|
|
58
|
+
"request_id": { "$ref": "#/$defs/uuid" },
|
|
59
|
+
"problem": { "$ref": "https://schemas.mdbase.dev/connect/problem/v1" }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|