@peers-app/peers-sdk 0.27.4 → 0.28.0
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/context/user-context.d.ts +7 -1
- package/dist/context/user-context.js +4 -9
- package/dist/contracts/contract-proxy.d.ts +5 -0
- package/dist/contracts/contract-proxy.js +2 -2
- package/dist/contracts/contract-resolvers.d.ts +2 -2
- package/dist/contracts/contract-resolvers.js +14 -15
- package/dist/contracts/contract-transport.d.ts +2 -1
- package/dist/contracts/contract-transport.js +24 -2
- package/dist/contracts/system/network-contracts.d.ts +1 -1
- package/dist/contracts/tool-catalog-service.js +1 -1
- package/dist/contracts/tool-catalog.js +6 -2
- package/dist/data/assistants.d.ts +3 -3
- package/dist/data/authority-write-checks.d.ts +42 -0
- package/dist/data/authority-write-checks.js +324 -0
- package/dist/data/change-tracking.d.ts +4 -4
- package/dist/data/create-group.js +1 -0
- package/dist/data/devices.d.ts +27 -4
- package/dist/data/devices.js +31 -0
- package/dist/data/group-authority.d.ts +111 -0
- package/dist/data/group-authority.js +281 -0
- package/dist/data/group-members.d.ts +8 -2
- package/dist/data/group-members.js +41 -18
- package/dist/data/group-permissions.d.ts +15 -31
- package/dist/data/group-permissions.js +25 -95
- package/dist/data/group-resign.d.ts +38 -0
- package/dist/data/group-resign.js +71 -0
- package/dist/data/groups.d.ts +11 -0
- package/dist/data/groups.js +31 -13
- package/dist/data/index.d.ts +3 -0
- package/dist/data/index.js +3 -0
- package/dist/data/invites.d.ts +14 -0
- package/dist/data/orm/index.d.ts +1 -0
- package/dist/data/orm/index.js +1 -0
- package/dist/data/orm/sql.data-source.d.ts +2 -2
- package/dist/data/orm/sql.data-source.js +8 -9
- package/dist/data/orm/table-container.js +14 -8
- package/dist/data/orm/write-checks.d.ts +89 -0
- package/dist/data/orm/write-checks.js +115 -0
- package/dist/data/package-table-identity.d.ts +6 -0
- package/dist/data/package-table-identity.js +51 -0
- package/dist/data/package-version-resolver.d.ts +15 -0
- package/dist/data/package-version-resolver.js +58 -3
- package/dist/data/package-versions.d.ts +20 -14
- package/dist/data/package-versions.js +15 -9
- package/dist/data/packages.d.ts +6 -1
- package/dist/data/packages.js +15 -20
- package/dist/data/persistent-vars.js +2 -39
- package/dist/data/sync-recovery-queue.d.ts +4 -4
- package/dist/data/sync-recovery-queue.js +7 -1
- package/dist/data/tool-access-approvals.d.ts +3 -3
- package/dist/data/user-permissions.d.ts +33 -2
- package/dist/data/user-permissions.js +87 -10
- package/dist/data/users.d.ts +49 -12
- package/dist/data/users.js +21 -1
- package/dist/data/workflows.d.ts +1 -1
- package/dist/device/binary-peer-connection-v2.d.ts +8 -16
- package/dist/device/binary-peer-connection-v2.js +15 -31
- package/dist/device/connection.d.ts +35 -44
- package/dist/device/connection.js +188 -186
- package/dist/device/device.d.ts +1 -8
- package/dist/device/device.js +1 -30
- package/dist/device/frame-cipher.d.ts +1 -1
- package/dist/device/frame-cipher.js +1 -1
- package/dist/device/get-trust-level-fn.js +3 -6
- package/dist/device/socket.type.d.ts +6 -12
- package/dist/device-pairing/types.d.ts +26 -26
- package/dist/identity/user-row-change.d.ts +3 -1
- package/dist/identity/user-row-change.js +33 -18
- package/dist/invites/group-approval.js +23 -24
- package/dist/invites/invite-messages.d.ts +250 -28
- package/dist/invites/invite-token.d.ts +18 -0
- package/dist/invites/invite-token.js +2 -0
- package/dist/keys.d.ts +7 -0
- package/dist/keys.js +27 -0
- package/dist/package-installer/package-installer.d.ts +1 -1
- package/dist/package-installer/package-installer.js +8 -3
- package/dist/package-installer/package-propagation.d.ts +2 -0
- package/dist/package-installer/package-propagation.js +20 -38
- package/dist/package-installer/package-remote-checker.js +15 -3
- package/dist/package-loader/isolated-artifact.js +0 -2
- package/dist/package-loader/package-loader.js +6 -0
- package/dist/types/peer-device.d.ts +2 -0
- package/dist/types/workflow.d.ts +2 -2
- package/package.json +1 -1
- package/dist/data/package-permissions.d.ts +0 -14
- package/dist/data/package-permissions.js +0 -26
- package/dist/data/package-version-permissions.d.ts +0 -14
- package/dist/data/package-version-permissions.js +0 -30
- package/dist/device/binary-peer-connection.d.ts +0 -58
- package/dist/device/binary-peer-connection.js +0 -516
- package/dist/device/streamed-socket.d.ts +0 -23
- package/dist/device/streamed-socket.js +0 -255
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getTrustLevelFn = getTrustLevelFn;
|
|
4
4
|
const context_1 = require("../context");
|
|
5
5
|
const data_1 = require("../data");
|
|
6
|
+
const user_permissions_1 = require("../data/user-permissions");
|
|
6
7
|
const key_change_1 = require("../identity/key-change");
|
|
7
8
|
const socket_type_1 = require("./socket.type");
|
|
8
9
|
function applyReportedDeviceName(device, deviceInfo) {
|
|
@@ -32,9 +33,7 @@ function getTrustLevelFn(me, serverUrl) {
|
|
|
32
33
|
return socket_type_1.TrustLevel.Untrusted;
|
|
33
34
|
}
|
|
34
35
|
// if this is my own device it is trusted
|
|
35
|
-
if (deviceInfo
|
|
36
|
-
deviceInfo.publicKey === me.publicKey &&
|
|
37
|
-
deviceInfo.publicBoxKey === me.publicBoxKey) {
|
|
36
|
+
if ((0, user_permissions_1.sameUserIdentity)(deviceInfo, me)) {
|
|
38
37
|
// if (deviceInfo.deviceId === thisDeviceId()) {
|
|
39
38
|
// return TrustLevel.Untrusted;
|
|
40
39
|
// }
|
|
@@ -96,9 +95,7 @@ function getTrustLevelFn(me, serverUrl) {
|
|
|
96
95
|
(device ? deviceInfo.userId !== device.userId : false))) {
|
|
97
96
|
return socket_type_1.TrustLevel.Untrusted;
|
|
98
97
|
}
|
|
99
|
-
if (effectiveUser &&
|
|
100
|
-
(deviceInfo.publicKey !== effectiveUser.publicKey ||
|
|
101
|
-
deviceInfo.publicBoxKey !== effectiveUser.publicBoxKey)) {
|
|
98
|
+
if (effectiveUser && !(0, user_permissions_1.sameUserIdentity)(deviceInfo, effectiveUser)) {
|
|
102
99
|
// A different box key for the key on record is a mismatch. A different signing key is
|
|
103
100
|
// accepted only when the anchors on record confirm a rotation.
|
|
104
101
|
if (deviceInfo.publicKey === effectiveUser.publicKey) {
|
|
@@ -14,8 +14,8 @@ export interface RPCSendOptions {
|
|
|
14
14
|
/** Arm the outbound frame cipher with these keys right after this reply frame has been sent. */
|
|
15
15
|
armFrameCipherAfter?: FrameKeys;
|
|
16
16
|
}
|
|
17
|
-
/** Reply callback handed to RPC handlers. */
|
|
18
|
-
export type RPCCallback = (error?: any, result?: any, sendOptions?: RPCSendOptions) => void
|
|
17
|
+
/** Reply callback handed to RPC handlers; async transports resolve after sending the reply. */
|
|
18
|
+
export type RPCCallback = (error?: any, result?: any, sendOptions?: RPCSendOptions) => void | Promise<void>;
|
|
19
19
|
/** Which direction(s) of the frame cipher to arm. */
|
|
20
20
|
export type FrameCipherDirection = "both" | "send" | "receive";
|
|
21
21
|
/**
|
|
@@ -40,11 +40,6 @@ export type TransportType = "ws" | "wrtc" | "unknown";
|
|
|
40
40
|
export interface ISocket {
|
|
41
41
|
id?: string;
|
|
42
42
|
connected?: boolean;
|
|
43
|
-
/**
|
|
44
|
-
* @deprecated No longer needed - all sockets handle their own encoding.
|
|
45
|
-
* Kept temporarily for backwards compatibility during v1->v2 transition.
|
|
46
|
-
*/
|
|
47
|
-
handlesOwnEncoding?: boolean;
|
|
48
43
|
/**
|
|
49
44
|
* Transport type for this socket. Used to optimize chunk sizes for raw byte streaming.
|
|
50
45
|
* - 'wrtc': WebRTC (64KB max due to SCTP limits)
|
|
@@ -82,8 +77,8 @@ export interface ISocket {
|
|
|
82
77
|
/**
|
|
83
78
|
* Arms the per-connection frame cipher (see `frame-cipher.ts`). Sockets that
|
|
84
79
|
* implement this seal every outbound frame and require every inbound frame to
|
|
85
|
-
* be sealed once the corresponding direction is armed. `Connection`
|
|
86
|
-
*
|
|
80
|
+
* be sealed once the corresponding direction is armed. `Connection` refuses
|
|
81
|
+
* to run a handshake on a socket without it.
|
|
87
82
|
* @param keys - This peer's send and receive keys
|
|
88
83
|
* @param direction - Defaults to `"both"`. The handshake server arms
|
|
89
84
|
* `"receive"` first and lets the reply's {@link RPCSendOptions} arm send.
|
|
@@ -94,9 +89,8 @@ export interface ISocket {
|
|
|
94
89
|
/**
|
|
95
90
|
* Controls delivery of inbound plaintext `STREAM_*` frames. Sockets start
|
|
96
91
|
* permissive so bare transports keep working; `Connection` turns this off on
|
|
97
|
-
* construction
|
|
98
|
-
*
|
|
99
|
-
* handshake.
|
|
92
|
+
* construction. Sealed stream frames are always delivered because arming
|
|
93
|
+
* implies a completed handshake.
|
|
100
94
|
*/
|
|
101
95
|
setPlaintextStreamsAllowed?(allowed: boolean): void;
|
|
102
96
|
}
|
|
@@ -1142,15 +1142,15 @@ export declare const devicePairingTranscriptSchema: z.ZodObject<{
|
|
|
1142
1142
|
}, "strip", z.ZodTypeAny, {
|
|
1143
1143
|
publicKey: string;
|
|
1144
1144
|
userId: string;
|
|
1145
|
-
deviceId: string;
|
|
1146
1145
|
publicBoxKey: string;
|
|
1146
|
+
deviceId: string;
|
|
1147
1147
|
userName?: string | undefined;
|
|
1148
1148
|
deviceName?: string | undefined;
|
|
1149
1149
|
}, {
|
|
1150
1150
|
publicKey: string;
|
|
1151
1151
|
userId: string;
|
|
1152
|
-
deviceId: string;
|
|
1153
1152
|
publicBoxKey: string;
|
|
1153
|
+
deviceId: string;
|
|
1154
1154
|
userName?: string | undefined;
|
|
1155
1155
|
deviceName?: string | undefined;
|
|
1156
1156
|
}>;
|
|
@@ -1164,15 +1164,15 @@ export declare const devicePairingTranscriptSchema: z.ZodObject<{
|
|
|
1164
1164
|
}, "strip", z.ZodTypeAny, {
|
|
1165
1165
|
publicKey: string;
|
|
1166
1166
|
userId: string;
|
|
1167
|
-
deviceId: string;
|
|
1168
1167
|
publicBoxKey: string;
|
|
1168
|
+
deviceId: string;
|
|
1169
1169
|
userName?: string | undefined;
|
|
1170
1170
|
deviceName?: string | undefined;
|
|
1171
1171
|
}, {
|
|
1172
1172
|
publicKey: string;
|
|
1173
1173
|
userId: string;
|
|
1174
|
-
deviceId: string;
|
|
1175
1174
|
publicBoxKey: string;
|
|
1175
|
+
deviceId: string;
|
|
1176
1176
|
userName?: string | undefined;
|
|
1177
1177
|
deviceName?: string | undefined;
|
|
1178
1178
|
}>;
|
|
@@ -1188,16 +1188,16 @@ export declare const devicePairingTranscriptSchema: z.ZodObject<{
|
|
|
1188
1188
|
sourceIdentity: {
|
|
1189
1189
|
publicKey: string;
|
|
1190
1190
|
userId: string;
|
|
1191
|
-
deviceId: string;
|
|
1192
1191
|
publicBoxKey: string;
|
|
1192
|
+
deviceId: string;
|
|
1193
1193
|
userName?: string | undefined;
|
|
1194
1194
|
deviceName?: string | undefined;
|
|
1195
1195
|
};
|
|
1196
1196
|
destinationIdentity: {
|
|
1197
1197
|
publicKey: string;
|
|
1198
1198
|
userId: string;
|
|
1199
|
-
deviceId: string;
|
|
1200
1199
|
publicBoxKey: string;
|
|
1200
|
+
deviceId: string;
|
|
1201
1201
|
userName?: string | undefined;
|
|
1202
1202
|
deviceName?: string | undefined;
|
|
1203
1203
|
};
|
|
@@ -1212,16 +1212,16 @@ export declare const devicePairingTranscriptSchema: z.ZodObject<{
|
|
|
1212
1212
|
sourceIdentity: {
|
|
1213
1213
|
publicKey: string;
|
|
1214
1214
|
userId: string;
|
|
1215
|
-
deviceId: string;
|
|
1216
1215
|
publicBoxKey: string;
|
|
1216
|
+
deviceId: string;
|
|
1217
1217
|
userName?: string | undefined;
|
|
1218
1218
|
deviceName?: string | undefined;
|
|
1219
1219
|
};
|
|
1220
1220
|
destinationIdentity: {
|
|
1221
1221
|
publicKey: string;
|
|
1222
1222
|
userId: string;
|
|
1223
|
-
deviceId: string;
|
|
1224
1223
|
publicBoxKey: string;
|
|
1224
|
+
deviceId: string;
|
|
1225
1225
|
userName?: string | undefined;
|
|
1226
1226
|
deviceName?: string | undefined;
|
|
1227
1227
|
};
|
|
@@ -1262,15 +1262,15 @@ export declare const pairingConfirmationContentsSchema: z.ZodObject<{
|
|
|
1262
1262
|
}, "strip", z.ZodTypeAny, {
|
|
1263
1263
|
publicKey: string;
|
|
1264
1264
|
userId: string;
|
|
1265
|
-
deviceId: string;
|
|
1266
1265
|
publicBoxKey: string;
|
|
1266
|
+
deviceId: string;
|
|
1267
1267
|
userName?: string | undefined;
|
|
1268
1268
|
deviceName?: string | undefined;
|
|
1269
1269
|
}, {
|
|
1270
1270
|
publicKey: string;
|
|
1271
1271
|
userId: string;
|
|
1272
|
-
deviceId: string;
|
|
1273
1272
|
publicBoxKey: string;
|
|
1273
|
+
deviceId: string;
|
|
1274
1274
|
userName?: string | undefined;
|
|
1275
1275
|
deviceName?: string | undefined;
|
|
1276
1276
|
}>;
|
|
@@ -1293,8 +1293,8 @@ export declare const pairingConfirmationContentsSchema: z.ZodObject<{
|
|
|
1293
1293
|
device: {
|
|
1294
1294
|
publicKey: string;
|
|
1295
1295
|
userId: string;
|
|
1296
|
-
deviceId: string;
|
|
1297
1296
|
publicBoxKey: string;
|
|
1297
|
+
deviceId: string;
|
|
1298
1298
|
userName?: string | undefined;
|
|
1299
1299
|
deviceName?: string | undefined;
|
|
1300
1300
|
};
|
|
@@ -1310,8 +1310,8 @@ export declare const pairingConfirmationContentsSchema: z.ZodObject<{
|
|
|
1310
1310
|
device: {
|
|
1311
1311
|
publicKey: string;
|
|
1312
1312
|
userId: string;
|
|
1313
|
-
deviceId: string;
|
|
1314
1313
|
publicBoxKey: string;
|
|
1314
|
+
deviceId: string;
|
|
1315
1315
|
userName?: string | undefined;
|
|
1316
1316
|
deviceName?: string | undefined;
|
|
1317
1317
|
};
|
|
@@ -1342,15 +1342,15 @@ export declare const pairingConfirmationSchema: z.ZodObject<{
|
|
|
1342
1342
|
}, "strip", z.ZodTypeAny, {
|
|
1343
1343
|
publicKey: string;
|
|
1344
1344
|
userId: string;
|
|
1345
|
-
deviceId: string;
|
|
1346
1345
|
publicBoxKey: string;
|
|
1346
|
+
deviceId: string;
|
|
1347
1347
|
userName?: string | undefined;
|
|
1348
1348
|
deviceName?: string | undefined;
|
|
1349
1349
|
}, {
|
|
1350
1350
|
publicKey: string;
|
|
1351
1351
|
userId: string;
|
|
1352
|
-
deviceId: string;
|
|
1353
1352
|
publicBoxKey: string;
|
|
1353
|
+
deviceId: string;
|
|
1354
1354
|
userName?: string | undefined;
|
|
1355
1355
|
deviceName?: string | undefined;
|
|
1356
1356
|
}>;
|
|
@@ -1375,8 +1375,8 @@ export declare const pairingConfirmationSchema: z.ZodObject<{
|
|
|
1375
1375
|
device: {
|
|
1376
1376
|
publicKey: string;
|
|
1377
1377
|
userId: string;
|
|
1378
|
-
deviceId: string;
|
|
1379
1378
|
publicBoxKey: string;
|
|
1379
|
+
deviceId: string;
|
|
1380
1380
|
userName?: string | undefined;
|
|
1381
1381
|
deviceName?: string | undefined;
|
|
1382
1382
|
};
|
|
@@ -1393,8 +1393,8 @@ export declare const pairingConfirmationSchema: z.ZodObject<{
|
|
|
1393
1393
|
device: {
|
|
1394
1394
|
publicKey: string;
|
|
1395
1395
|
userId: string;
|
|
1396
|
-
deviceId: string;
|
|
1397
1396
|
publicBoxKey: string;
|
|
1397
|
+
deviceId: string;
|
|
1398
1398
|
userName?: string | undefined;
|
|
1399
1399
|
deviceName?: string | undefined;
|
|
1400
1400
|
};
|
|
@@ -1460,15 +1460,15 @@ export declare const pairingInstallationReceiptContentsSchema: z.ZodObject<{
|
|
|
1460
1460
|
}, "strip", z.ZodTypeAny, {
|
|
1461
1461
|
publicKey: string;
|
|
1462
1462
|
userId: string;
|
|
1463
|
-
deviceId: string;
|
|
1464
1463
|
publicBoxKey: string;
|
|
1464
|
+
deviceId: string;
|
|
1465
1465
|
userName?: string | undefined;
|
|
1466
1466
|
deviceName?: string | undefined;
|
|
1467
1467
|
}, {
|
|
1468
1468
|
publicKey: string;
|
|
1469
1469
|
userId: string;
|
|
1470
|
-
deviceId: string;
|
|
1471
1470
|
publicBoxKey: string;
|
|
1471
|
+
deviceId: string;
|
|
1472
1472
|
userName?: string | undefined;
|
|
1473
1473
|
deviceName?: string | undefined;
|
|
1474
1474
|
}>;
|
|
@@ -1479,8 +1479,8 @@ export declare const pairingInstallationReceiptContentsSchema: z.ZodObject<{
|
|
|
1479
1479
|
initializedDevice: {
|
|
1480
1480
|
publicKey: string;
|
|
1481
1481
|
userId: string;
|
|
1482
|
-
deviceId: string;
|
|
1483
1482
|
publicBoxKey: string;
|
|
1483
|
+
deviceId: string;
|
|
1484
1484
|
userName?: string | undefined;
|
|
1485
1485
|
deviceName?: string | undefined;
|
|
1486
1486
|
};
|
|
@@ -1491,8 +1491,8 @@ export declare const pairingInstallationReceiptContentsSchema: z.ZodObject<{
|
|
|
1491
1491
|
initializedDevice: {
|
|
1492
1492
|
publicKey: string;
|
|
1493
1493
|
userId: string;
|
|
1494
|
-
deviceId: string;
|
|
1495
1494
|
publicBoxKey: string;
|
|
1495
|
+
deviceId: string;
|
|
1496
1496
|
userName?: string | undefined;
|
|
1497
1497
|
deviceName?: string | undefined;
|
|
1498
1498
|
};
|
|
@@ -1515,15 +1515,15 @@ export declare const signedPairingInstallationReceiptSchema: z.ZodObject<{
|
|
|
1515
1515
|
}, "strip", z.ZodTypeAny, {
|
|
1516
1516
|
publicKey: string;
|
|
1517
1517
|
userId: string;
|
|
1518
|
-
deviceId: string;
|
|
1519
1518
|
publicBoxKey: string;
|
|
1519
|
+
deviceId: string;
|
|
1520
1520
|
userName?: string | undefined;
|
|
1521
1521
|
deviceName?: string | undefined;
|
|
1522
1522
|
}, {
|
|
1523
1523
|
publicKey: string;
|
|
1524
1524
|
userId: string;
|
|
1525
|
-
deviceId: string;
|
|
1526
1525
|
publicBoxKey: string;
|
|
1526
|
+
deviceId: string;
|
|
1527
1527
|
userName?: string | undefined;
|
|
1528
1528
|
deviceName?: string | undefined;
|
|
1529
1529
|
}>;
|
|
@@ -1534,8 +1534,8 @@ export declare const signedPairingInstallationReceiptSchema: z.ZodObject<{
|
|
|
1534
1534
|
initializedDevice: {
|
|
1535
1535
|
publicKey: string;
|
|
1536
1536
|
userId: string;
|
|
1537
|
-
deviceId: string;
|
|
1538
1537
|
publicBoxKey: string;
|
|
1538
|
+
deviceId: string;
|
|
1539
1539
|
userName?: string | undefined;
|
|
1540
1540
|
deviceName?: string | undefined;
|
|
1541
1541
|
};
|
|
@@ -1546,8 +1546,8 @@ export declare const signedPairingInstallationReceiptSchema: z.ZodObject<{
|
|
|
1546
1546
|
initializedDevice: {
|
|
1547
1547
|
publicKey: string;
|
|
1548
1548
|
userId: string;
|
|
1549
|
-
deviceId: string;
|
|
1550
1549
|
publicBoxKey: string;
|
|
1550
|
+
deviceId: string;
|
|
1551
1551
|
userName?: string | undefined;
|
|
1552
1552
|
deviceName?: string | undefined;
|
|
1553
1553
|
};
|
|
@@ -1564,8 +1564,8 @@ export declare const signedPairingInstallationReceiptSchema: z.ZodObject<{
|
|
|
1564
1564
|
initializedDevice: {
|
|
1565
1565
|
publicKey: string;
|
|
1566
1566
|
userId: string;
|
|
1567
|
-
deviceId: string;
|
|
1568
1567
|
publicBoxKey: string;
|
|
1568
|
+
deviceId: string;
|
|
1569
1569
|
userName?: string | undefined;
|
|
1570
1570
|
deviceName?: string | undefined;
|
|
1571
1571
|
};
|
|
@@ -1580,8 +1580,8 @@ export declare const signedPairingInstallationReceiptSchema: z.ZodObject<{
|
|
|
1580
1580
|
initializedDevice: {
|
|
1581
1581
|
publicKey: string;
|
|
1582
1582
|
userId: string;
|
|
1583
|
-
deviceId: string;
|
|
1584
1583
|
publicBoxKey: string;
|
|
1584
|
+
deviceId: string;
|
|
1585
1585
|
userName?: string | undefined;
|
|
1586
1586
|
deviceName?: string | undefined;
|
|
1587
1587
|
};
|
|
@@ -33,9 +33,11 @@ export interface ResolveUserRowChangeParams {
|
|
|
33
33
|
* The record is the personal `Users` row when it exists, else the row already stored in the
|
|
34
34
|
* table being written. The rule:
|
|
35
35
|
*
|
|
36
|
-
* - Nothing stored yet: the
|
|
36
|
+
* - Nothing stored yet: bootstrap the identity; its initial anchors need an owner signature.
|
|
37
37
|
* - A different key: the anchors on record decide ({@link evaluatePresentedKey}). The
|
|
38
38
|
* presented anchor list is ignored; the applied row keeps the list on record.
|
|
39
|
+
* - The user's own row with their current keys: takes the anchor list from their personal row.
|
|
40
|
+
* - A row with no list keeps the list on record.
|
|
39
41
|
* - The same key and a different list: when nothing is on record the list is accepted as the
|
|
40
42
|
* bootstrap (an upgraded contact announcing its first anchors); when the personal record
|
|
41
43
|
* already holds the list it is accepted; otherwise the anchors on record must publish it
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.resolveUserRowChange = resolveUserRowChange;
|
|
4
|
+
const user_permissions_1 = require("../data/user-permissions");
|
|
4
5
|
const users_1 = require("../data/users");
|
|
5
6
|
const anchor_resolution_1 = require("./anchor-resolution");
|
|
6
7
|
const key_change_1 = require("./key-change");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return
|
|
8
|
+
/** `row` carrying `source`'s anchor list and the owner's signature over it, or no list. */
|
|
9
|
+
function withListOf(row, source) {
|
|
10
|
+
const { anchors: _anchors, anchorsSignature: _signature, ...profile } = row;
|
|
11
|
+
return { ...profile, ...(0, user_permissions_1.anchorFields)(source) };
|
|
12
|
+
}
|
|
13
|
+
/** `row` as a first record: its list only when the owner signed it, else no list. */
|
|
14
|
+
function bootstrap(row) {
|
|
15
|
+
return (0, user_permissions_1.hasSignedUserAnchors)(row) ? row : withListOf(row, {});
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
17
18
|
* The one decision for every path that writes another user's `Users` row: a direct save, a
|
|
@@ -20,9 +21,11 @@ function withAnchors(row, anchors) {
|
|
|
20
21
|
* The record is the personal `Users` row when it exists, else the row already stored in the
|
|
21
22
|
* table being written. The rule:
|
|
22
23
|
*
|
|
23
|
-
* - Nothing stored yet: the
|
|
24
|
+
* - Nothing stored yet: bootstrap the identity; its initial anchors need an owner signature.
|
|
24
25
|
* - A different key: the anchors on record decide ({@link evaluatePresentedKey}). The
|
|
25
26
|
* presented anchor list is ignored; the applied row keeps the list on record.
|
|
27
|
+
* - The user's own row with their current keys: takes the anchor list from their personal row.
|
|
28
|
+
* - A row with no list keeps the list on record.
|
|
26
29
|
* - The same key and a different list: when nothing is on record the list is accepted as the
|
|
27
30
|
* bootstrap (an upgraded contact announcing its first anchors); when the personal record
|
|
28
31
|
* already holds the list it is accepted; otherwise the anchors on record must publish it
|
|
@@ -31,12 +34,19 @@ function withAnchors(row, anchors) {
|
|
|
31
34
|
*/
|
|
32
35
|
async function resolveUserRowChange(params) {
|
|
33
36
|
const { existing, incoming, personalContext } = params;
|
|
34
|
-
if (!existing?.publicKey)
|
|
35
|
-
return { action: "apply", row: incoming };
|
|
36
37
|
const personal = await (0, users_1.Users)(personalContext).get(incoming.userId);
|
|
37
38
|
const record = personal?.publicKey ? personal : existing;
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
if (!record?.publicKey)
|
|
40
|
+
return { action: "apply", row: bootstrap(incoming) };
|
|
41
|
+
const recordAnchors = record.anchors ?? [];
|
|
42
|
+
// My own row with my current keys: my personal copy is the record of my anchors, so a copy
|
|
43
|
+
// anywhere else carries that list (a stale or replayed copy can't move it either way).
|
|
44
|
+
if (incoming.userId === personalContext.userContext.userId &&
|
|
45
|
+
personal?.publicKey === incoming.publicKey &&
|
|
46
|
+
personal.publicBoxKey === incoming.publicBoxKey) {
|
|
47
|
+
return { action: "apply", row: withListOf(incoming, personal) };
|
|
48
|
+
}
|
|
49
|
+
if (incoming.publicKey !== record.publicKey || incoming.publicBoxKey !== record.publicBoxKey) {
|
|
40
50
|
const decision = await (0, key_change_1.evaluatePresentedKey)({
|
|
41
51
|
dataContext: personalContext,
|
|
42
52
|
userId: incoming.userId,
|
|
@@ -47,18 +57,23 @@ async function resolveUserRowChange(params) {
|
|
|
47
57
|
if (decision.accepted) {
|
|
48
58
|
// The resolver may have just stored a confirmed list on the personal row.
|
|
49
59
|
const confirmed = await (0, users_1.Users)(personalContext).get(incoming.userId);
|
|
50
|
-
|
|
51
|
-
|
|
60
|
+
return {
|
|
61
|
+
action: "apply",
|
|
62
|
+
row: withListOf(incoming, confirmed?.anchors?.length ? confirmed : record),
|
|
63
|
+
};
|
|
52
64
|
}
|
|
53
65
|
if (decision.state === "pending" || decision.state === "recovery-pending") {
|
|
54
66
|
return { action: "defer", reason: "Key change is not confirmed by the anchors on record" };
|
|
55
67
|
}
|
|
56
68
|
return { action: "refuse", reason: "Key change is not confirmed by the anchors on record" };
|
|
57
69
|
}
|
|
58
|
-
if ((0, anchor_resolution_1.sameAnchorList)(
|
|
70
|
+
if ((0, anchor_resolution_1.sameAnchorList)(record.anchors, incoming.anchors))
|
|
59
71
|
return { action: "apply", row: incoming };
|
|
72
|
+
// A row with no list (a stub, a copy that dropped it) proposes no change: keep the record's.
|
|
73
|
+
if (!incoming.anchors?.length)
|
|
74
|
+
return { action: "apply", row: withListOf(incoming, record) };
|
|
60
75
|
if (recordAnchors.length === 0)
|
|
61
|
-
return { action: "apply", row: incoming };
|
|
76
|
+
return { action: "apply", row: bootstrap(incoming) };
|
|
62
77
|
if ((0, anchor_resolution_1.sameAnchorList)(personal?.anchors, incoming.anchors)) {
|
|
63
78
|
return { action: "apply", row: incoming };
|
|
64
79
|
}
|
|
@@ -76,6 +91,6 @@ async function resolveUserRowChange(params) {
|
|
|
76
91
|
reason: "Anchor list change is not confirmed by the anchors on record",
|
|
77
92
|
};
|
|
78
93
|
}
|
|
79
|
-
return { action: "apply", row:
|
|
94
|
+
return { action: "apply", row: withListOf(incoming, record) };
|
|
80
95
|
}
|
|
81
96
|
(0, users_1.setUserRowChangeGuard)((personalContext, incoming, existing) => resolveUserRowChange({ personalContext, incoming, existing }));
|
|
@@ -35,13 +35,15 @@ async function buildGroupApproval(userContext, input) {
|
|
|
35
35
|
groupId: input.groupId,
|
|
36
36
|
userId: userContext.userId,
|
|
37
37
|
role: data_1.GroupMemberRole.Founder,
|
|
38
|
+
publicKey: input.approverKeys.publicKey,
|
|
38
39
|
signature: "",
|
|
39
40
|
});
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
+
const approvingRole = await (0, data_1.getUserRole)(input.groupId, userContext.userId, userContext);
|
|
43
|
+
if (!approvingMember || approvingRole < data_1.GroupMemberRole.Admin) {
|
|
42
44
|
throw new Error("Only Admin or higher members can approve group joins");
|
|
43
45
|
}
|
|
44
|
-
if (input.role >
|
|
46
|
+
if (input.role > approvingRole) {
|
|
45
47
|
throw new Error("Cannot grant a role higher than your own");
|
|
46
48
|
}
|
|
47
49
|
const groupSecretKey = await (0, data_1.readGroupSecretKey)(userContext, input.groupId, input.approverKeys.secretKey);
|
|
@@ -58,27 +60,24 @@ async function buildGroupApproval(userContext, input) {
|
|
|
58
60
|
groupId: input.groupId,
|
|
59
61
|
userId: input.joiner.userId,
|
|
60
62
|
});
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (!adminMembers.some((member) => member.groupMemberId === approvingMember.groupMemberId)) {
|
|
80
|
-
adminMembers = [approvingMember, ...adminMembers];
|
|
81
|
-
}
|
|
63
|
+
// The same id on each approving device, while preserving an existing row's identity.
|
|
64
|
+
const membership = await groupMembersTable.signAndSave({
|
|
65
|
+
groupMemberId: (0, utils_1.deterministicGroupMemberId)(input.groupId, input.joiner.userId),
|
|
66
|
+
signature: "",
|
|
67
|
+
...existingMember,
|
|
68
|
+
groupId: input.groupId,
|
|
69
|
+
userId: input.joiner.userId,
|
|
70
|
+
role: input.role,
|
|
71
|
+
publicKey: input.joiner.publicKey,
|
|
72
|
+
deleted: undefined,
|
|
73
|
+
});
|
|
74
|
+
const authority = await (0, data_1.getGroupAuthority)(userContext, input.groupId);
|
|
75
|
+
const adminMembers = (await groupMembersTable.list({ groupId: input.groupId })).filter((member) => !member.deleted &&
|
|
76
|
+
member.role >= data_1.GroupMemberRole.Admin &&
|
|
77
|
+
authority.roles.get(member.userId) === member.role);
|
|
78
|
+
// A joiner must verify the complete grant chain before it can admit its first peer: the
|
|
79
|
+
// verified profile of each member whose key counts, and no other contact of the approver's.
|
|
80
|
+
const seedUsers = [...authority.keys.keys()].flatMap((userId) => authority.users.get(userId) ?? []);
|
|
82
81
|
const me = await (0, data_1.Users)(userContext.userDataContext).get(userContext.userId);
|
|
83
82
|
if (!me) {
|
|
84
83
|
throw new Error("My user object was not found in the DB. Is the user setup?");
|
|
@@ -100,7 +99,7 @@ async function buildGroupApproval(userContext, input) {
|
|
|
100
99
|
membership,
|
|
101
100
|
seed: {
|
|
102
101
|
groupMembers: adminMembers,
|
|
103
|
-
users:
|
|
102
|
+
users: seedUsers,
|
|
104
103
|
devices: seedDevices,
|
|
105
104
|
},
|
|
106
105
|
approver: {
|