@awiki/dsh-plugin 0.3.11 → 0.3.16
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/README.md +24 -2
- package/README.zh.md +12 -2
- package/cordis.patch.yml +1 -0
- package/lib/client.js +1119 -176
- package/lib/client.js.map +1 -1
- package/lib/index.js +362 -79
- package/lib/provider.js +3 -2
- package/lib/{sdk-adapter-DpqT2en9.mjs → sdk-adapter-DGcTiEZz.mjs} +110 -9
- package/lib/typert.host.js +359 -68
- package/lib/typert.remote-client.d.ts +9 -1
- package/lib/typert.remote-client.d.ts.map +1 -1
- package/lib/typert.remote-client.js +359 -68
- package/lib/types/client/AwikiDeviceJoinReminder.d.ts.map +1 -1
- package/lib/types/client/AwikiDeviceJoinReminder.js +1 -1
- package/lib/types/client/AwikiDeviceJoinReminder.js.map +1 -1
- package/lib/types/client/AwikiDevices.d.ts +5 -1
- package/lib/types/client/AwikiDevices.d.ts.map +1 -1
- package/lib/types/client/AwikiDevices.js +2 -1
- package/lib/types/client/AwikiDevices.js.map +1 -1
- package/lib/types/client/AwikiIdentityAccess.d.ts.map +1 -1
- package/lib/types/client/AwikiIdentityAccess.js +72 -24
- package/lib/types/client/AwikiIdentityAccess.js.map +1 -1
- package/lib/types/client/AwikiIdentityServices.d.ts +9 -0
- package/lib/types/client/AwikiIdentityServices.d.ts.map +1 -0
- package/lib/types/client/AwikiIdentityServices.js +66 -0
- package/lib/types/client/AwikiIdentityServices.js.map +1 -0
- package/lib/types/client/AwikiOverlay.js +1 -1
- package/lib/types/client/AwikiOverlay.js.map +1 -1
- package/lib/types/client/AwikiSettingsSection.js +1 -1
- package/lib/types/client/AwikiSettingsSection.js.map +1 -1
- package/lib/types/client/AwikiUpdates.d.ts.map +1 -1
- package/lib/types/client/AwikiUpdates.js +21 -10
- package/lib/types/client/AwikiUpdates.js.map +1 -1
- package/lib/types/client/controller.d.ts +8 -0
- package/lib/types/client/controller.d.ts.map +1 -1
- package/lib/types/client/controller.js +21 -3
- package/lib/types/client/controller.js.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +8 -0
- package/lib/types/client/index.js.map +1 -1
- package/lib/types/client/settings-controller.d.ts +1 -0
- package/lib/types/client/settings-controller.d.ts.map +1 -1
- package/lib/types/client/settings-controller.js +24 -10
- package/lib/types/client/settings-controller.js.map +1 -1
- package/lib/types/client/settings-locales.d.ts +1 -1
- package/lib/types/client/settings-locales.d.ts.map +1 -1
- package/lib/types/client/settings-locales.js +10 -4
- package/lib/types/client/settings-locales.js.map +1 -1
- package/lib/types/client/slots.d.ts +3 -1
- package/lib/types/client/slots.d.ts.map +1 -1
- package/lib/types/desktop-distribution.d.ts +7 -3
- package/lib/types/desktop-distribution.d.ts.map +1 -1
- package/lib/types/desktop-distribution.js +27 -8
- package/lib/types/desktop-distribution.js.map +1 -1
- package/lib/types/index.d.ts +8 -2
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +154 -47
- package/lib/types/index.js.map +1 -1
- package/lib/types/listener.js +1 -1
- package/lib/types/listener.js.map +1 -1
- package/lib/types/message-target.d.ts +4 -0
- package/lib/types/message-target.d.ts.map +1 -0
- package/lib/types/message-target.js +14 -0
- package/lib/types/message-target.js.map +1 -0
- package/lib/types/package-version.generated.d.ts +2 -2
- package/lib/types/package-version.generated.d.ts.map +1 -1
- package/lib/types/package-version.generated.js +2 -2
- package/lib/types/package-version.generated.js.map +1 -1
- package/lib/types/provider-api.d.ts +17 -1
- package/lib/types/provider-api.d.ts.map +1 -1
- package/lib/types/provider.d.ts.map +1 -1
- package/lib/types/provider.js +2 -1
- package/lib/types/provider.js.map +1 -1
- package/lib/types/registration-policy.d.ts +1 -1
- package/lib/types/registration-policy.d.ts.map +1 -1
- package/lib/types/registration-policy.js +1 -1
- package/lib/types/registration-policy.js.map +1 -1
- package/lib/types/sdk-adapter.d.ts +17 -1
- package/lib/types/sdk-adapter.d.ts.map +1 -1
- package/lib/types/sdk-adapter.js +90 -5
- package/lib/types/sdk-adapter.js.map +1 -1
- package/lib/types/settings-rpc-contract.d.ts +1 -0
- package/lib/types/settings-rpc-contract.d.ts.map +1 -1
- package/lib/types/settings-rpc-contract.js +2 -0
- package/lib/types/settings-rpc-contract.js.map +1 -1
- package/lib/types/types.d.ts +68 -2
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/types.js.map +1 -1
- package/lib/types/update-installation.d.ts +18 -0
- package/lib/types/update-installation.d.ts.map +1 -0
- package/lib/types/update-installation.js +101 -0
- package/lib/types/update-installation.js.map +1 -0
- package/lib/types/update-policy.d.ts +5 -2
- package/lib/types/update-policy.d.ts.map +1 -1
- package/lib/types/update-policy.js +14 -8
- package/lib/types/update-policy.js.map +1 -1
- package/package.json +7 -6
package/lib/types/index.js
CHANGED
|
@@ -35,6 +35,7 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
35
35
|
export { registerAwikiLoopbackRpc } from "./settings-transport.js";
|
|
36
36
|
import { registerAwikiSettingsTransport } from "./settings-transport.js";
|
|
37
37
|
import { registrationHandleLocalPart } from "./registration-policy.js";
|
|
38
|
+
import { isMessageTarget } from "./message-target.js";
|
|
38
39
|
import { decodeDesktopDistribution } from "./desktop-distribution.js";
|
|
39
40
|
/** Unified AWiki identity, messaging, attachment, Remote, and model-tool service. */
|
|
40
41
|
import { Context } from '@deepseek-ai/cordis';
|
|
@@ -99,6 +100,7 @@ export const Config = z.object({
|
|
|
99
100
|
messageServiceDid: z.string().default(DEFAULT_AWIKI_MESSAGE_SERVICE_DID),
|
|
100
101
|
allowedAttachmentOrigins: z.array(z.string()).default([]),
|
|
101
102
|
allowInsecureLoopbackForTesting: z.boolean().default(false),
|
|
103
|
+
caBundle: z.string(),
|
|
102
104
|
stateRoot: z.string(),
|
|
103
105
|
attachmentMaxBytes: z.number().default(DEFAULT_ATTACHMENT_MAX_BYTES),
|
|
104
106
|
mailAttachmentMaxCount: z.number().default(MAIL_ATTACHMENT_SERVICE_MAX_COUNT),
|
|
@@ -407,6 +409,7 @@ function resolveConfig(ctx, config) {
|
|
|
407
409
|
messageServiceDid: serviceDid(config.messageServiceDid ?? DEFAULT_AWIKI_MESSAGE_SERVICE_DID),
|
|
408
410
|
allowedAttachmentOrigins: attachmentOrigins(config.allowedAttachmentOrigins, messageServicePublicUrl, allowInsecureLoopbackForTesting),
|
|
409
411
|
allowInsecureLoopbackForTesting,
|
|
412
|
+
...(config.caBundle === undefined ? {} : { caBundle: config.caBundle }),
|
|
410
413
|
stateRoot,
|
|
411
414
|
attachmentMaxBytes,
|
|
412
415
|
mailAttachmentMaxCount,
|
|
@@ -615,7 +618,7 @@ function identityAccessTarget(request, configuredDomain) {
|
|
|
615
618
|
}
|
|
616
619
|
function normalizeSendTextRequest(request) {
|
|
617
620
|
if (typeof request?.text !== 'string' || typeof request.idempotencyKey !== 'string'
|
|
618
|
-
||
|
|
621
|
+
|| !isMessageTarget(request.target))
|
|
619
622
|
return undefined;
|
|
620
623
|
const text = request.text;
|
|
621
624
|
const codePoints = Array.from(text);
|
|
@@ -623,15 +626,9 @@ function normalizeSendTextRequest(request) {
|
|
|
623
626
|
|| request.idempotencyKey.length === 0 || request.idempotencyKey.length > 512)
|
|
624
627
|
return undefined;
|
|
625
628
|
if (request.target.kind === 'direct') {
|
|
626
|
-
if (
|
|
629
|
+
if (request.mentions !== undefined)
|
|
627
630
|
return undefined;
|
|
628
631
|
}
|
|
629
|
-
else if (request.target.kind === 'group') {
|
|
630
|
-
if (typeof request.target.group !== 'string')
|
|
631
|
-
return undefined;
|
|
632
|
-
}
|
|
633
|
-
else
|
|
634
|
-
return undefined;
|
|
635
632
|
if (request.mentions === undefined)
|
|
636
633
|
return request;
|
|
637
634
|
if (!Array.isArray(request.mentions) || request.mentions.length === 0 || request.mentions.length > 100)
|
|
@@ -800,8 +797,12 @@ let AwikiService = (() => {
|
|
|
800
797
|
let _getDeviceJoinStatus_decorators;
|
|
801
798
|
let _cancelDeviceJoin_decorators;
|
|
802
799
|
let _refreshDeviceManagement_decorators;
|
|
800
|
+
let _getIdentityServices_decorators;
|
|
801
|
+
let _updateIdentityServices_decorators;
|
|
802
|
+
let _resumeIdentityServicesUpdate_decorators;
|
|
803
803
|
let _startDeviceJoinVerification_decorators;
|
|
804
804
|
let _approveDeviceJoin_decorators;
|
|
805
|
+
let _retryDeviceManagement_decorators;
|
|
805
806
|
let _rejectDeviceJoin_decorators;
|
|
806
807
|
let _revokeDevice_decorators;
|
|
807
808
|
let _prepareRootTransfer_decorators;
|
|
@@ -865,8 +866,12 @@ let AwikiService = (() => {
|
|
|
865
866
|
_getDeviceJoinStatus_decorators = [Remote];
|
|
866
867
|
_cancelDeviceJoin_decorators = [Remote];
|
|
867
868
|
_refreshDeviceManagement_decorators = [Remote];
|
|
869
|
+
_getIdentityServices_decorators = [Remote];
|
|
870
|
+
_updateIdentityServices_decorators = [Remote];
|
|
871
|
+
_resumeIdentityServicesUpdate_decorators = [Remote];
|
|
868
872
|
_startDeviceJoinVerification_decorators = [Remote];
|
|
869
873
|
_approveDeviceJoin_decorators = [Remote];
|
|
874
|
+
_retryDeviceManagement_decorators = [Remote];
|
|
870
875
|
_rejectDeviceJoin_decorators = [Remote];
|
|
871
876
|
_revokeDevice_decorators = [Remote];
|
|
872
877
|
_prepareRootTransfer_decorators = [Remote];
|
|
@@ -927,8 +932,12 @@ let AwikiService = (() => {
|
|
|
927
932
|
__esDecorate(this, null, _getDeviceJoinStatus_decorators, { kind: "method", name: "getDeviceJoinStatus", static: false, private: false, access: { has: obj => "getDeviceJoinStatus" in obj, get: obj => obj.getDeviceJoinStatus }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
928
933
|
__esDecorate(this, null, _cancelDeviceJoin_decorators, { kind: "method", name: "cancelDeviceJoin", static: false, private: false, access: { has: obj => "cancelDeviceJoin" in obj, get: obj => obj.cancelDeviceJoin }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
929
934
|
__esDecorate(this, null, _refreshDeviceManagement_decorators, { kind: "method", name: "refreshDeviceManagement", static: false, private: false, access: { has: obj => "refreshDeviceManagement" in obj, get: obj => obj.refreshDeviceManagement }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
935
|
+
__esDecorate(this, null, _getIdentityServices_decorators, { kind: "method", name: "getIdentityServices", static: false, private: false, access: { has: obj => "getIdentityServices" in obj, get: obj => obj.getIdentityServices }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
936
|
+
__esDecorate(this, null, _updateIdentityServices_decorators, { kind: "method", name: "updateIdentityServices", static: false, private: false, access: { has: obj => "updateIdentityServices" in obj, get: obj => obj.updateIdentityServices }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
937
|
+
__esDecorate(this, null, _resumeIdentityServicesUpdate_decorators, { kind: "method", name: "resumeIdentityServicesUpdate", static: false, private: false, access: { has: obj => "resumeIdentityServicesUpdate" in obj, get: obj => obj.resumeIdentityServicesUpdate }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
930
938
|
__esDecorate(this, null, _startDeviceJoinVerification_decorators, { kind: "method", name: "startDeviceJoinVerification", static: false, private: false, access: { has: obj => "startDeviceJoinVerification" in obj, get: obj => obj.startDeviceJoinVerification }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
931
939
|
__esDecorate(this, null, _approveDeviceJoin_decorators, { kind: "method", name: "approveDeviceJoin", static: false, private: false, access: { has: obj => "approveDeviceJoin" in obj, get: obj => obj.approveDeviceJoin }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
940
|
+
__esDecorate(this, null, _retryDeviceManagement_decorators, { kind: "method", name: "retryDeviceManagement", static: false, private: false, access: { has: obj => "retryDeviceManagement" in obj, get: obj => obj.retryDeviceManagement }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
932
941
|
__esDecorate(this, null, _rejectDeviceJoin_decorators, { kind: "method", name: "rejectDeviceJoin", static: false, private: false, access: { has: obj => "rejectDeviceJoin" in obj, get: obj => obj.rejectDeviceJoin }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
933
942
|
__esDecorate(this, null, _revokeDevice_decorators, { kind: "method", name: "revokeDevice", static: false, private: false, access: { has: obj => "revokeDevice" in obj, get: obj => obj.revokeDevice }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
934
943
|
__esDecorate(this, null, _prepareRootTransfer_decorators, { kind: "method", name: "prepareRootTransfer", static: false, private: false, access: { has: obj => "prepareRootTransfer" in obj, get: obj => obj.prepareRootTransfer }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -1163,6 +1172,7 @@ let AwikiService = (() => {
|
|
|
1163
1172
|
: [messageServicePublicOrigin],
|
|
1164
1173
|
attachmentMaxBytes: this.resolved.attachmentMaxBytes,
|
|
1165
1174
|
allowInsecureLoopbackForTesting: this.resolved.allowInsecureLoopbackForTesting,
|
|
1175
|
+
...(this.resolved.caBundle === undefined ? {} : { caBundle: this.resolved.caBundle }),
|
|
1166
1176
|
stateRoot: this.ensureTenantRegistry().stateRoot(tenant),
|
|
1167
1177
|
};
|
|
1168
1178
|
}
|
|
@@ -1215,7 +1225,8 @@ let AwikiService = (() => {
|
|
|
1215
1225
|
}
|
|
1216
1226
|
/** Read the Host-owned catalog for trusted loopback settings surfaces. */
|
|
1217
1227
|
getTenantRegistryView() {
|
|
1218
|
-
|
|
1228
|
+
// The public generation fences runtime requests; the catalog keeps its own durable revision.
|
|
1229
|
+
return { ...this.ensureTenantRegistry().snapshot(this.tenantSwitching), generation: this.runtimeGeneration };
|
|
1219
1230
|
}
|
|
1220
1231
|
/** Browser-safe, same-process update state for Desktop and loopback settings. */
|
|
1221
1232
|
getUpdatePolicyStatus() {
|
|
@@ -1227,16 +1238,25 @@ let AwikiService = (() => {
|
|
|
1227
1238
|
...modelProxyVersion === undefined ? {} : { currentModelProxyVersion: modelProxyVersion },
|
|
1228
1239
|
});
|
|
1229
1240
|
}
|
|
1230
|
-
/**
|
|
1241
|
+
/** Project only the active tenant's Desktop state; retain legacy detection without its fixed source. */
|
|
1231
1242
|
getDesktopUpdate() {
|
|
1232
|
-
|
|
1243
|
+
const view = decodeDesktopDistribution(this.desktopDistribution?.getSnapshot());
|
|
1244
|
+
if (view === undefined || view.schemaVersion === 1)
|
|
1245
|
+
return view;
|
|
1246
|
+
const tenant = this.activeTenant ?? this.ensureTenantRegistry().active();
|
|
1247
|
+
if (this.tenantSwitching || view.tenantId !== tenant.tenantId
|
|
1248
|
+
|| view.policyOrigin !== new URL(tenant.backendBaseUrl).origin || view.tenantGeneration !== this.runtimeGeneration) {
|
|
1249
|
+
return { schemaVersion: 2, distributionId: 'awiki-dsh-desktop', currentVersion: view.currentVersion,
|
|
1250
|
+
channel: view.channel, state: 'unavailable', updateAvailable: false, usedCache: false };
|
|
1251
|
+
}
|
|
1252
|
+
return view;
|
|
1233
1253
|
}
|
|
1234
1254
|
async refreshDesktopUpdate() {
|
|
1235
1255
|
const provider = this.desktopDistribution;
|
|
1236
1256
|
if (provider === undefined)
|
|
1237
1257
|
return undefined;
|
|
1238
|
-
|
|
1239
|
-
return
|
|
1258
|
+
await provider.check();
|
|
1259
|
+
return this.getDesktopUpdate();
|
|
1240
1260
|
}
|
|
1241
1261
|
/** Refresh only the active generation; late results from old tenants are discarded. */
|
|
1242
1262
|
refreshUpdatePolicy() {
|
|
@@ -1705,49 +1725,58 @@ let AwikiService = (() => {
|
|
|
1705
1725
|
const target = identityAccessTarget(request, options.userServiceDomain);
|
|
1706
1726
|
if (target === undefined)
|
|
1707
1727
|
return { ok: false, error: failure('invalid-request') };
|
|
1708
|
-
|
|
1728
|
+
if ((request.inviteCode !== undefined && (typeof request.inviteCode !== 'string' || request.inviteCode.length > 512))
|
|
1729
|
+
|| (request.phone !== undefined && (typeof request.phone !== 'string' || request.phone.length > 64))) {
|
|
1730
|
+
return { ok: false, error: failure('invalid-request') };
|
|
1731
|
+
}
|
|
1732
|
+
const endpoint = new URL('/user-service/v1/handle/rpc', options.userServiceUrl);
|
|
1709
1733
|
const abort = new AbortController();
|
|
1710
1734
|
const timeout = setTimeout(() => { abort.abort(); }, 10_000);
|
|
1711
|
-
let response;
|
|
1712
1735
|
try {
|
|
1713
|
-
response = await fetch(endpoint, {
|
|
1714
|
-
method: '
|
|
1715
|
-
headers: { accept: 'application/json', 'cache-control': 'no-store' },
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1736
|
+
const response = await fetch(endpoint, {
|
|
1737
|
+
method: 'POST',
|
|
1738
|
+
headers: { accept: 'application/json', 'content-type': 'application/json', 'cache-control': 'no-store' },
|
|
1739
|
+
body: JSON.stringify({ jsonrpc: '2.0', id: 'registration-check', method: 'registration_check', params: {
|
|
1740
|
+
handle: target.localPart, domain: options.userServiceDomain,
|
|
1741
|
+
check_invite: request.inviteCode !== undefined,
|
|
1742
|
+
...(request.inviteCode === undefined ? {} : { invite_code: request.inviteCode }),
|
|
1743
|
+
...(request.phone === undefined ? {} : { phone: request.phone }),
|
|
1744
|
+
} }),
|
|
1745
|
+
cache: 'no-store', redirect: 'error', signal: abort.signal,
|
|
1719
1746
|
});
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
return { ok: false, error: failure('network') };
|
|
1723
|
-
}
|
|
1724
|
-
finally {
|
|
1725
|
-
clearTimeout(timeout);
|
|
1726
|
-
}
|
|
1727
|
-
if (response.status === 404) {
|
|
1728
|
-
return { ok: true, value: { status: 'available', fullHandle: target.fullHandle } };
|
|
1729
|
-
}
|
|
1730
|
-
if (!response.ok && response.status !== 410)
|
|
1731
|
-
return { ok: false, error: failure('remote') };
|
|
1732
|
-
try {
|
|
1747
|
+
if (!response.ok)
|
|
1748
|
+
return { ok: false, error: failure('remote') };
|
|
1733
1749
|
const text = await readBoundedResponseText(response, IDENTITY_ACCESS_RESPONSE_MAX_BYTES);
|
|
1734
1750
|
if (text === undefined)
|
|
1735
1751
|
return { ok: false, error: failure('remote') };
|
|
1736
|
-
|
|
1737
|
-
|
|
1752
|
+
let envelope;
|
|
1753
|
+
try {
|
|
1754
|
+
envelope = JSON.parse(text);
|
|
1755
|
+
}
|
|
1756
|
+
catch {
|
|
1738
1757
|
return { ok: false, error: failure('remote') };
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
||
|
|
1743
|
-
||
|
|
1744
|
-
||
|
|
1758
|
+
}
|
|
1759
|
+
const value = envelope?.result;
|
|
1760
|
+
if (envelope?.jsonrpc !== '2.0' || envelope.id !== 'registration-check' || (envelope.error !== undefined && envelope.error !== null)
|
|
1761
|
+
|| value?.full_handle !== target.fullHandle
|
|
1762
|
+
|| !['register', 'existing', 'unavailable'].includes(value.decision)
|
|
1763
|
+
|| typeof value.invite_required !== 'boolean'
|
|
1764
|
+
|| !['not_required', 'required', 'valid', 'invalid'].includes(value.invite_status)
|
|
1765
|
+
|| (value.decision === 'existing' && value.invite_required)
|
|
1766
|
+
|| (!value.invite_required && value.invite_status !== 'not_required')
|
|
1767
|
+
|| (value.invite_required && value.invite_status === 'not_required')) {
|
|
1745
1768
|
return { ok: false, error: failure('remote') };
|
|
1746
1769
|
}
|
|
1747
|
-
return { ok: true, value: {
|
|
1770
|
+
return { ok: true, value: {
|
|
1771
|
+
status: value.decision === 'register' ? 'available' : value.decision,
|
|
1772
|
+
fullHandle: target.fullHandle, inviteRequired: value.invite_required, inviteStatus: value.invite_status,
|
|
1773
|
+
} };
|
|
1748
1774
|
}
|
|
1749
1775
|
catch {
|
|
1750
|
-
return { ok: false, error: failure('
|
|
1776
|
+
return { ok: false, error: failure('network') };
|
|
1777
|
+
}
|
|
1778
|
+
finally {
|
|
1779
|
+
clearTimeout(timeout);
|
|
1751
1780
|
}
|
|
1752
1781
|
}
|
|
1753
1782
|
async sendRegistrationOtp(request) {
|
|
@@ -1783,6 +1812,7 @@ let AwikiService = (() => {
|
|
|
1783
1812
|
fullHandle: result.value.fullHandle,
|
|
1784
1813
|
mode: result.value.mode,
|
|
1785
1814
|
requiresUserPresence: result.value.requiresUserPresence,
|
|
1815
|
+
...result.value.methodCapabilities === undefined ? {} : { methodCapabilities: result.value.methodCapabilities },
|
|
1786
1816
|
};
|
|
1787
1817
|
return {
|
|
1788
1818
|
ok: true,
|
|
@@ -1791,6 +1821,7 @@ let AwikiService = (() => {
|
|
|
1791
1821
|
fullHandle: result.value.fullHandle,
|
|
1792
1822
|
mode: result.value.mode,
|
|
1793
1823
|
requiresUserPresence: result.value.requiresUserPresence,
|
|
1824
|
+
...result.value.methodCapabilities === undefined ? {} : { methodCapabilities: result.value.methodCapabilities },
|
|
1794
1825
|
},
|
|
1795
1826
|
};
|
|
1796
1827
|
}
|
|
@@ -1863,6 +1894,10 @@ let AwikiService = (() => {
|
|
|
1863
1894
|
return this.run(async (client) => {
|
|
1864
1895
|
const joining = await this.selectDeviceJoinSession(client) !== null;
|
|
1865
1896
|
const recoveries = await client.listPendingRecoveries();
|
|
1897
|
+
const pendingRegistrations = await client.pendingIdentityRegistrations();
|
|
1898
|
+
const creationMethods = await client.identityCreationMethods().catch(() => []);
|
|
1899
|
+
const identity = await client.getIdentity();
|
|
1900
|
+
const capabilities = identity === null ? undefined : await client.identityMethodCapabilities(identity.did);
|
|
1866
1901
|
const domain = this.activeClientOptions?.userServiceDomain;
|
|
1867
1902
|
const choice = this.pendingDeviceJoin;
|
|
1868
1903
|
return {
|
|
@@ -1870,8 +1905,12 @@ let AwikiService = (() => {
|
|
|
1870
1905
|
status: 'join-required',
|
|
1871
1906
|
fullHandle: choice.fullHandle,
|
|
1872
1907
|
mode: choice.mode, requiresUserPresence: choice.requiresUserPresence,
|
|
1908
|
+
...choice.methodCapabilities === undefined ? {} : { methodCapabilities: choice.methodCapabilities },
|
|
1873
1909
|
},
|
|
1874
1910
|
joining,
|
|
1911
|
+
creationMethods,
|
|
1912
|
+
pendingRegistrations,
|
|
1913
|
+
...capabilities === undefined ? {} : { methodCapabilities: capabilities },
|
|
1875
1914
|
recoveries: recoveries.filter(value => domain !== undefined && value.fullHandle.slice(value.fullHandle.indexOf('.') + 1) === domain),
|
|
1876
1915
|
};
|
|
1877
1916
|
}, { allowSignedOut: true });
|
|
@@ -1906,6 +1945,40 @@ let AwikiService = (() => {
|
|
|
1906
1945
|
refreshDeviceManagement() {
|
|
1907
1946
|
return this.run(client => this.deviceManagementSnapshot(client));
|
|
1908
1947
|
}
|
|
1948
|
+
getIdentityServices() {
|
|
1949
|
+
return this.run(client => client.getIdentityServices());
|
|
1950
|
+
}
|
|
1951
|
+
updateIdentityServices(request) {
|
|
1952
|
+
if (request === null || !Array.isArray(request.services))
|
|
1953
|
+
return Promise.resolve({ ok: false, error: failure('invalid-request') });
|
|
1954
|
+
return this.run(async (client) => {
|
|
1955
|
+
const did = await this.requireIdentityServicesManager(client);
|
|
1956
|
+
if (request.did !== did)
|
|
1957
|
+
throw Object.assign(new Error('identity changed'), { name: 'AwikiSdkError', code: 'conflict' });
|
|
1958
|
+
if ((await client.getIdentityServices()).pending) {
|
|
1959
|
+
throw Object.assign(new Error('pending service update'), { name: 'AwikiSdkError', code: 'conflict' });
|
|
1960
|
+
}
|
|
1961
|
+
await client.updateIdentityServices(request);
|
|
1962
|
+
return client.getIdentityServices();
|
|
1963
|
+
});
|
|
1964
|
+
}
|
|
1965
|
+
resumeIdentityServicesUpdate(request) {
|
|
1966
|
+
return this.run(async (client) => {
|
|
1967
|
+
const did = await this.requireIdentityServicesManager(client);
|
|
1968
|
+
if (request?.did !== did)
|
|
1969
|
+
throw Object.assign(new Error('identity changed'), { name: 'AwikiSdkError', code: 'conflict' });
|
|
1970
|
+
await client.resumeIdentityServicesUpdate();
|
|
1971
|
+
return client.getIdentityServices();
|
|
1972
|
+
});
|
|
1973
|
+
}
|
|
1974
|
+
async requireIdentityServicesManager(client) {
|
|
1975
|
+
await this.requireDeviceManager(client);
|
|
1976
|
+
const identity = await client.getIdentity();
|
|
1977
|
+
if (identity === null || !(await client.identityMethodCapabilities(identity.did)).servicesUpdate) {
|
|
1978
|
+
throw Object.assign(new Error('service update unavailable'), { name: 'AwikiSdkError', code: 'forbidden' });
|
|
1979
|
+
}
|
|
1980
|
+
return identity.did;
|
|
1981
|
+
}
|
|
1909
1982
|
async startDeviceJoinVerification(request) {
|
|
1910
1983
|
const joinSessionId = this.requestSessions.get(request?.requestRef);
|
|
1911
1984
|
if (joinSessionId === undefined)
|
|
@@ -1989,6 +2062,20 @@ let AwikiService = (() => {
|
|
|
1989
2062
|
});
|
|
1990
2063
|
return result.ok ? this.publicAdminJoinProgress(request.requestRef, result.value) : result;
|
|
1991
2064
|
}
|
|
2065
|
+
async retryDeviceManagement(request) {
|
|
2066
|
+
const deviceId = this.deviceIds.get(request?.deviceRef);
|
|
2067
|
+
if (deviceId === undefined)
|
|
2068
|
+
return { ok: false, error: failure('invalid-request') };
|
|
2069
|
+
return this.run(async (client) => {
|
|
2070
|
+
await this.requireDeviceManager(client);
|
|
2071
|
+
const task = (await client.deviceJoinManagementStatus()).find(value => value.recipientDeviceId === deviceId);
|
|
2072
|
+
if (task === undefined || task.phase !== 'failed' || ['root_transfer.delivery_expired', 'root_transfer.delivery_invalidated'].includes(task.failureCode ?? '')) {
|
|
2073
|
+
throw Object.assign(new Error('management retry unavailable'), { name: 'AwikiSdkError', code: 'forbidden' });
|
|
2074
|
+
}
|
|
2075
|
+
await client.retryDeviceJoinManagement(task.joinSessionId);
|
|
2076
|
+
return null;
|
|
2077
|
+
});
|
|
2078
|
+
}
|
|
1992
2079
|
async rejectDeviceJoin(request) {
|
|
1993
2080
|
const joinSessionId = this.requestSessions.get(request?.requestRef);
|
|
1994
2081
|
if (joinSessionId === undefined
|
|
@@ -2391,6 +2478,8 @@ let AwikiService = (() => {
|
|
|
2391
2478
|
* @returns The accepted attachment message or a closed failure.
|
|
2392
2479
|
*/
|
|
2393
2480
|
async sendAttachment(request) {
|
|
2481
|
+
if (!isMessageTarget(request?.target))
|
|
2482
|
+
return { ok: false, error: failure('invalid-request') };
|
|
2394
2483
|
const decoded = decodeAttachment(request.bytesBase64, this.resolved.attachmentMaxBytes);
|
|
2395
2484
|
if (!decoded.ok)
|
|
2396
2485
|
return decoded;
|
|
@@ -2749,6 +2838,9 @@ let AwikiService = (() => {
|
|
|
2749
2838
|
if (identity === null) {
|
|
2750
2839
|
throw Object.assign(new Error('identity required'), { name: 'AwikiSdkError', code: 'not-registered' });
|
|
2751
2840
|
}
|
|
2841
|
+
if (!(await client.identityMethodCapabilities(identity.did)).rootTransfer) {
|
|
2842
|
+
throw Object.assign(new Error('root transfer unavailable'), { name: 'AwikiSdkError', code: 'forbidden' });
|
|
2843
|
+
}
|
|
2752
2844
|
const target = (await client.getDeviceRegistry()).find(device => device.deviceId === deviceId);
|
|
2753
2845
|
if (target === undefined
|
|
2754
2846
|
|| target.isCurrent
|
|
@@ -2780,6 +2872,9 @@ let AwikiService = (() => {
|
|
|
2780
2872
|
async deviceManagementSnapshot(client) {
|
|
2781
2873
|
await client.syncDeviceManagement();
|
|
2782
2874
|
const current = await client.getCurrentDeviceSummary();
|
|
2875
|
+
const currentIdentity = await client.getIdentity();
|
|
2876
|
+
const capabilities = currentIdentity === null ? undefined : await client.identityMethodCapabilities(currentIdentity.did);
|
|
2877
|
+
const rootTransferSupported = capabilities?.rootTransfer === true && client.trustedUserPresenceSupported;
|
|
2783
2878
|
if (!current.canManage || current.role !== 'admin' || current.readiness !== 'admin_ready') {
|
|
2784
2879
|
this.requestRefs.clear();
|
|
2785
2880
|
this.requestSessions.clear();
|
|
@@ -2788,7 +2883,8 @@ let AwikiService = (() => {
|
|
|
2788
2883
|
this.rootTransfers.clear();
|
|
2789
2884
|
return {
|
|
2790
2885
|
canManage: false,
|
|
2791
|
-
rootTransferSupported
|
|
2886
|
+
rootTransferSupported,
|
|
2887
|
+
...capabilities === undefined ? {} : { methodCapabilities: capabilities },
|
|
2792
2888
|
...current.role === undefined ? {} : { role: current.role },
|
|
2793
2889
|
readiness: current.readiness,
|
|
2794
2890
|
devices: [],
|
|
@@ -2799,6 +2895,7 @@ let AwikiService = (() => {
|
|
|
2799
2895
|
await Promise.all(requests
|
|
2800
2896
|
.filter(request => request.claimedByCurrentDevice)
|
|
2801
2897
|
.map(request => client.getLocalDeviceJoinVerificationProgress(request.joinSessionId).catch(() => undefined)));
|
|
2898
|
+
const management = await client.deviceJoinManagementStatus();
|
|
2802
2899
|
const devices = await client.getDeviceRegistry();
|
|
2803
2900
|
const identity = await client.getIdentity();
|
|
2804
2901
|
const joinedAtByDeviceId = new Map();
|
|
@@ -2813,12 +2910,22 @@ let AwikiService = (() => {
|
|
|
2813
2910
|
: new Date(identity.registeredAt).toISOString();
|
|
2814
2911
|
return {
|
|
2815
2912
|
canManage: true,
|
|
2816
|
-
rootTransferSupported
|
|
2913
|
+
rootTransferSupported,
|
|
2914
|
+
...capabilities === undefined ? {} : { methodCapabilities: capabilities },
|
|
2817
2915
|
role: 'admin',
|
|
2818
2916
|
readiness: 'admin_ready',
|
|
2819
2917
|
devices: devices
|
|
2820
2918
|
.filter(device => device.status === 'active')
|
|
2821
|
-
.map(device =>
|
|
2919
|
+
.map(device => {
|
|
2920
|
+
const task = management.find(value => value.recipientDeviceId === device.deviceId);
|
|
2921
|
+
const phase = task?.phase === 'failed' ? 'failed'
|
|
2922
|
+
: task?.phase === 'management_registered' ? 'complete'
|
|
2923
|
+
: task?.phase === 'waiting_for_recipient' ? 'waiting' : 'pending';
|
|
2924
|
+
return {
|
|
2925
|
+
...this.publicDevice(device, joinedAtByDeviceId.get(device.deviceId) ?? (device.isCurrent ? initialDeviceJoinedAt : undefined)),
|
|
2926
|
+
...task === undefined ? {} : { provisioning: { phase, attempts: task.attempts, ...['root_transfer.delivery_expired', 'root_transfer.delivery_invalidated'].includes(task.failureCode ?? '') ? { requiresRejoin: true } : {} } },
|
|
2927
|
+
};
|
|
2928
|
+
}),
|
|
2822
2929
|
requests: requests.map(request => ({
|
|
2823
2930
|
requestRef: this.requestRef(request.joinSessionId),
|
|
2824
2931
|
candidateKeyFingerprint: request.candidateKeyFingerprint,
|