@meshline/sdk 0.0.0-stage → 0.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +43 -2
- package/dist/channels/repository.d.ts +73 -0
- package/dist/channels/repository.d.ts.map +1 -0
- package/dist/channels/repository.js +367 -0
- package/dist/channels/repository.js.map +1 -0
- package/dist/client/account-operations.d.ts +41 -0
- package/dist/client/account-operations.d.ts.map +1 -0
- package/dist/client/account-operations.js +304 -0
- package/dist/client/account-operations.js.map +1 -0
- package/dist/client/conversations.d.ts +36 -0
- package/dist/client/conversations.d.ts.map +1 -0
- package/dist/client/conversations.js +144 -0
- package/dist/client/conversations.js.map +1 -0
- package/dist/client.d.ts +53 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +162 -0
- package/dist/client.js.map +1 -0
- package/dist/components/account.d.ts +38 -0
- package/dist/components/account.d.ts.map +1 -0
- package/dist/components/account.js +243 -0
- package/dist/components/account.js.map +1 -0
- package/dist/components/channel.d.ts +78 -0
- package/dist/components/channel.d.ts.map +1 -0
- package/dist/components/channel.js +475 -0
- package/dist/components/channel.js.map +1 -0
- package/dist/components/component.d.ts +49 -0
- package/dist/components/component.d.ts.map +1 -0
- package/dist/components/component.js +194 -0
- package/dist/components/component.js.map +1 -0
- package/dist/components/device.d.ts +60 -0
- package/dist/components/device.d.ts.map +1 -0
- package/dist/components/device.js +648 -0
- package/dist/components/device.js.map +1 -0
- package/dist/components/group.d.ts +141 -0
- package/dist/components/group.d.ts.map +1 -0
- package/dist/components/group.js +933 -0
- package/dist/components/group.js.map +1 -0
- package/dist/components/message.d.ts +63 -0
- package/dist/components/message.d.ts.map +1 -0
- package/dist/components/message.js +439 -0
- package/dist/components/message.js.map +1 -0
- package/dist/components/profile.d.ts +37 -0
- package/dist/components/profile.d.ts.map +1 -0
- package/dist/components/profile.js +232 -0
- package/dist/components/profile.js.map +1 -0
- package/dist/crypto/groups.d.ts +56 -0
- package/dist/crypto/groups.d.ts.map +1 -0
- package/dist/crypto/groups.js +163 -0
- package/dist/crypto/groups.js.map +1 -0
- package/dist/crypto/messages.d.ts +52 -0
- package/dist/crypto/messages.d.ts.map +1 -0
- package/dist/crypto/messages.js +180 -0
- package/dist/crypto/messages.js.map +1 -0
- package/dist/crypto/primitives.d.ts +30 -0
- package/dist/crypto/primitives.d.ts.map +1 -0
- package/dist/crypto/primitives.js +102 -0
- package/dist/crypto/primitives.js.map +1 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +14 -0
- package/dist/errors.js.map +1 -0
- package/dist/groups/account-sync.d.ts +28 -0
- package/dist/groups/account-sync.d.ts.map +1 -0
- package/dist/groups/account-sync.js +235 -0
- package/dist/groups/account-sync.js.map +1 -0
- package/dist/groups/messages.d.ts +39 -0
- package/dist/groups/messages.d.ts.map +1 -0
- package/dist/groups/messages.js +141 -0
- package/dist/groups/messages.js.map +1 -0
- package/dist/groups/operations.d.ts +57 -0
- package/dist/groups/operations.d.ts.map +1 -0
- package/dist/groups/operations.js +225 -0
- package/dist/groups/operations.js.map +1 -0
- package/dist/groups/repository.d.ts +56 -0
- package/dist/groups/repository.d.ts.map +1 -0
- package/dist/groups/repository.js +254 -0
- package/dist/groups/repository.js.map +1 -0
- package/dist/groups/secrets.d.ts +67 -0
- package/dist/groups/secrets.d.ts.map +1 -0
- package/dist/groups/secrets.js +452 -0
- package/dist/groups/secrets.js.map +1 -0
- package/dist/groups/state.d.ts +39 -0
- package/dist/groups/state.d.ts.map +1 -0
- package/dist/groups/state.js +201 -0
- package/dist/groups/state.js.map +1 -0
- package/dist/identity/identifiers.d.ts +9 -0
- package/dist/identity/identifiers.d.ts.map +1 -0
- package/dist/identity/identifiers.js +37 -0
- package/dist/identity/identifiers.js.map +1 -0
- package/dist/identity/neo.d.ts +11 -0
- package/dist/identity/neo.d.ts.map +1 -0
- package/dist/identity/neo.js +77 -0
- package/dist/identity/neo.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/interactions.d.ts +31 -0
- package/dist/interactions.d.ts.map +1 -0
- package/dist/interactions.js +2 -0
- package/dist/interactions.js.map +1 -0
- package/dist/messages/account-sender.d.ts +9 -0
- package/dist/messages/account-sender.d.ts.map +1 -0
- package/dist/messages/account-sender.js +46 -0
- package/dist/messages/account-sender.js.map +1 -0
- package/dist/messages/contacts.d.ts +103 -0
- package/dist/messages/contacts.d.ts.map +1 -0
- package/dist/messages/contacts.js +525 -0
- package/dist/messages/contacts.js.map +1 -0
- package/dist/messages/outbox.d.ts +66 -0
- package/dist/messages/outbox.d.ts.map +1 -0
- package/dist/messages/outbox.js +167 -0
- package/dist/messages/outbox.js.map +1 -0
- package/dist/messages/receiver.d.ts +35 -0
- package/dist/messages/receiver.d.ts.map +1 -0
- package/dist/messages/receiver.js +113 -0
- package/dist/messages/receiver.js.map +1 -0
- package/dist/messages/repository.d.ts +89 -0
- package/dist/messages/repository.d.ts.map +1 -0
- package/dist/messages/repository.js +295 -0
- package/dist/messages/repository.js.map +1 -0
- package/dist/models/authentication.d.ts +37 -0
- package/dist/models/authentication.d.ts.map +1 -0
- package/dist/models/authentication.js +53 -0
- package/dist/models/authentication.js.map +1 -0
- package/dist/models/channels.d.ts +141 -0
- package/dist/models/channels.d.ts.map +1 -0
- package/dist/models/channels.js +258 -0
- package/dist/models/channels.js.map +1 -0
- package/dist/models/contacts.d.ts +68 -0
- package/dist/models/contacts.d.ts.map +1 -0
- package/dist/models/contacts.js +186 -0
- package/dist/models/contacts.js.map +1 -0
- package/dist/models/content.d.ts +37 -0
- package/dist/models/content.d.ts.map +1 -0
- package/dist/models/content.js +137 -0
- package/dist/models/content.js.map +1 -0
- package/dist/models/device-state.d.ts +8 -0
- package/dist/models/device-state.d.ts.map +1 -0
- package/dist/models/device-state.js +22 -0
- package/dist/models/device-state.js.map +1 -0
- package/dist/models/group-admission.d.ts +111 -0
- package/dist/models/group-admission.d.ts.map +1 -0
- package/dist/models/group-admission.js +153 -0
- package/dist/models/group-admission.js.map +1 -0
- package/dist/models/group-keys.d.ts +30 -0
- package/dist/models/group-keys.d.ts.map +1 -0
- package/dist/models/group-keys.js +52 -0
- package/dist/models/group-keys.js.map +1 -0
- package/dist/models/group-management.d.ts +190 -0
- package/dist/models/group-management.d.ts.map +1 -0
- package/dist/models/group-management.js +263 -0
- package/dist/models/group-management.js.map +1 -0
- package/dist/models/groups.d.ts +81 -0
- package/dist/models/groups.d.ts.map +1 -0
- package/dist/models/groups.js +127 -0
- package/dist/models/groups.js.map +1 -0
- package/dist/models/identity.d.ts +47 -0
- package/dist/models/identity.d.ts.map +1 -0
- package/dist/models/identity.js +136 -0
- package/dist/models/identity.js.map +1 -0
- package/dist/models/messages.d.ts +104 -0
- package/dist/models/messages.d.ts.map +1 -0
- package/dist/models/messages.js +168 -0
- package/dist/models/messages.js.map +1 -0
- package/dist/models/profile.d.ts +24 -0
- package/dist/models/profile.d.ts.map +1 -0
- package/dist/models/profile.js +47 -0
- package/dist/models/profile.js.map +1 -0
- package/dist/models/relay.d.ts +39 -0
- package/dist/models/relay.d.ts.map +1 -0
- package/dist/models/relay.js +160 -0
- package/dist/models/relay.js.map +1 -0
- package/dist/protocol/codec.d.ts +36 -0
- package/dist/protocol/codec.d.ts.map +1 -0
- package/dist/protocol/codec.js +144 -0
- package/dist/protocol/codec.js.map +1 -0
- package/dist/protocol/context.d.ts +14 -0
- package/dist/protocol/context.d.ts.map +1 -0
- package/dist/protocol/context.js +43 -0
- package/dist/protocol/context.js.map +1 -0
- package/dist/protocol/encoding.d.ts +15 -0
- package/dist/protocol/encoding.d.ts.map +1 -0
- package/dist/protocol/encoding.js +133 -0
- package/dist/protocol/encoding.js.map +1 -0
- package/dist/protocol/json.d.ts +16 -0
- package/dist/protocol/json.d.ts.map +1 -0
- package/dist/protocol/json.js +172 -0
- package/dist/protocol/json.js.map +1 -0
- package/dist/protocol/validation.d.ts +4 -0
- package/dist/protocol/validation.d.ts.map +1 -0
- package/dist/protocol/validation.js +18 -0
- package/dist/protocol/validation.js.map +1 -0
- package/dist/runtime/abort.d.ts +6 -0
- package/dist/runtime/abort.d.ts.map +1 -0
- package/dist/runtime/abort.js +32 -0
- package/dist/runtime/abort.js.map +1 -0
- package/dist/runtime/async-gate.d.ts +6 -0
- package/dist/runtime/async-gate.d.ts.map +1 -0
- package/dist/runtime/async-gate.js +15 -0
- package/dist/runtime/async-gate.js.map +1 -0
- package/dist/runtime/async-pulse.d.ts +7 -0
- package/dist/runtime/async-pulse.d.ts.map +1 -0
- package/dist/runtime/async-pulse.js +23 -0
- package/dist/runtime/async-pulse.js.map +1 -0
- package/dist/runtime/clock.d.ts +16 -0
- package/dist/runtime/clock.d.ts.map +1 -0
- package/dist/runtime/clock.js +62 -0
- package/dist/runtime/clock.js.map +1 -0
- package/dist/runtime/events.d.ts +11 -0
- package/dist/runtime/events.d.ts.map +1 -0
- package/dist/runtime/events.js +45 -0
- package/dist/runtime/events.js.map +1 -0
- package/dist/runtime/url.d.ts +3 -0
- package/dist/runtime/url.d.ts.map +1 -0
- package/dist/runtime/url.js +23 -0
- package/dist/runtime/url.js.map +1 -0
- package/dist/storage/signed-request.d.ts +14 -0
- package/dist/storage/signed-request.d.ts.map +1 -0
- package/dist/storage/signed-request.js +26 -0
- package/dist/storage/signed-request.js.map +1 -0
- package/dist/storage/store.d.ts +58 -0
- package/dist/storage/store.d.ts.map +1 -0
- package/dist/storage/store.js +52 -0
- package/dist/storage/store.js.map +1 -0
- package/dist/storage/transaction.d.ts +7 -0
- package/dist/storage/transaction.d.ts.map +1 -0
- package/dist/storage/transaction.js +22 -0
- package/dist/storage/transaction.js.map +1 -0
- package/dist/transport/client.d.ts +61 -0
- package/dist/transport/client.d.ts.map +1 -0
- package/dist/transport/client.js +392 -0
- package/dist/transport/client.js.map +1 -0
- package/dist/transport/discovery.d.ts +19 -0
- package/dist/transport/discovery.d.ts.map +1 -0
- package/dist/transport/discovery.js +75 -0
- package/dist/transport/discovery.js.map +1 -0
- package/dist/transport/endpoint.d.ts +6 -0
- package/dist/transport/endpoint.d.ts.map +1 -0
- package/dist/transport/endpoint.js +35 -0
- package/dist/transport/endpoint.js.map +1 -0
- package/dist/transport/http.d.ts +52 -0
- package/dist/transport/http.d.ts.map +1 -0
- package/dist/transport/http.js +128 -0
- package/dist/transport/http.js.map +1 -0
- package/dist/transport/pool.d.ts +31 -0
- package/dist/transport/pool.d.ts.map +1 -0
- package/dist/transport/pool.js +137 -0
- package/dist/transport/pool.js.map +1 -0
- package/dist/transport/relay-error.d.ts +23 -0
- package/dist/transport/relay-error.d.ts.map +1 -0
- package/dist/transport/relay-error.js +47 -0
- package/dist/transport/relay-error.js.map +1 -0
- package/dist/transport/rpc.d.ts +31 -0
- package/dist/transport/rpc.d.ts.map +1 -0
- package/dist/transport/rpc.js +56 -0
- package/dist/transport/rpc.js.map +1 -0
- package/dist/transport/session.d.ts +49 -0
- package/dist/transport/session.d.ts.map +1 -0
- package/dist/transport/session.js +169 -0
- package/dist/transport/session.js.map +1 -0
- package/dist/transport/socket.d.ts +55 -0
- package/dist/transport/socket.d.ts.map +1 -0
- package/dist/transport/socket.js +266 -0
- package/dist/transport/socket.js.map +1 -0
- package/dist/transport/subscription.d.ts +36 -0
- package/dist/transport/subscription.d.ts.map +1 -0
- package/dist/transport/subscription.js +169 -0
- package/dist/transport/subscription.js.map +1 -0
- package/package.json +35 -4
- package/src/channels/repository.ts +244 -0
- package/src/client/account-operations.ts +183 -0
- package/src/client/conversations.ts +95 -0
- package/src/client.ts +108 -0
- package/src/components/account.ts +206 -0
- package/src/components/channel.ts +253 -0
- package/src/components/component.ts +151 -0
- package/src/components/device.ts +455 -0
- package/src/components/group.ts +546 -0
- package/src/components/message.ts +253 -0
- package/src/components/profile.ts +179 -0
- package/src/crypto/groups.ts +107 -0
- package/src/crypto/messages.ts +129 -0
- package/src/crypto/primitives.ts +103 -0
- package/src/errors.ts +13 -0
- package/src/groups/account-sync.ts +144 -0
- package/src/groups/messages.ts +89 -0
- package/src/groups/operations.ts +145 -0
- package/src/groups/repository.ts +161 -0
- package/src/groups/secrets.ts +256 -0
- package/src/groups/state.ts +138 -0
- package/src/identity/identifiers.ts +41 -0
- package/src/identity/neo.ts +72 -0
- package/src/index.ts +52 -0
- package/src/interactions.ts +35 -0
- package/src/messages/account-sender.ts +33 -0
- package/src/messages/contacts.ts +379 -0
- package/src/messages/outbox.ts +152 -0
- package/src/messages/receiver.ts +86 -0
- package/src/messages/repository.ts +230 -0
- package/src/models/authentication.ts +63 -0
- package/src/models/channels.ts +155 -0
- package/src/models/contacts.ts +141 -0
- package/src/models/content.ts +105 -0
- package/src/models/device-state.ts +18 -0
- package/src/models/group-admission.ts +110 -0
- package/src/models/group-keys.ts +34 -0
- package/src/models/group-management.ts +182 -0
- package/src/models/groups.ts +100 -0
- package/src/models/identity.ts +164 -0
- package/src/models/messages.ts +139 -0
- package/src/models/profile.ts +46 -0
- package/src/models/relay.ts +151 -0
- package/src/protocol/codec.ts +144 -0
- package/src/protocol/context.ts +39 -0
- package/src/protocol/encoding.ts +106 -0
- package/src/protocol/json.ts +140 -0
- package/src/protocol/validation.ts +13 -0
- package/src/runtime/abort.ts +27 -0
- package/src/runtime/async-gate.ts +16 -0
- package/src/runtime/async-pulse.ts +20 -0
- package/src/runtime/clock.ts +63 -0
- package/src/runtime/events.ts +31 -0
- package/src/runtime/url.ts +17 -0
- package/src/storage/signed-request.ts +26 -0
- package/src/storage/store.ts +90 -0
- package/src/storage/transaction.ts +17 -0
- package/src/transport/client.ts +328 -0
- package/src/transport/discovery.ts +64 -0
- package/src/transport/endpoint.ts +32 -0
- package/src/transport/http.ts +129 -0
- package/src/transport/pool.ts +115 -0
- package/src/transport/relay-error.ts +46 -0
- package/src/transport/rpc.ts +56 -0
- package/src/transport/session.ts +154 -0
- package/src/transport/socket.ts +248 -0
- package/src/transport/subscription.ts +117 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { requireLength, verifyDevice } from '../crypto/primitives.js';
|
|
2
|
+
import { ProtocolError } from '../errors.js';
|
|
3
|
+
import { deriveResourceId, validateIdentifier } from '../identity/identifiers.js';
|
|
4
|
+
import { validateAccountId, validateRelayId } from '../identity/neo.js';
|
|
5
|
+
import { array, boolean, bytes, defineCodec, enumeration, integer, text } from '../protocol/codec.js';
|
|
6
|
+
import { signingInput } from '../protocol/context.js';
|
|
7
|
+
import { encodeUtf8 } from '../protocol/encoding.js';
|
|
8
|
+
import { canonicalJson, requireObject, requireSafeInteger } from '../protocol/json.js';
|
|
9
|
+
import { validateCompleteObject } from '../protocol/validation.js';
|
|
10
|
+
import { containsNonWhitespace, contentReferenceCodec, messageBodyCodec, validateAttachments, validateMessageBody } from './content.js';
|
|
11
|
+
import { certificateId, deviceCertificateCodec, validateCertificate } from './identity.js';
|
|
12
|
+
export function validateChannelRef(value) { validateIdentifier('channel', value.channelId); validateRelayId(value.relayId); }
|
|
13
|
+
export function validateChannelPostRef(value) { validateChannelRef(value.channel); requireSafeInteger(value.sequence, 1); }
|
|
14
|
+
export const channelDescriptorCodec = defineCodec({
|
|
15
|
+
channelId: { wire: 'channel_id', codec: text }, nonce: { wire: 'nonce', codec: bytes }, creator: { wire: 'creator', codec: text }, relayId: { wire: 'relay_id', codec: text },
|
|
16
|
+
name: { wire: 'name', codec: text }, description: { wire: 'description', codec: text, optional: true }, moderators: { wire: 'moderators', codec: array(text), optional: true },
|
|
17
|
+
revision: { wire: 'revision', codec: integer }, status: { wire: 'status', codec: enumeration('active', 'closed') },
|
|
18
|
+
createdAt: { wire: 'created_at', codec: integer }, updatedAt: { wire: 'updated_at', codec: integer }, deviceSignature: { wire: 'device_signature', codec: bytes },
|
|
19
|
+
}, 'meshline.channel.descriptor');
|
|
20
|
+
export const channelDescriptorInput = (value, context) => signingInput(channelDescriptorCodec.encode(value), context, ['device_signature']);
|
|
21
|
+
function size(value, limit) { if (encodeUtf8(canonicalJson(value)).length > limit)
|
|
22
|
+
throw new ProtocolError('invalid_size', `Channel document exceeds ${limit} canonical JSON bytes.`); }
|
|
23
|
+
export function validateChannelDescriptor(value, context) {
|
|
24
|
+
const wire = channelDescriptorCodec.encode(value);
|
|
25
|
+
validateCompleteObject(wire);
|
|
26
|
+
validateChannelRef(value);
|
|
27
|
+
validateAccountId(value.creator);
|
|
28
|
+
requireLength(value.nonce, 16, 'Channel nonce');
|
|
29
|
+
if (!containsNonWhitespace(value.name) || encodeUtf8(value.name).length > 256)
|
|
30
|
+
throw new ProtocolError('invalid_name', 'Channel name requires text and at most 256 UTF-8 bytes.');
|
|
31
|
+
if (value.description !== undefined && value.description.length > 0 && (!containsNonWhitespace(value.description) || encodeUtf8(value.description).length > 4096))
|
|
32
|
+
throw new ProtocolError('invalid_description', 'Nonempty channel description requires text and at most 4096 UTF-8 bytes.');
|
|
33
|
+
requireSafeInteger(value.revision, 0);
|
|
34
|
+
requireSafeInteger(value.createdAt, 0);
|
|
35
|
+
requireSafeInteger(value.updatedAt, 0);
|
|
36
|
+
requireLength(value.deviceSignature, 64, 'Channel signature');
|
|
37
|
+
if (value.revision === 0 && (value.status !== 'active' || value.createdAt !== value.updatedAt))
|
|
38
|
+
throw new ProtocolError('invalid_initial_state', 'Initial channel descriptor must be active with equal creation and update times.');
|
|
39
|
+
if (value.moderators) {
|
|
40
|
+
if (value.moderators.length > 10)
|
|
41
|
+
throw new ProtocolError('invalid_size', 'At most ten channel moderators are permitted.');
|
|
42
|
+
const seen = new Set([value.creator]);
|
|
43
|
+
for (const account of value.moderators) {
|
|
44
|
+
validateAccountId(account);
|
|
45
|
+
if (seen.has(account))
|
|
46
|
+
throw new ProtocolError('duplicate_moderator', 'Moderators must be distinct and cannot include the creator.');
|
|
47
|
+
seen.add(account);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (deriveResourceId('channel', value.creator, value.relayId, value.nonce, context) !== value.channelId)
|
|
51
|
+
throw new ProtocolError('invalid_identity', 'Channel ID does not bind its creator, relay, nonce and context.');
|
|
52
|
+
size(wire, 8192);
|
|
53
|
+
}
|
|
54
|
+
export const channelPostCodec = defineCodec({ channelId: { wire: 'channel_id', codec: text }, messageId: { wire: 'message_id', codec: text }, body: { wire: 'body', codec: messageBodyCodec, optional: true },
|
|
55
|
+
attachments: { wire: 'attachments', codec: array(contentReferenceCodec), optional: true }, deviceSignature: { wire: 'device_signature', codec: bytes } }, 'meshline.channel.post');
|
|
56
|
+
export const channelPostInput = (value, context) => signingInput(channelPostCodec.encode(value), context, ['device_signature']);
|
|
57
|
+
export function validateChannelPost(value) {
|
|
58
|
+
const wire = channelPostCodec.encode(value);
|
|
59
|
+
validateCompleteObject(wire);
|
|
60
|
+
validateIdentifier('channel', value.channelId);
|
|
61
|
+
validateIdentifier('message', value.messageId);
|
|
62
|
+
requireLength(value.deviceSignature, 64, 'Post signature');
|
|
63
|
+
if (!value.body && !value.attachments?.length)
|
|
64
|
+
throw new ProtocolError('content_required', 'Channel posts require a body or at least one attachment.');
|
|
65
|
+
if (value.body)
|
|
66
|
+
validateMessageBody(value.body);
|
|
67
|
+
if (value.attachments)
|
|
68
|
+
validateAttachments(value.attachments);
|
|
69
|
+
size(wire, 65536);
|
|
70
|
+
}
|
|
71
|
+
export const channelPostEditCodec = defineCodec({ channelId: { wire: 'channel_id', codec: text }, targetSequence: { wire: 'target_sequence', codec: integer },
|
|
72
|
+
body: { wire: 'body', codec: messageBodyCodec, optional: true, nullable: true }, attachments: { wire: 'attachments', codec: array(contentReferenceCodec), optional: true, nullable: true },
|
|
73
|
+
deviceSignature: { wire: 'device_signature', codec: bytes } }, 'meshline.channel.post.edit');
|
|
74
|
+
export const channelPostEditInput = (value, context) => signingInput(channelPostEditCodec.encode(value), context, ['device_signature']);
|
|
75
|
+
export function validateChannelPostEdit(value) {
|
|
76
|
+
const wire = channelPostEditCodec.encode(value);
|
|
77
|
+
validateIdentifier('channel', value.channelId);
|
|
78
|
+
requireSafeInteger(value.targetSequence, 1);
|
|
79
|
+
requireLength(value.deviceSignature, 64, 'Post edit signature');
|
|
80
|
+
if (value.body === undefined && value.attachments === undefined && !Object.keys(value.additionalProperties ?? {}).length)
|
|
81
|
+
throw new ProtocolError('empty_edit', 'A channel edit must change at least one field.');
|
|
82
|
+
for (const key of Object.keys(value.additionalProperties ?? {}))
|
|
83
|
+
if (['$type', '$context', 'channel_id', 'message_id', 'body', 'attachments', 'device_signature'].includes(key))
|
|
84
|
+
throw new ProtocolError('invalid_extension', 'Edit extensions cannot replace defined post fields or context.');
|
|
85
|
+
// Only root field deletion markers may be null. Nested values remain complete objects.
|
|
86
|
+
for (const [key, field] of Object.entries(wire))
|
|
87
|
+
if (field !== null)
|
|
88
|
+
validateCompleteObject({ [key]: field });
|
|
89
|
+
if (value.body)
|
|
90
|
+
validateMessageBody(value.body);
|
|
91
|
+
if (value.attachments)
|
|
92
|
+
validateAttachments(value.attachments);
|
|
93
|
+
if (value.body === null && (value.attachments === null || value.attachments?.length === 0))
|
|
94
|
+
throw new ProtocolError('content_required', 'An edit cannot remove both body and every attachment.');
|
|
95
|
+
size(wire, 65536);
|
|
96
|
+
}
|
|
97
|
+
/** Applies replacement/deletion/omission in acceptance order and validates the resulting complete post. Does not alter signed evidence. */
|
|
98
|
+
export function applyChannelPostEdit(post, edit) {
|
|
99
|
+
validateChannelPost(post);
|
|
100
|
+
validateChannelPostEdit(edit);
|
|
101
|
+
if (post.channelId !== edit.channelId)
|
|
102
|
+
throw new ProtocolError('invalid_binding', 'Post edit belongs to another channel.');
|
|
103
|
+
const wire = channelPostCodec.encode(post);
|
|
104
|
+
const changes = channelPostEditCodec.encode(edit);
|
|
105
|
+
for (const [key, value] of Object.entries(changes))
|
|
106
|
+
if (!['$type', 'channel_id', 'target_sequence', 'device_signature'].includes(key)) {
|
|
107
|
+
if (value === null)
|
|
108
|
+
delete wire[key];
|
|
109
|
+
else
|
|
110
|
+
wire[key] = value;
|
|
111
|
+
}
|
|
112
|
+
const result = channelPostCodec.decode(wire);
|
|
113
|
+
validateChannelPost(result);
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
export const channelPostDeleteCodec = defineCodec({ channelId: { wire: 'channel_id', codec: text }, targetSequence: { wire: 'target_sequence', codec: integer }, reason: { wire: 'reason', codec: text, optional: true }, deviceSignature: { wire: 'device_signature', codec: bytes } }, 'meshline.channel.post.delete');
|
|
117
|
+
export const channelPostDeleteInput = (value, context) => signingInput(channelPostDeleteCodec.encode(value), context, ['device_signature']);
|
|
118
|
+
export function validateChannelPostDelete(value) {
|
|
119
|
+
const wire = channelPostDeleteCodec.encode(value);
|
|
120
|
+
validateCompleteObject(wire);
|
|
121
|
+
validateIdentifier('channel', value.channelId);
|
|
122
|
+
requireSafeInteger(value.targetSequence, 1);
|
|
123
|
+
requireLength(value.deviceSignature, 64, 'Post deletion signature');
|
|
124
|
+
if (value.reason !== undefined && !containsNonWhitespace(value.reason))
|
|
125
|
+
throw new ProtocolError('invalid_reason', 'Deletion reason must contain text when present.');
|
|
126
|
+
size(wire, 65536);
|
|
127
|
+
}
|
|
128
|
+
export const channelPayloadCodec = {
|
|
129
|
+
decode(value) {
|
|
130
|
+
switch (requireObject(value)['$type']) {
|
|
131
|
+
case 'meshline.channel.descriptor': return { kind: 'descriptor', value: channelDescriptorCodec.decode(value) };
|
|
132
|
+
case 'meshline.channel.post': return { kind: 'post', value: channelPostCodec.decode(value) };
|
|
133
|
+
case 'meshline.channel.post.edit': return { kind: 'edit', value: channelPostEditCodec.decode(value) };
|
|
134
|
+
case 'meshline.channel.post.delete': return { kind: 'delete', value: channelPostDeleteCodec.decode(value) };
|
|
135
|
+
default: throw new ProtocolError('unsupported_type', 'Unsupported channel event payload.');
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
encode(payload) { switch (payload.kind) {
|
|
139
|
+
case 'descriptor': return channelDescriptorCodec.encode(payload.value);
|
|
140
|
+
case 'post': return channelPostCodec.encode(payload.value);
|
|
141
|
+
case 'edit': return channelPostEditCodec.encode(payload.value);
|
|
142
|
+
case 'delete': return channelPostDeleteCodec.encode(payload.value);
|
|
143
|
+
} },
|
|
144
|
+
};
|
|
145
|
+
export function validateChannelPayload(payload, context) {
|
|
146
|
+
switch (payload.kind) {
|
|
147
|
+
case 'descriptor': return validateChannelDescriptor(payload.value, context);
|
|
148
|
+
case 'post': return validateChannelPost(payload.value);
|
|
149
|
+
case 'edit': return validateChannelPostEdit(payload.value);
|
|
150
|
+
case 'delete': return validateChannelPostDelete(payload.value);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
export const channelPayloadInput = (payload, context) => signingInput(requireObject(channelPayloadCodec.encode(payload)), context, ['device_signature']);
|
|
154
|
+
export const channelEventCodec = defineCodec({ sequence: { wire: 'sequence', codec: integer }, descriptorRev: { wire: 'descriptor_rev', codec: integer }, payload: { wire: 'payload', codec: channelPayloadCodec }, acceptedAt: { wire: 'accepted_at', codec: integer }, signerDeviceId: { wire: 'signer_device_id', codec: text } });
|
|
155
|
+
export function validateChannelEvent(value, context) {
|
|
156
|
+
const { payload, ...outer } = channelEventCodec.encode(value);
|
|
157
|
+
validateCompleteObject(outer);
|
|
158
|
+
validateChannelPayload(value.payload, context);
|
|
159
|
+
requireSafeInteger(value.sequence, 0);
|
|
160
|
+
requireSafeInteger(value.descriptorRev, 0);
|
|
161
|
+
requireSafeInteger(value.acceptedAt, 0);
|
|
162
|
+
validateIdentifier('device', value.signerDeviceId);
|
|
163
|
+
if (value.sequence === 0 && (value.payload.kind !== 'descriptor' || value.payload.value.revision !== 0))
|
|
164
|
+
throw new ProtocolError('invalid_sequence', 'Sequence zero requires the initial channel descriptor.');
|
|
165
|
+
if (value.payload.kind === 'descriptor' && (value.payload.value.revision !== value.descriptorRev || value.sequence > 0 && value.payload.value.revision === 0))
|
|
166
|
+
throw new ProtocolError('invalid_revision', 'Descriptor event revision or initial sequence is inconsistent.');
|
|
167
|
+
if ((value.payload.kind === 'edit' || value.payload.kind === 'delete') && value.payload.value.targetSequence >= value.sequence)
|
|
168
|
+
throw new ProtocolError('invalid_sequence', 'A channel edit or deletion must target an earlier positive post sequence.');
|
|
169
|
+
}
|
|
170
|
+
export const channelResolveResultCodec = defineCodec({ descriptor: { wire: 'descriptor', codec: channelDescriptorCodec }, signerCertificate: { wire: 'signer_certificate', codec: deviceCertificateCodec } });
|
|
171
|
+
export function verifyChannelDescriptor(value, context, channel) {
|
|
172
|
+
validateCompleteObject(channelResolveResultCodec.encode(value));
|
|
173
|
+
validateChannelRef(channel);
|
|
174
|
+
validateChannelDescriptor(value.descriptor, context);
|
|
175
|
+
validateCertificate(value.signerCertificate, context);
|
|
176
|
+
if (value.descriptor.channelId !== channel.channelId || value.descriptor.relayId !== channel.relayId || value.signerCertificate.account !== value.descriptor.creator)
|
|
177
|
+
throw new ProtocolError('invalid_binding', 'Channel descriptor or signer belongs to another resource or account.');
|
|
178
|
+
if (!verifyDevice(channelDescriptorInput(value.descriptor, context), value.descriptor.deviceSignature, value.signerCertificate.signingPublicKey))
|
|
179
|
+
throw new ProtocolError('invalid_signature', 'Invalid channel descriptor signature.');
|
|
180
|
+
}
|
|
181
|
+
export function verifyChannelEvent(value, certificate, descriptor, context, channel) {
|
|
182
|
+
validateChannelEvent(value, context);
|
|
183
|
+
validateCertificate(certificate, context);
|
|
184
|
+
validateChannelRef(channel);
|
|
185
|
+
if (certificateId(certificate, context) !== value.signerDeviceId || value.payload.value.channelId !== channel.channelId)
|
|
186
|
+
throw new ProtocolError('invalid_binding', 'Channel event signer or resource binding is invalid.');
|
|
187
|
+
if (value.payload.kind === 'descriptor') {
|
|
188
|
+
verifyChannelDescriptor({ descriptor: value.payload.value, signerCertificate: certificate }, context, channel);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
validateChannelDescriptor(descriptor, context);
|
|
192
|
+
if (descriptor.channelId !== channel.channelId || descriptor.relayId !== channel.relayId || descriptor.revision !== value.descriptorRev || descriptor.status !== 'active'
|
|
193
|
+
|| descriptor.creator !== certificate.account && !descriptor.moderators?.includes(certificate.account))
|
|
194
|
+
throw new ProtocolError('unauthorized_event', 'Channel content signer is not authorized by the accepted descriptor revision.');
|
|
195
|
+
if (!verifyDevice(channelPayloadInput(value.payload, context), value.payload.value.deviceSignature, certificate.signingPublicKey))
|
|
196
|
+
throw new ProtocolError('invalid_signature', 'Invalid channel content signature.');
|
|
197
|
+
}
|
|
198
|
+
export const channelReadQueryCodec = defineCodec({ channelId: { wire: 'channel_id', codec: text }, before: { wire: 'before', codec: integer, optional: true }, after: { wire: 'after', codec: integer, optional: true }, limit: { wire: 'limit', codec: integer, optional: true } });
|
|
199
|
+
export function validateChannelReadQuery(value) {
|
|
200
|
+
validateCompleteObject(channelReadQueryCodec.encode(value));
|
|
201
|
+
validateIdentifier('channel', value.channelId);
|
|
202
|
+
if (value.before !== undefined)
|
|
203
|
+
requireSafeInteger(value.before, 0);
|
|
204
|
+
if (value.after !== undefined)
|
|
205
|
+
requireSafeInteger(value.after, -1);
|
|
206
|
+
if (value.limit !== undefined)
|
|
207
|
+
requireSafeInteger(value.limit, 1);
|
|
208
|
+
if (value.before !== undefined && value.after !== undefined)
|
|
209
|
+
throw new ProtocolError('invalid_bounds', 'Channel before and after cursors cannot be combined.');
|
|
210
|
+
}
|
|
211
|
+
export const channelReadPageCodec = defineCodec({ events: { wire: 'events', codec: array(channelEventCodec) }, certificates: { wire: 'certificates', codec: array(deviceCertificateCodec) }, hasMore: { wire: 'has_more', codec: boolean } });
|
|
212
|
+
/** Validates page boundaries and historical certificate coverage; descriptor authorization is checked by the reader before persistence. */
|
|
213
|
+
export function validateChannelReadPage(value, query, context) {
|
|
214
|
+
validateChannelReadQuery(query);
|
|
215
|
+
const { events, ...outer } = channelReadPageCodec.encode(value);
|
|
216
|
+
validateCompleteObject(outer);
|
|
217
|
+
if (value.hasMore && !value.events.length || query.limit !== undefined && value.events.length > query.limit)
|
|
218
|
+
throw new ProtocolError('invalid_page', 'Invalid channel page size or pagination.');
|
|
219
|
+
const certificates = new Map();
|
|
220
|
+
for (const certificate of value.certificates) {
|
|
221
|
+
validateCertificate(certificate, context);
|
|
222
|
+
const id = certificateId(certificate, context);
|
|
223
|
+
if (certificates.has(id))
|
|
224
|
+
throw new ProtocolError('duplicate_certificate', 'Channel page contains duplicate device identities.');
|
|
225
|
+
certificates.set(id, certificate);
|
|
226
|
+
}
|
|
227
|
+
let previous = query.after ?? -1;
|
|
228
|
+
const revisions = new Set();
|
|
229
|
+
for (const event of value.events) {
|
|
230
|
+
validateChannelEvent(event, context);
|
|
231
|
+
if (event.sequence <= previous || query.before !== undefined && event.sequence >= query.before)
|
|
232
|
+
throw new ProtocolError('invalid_sequence', 'Channel page violates requested bounds or sequence order.');
|
|
233
|
+
previous = event.sequence;
|
|
234
|
+
if (!certificates.has(event.signerDeviceId))
|
|
235
|
+
throw new ProtocolError('missing_certificate', 'Channel event lacks signing evidence.');
|
|
236
|
+
if (event.payload.kind === 'descriptor') {
|
|
237
|
+
if (revisions.has(event.descriptorRev))
|
|
238
|
+
throw new ProtocolError('duplicate_revision', 'Descriptor revision occurs twice in one page.');
|
|
239
|
+
revisions.add(event.descriptorRev);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return certificates;
|
|
243
|
+
}
|
|
244
|
+
export const channelResolveQueryCodec = defineCodec({ channelId: { wire: 'channel_id', codec: text }, revision: { wire: 'revision', codec: integer, optional: true } });
|
|
245
|
+
export const channelCloseRequestCodec = defineCodec({ channelId: { wire: 'channel_id', codec: text }, revision: { wire: 'revision', codec: integer }, updatedAt: { wire: 'updated_at', codec: integer }, deviceSignature: { wire: 'device_signature', codec: bytes } });
|
|
246
|
+
export const channelReportRequestCodec = defineCodec({ channelId: { wire: 'channel_id', codec: text }, targetSequence: { wire: 'target_sequence', codec: integer }, reason: { wire: 'reason', codec: text } });
|
|
247
|
+
export function validateChannelReportRequest(value) { validateCompleteObject(channelReportRequestCodec.encode(value)); validateIdentifier('channel', value.channelId); requireSafeInteger(value.targetSequence, 1); if (!containsNonWhitespace(value.reason))
|
|
248
|
+
throw new ProtocolError('invalid_reason', 'A channel report requires a reason.'); }
|
|
249
|
+
export const channelSubscriptionRequestCodec = defineCodec({ channelIds: { wire: 'channel_ids', codec: array(text) } });
|
|
250
|
+
export function validateChannelSubscriptionRequest(value) { validateCompleteObject(channelSubscriptionRequestCodec.encode(value)); const seen = new Set(); for (const id of value.channelIds) {
|
|
251
|
+
validateIdentifier('channel', id);
|
|
252
|
+
if (seen.has(id))
|
|
253
|
+
throw new ProtocolError('duplicate_channel', 'Subscription contains a duplicate channel.');
|
|
254
|
+
seen.add(id);
|
|
255
|
+
} }
|
|
256
|
+
export const channelTimelineChangedCodec = defineCodec({ channelId: { wire: 'channel_id', codec: text }, head: { wire: 'head', codec: integer } });
|
|
257
|
+
export function validateChannelTimelineChanged(value) { validateCompleteObject(channelTimelineChangedCodec.encode(value)); validateIdentifier('channel', value.channelId); requireSafeInteger(value.head, 0); }
|
|
258
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/models/channels.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type ExtensibleModel, type ValueCodec } from '../protocol/codec.js';
|
|
2
|
+
import { type NetworkContext } from '../protocol/context.js';
|
|
3
|
+
import { type AccountDeviceState, type DeviceCertificate } from './identity.js';
|
|
4
|
+
export interface ContactGrant extends ExtensibleModel {
|
|
5
|
+
readonly grantor: string;
|
|
6
|
+
readonly grantee: string;
|
|
7
|
+
readonly expiresAt?: number;
|
|
8
|
+
readonly signatures: Readonly<Record<string, Uint8Array>>;
|
|
9
|
+
}
|
|
10
|
+
export declare const contactGrantCodec: import("../protocol/codec.js").ProtocolCodec<ContactGrant>;
|
|
11
|
+
export declare const contactGrantInput: (value: ContactGrant, context: NetworkContext) => Uint8Array;
|
|
12
|
+
export declare function validateContactGrant(value: ContactGrant, now: number): void;
|
|
13
|
+
export declare function verifyContactGrant(value: ContactGrant, state: AccountDeviceState, context: NetworkContext, now: number): void;
|
|
14
|
+
/** Returns a copy containing only signatures whose device identity is currently authorized by the verified state. */
|
|
15
|
+
export declare function filterContactGrantSignatures(value: ContactGrant, state: AccountDeviceState, context: NetworkContext, now: number): ContactGrant;
|
|
16
|
+
export interface ContactGrantSelection {
|
|
17
|
+
readonly action: 'replace' | 'keep' | 'merge' | 'out_of_scope' | 'invalid';
|
|
18
|
+
readonly grant: ContactGrant | undefined;
|
|
19
|
+
readonly error?: unknown;
|
|
20
|
+
}
|
|
21
|
+
/** Saved grants are scoped to one network/account direction. Equal-expiry bodies never replace differing signed extensions. */
|
|
22
|
+
export declare function selectContactGrant(current: ContactGrant | undefined, candidate: ContactGrant, state: AccountDeviceState, context: NetworkContext, now: number, candidateContext?: NetworkContext): ContactGrantSelection;
|
|
23
|
+
export interface ContactInvite extends ExtensibleModel {
|
|
24
|
+
readonly inviter: string;
|
|
25
|
+
readonly expiresAt: number;
|
|
26
|
+
readonly signerDeviceId: string;
|
|
27
|
+
readonly deviceSignature: Uint8Array;
|
|
28
|
+
}
|
|
29
|
+
export declare const contactInviteCodec: import("../protocol/codec.js").ProtocolCodec<ContactInvite>;
|
|
30
|
+
export declare const contactInviteInput: (value: ContactInvite, context: NetworkContext) => Uint8Array;
|
|
31
|
+
export declare function validateContactInvite(value: ContactInvite, now: number): void;
|
|
32
|
+
export declare function verifyContactInvite(value: ContactInvite, state: AccountDeviceState, context: NetworkContext, now: number): void;
|
|
33
|
+
export type ContactAuthorization = ContactGrant | ContactInvite;
|
|
34
|
+
export declare const contactAuthorizationCodec: ValueCodec<ContactAuthorization>;
|
|
35
|
+
export interface SignedDeviceStateQuery extends ExtensibleModel {
|
|
36
|
+
readonly account: string;
|
|
37
|
+
readonly authorization: ContactAuthorization;
|
|
38
|
+
readonly signerCertificate: DeviceCertificate;
|
|
39
|
+
readonly createdAt: number;
|
|
40
|
+
readonly deviceSignature: Uint8Array;
|
|
41
|
+
}
|
|
42
|
+
export declare const signedDeviceStateQueryCodec: import("../protocol/codec.js").ProtocolCodec<SignedDeviceStateQuery>;
|
|
43
|
+
export declare const deviceStateQueryInput: (value: SignedDeviceStateQuery, context: NetworkContext) => Uint8Array;
|
|
44
|
+
export declare function validateDeviceStateQuery(value: SignedDeviceStateQuery, context: NetworkContext, now: number): void;
|
|
45
|
+
export interface ContactConsent extends ExtensibleModel {
|
|
46
|
+
readonly deviceState: AccountDeviceState;
|
|
47
|
+
readonly grant: ContactGrant;
|
|
48
|
+
readonly note?: string;
|
|
49
|
+
}
|
|
50
|
+
export declare const contactConsentCodec: import("../protocol/codec.js").ProtocolCodec<ContactConsent>;
|
|
51
|
+
export declare function validateContactConsent(value: ContactConsent, context: NetworkContext, now: number): void;
|
|
52
|
+
export interface ContactRecord extends ExtensibleModel {
|
|
53
|
+
readonly account: string;
|
|
54
|
+
readonly alias?: string;
|
|
55
|
+
readonly status: 'active' | 'deleted';
|
|
56
|
+
readonly grantFromContact?: ContactGrant;
|
|
57
|
+
readonly grantToContact?: ContactGrant;
|
|
58
|
+
readonly updatedAt: number;
|
|
59
|
+
}
|
|
60
|
+
export declare const contactRecordCodec: import("../protocol/codec.js").ProtocolCodec<ContactRecord>;
|
|
61
|
+
export declare function validateContactRecord(value: ContactRecord, now: number): void;
|
|
62
|
+
export interface AccountContactSync extends ExtensibleModel {
|
|
63
|
+
readonly records?: readonly ContactRecord[];
|
|
64
|
+
readonly requestSnapshot?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export declare const accountContactSyncCodec: import("../protocol/codec.js").ProtocolCodec<AccountContactSync>;
|
|
67
|
+
export declare function validateAccountContactSync(value: AccountContactSync, now: number, ownerAccount?: string): void;
|
|
68
|
+
//# sourceMappingURL=contacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contacts.d.ts","sourceRoot":"","sources":["../../src/models/contacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { requireLength, verifyDevice } from '../crypto/primitives.js';
|
|
2
|
+
import { ProtocolError } from '../errors.js';
|
|
3
|
+
import { validateIdentifier } from '../identity/identifiers.js';
|
|
4
|
+
import { validateAccountId } from '../identity/neo.js';
|
|
5
|
+
import { array, boolean, bytes, defineCodec, dictionary, enumeration, integer, text } from '../protocol/codec.js';
|
|
6
|
+
import { signingInput } from '../protocol/context.js';
|
|
7
|
+
import { encodeUtf8, equalBytes } from '../protocol/encoding.js';
|
|
8
|
+
import { requireObject, requireSafeInteger } from '../protocol/json.js';
|
|
9
|
+
import { validateCompleteObject } from '../protocol/validation.js';
|
|
10
|
+
import { containsNonWhitespace } from './content.js';
|
|
11
|
+
import { accountDeviceStateCodec, authorizedDevice, certificateId, deviceCertificateCodec, validateCertificate, validateDeviceState } from './identity.js';
|
|
12
|
+
export const contactGrantCodec = defineCodec({ grantor: { wire: 'grantor', codec: text }, grantee: { wire: 'grantee', codec: text },
|
|
13
|
+
expiresAt: { wire: 'expires_at', codec: integer, optional: true }, signatures: { wire: 'signatures', codec: dictionary(bytes) } }, 'meshline.contact.grant');
|
|
14
|
+
export const contactGrantInput = (value, context) => signingInput(contactGrantCodec.encode(value), context, ['signatures']);
|
|
15
|
+
export function validateContactGrant(value, now) {
|
|
16
|
+
validateCompleteObject(contactGrantCodec.encode(value));
|
|
17
|
+
validateAccountId(value.grantor);
|
|
18
|
+
validateAccountId(value.grantee);
|
|
19
|
+
requireSafeInteger(now, 0);
|
|
20
|
+
if (value.expiresAt !== undefined) {
|
|
21
|
+
requireSafeInteger(value.expiresAt, 0);
|
|
22
|
+
if (value.expiresAt <= now)
|
|
23
|
+
throw new ProtocolError('expired_grant', 'Contact grant has expired.');
|
|
24
|
+
}
|
|
25
|
+
const signatures = Object.entries(value.signatures);
|
|
26
|
+
if (!signatures.length)
|
|
27
|
+
throw new ProtocolError('invalid_grant', 'A contact grant requires at least one signature.');
|
|
28
|
+
for (const [id, signature] of signatures) {
|
|
29
|
+
validateIdentifier('device', id);
|
|
30
|
+
requireLength(signature, 64, 'Grant signature');
|
|
31
|
+
}
|
|
32
|
+
contactGrantCodec.encode(value);
|
|
33
|
+
}
|
|
34
|
+
export function verifyContactGrant(value, state, context, now) {
|
|
35
|
+
if (Object.keys(filterContactGrantSignatures(value, state, context, now).signatures).length === 0)
|
|
36
|
+
throw new ProtocolError('unauthorized_grant', 'Contact grant has no valid signature from a currently authorized device.');
|
|
37
|
+
}
|
|
38
|
+
/** Returns a copy containing only signatures whose device identity is currently authorized by the verified state. */
|
|
39
|
+
export function filterContactGrantSignatures(value, state, context, now) {
|
|
40
|
+
validateContactGrant(value, now);
|
|
41
|
+
validateDeviceState(state, context);
|
|
42
|
+
if (value.grantor !== state.account)
|
|
43
|
+
throw new ProtocolError('invalid_identity', 'Contact grant state belongs to another grantor.');
|
|
44
|
+
const input = contactGrantInput(value, context);
|
|
45
|
+
const signatures = Object.create(null);
|
|
46
|
+
for (const certificate of state.certificates) {
|
|
47
|
+
const id = certificateId(certificate, context);
|
|
48
|
+
const signature = value.signatures[id];
|
|
49
|
+
if (certificate.notBefore <= now && now < certificate.expiresAt && signature !== undefined && verifyDevice(input, signature, certificate.signingPublicKey))
|
|
50
|
+
signatures[id] = signature.slice();
|
|
51
|
+
}
|
|
52
|
+
return contactGrantCodec.decode(contactGrantCodec.encode({ ...value, signatures }));
|
|
53
|
+
}
|
|
54
|
+
/** Saved grants are scoped to one network/account direction. Equal-expiry bodies never replace differing signed extensions. */
|
|
55
|
+
export function selectContactGrant(current, candidate, state, context, now, candidateContext = context) {
|
|
56
|
+
const previous = current && contactGrantCodec.decode(contactGrantCodec.encode(current));
|
|
57
|
+
if (candidateContext.toString() !== context.toString() || previous && (candidate.grantor !== previous.grantor || candidate.grantee !== previous.grantee))
|
|
58
|
+
return { action: 'out_of_scope', grant: previous };
|
|
59
|
+
let incoming;
|
|
60
|
+
try {
|
|
61
|
+
incoming = filterContactGrantSignatures(candidate, state, context, now);
|
|
62
|
+
if (Object.keys(incoming.signatures).length === 0)
|
|
63
|
+
throw new ProtocolError('unauthorized_grant', 'Candidate has no currently authorized signature.');
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (!(error instanceof ProtocolError))
|
|
67
|
+
throw error;
|
|
68
|
+
return { action: 'invalid', grant: previous, error };
|
|
69
|
+
}
|
|
70
|
+
if (!previous)
|
|
71
|
+
return { action: 'replace', grant: incoming };
|
|
72
|
+
if (!equalBytes(contactGrantInput(previous, context), contactGrantInput(incoming, context)))
|
|
73
|
+
return (incoming.expiresAt ?? Infinity) > (previous.expiresAt ?? Infinity) ? { action: 'replace', grant: incoming } : { action: 'keep', grant: previous };
|
|
74
|
+
const saved = filterContactGrantSignatures(previous, state, context, now);
|
|
75
|
+
return { action: 'merge', grant: { ...incoming, signatures: { ...incoming.signatures, ...saved.signatures } } };
|
|
76
|
+
}
|
|
77
|
+
export const contactInviteCodec = defineCodec({ inviter: { wire: 'inviter', codec: text }, expiresAt: { wire: 'expires_at', codec: integer },
|
|
78
|
+
signerDeviceId: { wire: 'signer_device_id', codec: text }, deviceSignature: { wire: 'device_signature', codec: bytes } }, 'meshline.contact.invite');
|
|
79
|
+
export const contactInviteInput = (value, context) => signingInput(contactInviteCodec.encode(value), context, ['device_signature']);
|
|
80
|
+
export function validateContactInvite(value, now) {
|
|
81
|
+
validateCompleteObject(contactInviteCodec.encode(value));
|
|
82
|
+
validateAccountId(value.inviter);
|
|
83
|
+
requireSafeInteger(now, 0);
|
|
84
|
+
requireSafeInteger(value.expiresAt, 0);
|
|
85
|
+
validateIdentifier('device', value.signerDeviceId);
|
|
86
|
+
requireLength(value.deviceSignature, 64, 'Invitation signature');
|
|
87
|
+
if (value.expiresAt <= now)
|
|
88
|
+
throw new ProtocolError('expired_invite', 'Contact invitation has expired.');
|
|
89
|
+
contactInviteCodec.encode(value);
|
|
90
|
+
}
|
|
91
|
+
export function verifyContactInvite(value, state, context, now) {
|
|
92
|
+
validateContactInvite(value, now);
|
|
93
|
+
validateDeviceState(state, context);
|
|
94
|
+
if (value.inviter !== state.account)
|
|
95
|
+
throw new ProtocolError('invalid_identity', 'Invitation belongs to another account.');
|
|
96
|
+
const certificate = authorizedDevice(state, value.signerDeviceId, context, now);
|
|
97
|
+
if (!verifyDevice(contactInviteInput(value, context), value.deviceSignature, certificate.signingPublicKey))
|
|
98
|
+
throw new ProtocolError('invalid_signature', 'Invalid contact invitation signature.');
|
|
99
|
+
}
|
|
100
|
+
export const contactAuthorizationCodec = {
|
|
101
|
+
decode(value) {
|
|
102
|
+
const type = requireObject(value)['$type'];
|
|
103
|
+
if (type === 'meshline.contact.grant')
|
|
104
|
+
return contactGrantCodec.decode(value);
|
|
105
|
+
if (type === 'meshline.contact.invite')
|
|
106
|
+
return contactInviteCodec.decode(value);
|
|
107
|
+
throw new ProtocolError('invalid_type', 'Expected a contact grant or invitation.');
|
|
108
|
+
},
|
|
109
|
+
encode(value) { return 'grantor' in value ? contactGrantCodec.encode(value) : contactInviteCodec.encode(value); },
|
|
110
|
+
};
|
|
111
|
+
export const signedDeviceStateQueryCodec = defineCodec({ account: { wire: 'account', codec: text }, authorization: { wire: 'authorization', codec: contactAuthorizationCodec },
|
|
112
|
+
signerCertificate: { wire: 'signer_certificate', codec: deviceCertificateCodec }, createdAt: { wire: 'created_at', codec: integer }, deviceSignature: { wire: 'device_signature', codec: bytes } }, 'meshline.device.state.resolve');
|
|
113
|
+
export const deviceStateQueryInput = (value, context) => signingInput(signedDeviceStateQueryCodec.encode(value), context, ['device_signature']);
|
|
114
|
+
export function validateDeviceStateQuery(value, context, now) {
|
|
115
|
+
validateCompleteObject(signedDeviceStateQueryCodec.encode(value));
|
|
116
|
+
validateAccountId(value.account);
|
|
117
|
+
validateCertificate(value.signerCertificate, context);
|
|
118
|
+
requireSafeInteger(value.createdAt, 0);
|
|
119
|
+
if (value.account === value.signerCertificate.account)
|
|
120
|
+
throw new ProtocolError('invalid_authorization', 'Signed device queries cannot target the caller account.');
|
|
121
|
+
if ('grantor' in value.authorization) {
|
|
122
|
+
validateContactGrant(value.authorization, now);
|
|
123
|
+
if (value.authorization.grantor !== value.account || value.authorization.grantee !== value.signerCertificate.account)
|
|
124
|
+
throw new ProtocolError('invalid_authorization', 'Contact grant does not authorize this query.');
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
validateContactInvite(value.authorization, now);
|
|
128
|
+
if (value.authorization.inviter !== value.account)
|
|
129
|
+
throw new ProtocolError('invalid_authorization', 'Invitation is for another account.');
|
|
130
|
+
}
|
|
131
|
+
if (!verifyDevice(deviceStateQueryInput(value, context), value.deviceSignature, value.signerCertificate.signingPublicKey))
|
|
132
|
+
throw new ProtocolError('invalid_signature', 'Invalid signed device query.');
|
|
133
|
+
}
|
|
134
|
+
export const contactConsentCodec = defineCodec({ deviceState: { wire: 'device_state', codec: accountDeviceStateCodec }, grant: { wire: 'grant', codec: contactGrantCodec }, note: { wire: 'note', codec: text, optional: true } }, 'meshline.contact.consent');
|
|
135
|
+
export function validateContactConsent(value, context, now) {
|
|
136
|
+
validateCompleteObject(contactConsentCodec.encode(value));
|
|
137
|
+
if (value.note !== undefined && (!containsNonWhitespace(value.note) || encodeUtf8(value.note).length > 1024))
|
|
138
|
+
throw new ProtocolError('invalid_note', 'Consent note must contain non-whitespace text and fit 1024 UTF-8 bytes.');
|
|
139
|
+
verifyContactGrant(value.grant, value.deviceState, context, now);
|
|
140
|
+
contactConsentCodec.encode(value);
|
|
141
|
+
}
|
|
142
|
+
export const contactRecordCodec = defineCodec({ account: { wire: 'account', codec: text }, alias: { wire: 'alias', codec: text, optional: true }, status: { wire: 'status', codec: enumeration('active', 'deleted') },
|
|
143
|
+
grantFromContact: { wire: 'grant_from_contact', codec: contactGrantCodec, optional: true }, grantToContact: { wire: 'grant_to_contact', codec: contactGrantCodec, optional: true }, updatedAt: { wire: 'updated_at', codec: integer } });
|
|
144
|
+
export function validateContactRecord(value, now) {
|
|
145
|
+
validateCompleteObject(contactRecordCodec.encode(value));
|
|
146
|
+
validateAccountId(value.account);
|
|
147
|
+
requireSafeInteger(value.updatedAt, 0);
|
|
148
|
+
requireSafeInteger(now, 0);
|
|
149
|
+
if (value.updatedAt > now + 300)
|
|
150
|
+
throw new ProtocolError('invalid_time', 'Contact update is more than five minutes in the future.');
|
|
151
|
+
if (value.alias !== undefined && value.alias !== '' && (!containsNonWhitespace(value.alias) || encodeUtf8(value.alias).length > 256))
|
|
152
|
+
throw new ProtocolError('invalid_alias', 'Nonempty contact alias must contain non-whitespace text and fit 256 UTF-8 bytes.');
|
|
153
|
+
if (value.status === 'deleted' && (value.grantFromContact || value.grantToContact))
|
|
154
|
+
throw new ProtocolError('invalid_contact', 'Deleted contact records cannot contain grants.');
|
|
155
|
+
contactRecordCodec.encode(value);
|
|
156
|
+
}
|
|
157
|
+
export const accountContactSyncCodec = defineCodec({ records: { wire: 'records', codec: array(contactRecordCodec), optional: true }, requestSnapshot: { wire: 'request_snapshot', codec: boolean, optional: true } }, 'meshline.account.contacts.sync');
|
|
158
|
+
export function validateAccountContactSync(value, now, ownerAccount) {
|
|
159
|
+
validateCompleteObject(accountContactSyncCodec.encode(value));
|
|
160
|
+
const accounts = new Set();
|
|
161
|
+
let owner = ownerAccount;
|
|
162
|
+
for (const record of value.records ?? []) {
|
|
163
|
+
validateContactRecord(record, now);
|
|
164
|
+
if (accounts.has(record.account))
|
|
165
|
+
throw new ProtocolError('duplicate_contact', 'A contact sync batch cannot contain duplicate accounts.');
|
|
166
|
+
accounts.add(record.account);
|
|
167
|
+
if (record.grantFromContact) {
|
|
168
|
+
const grant = record.grantFromContact;
|
|
169
|
+
validateContactGrant(grant, now);
|
|
170
|
+
if (grant.grantor !== record.account || owner !== undefined && grant.grantee !== owner)
|
|
171
|
+
throw new ProtocolError('invalid_identity', 'Incoming contact grant has inconsistent accounts.');
|
|
172
|
+
owner = grant.grantee;
|
|
173
|
+
}
|
|
174
|
+
if (record.grantToContact) {
|
|
175
|
+
const grant = record.grantToContact;
|
|
176
|
+
validateContactGrant(grant, now);
|
|
177
|
+
if (grant.grantee !== record.account || owner !== undefined && grant.grantor !== owner)
|
|
178
|
+
throw new ProtocolError('invalid_identity', 'Outgoing contact grant has inconsistent accounts.');
|
|
179
|
+
owner = grant.grantor;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (owner !== undefined && accounts.has(owner))
|
|
183
|
+
throw new ProtocolError('invalid_identity', 'A contact sync batch cannot contain its owner.');
|
|
184
|
+
accountContactSyncCodec.encode(value);
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=contacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contacts.js","sourceRoot":"","sources":["../../src/models/contacts.ts"],"names":[],"mappings":"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"}
|