@mdbase-dev/connect-protocol 0.1.0-beta.55 → 0.1.0-beta.57
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 +14 -3
- package/dist/compatibility.js +34 -5
- package/dist/connect-problems.generated.d.ts +22 -0
- package/dist/connect-problems.generated.js +2 -0
- package/dist/index.d.ts +19 -9
- package/dist/index.js +5 -2
- package/package.json +1 -1
- package/schemas/catalog.json +2 -1
- package/schemas/connect-problem.v1.schema.json +80 -0
- package/schemas/connect-problems.v1.catalog.json +2 -0
- package/schemas/connect-protocol.v1.schema.json +4 -4
- package/schemas/encrypted-relay.v3.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
|
-
export declare const OPERATION_TRANSPORT_PROTOCOL_VERSION:
|
|
4
|
-
export declare const
|
|
3
|
+
export declare const OPERATION_TRANSPORT_PROTOCOL_VERSION: 3;
|
|
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
|
-
export const OPERATION_TRANSPORT_PROTOCOL_VERSION =
|
|
3
|
-
export const
|
|
2
|
+
export const OPERATION_TRANSPORT_PROTOCOL_VERSION = 3;
|
|
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
|
+
}
|
|
@@ -104,6 +104,10 @@ export declare const CONNECT_PROBLEM_CATALOG: {
|
|
|
104
104
|
readonly category: "conflict";
|
|
105
105
|
readonly recovery: "refresh";
|
|
106
106
|
};
|
|
107
|
+
readonly connector_busy: {
|
|
108
|
+
readonly category: "availability";
|
|
109
|
+
readonly recovery: "retry";
|
|
110
|
+
};
|
|
107
111
|
readonly connector_identity_changed: {
|
|
108
112
|
readonly category: "integrity";
|
|
109
113
|
readonly recovery: "reauthorize";
|
|
@@ -172,6 +176,10 @@ export declare const CONNECT_PROBLEM_CATALOG: {
|
|
|
172
176
|
readonly category: "conflict";
|
|
173
177
|
readonly recovery: "retry";
|
|
174
178
|
};
|
|
179
|
+
readonly fresh_request_required: {
|
|
180
|
+
readonly category: "availability";
|
|
181
|
+
readonly recovery: "retry";
|
|
182
|
+
};
|
|
175
183
|
readonly hosted_provider_unavailable: {
|
|
176
184
|
readonly category: "availability";
|
|
177
185
|
readonly recovery: "retry";
|
|
@@ -496,6 +504,7 @@ export interface ConnectProblemDetailsByCode {
|
|
|
496
504
|
"required_version": string;
|
|
497
505
|
};
|
|
498
506
|
"concurrent_modification": undefined;
|
|
507
|
+
"connector_busy": undefined;
|
|
499
508
|
"connector_identity_changed": undefined;
|
|
500
509
|
"connector_offline": {
|
|
501
510
|
"connector_name"?: string;
|
|
@@ -521,6 +530,7 @@ export interface ConnectProblemDetailsByCode {
|
|
|
521
530
|
"file_not_found": undefined;
|
|
522
531
|
"file_source_mismatch": undefined;
|
|
523
532
|
"file_upload_incomplete": undefined;
|
|
533
|
+
"fresh_request_required": undefined;
|
|
524
534
|
"hosted_provider_unavailable": undefined;
|
|
525
535
|
"insufficient_access": {
|
|
526
536
|
"required_operations": Array<string>;
|
|
@@ -768,6 +778,12 @@ export interface ConnectProblemByCode {
|
|
|
768
778
|
recovery: "refresh";
|
|
769
779
|
details?: never;
|
|
770
780
|
};
|
|
781
|
+
"connector_busy": ConnectProblemBase & {
|
|
782
|
+
code: "connector_busy";
|
|
783
|
+
category: "availability";
|
|
784
|
+
recovery: "retry";
|
|
785
|
+
details?: never;
|
|
786
|
+
};
|
|
771
787
|
"connector_identity_changed": ConnectProblemBase & {
|
|
772
788
|
code: "connector_identity_changed";
|
|
773
789
|
category: "integrity";
|
|
@@ -870,6 +886,12 @@ export interface ConnectProblemByCode {
|
|
|
870
886
|
recovery: "retry";
|
|
871
887
|
details?: never;
|
|
872
888
|
};
|
|
889
|
+
"fresh_request_required": ConnectProblemBase & {
|
|
890
|
+
code: "fresh_request_required";
|
|
891
|
+
category: "availability";
|
|
892
|
+
recovery: "retry";
|
|
893
|
+
details?: never;
|
|
894
|
+
};
|
|
873
895
|
"hosted_provider_unavailable": ConnectProblemBase & {
|
|
874
896
|
code: "hosted_provider_unavailable";
|
|
875
897
|
category: "availability";
|
|
@@ -27,6 +27,7 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
27
27
|
"collection_type_registry_invalid": { category: "validation", recovery: "repair_collection" },
|
|
28
28
|
"collection_version_unsupported": { category: "compatibility", recovery: "upgrade_collection" },
|
|
29
29
|
"concurrent_modification": { category: "conflict", recovery: "refresh" },
|
|
30
|
+
"connector_busy": { category: "availability", recovery: "retry" },
|
|
30
31
|
"connector_identity_changed": { category: "integrity", recovery: "reauthorize" },
|
|
31
32
|
"connector_offline": { category: "availability", recovery: "retry" },
|
|
32
33
|
"connector_upgrade_required": { category: "compatibility", recovery: "upgrade_connector" },
|
|
@@ -44,6 +45,7 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
44
45
|
"file_not_found": { category: "conflict", recovery: "refresh" },
|
|
45
46
|
"file_source_mismatch": { category: "conflict", recovery: "refresh" },
|
|
46
47
|
"file_upload_incomplete": { category: "conflict", recovery: "retry" },
|
|
48
|
+
"fresh_request_required": { category: "availability", recovery: "retry" },
|
|
47
49
|
"hosted_provider_unavailable": { category: "availability", recovery: "retry" },
|
|
48
50
|
"insufficient_access": { category: "authorization", recovery: "reauthorize" },
|
|
49
51
|
"invalid_application_authorization": { category: "validation", recovery: "fix_request" },
|
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";
|
|
@@ -49,7 +50,7 @@ export declare const CONNECT_SCHEMA_IDS: {
|
|
|
49
50
|
readonly dataContract: "https://mdbase.dev/schemas/v0.3/data-contract.schema.json";
|
|
50
51
|
readonly eventActionInterop: "https://mdbase.dev/schemas/interop/v0.1/profile.schema.json";
|
|
51
52
|
readonly protocol: "https://mdbase.dev/connect/schemas/connect-protocol.v1.json";
|
|
52
|
-
readonly encryptedRelay: "https://mdbase.dev/connect/schemas/encrypted-relay.
|
|
53
|
+
readonly encryptedRelay: "https://mdbase.dev/connect/schemas/encrypted-relay.v3.json";
|
|
53
54
|
readonly files: "https://mdbase.dev/connect/schemas/files.v1.json";
|
|
54
55
|
readonly sync: "https://mdbase.dev/connect/schemas/sync.v1.json";
|
|
55
56
|
};
|
|
@@ -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";
|
|
@@ -74,7 +77,7 @@ export const CONNECT_SCHEMA_IDS = {
|
|
|
74
77
|
dataContract: "https://mdbase.dev/schemas/v0.3/data-contract.schema.json",
|
|
75
78
|
eventActionInterop: "https://mdbase.dev/schemas/interop/v0.1/profile.schema.json",
|
|
76
79
|
protocol: "https://mdbase.dev/connect/schemas/connect-protocol.v1.json",
|
|
77
|
-
encryptedRelay: "https://mdbase.dev/connect/schemas/encrypted-relay.
|
|
80
|
+
encryptedRelay: "https://mdbase.dev/connect/schemas/encrypted-relay.v3.json",
|
|
78
81
|
files: "https://mdbase.dev/connect/schemas/files.v1.json",
|
|
79
82
|
sync: "https://mdbase.dev/connect/schemas/sync.v1.json"
|
|
80
83
|
};
|
package/package.json
CHANGED
package/schemas/catalog.json
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"connect_problem": "./connect-problem.v1.schema.json",
|
|
9
9
|
"connect_problem_catalog": "./connect-problems.v1.catalog.json",
|
|
10
10
|
"mdbase_query_v0_3": "./mdbase-query.v0.3.schema.json",
|
|
11
|
-
"encrypted_relay": "./encrypted-relay.
|
|
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"
|
|
@@ -1244,6 +1244,46 @@
|
|
|
1244
1244
|
}
|
|
1245
1245
|
}
|
|
1246
1246
|
},
|
|
1247
|
+
{
|
|
1248
|
+
"type": "object",
|
|
1249
|
+
"additionalProperties": false,
|
|
1250
|
+
"required": [
|
|
1251
|
+
"problem_version",
|
|
1252
|
+
"code",
|
|
1253
|
+
"category",
|
|
1254
|
+
"recovery",
|
|
1255
|
+
"message"
|
|
1256
|
+
],
|
|
1257
|
+
"properties": {
|
|
1258
|
+
"problem_version": {
|
|
1259
|
+
"const": 1
|
|
1260
|
+
},
|
|
1261
|
+
"code": {
|
|
1262
|
+
"const": "connector_busy"
|
|
1263
|
+
},
|
|
1264
|
+
"category": {
|
|
1265
|
+
"const": "availability"
|
|
1266
|
+
},
|
|
1267
|
+
"recovery": {
|
|
1268
|
+
"const": "retry"
|
|
1269
|
+
},
|
|
1270
|
+
"message": {
|
|
1271
|
+
"type": "string",
|
|
1272
|
+
"minLength": 1
|
|
1273
|
+
},
|
|
1274
|
+
"operation_outcome": {
|
|
1275
|
+
"enum": [
|
|
1276
|
+
"not_sent",
|
|
1277
|
+
"rejected",
|
|
1278
|
+
"unknown"
|
|
1279
|
+
]
|
|
1280
|
+
},
|
|
1281
|
+
"trace_id": {
|
|
1282
|
+
"type": "string",
|
|
1283
|
+
"minLength": 1
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
},
|
|
1247
1287
|
{
|
|
1248
1288
|
"type": "object",
|
|
1249
1289
|
"additionalProperties": false,
|
|
@@ -1968,6 +2008,46 @@
|
|
|
1968
2008
|
}
|
|
1969
2009
|
}
|
|
1970
2010
|
},
|
|
2011
|
+
{
|
|
2012
|
+
"type": "object",
|
|
2013
|
+
"additionalProperties": false,
|
|
2014
|
+
"required": [
|
|
2015
|
+
"problem_version",
|
|
2016
|
+
"code",
|
|
2017
|
+
"category",
|
|
2018
|
+
"recovery",
|
|
2019
|
+
"message"
|
|
2020
|
+
],
|
|
2021
|
+
"properties": {
|
|
2022
|
+
"problem_version": {
|
|
2023
|
+
"const": 1
|
|
2024
|
+
},
|
|
2025
|
+
"code": {
|
|
2026
|
+
"const": "fresh_request_required"
|
|
2027
|
+
},
|
|
2028
|
+
"category": {
|
|
2029
|
+
"const": "availability"
|
|
2030
|
+
},
|
|
2031
|
+
"recovery": {
|
|
2032
|
+
"const": "retry"
|
|
2033
|
+
},
|
|
2034
|
+
"message": {
|
|
2035
|
+
"type": "string",
|
|
2036
|
+
"minLength": 1
|
|
2037
|
+
},
|
|
2038
|
+
"operation_outcome": {
|
|
2039
|
+
"enum": [
|
|
2040
|
+
"not_sent",
|
|
2041
|
+
"rejected",
|
|
2042
|
+
"unknown"
|
|
2043
|
+
]
|
|
2044
|
+
},
|
|
2045
|
+
"trace_id": {
|
|
2046
|
+
"type": "string",
|
|
2047
|
+
"minLength": 1
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
},
|
|
1971
2051
|
{
|
|
1972
2052
|
"type": "object",
|
|
1973
2053
|
"additionalProperties": false,
|
|
@@ -156,6 +156,7 @@
|
|
|
156
156
|
}
|
|
157
157
|
},
|
|
158
158
|
"concurrent_modification": { "category": "conflict", "recovery": "refresh" },
|
|
159
|
+
"connector_busy": { "category": "availability", "recovery": "retry" },
|
|
159
160
|
"connector_identity_changed": { "category": "integrity", "recovery": "reauthorize" },
|
|
160
161
|
"connector_offline": {
|
|
161
162
|
"category": "availability",
|
|
@@ -195,6 +196,7 @@
|
|
|
195
196
|
"file_not_found": { "category": "conflict", "recovery": "refresh" },
|
|
196
197
|
"file_source_mismatch": { "category": "conflict", "recovery": "refresh" },
|
|
197
198
|
"file_upload_incomplete": { "category": "conflict", "recovery": "retry" },
|
|
199
|
+
"fresh_request_required": { "category": "availability", "recovery": "retry" },
|
|
198
200
|
"hosted_provider_unavailable": { "category": "availability", "recovery": "retry" },
|
|
199
201
|
"insufficient_access": {
|
|
200
202
|
"category": "authorization",
|
|
@@ -170,7 +170,7 @@
|
|
|
170
170
|
"required": ["type", "protocol_version", "request_id", "grant_id", "collection_id", "application_id", "operation", "input"],
|
|
171
171
|
"properties": {
|
|
172
172
|
"type": { "const": "operation_request" },
|
|
173
|
-
"protocol_version": { "const":
|
|
173
|
+
"protocol_version": { "const": 3 },
|
|
174
174
|
"request_id": { "$ref": "#/$defs/uuid" },
|
|
175
175
|
"grant_id": { "$ref": "#/$defs/uuid" },
|
|
176
176
|
"collection_id": { "$ref": "#/$defs/uuid" },
|
|
@@ -184,7 +184,7 @@
|
|
|
184
184
|
"additionalProperties": false,
|
|
185
185
|
"required": ["protocol_version", "request_id", "input"],
|
|
186
186
|
"properties": {
|
|
187
|
-
"protocol_version": { "const":
|
|
187
|
+
"protocol_version": { "const": 3 },
|
|
188
188
|
"request_id": { "$ref": "#/$defs/uuid" },
|
|
189
189
|
"input": true
|
|
190
190
|
}
|
|
@@ -194,7 +194,7 @@
|
|
|
194
194
|
"additionalProperties": false,
|
|
195
195
|
"required": ["protocol_version", "request_id", "ok"],
|
|
196
196
|
"properties": {
|
|
197
|
-
"protocol_version": { "const":
|
|
197
|
+
"protocol_version": { "const": 3 },
|
|
198
198
|
"request_id": { "$ref": "#/$defs/uuid" },
|
|
199
199
|
"ok": { "type": "boolean" },
|
|
200
200
|
"result": true,
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
"required": ["type", "protocol_version", "request_id", "ok"],
|
|
221
221
|
"properties": {
|
|
222
222
|
"type": { "const": "operation_response" },
|
|
223
|
-
"protocol_version": { "const":
|
|
223
|
+
"protocol_version": { "const": 3 },
|
|
224
224
|
"request_id": { "$ref": "#/$defs/uuid" },
|
|
225
225
|
"ok": { "type": "boolean" },
|
|
226
226
|
"result": true,
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://mdbase.dev/connect/schemas/encrypted-relay.v3.json",
|
|
4
|
+
"title": "mdbase connect encrypted operation transport 3",
|
|
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": 3 },
|
|
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": 3 },
|
|
58
|
+
"request_id": { "$ref": "#/$defs/uuid" },
|
|
59
|
+
"problem": { "$ref": "https://schemas.mdbase.dev/connect/problem/v1" }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|