@peers-app/peers-sdk 0.25.1 → 0.25.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contracts/__tests__/contract-resolvers.test.js +35 -2
- package/dist/contracts/__tests__/host-contract-consumer.test.d.ts +1 -0
- package/dist/contracts/__tests__/host-contract-consumer.test.js +163 -0
- package/dist/contracts/__tests__/system-contracts.test.js +14 -0
- package/dist/contracts/contract-resolvers.d.ts +14 -2
- package/dist/contracts/contract-resolvers.js +69 -6
- package/dist/contracts/host-contract-consumer.d.ts +40 -0
- package/dist/contracts/host-contract-consumer.js +105 -0
- package/dist/contracts/index.d.ts +2 -0
- package/dist/contracts/index.js +7 -2
- package/dist/contracts/system/identity-contract.d.ts +43 -0
- package/dist/contracts/system/identity-contract.js +133 -0
- package/dist/contracts/system/index.d.ts +2 -0
- package/dist/contracts/system/index.js +5 -1
- package/dist/contracts/types.d.ts +6 -0
- package/dist/data/devices.d.ts +4 -4
- package/dist/data/group-share.js +0 -38
- package/dist/data/index.d.ts +1 -0
- package/dist/data/index.js +1 -0
- package/dist/data/invites.d.ts +40 -40
- package/dist/data/invites.js +4 -2
- package/dist/data/peers-services-registration.pvar.d.ts +37 -0
- package/dist/data/peers-services-registration.pvar.js +57 -0
- package/dist/data/tool-access-approvals.d.ts +3 -3
- package/dist/device/connection.d.ts +1 -1
- package/dist/device/device.d.ts +1 -1
- package/dist/device-pairing/constants.d.ts +0 -2
- package/dist/device-pairing/constants.js +1 -3
- package/dist/device-pairing/types.d.ts +80 -80
- package/dist/invites/invite-messages.d.ts +12 -12
- package/dist/rpc-types.d.ts +0 -14
- package/dist/rpc-types.js +0 -13
- package/dist/system-ids.d.ts +17 -0
- package/dist/system-ids.js +18 -1
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { DevicePairingCeremonyAction, DevicePairingStartDestinationInput, DevicePairingStartSourceInput, DevicePairingState } from "../../device-pairing";
|
|
2
|
+
import type { Observable } from "../../observable";
|
|
3
|
+
import type { IContractConsumerBase } from "../contract-proxy";
|
|
4
|
+
import type { IContractDefinition } from "../types";
|
|
5
|
+
/** Version of the built-in System Identity contract. */
|
|
6
|
+
export declare const IDENTITY_CONTRACT_VERSION = 1;
|
|
7
|
+
/** Who is signed in on this host, and whether they registered with peers-services. */
|
|
8
|
+
export interface IIdentitySessionInfo {
|
|
9
|
+
/** Signed-in user, absent on the setup screen. */
|
|
10
|
+
userId?: string;
|
|
11
|
+
/** True when this user has completed peers-services registration on this device. */
|
|
12
|
+
registered: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Local-only host contract for device pairing and the signed-in session.
|
|
16
|
+
*
|
|
17
|
+
* It resolves before sign-in (`requiresUserContext: false`) so the setup screen can
|
|
18
|
+
* show a pairing code. Remote device connections must not resolve it. Pairing progress
|
|
19
|
+
* is the `state` observable; there is no separate get-state tool.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getIdentityContractDefinition(): IContractDefinition;
|
|
22
|
+
/** Consumer-side TypeScript shape for System Identity. */
|
|
23
|
+
export interface IIdentityConsumer extends IContractConsumerBase {
|
|
24
|
+
tools: {
|
|
25
|
+
startSource(input: DevicePairingStartSourceInput): Promise<DevicePairingState>;
|
|
26
|
+
startDestination(input?: DevicePairingStartDestinationInput): Promise<DevicePairingState>;
|
|
27
|
+
approve(input: DevicePairingCeremonyAction): Promise<DevicePairingState>;
|
|
28
|
+
reject(input: DevicePairingCeremonyAction): Promise<DevicePairingState>;
|
|
29
|
+
cancel(input: DevicePairingCeremonyAction): Promise<DevicePairingState>;
|
|
30
|
+
getSession(): Promise<IIdentitySessionInfo>;
|
|
31
|
+
signIn(input: {
|
|
32
|
+
userId: string;
|
|
33
|
+
secretKey: string;
|
|
34
|
+
}): Promise<void>;
|
|
35
|
+
signOut(): Promise<void>;
|
|
36
|
+
registerWithPeersServices(): Promise<{
|
|
37
|
+
token: string;
|
|
38
|
+
}>;
|
|
39
|
+
};
|
|
40
|
+
observables: {
|
|
41
|
+
state: Observable<DevicePairingState>;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IDENTITY_CONTRACT_VERSION = void 0;
|
|
4
|
+
exports.getIdentityContractDefinition = getIdentityContractDefinition;
|
|
5
|
+
const system_ids_1 = require("../../system-ids");
|
|
6
|
+
const field_type_1 = require("../../types/field-type");
|
|
7
|
+
const system_contracts_1 = require("../system-contracts");
|
|
8
|
+
/** Version of the built-in System Identity contract. */
|
|
9
|
+
exports.IDENTITY_CONTRACT_VERSION = 1;
|
|
10
|
+
const field = (name, type, description, opts = {}) => ({ name, type, description, ...opts });
|
|
11
|
+
let definition;
|
|
12
|
+
/**
|
|
13
|
+
* Fields of {@link DevicePairingState}. Ceremony tools return this object directly.
|
|
14
|
+
*/
|
|
15
|
+
const pairingStateFields = [
|
|
16
|
+
field("sessionId", field_type_1.FieldType.id, "Active ceremony id.", { optional: true }),
|
|
17
|
+
field("role", field_type_1.FieldType.string, "source or destination.", { optional: true }),
|
|
18
|
+
field("phase", field_type_1.FieldType.string, "idle, showing-code, connecting, authenticating, waiting-for-approval, transferring, complete, rejected, or error."),
|
|
19
|
+
field("expiresAt", field_type_1.FieldType.number, "Unix milliseconds when the ceremony expires.", {
|
|
20
|
+
optional: true,
|
|
21
|
+
}),
|
|
22
|
+
field("remoteDevice", field_type_1.FieldType.object, "Name, user, and type presented by the other device.", {
|
|
23
|
+
optional: true,
|
|
24
|
+
}),
|
|
25
|
+
field("code", field_type_1.FieldType.string, "Pairing code the destination is showing.", { optional: true }),
|
|
26
|
+
field("notice", field_type_1.FieldType.string, "Non-fatal message alongside the current phase.", {
|
|
27
|
+
optional: true,
|
|
28
|
+
}),
|
|
29
|
+
field("error", field_type_1.FieldType.string, "Failure message when the phase is error.", { optional: true }),
|
|
30
|
+
];
|
|
31
|
+
/**
|
|
32
|
+
* Local-only host contract for device pairing and the signed-in session.
|
|
33
|
+
*
|
|
34
|
+
* It resolves before sign-in (`requiresUserContext: false`) so the setup screen can
|
|
35
|
+
* show a pairing code. Remote device connections must not resolve it. Pairing progress
|
|
36
|
+
* is the `state` observable; there is no separate get-state tool.
|
|
37
|
+
*/
|
|
38
|
+
function getIdentityContractDefinition() {
|
|
39
|
+
definition ??= {
|
|
40
|
+
contractId: system_ids_1.identityContractId,
|
|
41
|
+
version: exports.IDENTITY_CONTRACT_VERSION,
|
|
42
|
+
devTag: "dev",
|
|
43
|
+
name: "System Identity",
|
|
44
|
+
description: "Device pairing ceremony and the local signed-in session.",
|
|
45
|
+
requiresUserContext: false,
|
|
46
|
+
tables: [],
|
|
47
|
+
tools: [
|
|
48
|
+
{
|
|
49
|
+
name: "startSource",
|
|
50
|
+
usageDescription: "Join a pairing room from a code shown on a new device.",
|
|
51
|
+
inputFields: [field("code", field_type_1.FieldType.string, "Pairing code from the new device.")],
|
|
52
|
+
outputFields: pairingStateFields,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "startDestination",
|
|
56
|
+
usageDescription: "Show a pairing code on this signed-out device.",
|
|
57
|
+
inputFields: [
|
|
58
|
+
field("deviceName", field_type_1.FieldType.string, "Name to present for this device.", {
|
|
59
|
+
optional: true,
|
|
60
|
+
}),
|
|
61
|
+
field("deviceType", field_type_1.FieldType.string, "Kind of device, such as browser or desktop.", {
|
|
62
|
+
optional: true,
|
|
63
|
+
}),
|
|
64
|
+
],
|
|
65
|
+
outputFields: pairingStateFields,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "approve",
|
|
69
|
+
usageDescription: "Approve the active pairing ceremony and send credentials.",
|
|
70
|
+
inputFields: [field("sessionId", field_type_1.FieldType.id, "Active ceremony id.")],
|
|
71
|
+
outputFields: pairingStateFields,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "reject",
|
|
75
|
+
usageDescription: "Reject the active pairing ceremony.",
|
|
76
|
+
inputFields: [field("sessionId", field_type_1.FieldType.id, "Active ceremony id.")],
|
|
77
|
+
outputFields: pairingStateFields,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: "cancel",
|
|
81
|
+
usageDescription: "Cancel the active pairing ceremony.",
|
|
82
|
+
inputFields: [field("sessionId", field_type_1.FieldType.id, "Active ceremony id.")],
|
|
83
|
+
outputFields: pairingStateFields,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "getSession",
|
|
87
|
+
usageDescription: "Return the signed-in user, if any, and peers-services registration.",
|
|
88
|
+
inputFields: [],
|
|
89
|
+
outputFields: [
|
|
90
|
+
field("userId", field_type_1.FieldType.id, "Signed-in user id.", { optional: true }),
|
|
91
|
+
field("registered", field_type_1.FieldType.boolean, "Whether peers-services registration completed."),
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: "signIn",
|
|
96
|
+
usageDescription: "Store a user id and secret key and start the local runtime.",
|
|
97
|
+
inputFields: [
|
|
98
|
+
field("userId", field_type_1.FieldType.id, "User id to sign in as."),
|
|
99
|
+
field("secretKey", field_type_1.FieldType.string, "Secret key for that user."),
|
|
100
|
+
],
|
|
101
|
+
outputFields: [],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "signOut",
|
|
105
|
+
usageDescription: "Clear the local credentials and leave the signed-in session.",
|
|
106
|
+
inputFields: [],
|
|
107
|
+
outputFields: [],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "registerWithPeersServices",
|
|
111
|
+
usageDescription: "Register or authenticate this user with peers-services and return a JWT.",
|
|
112
|
+
inputFields: [],
|
|
113
|
+
outputFields: [field("token", field_type_1.FieldType.string, "peers-services JWT.")],
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
observables: [
|
|
117
|
+
{
|
|
118
|
+
name: "state",
|
|
119
|
+
description: "Live device-pairing ceremony state.",
|
|
120
|
+
valueType: field_type_1.FieldType.object,
|
|
121
|
+
writable: false,
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
events: [],
|
|
125
|
+
};
|
|
126
|
+
return definition;
|
|
127
|
+
}
|
|
128
|
+
(0, system_contracts_1.registerSystemContract)({
|
|
129
|
+
providerPackageId: system_ids_1.peersSystemPackageId,
|
|
130
|
+
contractId: system_ids_1.identityContractId,
|
|
131
|
+
version: exports.IDENTITY_CONTRACT_VERSION,
|
|
132
|
+
getDefinition: getIdentityContractDefinition,
|
|
133
|
+
});
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
* {@link registerSystemContract} side effect so the catalog is populated.
|
|
4
4
|
*/
|
|
5
5
|
import "./device-operations-contract";
|
|
6
|
+
import "./identity-contract";
|
|
6
7
|
import "./invites-contract";
|
|
7
8
|
import "./logs-contract";
|
|
8
9
|
import "./network-contracts";
|
|
9
10
|
import "./tool-access-control-contract";
|
|
10
11
|
export { DEVICE_OPERATIONS_CONTRACT_VERSION, DEVICE_OPERATIONS_MAX_QUERY_LENGTH, DEVICE_OPERATIONS_MAX_RESULT_BYTES, DEVICE_OPERATIONS_MAX_ROWS, DEVICE_OPERATIONS_MAX_TOOLS, type DeviceOperationCapability, deviceOperationsProviderPackageId, deviceOperationsToolIds, getDeviceOperationsContractDefinition, type IDeviceDatabaseQueryInput, type IDeviceDatabaseQueryResult, type IDeviceOperationStatus, type IDeviceToolListInput, type IDeviceToolLookupInput, type IDeviceToolLookupResult, type IDeviceToolRunInput, } from "./device-operations-contract";
|
|
12
|
+
export { getIdentityContractDefinition, IDENTITY_CONTRACT_VERSION, type IIdentityConsumer, type IIdentitySessionInfo, } from "./identity-contract";
|
|
11
13
|
export { getInvitesContractDefinition, type IAcceptInviteResult, type ICreatedInvite, type IInvitePreview, type IInvitesConsumer, INVITES_CONTRACT_VERSION, } from "./invites-contract";
|
|
12
14
|
export { getLogsContractDefinition, type ILogsConsumer, LOGS_CONTRACT_VERSION, resolveLogsContract, } from "./logs-contract";
|
|
13
15
|
export * from "./network-contracts";
|
|
@@ -14,12 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.TOOL_ACCESS_CONTROL_CONTRACT_VERSION = exports.getToolAccessControlContractDefinition = exports.resolveLogsContract = exports.LOGS_CONTRACT_VERSION = exports.getLogsContractDefinition = exports.INVITES_CONTRACT_VERSION = exports.getInvitesContractDefinition = exports.getDeviceOperationsContractDefinition = exports.deviceOperationsToolIds = exports.deviceOperationsProviderPackageId = exports.DEVICE_OPERATIONS_MAX_TOOLS = exports.DEVICE_OPERATIONS_MAX_ROWS = exports.DEVICE_OPERATIONS_MAX_RESULT_BYTES = exports.DEVICE_OPERATIONS_MAX_QUERY_LENGTH = exports.DEVICE_OPERATIONS_CONTRACT_VERSION = void 0;
|
|
17
|
+
exports.TOOL_ACCESS_CONTROL_CONTRACT_VERSION = exports.getToolAccessControlContractDefinition = exports.resolveLogsContract = exports.LOGS_CONTRACT_VERSION = exports.getLogsContractDefinition = exports.INVITES_CONTRACT_VERSION = exports.getInvitesContractDefinition = exports.IDENTITY_CONTRACT_VERSION = exports.getIdentityContractDefinition = exports.getDeviceOperationsContractDefinition = exports.deviceOperationsToolIds = exports.deviceOperationsProviderPackageId = exports.DEVICE_OPERATIONS_MAX_TOOLS = exports.DEVICE_OPERATIONS_MAX_ROWS = exports.DEVICE_OPERATIONS_MAX_RESULT_BYTES = exports.DEVICE_OPERATIONS_MAX_QUERY_LENGTH = exports.DEVICE_OPERATIONS_CONTRACT_VERSION = void 0;
|
|
18
18
|
/**
|
|
19
19
|
* Built-in system contracts. Importing this barrel runs each module's
|
|
20
20
|
* {@link registerSystemContract} side effect so the catalog is populated.
|
|
21
21
|
*/
|
|
22
22
|
require("./device-operations-contract");
|
|
23
|
+
require("./identity-contract");
|
|
23
24
|
require("./invites-contract");
|
|
24
25
|
require("./logs-contract");
|
|
25
26
|
require("./network-contracts");
|
|
@@ -33,6 +34,9 @@ Object.defineProperty(exports, "DEVICE_OPERATIONS_MAX_TOOLS", { enumerable: true
|
|
|
33
34
|
Object.defineProperty(exports, "deviceOperationsProviderPackageId", { enumerable: true, get: function () { return device_operations_contract_1.deviceOperationsProviderPackageId; } });
|
|
34
35
|
Object.defineProperty(exports, "deviceOperationsToolIds", { enumerable: true, get: function () { return device_operations_contract_1.deviceOperationsToolIds; } });
|
|
35
36
|
Object.defineProperty(exports, "getDeviceOperationsContractDefinition", { enumerable: true, get: function () { return device_operations_contract_1.getDeviceOperationsContractDefinition; } });
|
|
37
|
+
var identity_contract_1 = require("./identity-contract");
|
|
38
|
+
Object.defineProperty(exports, "getIdentityContractDefinition", { enumerable: true, get: function () { return identity_contract_1.getIdentityContractDefinition; } });
|
|
39
|
+
Object.defineProperty(exports, "IDENTITY_CONTRACT_VERSION", { enumerable: true, get: function () { return identity_contract_1.IDENTITY_CONTRACT_VERSION; } });
|
|
36
40
|
var invites_contract_1 = require("./invites-contract");
|
|
37
41
|
Object.defineProperty(exports, "getInvitesContractDefinition", { enumerable: true, get: function () { return invites_contract_1.getInvitesContractDefinition; } });
|
|
38
42
|
Object.defineProperty(exports, "INVITES_CONTRACT_VERSION", { enumerable: true, get: function () { return invites_contract_1.INVITES_CONTRACT_VERSION; } });
|
|
@@ -25,6 +25,12 @@ export interface IContractDefinition {
|
|
|
25
25
|
* emits an array (possibly empty) and consumers read `contract.events ?? []`.
|
|
26
26
|
*/
|
|
27
27
|
events?: IContractEvent[];
|
|
28
|
+
/**
|
|
29
|
+
* When `false`, the local host may resolve this contract before anyone is
|
|
30
|
+
* signed in. Defaults to requiring a user context. The host router honors this
|
|
31
|
+
* only when the provider registers with `requiresUserContext: false`.
|
|
32
|
+
*/
|
|
33
|
+
requiresUserContext?: boolean;
|
|
28
34
|
}
|
|
29
35
|
/** Table shape within a contract — derived from ITableMetaData + IField[]. */
|
|
30
36
|
export interface IContractTable {
|
package/dist/data/devices.d.ts
CHANGED
|
@@ -49,15 +49,15 @@ export declare const deviceInfoSchema: z.ZodObject<{
|
|
|
49
49
|
publicBoxKey: string;
|
|
50
50
|
userId: string;
|
|
51
51
|
deviceId: string;
|
|
52
|
-
deviceName?: string | undefined;
|
|
53
52
|
userName?: string | undefined;
|
|
53
|
+
deviceName?: string | undefined;
|
|
54
54
|
}, {
|
|
55
55
|
publicKey: string;
|
|
56
56
|
publicBoxKey: string;
|
|
57
57
|
userId: string;
|
|
58
58
|
deviceId: string;
|
|
59
|
-
deviceName?: string | undefined;
|
|
60
59
|
userName?: string | undefined;
|
|
60
|
+
deviceName?: string | undefined;
|
|
61
61
|
}>;
|
|
62
62
|
/** Signed identity and optional presentation hints advertised by a device. */
|
|
63
63
|
export type IDeviceInfo = z.infer<typeof deviceInfoSchema>;
|
|
@@ -81,8 +81,8 @@ export declare const deviceHandshakeSchema: z.ZodObject<{
|
|
|
81
81
|
deviceId: string;
|
|
82
82
|
connectionId: string;
|
|
83
83
|
serverAddress: string;
|
|
84
|
-
deviceName?: string | undefined;
|
|
85
84
|
userName?: string | undefined;
|
|
85
|
+
deviceName?: string | undefined;
|
|
86
86
|
}, {
|
|
87
87
|
timestamp: number;
|
|
88
88
|
publicKey: string;
|
|
@@ -91,8 +91,8 @@ export declare const deviceHandshakeSchema: z.ZodObject<{
|
|
|
91
91
|
deviceId: string;
|
|
92
92
|
connectionId: string;
|
|
93
93
|
serverAddress: string;
|
|
94
|
-
deviceName?: string | undefined;
|
|
95
94
|
userName?: string | undefined;
|
|
95
|
+
deviceName?: string | undefined;
|
|
96
96
|
}>;
|
|
97
97
|
/** Signed device information bound to one connection handshake. */
|
|
98
98
|
export type IDeviceHandshake = z.infer<typeof deviceHandshakeSchema>;
|
package/dist/data/group-share.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.generateGroupShare = generateGroupShare;
|
|
|
4
4
|
exports.seedGroupContextFromShare = seedGroupContextFromShare;
|
|
5
5
|
exports.validateGroupShare = validateGroupShare;
|
|
6
6
|
exports.copyToClipboard = copyToClipboard;
|
|
7
|
-
const __1 = require("..");
|
|
8
7
|
const user_context_singleton_1 = require("../context/user-context-singleton");
|
|
9
8
|
const group_member_roles_1 = require("./group-member-roles");
|
|
10
9
|
const group_members_1 = require("./group-members");
|
|
@@ -36,37 +35,6 @@ async function generateGroupShare(groupId) {
|
|
|
36
35
|
};
|
|
37
36
|
return groupShare;
|
|
38
37
|
}
|
|
39
|
-
/**
|
|
40
|
-
* Imports a GroupShare object, creating the group and seeding admin members
|
|
41
|
-
* @param groupShareJson JSON string containing the GroupShare data
|
|
42
|
-
* @returns Promise<string> The imported group ID
|
|
43
|
-
* @throws Error if JSON invalid or import fails
|
|
44
|
-
*/
|
|
45
|
-
async function importGroupShare(groupShareJson) {
|
|
46
|
-
// Parse and validate JSON
|
|
47
|
-
let groupShare;
|
|
48
|
-
try {
|
|
49
|
-
groupShare = JSON.parse(groupShareJson);
|
|
50
|
-
}
|
|
51
|
-
catch (_error) {
|
|
52
|
-
throw new Error("Invalid JSON format");
|
|
53
|
-
}
|
|
54
|
-
// Validate structure - maybe redo this with a zod schema
|
|
55
|
-
if (!validateGroupShare(groupShare)) {
|
|
56
|
-
throw new Error("Invalid GroupShare structure");
|
|
57
|
-
}
|
|
58
|
-
const userContext = await (0, user_context_singleton_1.getUserContext)();
|
|
59
|
-
const { group } = groupShare;
|
|
60
|
-
// Check if group already exists
|
|
61
|
-
const existingGroup = await (0, groups_1.Groups)(userContext.userDataContext).get(group.groupId);
|
|
62
|
-
if (existingGroup) {
|
|
63
|
-
throw new Error(`Group "${group.name}" already exists`);
|
|
64
|
-
}
|
|
65
|
-
// Save group to user's groups table
|
|
66
|
-
await (0, groups_1.Groups)(userContext.userDataContext).save(group, { restoreIfDeleted: true });
|
|
67
|
-
await seedGroupContextFromShare(userContext, groupShare);
|
|
68
|
-
return group.groupId;
|
|
69
|
-
}
|
|
70
38
|
/**
|
|
71
39
|
* Write a group record and missing membership rows into the group's data context.
|
|
72
40
|
*
|
|
@@ -172,12 +140,6 @@ async function copyToClipboard(text) {
|
|
|
172
140
|
return false;
|
|
173
141
|
}
|
|
174
142
|
}
|
|
175
|
-
// get around circular dependency issue
|
|
176
|
-
setTimeout(() => {
|
|
177
|
-
if (__1.rpcServerCalls) {
|
|
178
|
-
__1.rpcServerCalls.importGroupShare = (groupShareJson) => importGroupShare(groupShareJson);
|
|
179
|
-
}
|
|
180
|
-
}, 10);
|
|
181
143
|
function getLowestDataSource(table) {
|
|
182
144
|
let ds = table.dataSource;
|
|
183
145
|
for (let i = 0; i < 100; i++) {
|
package/dist/data/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export * from "./package-versions";
|
|
|
21
21
|
export * from "./packages";
|
|
22
22
|
export * from "./packages.utils";
|
|
23
23
|
export * from "./peer-types";
|
|
24
|
+
export * from "./peers-services-registration.pvar";
|
|
24
25
|
export * from "./persistent-vars";
|
|
25
26
|
export * from "./sync-recovery-queue";
|
|
26
27
|
export * from "./table-definitions-table";
|
package/dist/data/index.js
CHANGED
|
@@ -37,6 +37,7 @@ __exportStar(require("./package-versions"), exports);
|
|
|
37
37
|
__exportStar(require("./packages"), exports);
|
|
38
38
|
__exportStar(require("./packages.utils"), exports);
|
|
39
39
|
__exportStar(require("./peer-types"), exports);
|
|
40
|
+
__exportStar(require("./peers-services-registration.pvar"), exports);
|
|
40
41
|
__exportStar(require("./persistent-vars"), exports);
|
|
41
42
|
__exportStar(require("./sync-recovery-queue"), exports);
|
|
42
43
|
__exportStar(require("./table-definitions-table"), exports);
|
package/dist/data/invites.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type InviteStatus = z.infer<typeof inviteStatusSchema>;
|
|
|
10
10
|
* - `direct`: a known contact was invited to a group (3a); the payload is the approval.
|
|
11
11
|
* - `approve`: group link whose join requests the inviter approves (3b).
|
|
12
12
|
* - `open`: group link any Admin+ member auto-approves (3c).
|
|
13
|
-
* - `profile`: the reusable contact QR on
|
|
13
|
+
* - `profile`: the reusable contact QR on Identity → People.
|
|
14
14
|
* - `contact`: a one-off contact token.
|
|
15
15
|
*/
|
|
16
16
|
export declare const inviteModeSchema: z.ZodEnum<["direct", "approve", "open", "profile", "contact"]>;
|
|
@@ -28,7 +28,7 @@ export declare const inviteDeliveryStateSchema: z.ZodEnum<["queued", "sent"]>;
|
|
|
28
28
|
export declare const inviteSchema: z.ZodObject<{
|
|
29
29
|
inviteId: z.ZodEffects<z.ZodString, string, string>;
|
|
30
30
|
direction: z.ZodEnum<["in", "out"]>;
|
|
31
|
-
type: z.ZodEnum<["contact", "group"]>;
|
|
31
|
+
type: z.ZodEnum<["contact", "group", "device"]>;
|
|
32
32
|
status: z.ZodDefault<z.ZodEnum<["pending", "accepted", "declined", "expired", "revoked"]>>;
|
|
33
33
|
mode: z.ZodEnum<["direct", "approve", "open", "profile", "contact"]>;
|
|
34
34
|
/** The other party, once known (unknown for outstanding link invites). */
|
|
@@ -179,25 +179,22 @@ export declare const inviteSchema: z.ZodObject<{
|
|
|
179
179
|
resolvedAt: z.ZodOptional<z.ZodDate>;
|
|
180
180
|
note: z.ZodOptional<z.ZodString>;
|
|
181
181
|
}, "strip", z.ZodTypeAny, {
|
|
182
|
-
type: "group" | "contact";
|
|
182
|
+
type: "group" | "device" | "contact";
|
|
183
183
|
direction: "in" | "out";
|
|
184
184
|
status: "pending" | "expired" | "accepted" | "declined" | "revoked";
|
|
185
|
-
expiresAt: Date;
|
|
186
185
|
createdAt: Date;
|
|
186
|
+
expiresAt: Date;
|
|
187
187
|
mode: "direct" | "open" | "approve" | "contact" | "profile";
|
|
188
188
|
epoch: number;
|
|
189
189
|
inviteId: string;
|
|
190
190
|
role?: GroupMemberRole | undefined;
|
|
191
191
|
nonce?: string | undefined;
|
|
192
192
|
groupId?: string | undefined;
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
displayName?: string | undefined;
|
|
193
|
+
payload?: {
|
|
194
|
+
nonce: string;
|
|
195
|
+
contents: string;
|
|
196
|
+
fromPublicKey: string;
|
|
198
197
|
} | undefined;
|
|
199
|
-
counterpartDeviceId?: string | undefined;
|
|
200
|
-
groupName?: string | undefined;
|
|
201
198
|
token?: {
|
|
202
199
|
type: "group" | "contact";
|
|
203
200
|
nonce: string;
|
|
@@ -221,18 +218,21 @@ export declare const inviteSchema: z.ZodObject<{
|
|
|
221
218
|
mode: "open" | "approve";
|
|
222
219
|
} | undefined;
|
|
223
220
|
} | undefined;
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
221
|
+
counterpart?: {
|
|
222
|
+
publicKey: string;
|
|
223
|
+
publicBoxKey: string;
|
|
224
|
+
userId: string;
|
|
225
|
+
displayName?: string | undefined;
|
|
228
226
|
} | undefined;
|
|
227
|
+
counterpartDeviceId?: string | undefined;
|
|
228
|
+
groupName?: string | undefined;
|
|
229
229
|
parentInviteId?: string | undefined;
|
|
230
230
|
deliveryState?: "queued" | "sent" | undefined;
|
|
231
231
|
recipientUserId?: string | undefined;
|
|
232
232
|
resolvedAt?: Date | undefined;
|
|
233
233
|
note?: string | undefined;
|
|
234
234
|
}, {
|
|
235
|
-
type: "group" | "contact";
|
|
235
|
+
type: "group" | "device" | "contact";
|
|
236
236
|
direction: "in" | "out";
|
|
237
237
|
expiresAt: Date;
|
|
238
238
|
mode: "direct" | "open" | "approve" | "contact" | "profile";
|
|
@@ -243,14 +243,11 @@ export declare const inviteSchema: z.ZodObject<{
|
|
|
243
243
|
status?: "pending" | "expired" | "accepted" | "declined" | "revoked" | undefined;
|
|
244
244
|
groupId?: string | undefined;
|
|
245
245
|
createdAt?: Date | undefined;
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
displayName?: string | undefined;
|
|
246
|
+
payload?: {
|
|
247
|
+
nonce: string;
|
|
248
|
+
contents: string;
|
|
249
|
+
fromPublicKey: string;
|
|
251
250
|
} | undefined;
|
|
252
|
-
counterpartDeviceId?: string | undefined;
|
|
253
|
-
groupName?: string | undefined;
|
|
254
251
|
token?: {
|
|
255
252
|
type: "group" | "contact";
|
|
256
253
|
nonce: string;
|
|
@@ -274,11 +271,14 @@ export declare const inviteSchema: z.ZodObject<{
|
|
|
274
271
|
mode: "open" | "approve";
|
|
275
272
|
} | undefined;
|
|
276
273
|
} | undefined;
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
274
|
+
counterpart?: {
|
|
275
|
+
publicKey: string;
|
|
276
|
+
publicBoxKey: string;
|
|
277
|
+
userId: string;
|
|
278
|
+
displayName?: string | undefined;
|
|
281
279
|
} | undefined;
|
|
280
|
+
counterpartDeviceId?: string | undefined;
|
|
281
|
+
groupName?: string | undefined;
|
|
282
282
|
parentInviteId?: string | undefined;
|
|
283
283
|
deliveryState?: "queued" | "sent" | undefined;
|
|
284
284
|
recipientUserId?: string | undefined;
|
|
@@ -293,25 +293,22 @@ export type IInvite = z.infer<typeof inviteSchema>;
|
|
|
293
293
|
* @param dataContext - Optional data context; defaults to the current singleton.
|
|
294
294
|
*/
|
|
295
295
|
export declare function Invites(dataContext?: DataContext): import("..").Table<{
|
|
296
|
-
type: "group" | "contact";
|
|
296
|
+
type: "group" | "device" | "contact";
|
|
297
297
|
direction: "in" | "out";
|
|
298
298
|
status: "pending" | "expired" | "accepted" | "declined" | "revoked";
|
|
299
|
-
expiresAt: Date;
|
|
300
299
|
createdAt: Date;
|
|
300
|
+
expiresAt: Date;
|
|
301
301
|
mode: "direct" | "open" | "approve" | "contact" | "profile";
|
|
302
302
|
epoch: number;
|
|
303
303
|
inviteId: string;
|
|
304
304
|
role?: GroupMemberRole | undefined;
|
|
305
305
|
nonce?: string | undefined;
|
|
306
306
|
groupId?: string | undefined;
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
displayName?: string | undefined;
|
|
307
|
+
payload?: {
|
|
308
|
+
nonce: string;
|
|
309
|
+
contents: string;
|
|
310
|
+
fromPublicKey: string;
|
|
312
311
|
} | undefined;
|
|
313
|
-
counterpartDeviceId?: string | undefined;
|
|
314
|
-
groupName?: string | undefined;
|
|
315
312
|
token?: {
|
|
316
313
|
type: "group" | "contact";
|
|
317
314
|
nonce: string;
|
|
@@ -335,11 +332,14 @@ export declare function Invites(dataContext?: DataContext): import("..").Table<{
|
|
|
335
332
|
mode: "open" | "approve";
|
|
336
333
|
} | undefined;
|
|
337
334
|
} | undefined;
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
335
|
+
counterpart?: {
|
|
336
|
+
publicKey: string;
|
|
337
|
+
publicBoxKey: string;
|
|
338
|
+
userId: string;
|
|
339
|
+
displayName?: string | undefined;
|
|
342
340
|
} | undefined;
|
|
341
|
+
counterpartDeviceId?: string | undefined;
|
|
342
|
+
groupName?: string | undefined;
|
|
343
343
|
parentInviteId?: string | undefined;
|
|
344
344
|
deliveryState?: "queued" | "sent" | undefined;
|
|
345
345
|
recipientUserId?: string | undefined;
|
package/dist/data/invites.js
CHANGED
|
@@ -17,7 +17,7 @@ exports.inviteStatusSchema = zod_1.z.enum(["pending", "accepted", "declined", "e
|
|
|
17
17
|
* - `direct`: a known contact was invited to a group (3a); the payload is the approval.
|
|
18
18
|
* - `approve`: group link whose join requests the inviter approves (3b).
|
|
19
19
|
* - `open`: group link any Admin+ member auto-approves (3c).
|
|
20
|
-
* - `profile`: the reusable contact QR on
|
|
20
|
+
* - `profile`: the reusable contact QR on Identity → People.
|
|
21
21
|
* - `contact`: a one-off contact token.
|
|
22
22
|
*/
|
|
23
23
|
exports.inviteModeSchema = zod_1.z.enum(["direct", "approve", "open", "profile", "contact"]);
|
|
@@ -33,7 +33,9 @@ exports.inviteDeliveryStateSchema = zod_1.z.enum(["queued", "sent"]);
|
|
|
33
33
|
exports.inviteSchema = zod_1.z.object({
|
|
34
34
|
inviteId: zod_types_1.zodPeerId,
|
|
35
35
|
direction: zod_1.z.enum(["in", "out"]).describe("Whether I issued (out) or received (in) this item"),
|
|
36
|
-
type: zod_1.z
|
|
36
|
+
type: zod_1.z
|
|
37
|
+
.enum(["contact", "group", "device"])
|
|
38
|
+
.describe("contact, group, or a device admission slot (nothing produces device rows yet)"),
|
|
37
39
|
status: exports.inviteStatusSchema.default("pending"),
|
|
38
40
|
mode: exports.inviteModeSchema,
|
|
39
41
|
/** The other party, once known (unknown for outstanding link invites). */
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent variables that record a user's registration with `peers-services`.
|
|
3
|
+
*
|
|
4
|
+
* These are the single definition of the variable names. The device runtime reads
|
|
5
|
+
* {@link PEERS_SERVICES_TOKEN_VAR} to authenticate mailbox calls; UIs and headless hosts write
|
|
6
|
+
* both variables through {@link persistPeersServicesRegistration} after a successful
|
|
7
|
+
* `registerWithPeersServices` RPC.
|
|
8
|
+
*/
|
|
9
|
+
/** Name of the secret user variable that holds the `peers-services` JWT. */
|
|
10
|
+
export declare const PEERS_SERVICES_TOKEN_VAR = "PEERS_SERVICES_TOKEN";
|
|
11
|
+
/** Name of the user variable that records when registration completed (ISO timestamp). */
|
|
12
|
+
export declare const PEERS_SERVICES_REGISTERED_VAR = "PEERS_SERVICES_REGISTERED";
|
|
13
|
+
/** Set when the user has completed challenge-response registration (ISO timestamp). */
|
|
14
|
+
export declare const registrationStatusPvar: import("./persistent-vars").PersistentVar<string>;
|
|
15
|
+
/**
|
|
16
|
+
* The `peers-services` JWT, encrypted at rest with the user's secret key and synced to all of
|
|
17
|
+
* the user's devices.
|
|
18
|
+
*/
|
|
19
|
+
export declare const servicesTokenPvar: import("./persistent-vars").PersistentVar<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Store the JWT and the local "registered" flag after a successful `registerWithPeersServices`
|
|
22
|
+
* call.
|
|
23
|
+
*
|
|
24
|
+
* Waits for both variables to finish loading first: a value written before the initial load
|
|
25
|
+
* completes is overwritten by the stored (empty) value when the load lands. Resolves once the
|
|
26
|
+
* new values have been saved, so a host can register, persist, and only then report ready.
|
|
27
|
+
* UIs may call this without awaiting.
|
|
28
|
+
*/
|
|
29
|
+
export declare function persistPeersServicesRegistration(token: string): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Replace the stored JWT after a routine re-authentication.
|
|
32
|
+
*
|
|
33
|
+
* Unlike {@link persistPeersServicesRegistration} this leaves the "registered" timestamp
|
|
34
|
+
* alone: the user registered once, and the Account screen shows that date, not the date of
|
|
35
|
+
* the latest token renewal. Same loading-promise discipline as the registration write.
|
|
36
|
+
*/
|
|
37
|
+
export declare function persistPeersServicesToken(token: string): Promise<void>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Persistent variables that record a user's registration with `peers-services`.
|
|
4
|
+
*
|
|
5
|
+
* These are the single definition of the variable names. The device runtime reads
|
|
6
|
+
* {@link PEERS_SERVICES_TOKEN_VAR} to authenticate mailbox calls; UIs and headless hosts write
|
|
7
|
+
* both variables through {@link persistPeersServicesRegistration} after a successful
|
|
8
|
+
* `registerWithPeersServices` RPC.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.servicesTokenPvar = exports.registrationStatusPvar = exports.PEERS_SERVICES_REGISTERED_VAR = exports.PEERS_SERVICES_TOKEN_VAR = void 0;
|
|
12
|
+
exports.persistPeersServicesRegistration = persistPeersServicesRegistration;
|
|
13
|
+
exports.persistPeersServicesToken = persistPeersServicesToken;
|
|
14
|
+
const persistent_vars_1 = require("./persistent-vars");
|
|
15
|
+
/** Name of the secret user variable that holds the `peers-services` JWT. */
|
|
16
|
+
exports.PEERS_SERVICES_TOKEN_VAR = "PEERS_SERVICES_TOKEN";
|
|
17
|
+
/** Name of the user variable that records when registration completed (ISO timestamp). */
|
|
18
|
+
exports.PEERS_SERVICES_REGISTERED_VAR = "PEERS_SERVICES_REGISTERED";
|
|
19
|
+
/** Set when the user has completed challenge-response registration (ISO timestamp). */
|
|
20
|
+
exports.registrationStatusPvar = (0, persistent_vars_1.userVar)(exports.PEERS_SERVICES_REGISTERED_VAR, {
|
|
21
|
+
defaultValue: "",
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* The `peers-services` JWT, encrypted at rest with the user's secret key and synced to all of
|
|
25
|
+
* the user's devices.
|
|
26
|
+
*/
|
|
27
|
+
exports.servicesTokenPvar = (0, persistent_vars_1.userVar)(exports.PEERS_SERVICES_TOKEN_VAR, {
|
|
28
|
+
isSecret: true,
|
|
29
|
+
defaultValue: "",
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* Store the JWT and the local "registered" flag after a successful `registerWithPeersServices`
|
|
33
|
+
* call.
|
|
34
|
+
*
|
|
35
|
+
* Waits for both variables to finish loading first: a value written before the initial load
|
|
36
|
+
* completes is overwritten by the stored (empty) value when the load lands. Resolves once the
|
|
37
|
+
* new values have been saved, so a host can register, persist, and only then report ready.
|
|
38
|
+
* UIs may call this without awaiting.
|
|
39
|
+
*/
|
|
40
|
+
async function persistPeersServicesRegistration(token) {
|
|
41
|
+
await Promise.all([exports.servicesTokenPvar.loadingPromise, exports.registrationStatusPvar.loadingPromise]);
|
|
42
|
+
(0, exports.servicesTokenPvar)(token);
|
|
43
|
+
(0, exports.registrationStatusPvar)(new Date().toISOString());
|
|
44
|
+
await Promise.all([exports.servicesTokenPvar.loadingPromise, exports.registrationStatusPvar.loadingPromise]);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Replace the stored JWT after a routine re-authentication.
|
|
48
|
+
*
|
|
49
|
+
* Unlike {@link persistPeersServicesRegistration} this leaves the "registered" timestamp
|
|
50
|
+
* alone: the user registered once, and the Account screen shows that date, not the date of
|
|
51
|
+
* the latest token renewal. Same loading-promise discipline as the registration write.
|
|
52
|
+
*/
|
|
53
|
+
async function persistPeersServicesToken(token) {
|
|
54
|
+
await exports.servicesTokenPvar.loadingPromise;
|
|
55
|
+
(0, exports.servicesTokenPvar)(token);
|
|
56
|
+
await exports.servicesTokenPvar.loadingPromise;
|
|
57
|
+
}
|