@mdbase-dev/connect 0.1.0-beta.23 → 0.1.0-beta.24

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.
@@ -0,0 +1,145 @@
1
+ import { FIRST_CONTACT_PROTOCOL_VERSION } from "@mdbase-dev/connect-protocol";
2
+ const TRANSCRIPT_DOMAIN = new TextEncoder().encode("mdbase-connect first-contact transcript\0");
3
+ const SAS_INFO = new TextEncoder().encode("mdbase-connect first-contact sas v1");
4
+ const CROCKFORD_BASE32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
5
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
6
+ export class FirstContactCryptoError extends Error {
7
+ code;
8
+ constructor(code, message) {
9
+ super(message);
10
+ this.code = code;
11
+ }
12
+ }
13
+ /**
14
+ * Derive the independently displayed first-contact authentication string.
15
+ * The private key must belong to the endpoint role named in the transcript.
16
+ */
17
+ export async function deriveFirstContactSas(binding, role, identity) {
18
+ const keys = await validatedKeys(binding);
19
+ const own = role === "application"
20
+ ? binding.application_agreement_public_key
21
+ : binding.connector_agreement_public_key;
22
+ const peer = role === "application"
23
+ ? keys.connector
24
+ : keys.applicationAgreement;
25
+ if (identity.agreementPublicKey !== own) {
26
+ throw new FirstContactCryptoError("identity_mismatch", "The first-contact identity does not match the transcript.");
27
+ }
28
+ let peerKey;
29
+ try {
30
+ peerKey = await crypto.subtle.importKey("raw", peer, { name: "ECDH", namedCurve: "P-256" }, false, []);
31
+ }
32
+ catch {
33
+ throw new FirstContactCryptoError("invalid_public_key", "The first-contact public key is invalid.");
34
+ }
35
+ const shared = await crypto.subtle.deriveBits({ name: "ECDH", public: peerKey }, identity.agreementPrivateKey, 256);
36
+ const transcript = firstContactTranscript(binding, keys);
37
+ const salt = await crypto.subtle.digest("SHA-256", transcript);
38
+ const hkdfKey = await crypto.subtle.importKey("raw", shared, "HKDF", false, ["deriveBits"]);
39
+ const sas = new Uint8Array(await crypto.subtle.deriveBits({ name: "HKDF", hash: "SHA-256", salt, info: SAS_INFO }, hkdfKey, 40));
40
+ return formatSas(sas);
41
+ }
42
+ async function validatedKeys(binding) {
43
+ if (binding.protocol_version !== FIRST_CONTACT_PROTOCOL_VERSION) {
44
+ throw new FirstContactCryptoError("unsupported_version", "The first-contact protocol version is not supported.");
45
+ }
46
+ const applicationAgreement = canonicalPublicKey(binding.application_agreement_public_key);
47
+ const applicationSigning = canonicalPublicKey(binding.application_signing_public_key);
48
+ const connector = canonicalPublicKey(binding.connector_agreement_public_key);
49
+ if (equalBytes(applicationAgreement, applicationSigning)
50
+ || equalBytes(applicationAgreement, connector)
51
+ || equalBytes(applicationSigning, connector)) {
52
+ throw new FirstContactCryptoError("invalid_public_key", "First contact requires distinct endpoint agreement and signing keys.");
53
+ }
54
+ try {
55
+ await Promise.all([
56
+ applicationAgreement,
57
+ applicationSigning,
58
+ connector
59
+ ].map((key) => crypto.subtle.importKey("raw", key, { name: "ECDH", namedCurve: "P-256" }, false, [])));
60
+ }
61
+ catch {
62
+ throw new FirstContactCryptoError("invalid_public_key", "The first-contact public key is invalid.");
63
+ }
64
+ return { applicationAgreement, applicationSigning, connector };
65
+ }
66
+ function firstContactTranscript(binding, keys) {
67
+ const chunks = [
68
+ TRANSCRIPT_DOMAIN,
69
+ u32(binding.protocol_version),
70
+ field(uuidBytes(binding.application_id)),
71
+ field(uuidBytes(binding.application_installation_id)),
72
+ field(keys.applicationAgreement),
73
+ field(keys.applicationSigning),
74
+ field(uuidBytes(binding.connector_id)),
75
+ field(keys.connector)
76
+ ];
77
+ const length = chunks.reduce((total, chunk) => total + chunk.byteLength, 0);
78
+ const output = new Uint8Array(length);
79
+ let offset = 0;
80
+ for (const chunk of chunks) {
81
+ output.set(chunk, offset);
82
+ offset += chunk.byteLength;
83
+ }
84
+ return output;
85
+ }
86
+ function field(value) {
87
+ const output = new Uint8Array(4 + value.byteLength);
88
+ output.set(u32(value.byteLength));
89
+ output.set(value, 4);
90
+ return output;
91
+ }
92
+ function u32(value) {
93
+ const output = new Uint8Array(4);
94
+ new DataView(output.buffer).setUint32(0, value, false);
95
+ return output;
96
+ }
97
+ function uuidBytes(value) {
98
+ if (!UUID_PATTERN.test(value)) {
99
+ throw new FirstContactCryptoError("invalid_binding", "The first-contact transcript contains an invalid identifier.");
100
+ }
101
+ const compact = value.replaceAll("-", "");
102
+ return Uint8Array.from({ length: 16 }, (_, index) => Number.parseInt(compact.slice(index * 2, index * 2 + 2), 16));
103
+ }
104
+ function canonicalPublicKey(value) {
105
+ if (!/^[A-Za-z0-9_-]+$/.test(value)) {
106
+ throw new FirstContactCryptoError("invalid_public_key", "The first-contact public key is invalid.");
107
+ }
108
+ const normalized = value.replaceAll("-", "+").replaceAll("_", "/");
109
+ const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "=");
110
+ let bytes;
111
+ try {
112
+ bytes = Uint8Array.from(atob(padded), (character) => character.charCodeAt(0));
113
+ }
114
+ catch {
115
+ throw new FirstContactCryptoError("invalid_public_key", "The first-contact public key is invalid.");
116
+ }
117
+ if (bytes.byteLength !== 65
118
+ || bytes[0] !== 4
119
+ || base64Url(bytes) !== value) {
120
+ throw new FirstContactCryptoError("invalid_public_key", "The first-contact public key is invalid.");
121
+ }
122
+ return bytes;
123
+ }
124
+ function base64Url(value) {
125
+ return btoa(String.fromCharCode(...value))
126
+ .replaceAll("+", "-")
127
+ .replaceAll("/", "_")
128
+ .replace(/=+$/u, "");
129
+ }
130
+ function equalBytes(left, right) {
131
+ return left.byteLength === right.byteLength
132
+ && left.every((value, index) => value === right[index]);
133
+ }
134
+ function formatSas(value) {
135
+ let bits = 0n;
136
+ for (const byte of value)
137
+ bits = (bits << 8n) | BigInt(byte);
138
+ let output = "";
139
+ for (let index = 7; index >= 0; index -= 1) {
140
+ output += CROCKFORD_BASE32[Number((bits >> BigInt(index * 5)) & 31n)];
141
+ if (index === 4)
142
+ output += "-";
143
+ }
144
+ return output;
145
+ }
package/dist/index.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  export { decryptRelayResponse, encryptRelayRequest, IndexedDbGrantKeyStore, MemoryGrantKeyStore, RelayCryptoError, type RelayBinding, type GrantKeyRecord, type GrantKeyStore } from "./crypto.js";
2
2
  export { FileTransferCryptoError, GrantFileTransferCipher, type FileTransferBinding } from "./file-crypto.js";
3
+ export { deriveFirstContactSas, FirstContactCryptoError, type FirstContactRole } from "./first-contact.js";
4
+ export { applicationInstallationId, authorizationSigningMessage, signApplicationAuthorization } from "./application-identity.js";
3
5
  export * from "./authorization-types.js";
4
6
  export * from "./collection-client.js";
5
- export * from "./connect.js";
7
+ export * from "./connect-options.js";
8
+ export * from "./mdbase-connect.js";
6
9
  export * from "./connection.js";
7
10
  export * from "./connection-types.js";
8
11
  export * from "./errors.js";
@@ -13,4 +16,4 @@ export * from "./operation-types.js";
13
16
  export * from "./selection.js";
14
17
  export * from "./session.js";
15
18
  export { createPkce } from "./runtime-utils.js";
16
- export type { ApplicationProvisions, ApplicationRequirements, ApplicationNotifications, CollectionChange, CollectionChangesPage, CollectionContractDescriptor, CollectionDescription, CollectionFileMetadata, CollectionOperation as MdbaseOperation, CollectionTypeDescriptor, CollectionTypeDocument, ConnectOperationOutcome, ConnectProblem, ConnectProblemCategory, ConnectProblemCode, ConnectProblemDetailsByCode, ConnectRecoveryAction, ContractRequirement, DataContractViewIdentity, GrantScope, JsonObject, MdbaseAppManifest, NotificationCriterion, MdbaseDiagnostic, MdbaseOperationEnvelope, KnownConnectProblem, RecordDocument, QueryRecord, SavedNamedView, SavedViewDocument, SavedViewExecution, SavedViewList, SavedViewPresentation, SavedViewProperty, SavedViewSource, SavedViewSourceDocument, ReadViewSourceInput, CreateViewSourceInput, UpdateViewSourceInput, DeleteViewSourceInput, DeleteViewSourceResult, ExecuteViewInput, TypePackManifest, TypePackManifestResource, TypePackInstallResult, TypePackProvision, TypePackResourceDiff, TypePackSourceResource, UnknownConnectProblem } from "@mdbase-dev/connect-protocol";
19
+ export type { ApplicationProvisions, ApplicationRequirements, ApplicationNotifications, ApplicationAuthorizationBinding, ApplicationAuthorizationProof, CollectionChange, CollectionChangesPage, CollectionContractDescriptor, CollectionDescription, CollectionFileMetadata, CollectionOperation as MdbaseOperation, CollectionTypeDescriptor, CollectionTypeDocument, ConnectOperationOutcome, ConnectProblem, ConnectProblemCategory, ConnectProblemCode, ConnectProblemDetailsByCode, ConnectRecoveryAction, ContractRequirement, DataContractViewIdentity, GrantScope, FirstContactBinding, JsonObject, MdbaseAppManifest, NotificationCriterion, MdbaseDiagnostic, MdbaseOperationEnvelope, KnownConnectProblem, RecordDocument, QueryRecord, SavedNamedView, SavedViewDocument, SavedViewExecution, SavedViewList, SavedViewPresentation, SavedViewProperty, SavedViewSource, SavedViewSourceDocument, ReadViewSourceInput, CreateViewSourceInput, UpdateViewSourceInput, DeleteViewSourceInput, DeleteViewSourceResult, ExecuteViewInput, TypePackManifest, TypePackManifestResource, TypePackInstallResult, TypePackProvision, TypePackResourceDiff, TypePackSourceResource, UnknownConnectProblem } from "@mdbase-dev/connect-protocol";
package/dist/index.js CHANGED
@@ -1,8 +1,11 @@
1
1
  export { decryptRelayResponse, encryptRelayRequest, IndexedDbGrantKeyStore, MemoryGrantKeyStore, RelayCryptoError } from "./crypto.js";
2
2
  export { FileTransferCryptoError, GrantFileTransferCipher } from "./file-crypto.js";
3
+ export { deriveFirstContactSas, FirstContactCryptoError } from "./first-contact.js";
4
+ export { applicationInstallationId, authorizationSigningMessage, signApplicationAuthorization } from "./application-identity.js";
3
5
  export * from "./authorization-types.js";
4
6
  export * from "./collection-client.js";
5
- export * from "./connect.js";
7
+ export * from "./connect-options.js";
8
+ export * from "./mdbase-connect.js";
6
9
  export * from "./connection.js";
7
10
  export * from "./connection-types.js";
8
11
  export * from "./errors.js";
@@ -1,12 +1,14 @@
1
- import type { ApplicationNotifications, CollectionOperation, EncryptedRelayOperationRequest, GrantEncryption, FileCapability, GrantScope } from "@mdbase-dev/connect-protocol";
1
+ import type { ApplicationNotifications, ApplicationRequirements, CollectionOperation, EncryptedRelayOperationRequest, GrantEncryption, FileCapability, GrantScope } from "@mdbase-dev/connect-protocol";
2
2
  import { encryptRelayRequest } from "./crypto.js";
3
3
  export interface Application {
4
4
  id: string;
5
+ manifest_digest: string;
5
6
  name: string;
6
7
  distribution?: "web" | "portable";
7
8
  homepage?: string;
8
9
  project_url?: string;
9
10
  notifications?: ApplicationNotifications;
11
+ requirements: ApplicationRequirements;
10
12
  }
11
13
  export interface StoredAuthorization {
12
14
  version: 1;
@@ -18,6 +20,8 @@ export interface StoredAuthorization {
18
20
  collectionId?: string;
19
21
  returnTo?: string;
20
22
  keyHandle?: string;
23
+ installationKeyHandle?: string;
24
+ authorizationId?: string;
21
25
  applicationAgreementPublicKey?: string;
22
26
  applicationSigningPublicKey?: string;
23
27
  }
@@ -0,0 +1,21 @@
1
+ import type { JsonObject } from "@mdbase-dev/connect-protocol";
2
+ import type { MdbaseConnectOptions } from "./connect-options.js";
3
+ import { MdbaseConnection, type MdbaseAuthorizationOutcome, type MdbaseAuthorizationResult, type MdbaseAuthorizeOptions, type MdbaseConnectEnvironment } from "./connection.js";
4
+ import type { MdbaseConnectionInfo } from "./connection-types.js";
5
+ import { type AuthorizationProblemCode, type ConnectOutcome, type RegistrationProblemCode } from "./outcomes.js";
6
+ import { MdbaseSession, type MdbaseSessionOptions, type MdbaseUnavailableReason } from "./session.js";
7
+ import type { Application } from "./internal-types.js";
8
+ export declare class MdbaseConnect<Frontmatter extends JsonObject = JsonObject> {
9
+ private readonly internals;
10
+ constructor(options: MdbaseConnectOptions);
11
+ register(): Promise<ConnectOutcome<Application, RegistrationProblemCode>>;
12
+ authorize(options?: MdbaseAuthorizeOptions): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter>, AuthorizationProblemCode>>;
13
+ createSession(options: MdbaseSessionOptions): MdbaseSession<Frontmatter>;
14
+ environment(): MdbaseConnectEnvironment;
15
+ completeAuthorization(callbackUrl?: string): Promise<ConnectOutcome<MdbaseAuthorizationResult<Frontmatter>, AuthorizationProblemCode>>;
16
+ connections(): MdbaseConnectionInfo[];
17
+ connection(collectionId: string): MdbaseConnection<Frontmatter> | null;
18
+ unavailableReason(collectionId: string): MdbaseUnavailableReason | null;
19
+ onConnectionsChange(listener: (connections: MdbaseConnectionInfo[]) => void): () => void;
20
+ forgetAll(): void;
21
+ }
@@ -0,0 +1,42 @@
1
+ import { MdbaseConnectInternals } from "./connect.js";
2
+ import { defaultCallbackUrl } from "./runtime-utils.js";
3
+ import { AUTHORIZATION_PROBLEM_CODES, REGISTRATION_PROBLEM_CODES, captureConnectOutcome } from "./outcomes.js";
4
+ import { MdbaseSession } from "./session.js";
5
+ export class MdbaseConnect {
6
+ internals;
7
+ constructor(options) {
8
+ this.internals = new MdbaseConnectInternals(options);
9
+ }
10
+ register() {
11
+ return captureConnectOutcome(() => this.internals.register(), REGISTRATION_PROBLEM_CODES);
12
+ }
13
+ authorize(options = {}) {
14
+ return captureConnectOutcome(() => this.internals.authorize(options), AUTHORIZATION_PROBLEM_CODES);
15
+ }
16
+ createSession(options) {
17
+ return new MdbaseSession(this, options);
18
+ }
19
+ environment() {
20
+ return this.internals.environment();
21
+ }
22
+ completeAuthorization(callbackUrl) {
23
+ return captureConnectOutcome(() => this.internals.completeAuthorization(callbackUrl ?? defaultCallbackUrl()), AUTHORIZATION_PROBLEM_CODES);
24
+ }
25
+ connections() {
26
+ return this.internals.connections();
27
+ }
28
+ connection(collectionId) {
29
+ return this.internals.connection(collectionId);
30
+ }
31
+ unavailableReason(collectionId) {
32
+ return this.internals.unavailableReason(collectionId);
33
+ }
34
+ onConnectionsChange(listener) {
35
+ return this.internals.onConnectionsChange(listener);
36
+ }
37
+ forgetAll() {
38
+ for (const connection of this.connections()) {
39
+ this.connection(connection.collectionId)?.forget();
40
+ }
41
+ }
42
+ }
@@ -18,14 +18,14 @@ export declare const COMMON_OPERATION_PROBLEM_CODES: readonly ["access_denied",
18
18
  export declare const ALL_CONNECT_PROBLEM_CODES: ConnectProblemCode[];
19
19
  export type RegistrationProblemCode = "discovery_failed" | "invalid_application_manifest" | "invalid_request" | "manifest_load_failed" | "rate_limited" | "temporarily_unavailable" | "timeout";
20
20
  export declare const REGISTRATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout"];
21
- export type AuthorizationProblemCode = RegistrationProblemCode | "access_denied" | "approval_window_blocked" | "authorization_cancelled" | "browser_required" | "collection_access_denied" | "collection_configuration_invalid" | "collection_contracts_missing" | "collection_incompatible" | "collection_invalid" | "collection_kind_unsupported" | "collection_mismatch" | "collection_not_found" | "collection_type_registry_invalid" | "collection_version_unsupported" | "connector_identity_changed" | "connector_offline" | "connector_upgrade_required" | "device_authorization_failed" | "encryption_required" | "expired_token" | "invalid_callback" | "invalid_device_authorization_response" | "invalid_token_response" | "scope_denied" | "token_exchange_failed";
22
- export declare const AUTHORIZATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "access_denied", "approval_window_blocked", "authorization_cancelled", "browser_required", "collection_access_denied", "collection_configuration_invalid", "collection_contracts_missing", "collection_incompatible", "collection_invalid", "collection_kind_unsupported", "collection_mismatch", "collection_not_found", "collection_type_registry_invalid", "collection_version_unsupported", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "device_authorization_failed", "encryption_required", "expired_token", "invalid_callback", "invalid_device_authorization_response", "invalid_token_response", "scope_denied", "token_exchange_failed"];
21
+ export type AuthorizationProblemCode = RegistrationProblemCode | "access_denied" | "approval_window_blocked" | "authorization_cancelled" | "browser_required" | "collection_access_denied" | "collection_configuration_invalid" | "collection_contracts_missing" | "collection_incompatible" | "collection_invalid" | "collection_kind_unsupported" | "collection_mismatch" | "collection_not_found" | "collection_type_registry_invalid" | "collection_version_unsupported" | "connector_identity_changed" | "connector_offline" | "connector_upgrade_required" | "device_authorization_failed" | "encryption_required" | "expired_token" | "first_contact_handler_required" | "invalid_callback" | "invalid_device_authorization_response" | "invalid_first_contact" | "invalid_token_response" | "scope_denied" | "token_exchange_failed";
22
+ export declare const AUTHORIZATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "access_denied", "approval_window_blocked", "authorization_cancelled", "browser_required", "collection_access_denied", "collection_configuration_invalid", "collection_contracts_missing", "collection_incompatible", "collection_invalid", "collection_kind_unsupported", "collection_mismatch", "collection_not_found", "collection_type_registry_invalid", "collection_version_unsupported", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "device_authorization_failed", "encryption_required", "expired_token", "first_contact_handler_required", "invalid_callback", "invalid_device_authorization_response", "invalid_first_contact", "invalid_token_response", "scope_denied", "token_exchange_failed"];
23
23
  export type NotificationProblemCode = RegistrationProblemCode | "authorization_expired" | "invalid_push_subscription" | "managed_fcm_not_declared" | "not_authorized" | "notification_criterion_not_declared" | "notification_reauthorization_required" | "notification_registration_failed" | "notification_unregistration_failed" | "notifications_not_declared" | "notifications_unavailable";
24
24
  export declare const NOTIFICATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "authorization_expired", "invalid_push_subscription", "managed_fcm_not_declared", "not_authorized", "notification_criterion_not_declared", "notification_reauthorization_required", "notification_registration_failed", "notification_unregistration_failed", "notifications_not_declared", "notifications_unavailable"];
25
25
  export type DirectAccessProblemCode = "connector_offline" | "connector_upgrade_required" | "invalid_operation_response" | "not_authorized" | "operation_failed" | "temporarily_unavailable" | "timeout";
26
26
  export declare const DIRECT_ACCESS_PROBLEM_CODES: readonly ["connector_offline", "connector_upgrade_required", "invalid_operation_response", "not_authorized", "operation_failed", "temporarily_unavailable", "timeout"];
27
27
  export type SessionProblemCode = AuthorizationProblemCode | "collection_not_ready" | "collection_not_selected" | "unknown_collection";
28
- export declare const SESSION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "access_denied", "approval_window_blocked", "authorization_cancelled", "browser_required", "collection_access_denied", "collection_configuration_invalid", "collection_contracts_missing", "collection_incompatible", "collection_invalid", "collection_kind_unsupported", "collection_mismatch", "collection_not_found", "collection_type_registry_invalid", "collection_version_unsupported", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "device_authorization_failed", "encryption_required", "expired_token", "invalid_callback", "invalid_device_authorization_response", "invalid_token_response", "scope_denied", "token_exchange_failed", "collection_not_ready", "collection_not_selected", "unknown_collection"];
28
+ export declare const SESSION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "access_denied", "approval_window_blocked", "authorization_cancelled", "browser_required", "collection_access_denied", "collection_configuration_invalid", "collection_contracts_missing", "collection_incompatible", "collection_invalid", "collection_kind_unsupported", "collection_mismatch", "collection_not_found", "collection_type_registry_invalid", "collection_version_unsupported", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "device_authorization_failed", "encryption_required", "expired_token", "first_contact_handler_required", "invalid_callback", "invalid_device_authorization_response", "invalid_first_contact", "invalid_token_response", "scope_denied", "token_exchange_failed", "collection_not_ready", "collection_not_selected", "unknown_collection"];
29
29
  export type CollectionSetupProblemCode = "collection_configuration_invalid" | "collection_invalid" | "collection_type_registry_invalid" | "collection_version_unsupported";
30
30
  export type CollectionDescriptionProblemCode = CommonOperationProblemCode | CollectionSetupProblemCode;
31
31
  export type CollectionReadProblemCode = CollectionDescriptionProblemCode | "invalid_path" | "operation_invalid";
package/dist/outcomes.js CHANGED
@@ -60,8 +60,10 @@ export const AUTHORIZATION_PROBLEM_CODES = [
60
60
  "device_authorization_failed",
61
61
  "encryption_required",
62
62
  "expired_token",
63
+ "first_contact_handler_required",
63
64
  "invalid_callback",
64
65
  "invalid_device_authorization_response",
66
+ "invalid_first_contact",
65
67
  "invalid_token_response",
66
68
  "scope_denied",
67
69
  "token_exchange_failed"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mdbase-dev/connect",
3
- "version": "0.1.0-beta.23",
3
+ "version": "0.1.0-beta.24",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,7 +25,7 @@
25
25
  "README.md"
26
26
  ],
27
27
  "dependencies": {
28
- "@mdbase-dev/connect-protocol": "0.1.0-beta.23"
28
+ "@mdbase-dev/connect-protocol": "0.1.0-beta.24"
29
29
  },
30
30
  "devDependencies": {
31
31
  "esbuild": "^0.28.1",