shogun-core 4.2.1 → 4.2.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/browser/shogun-core.js +214 -91
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/gundb/db.js +214 -91
- package/package.json +1 -1
package/dist/gundb/db.js
CHANGED
|
@@ -383,7 +383,16 @@ class DataBase {
|
|
|
383
383
|
*/
|
|
384
384
|
async put(path, data) {
|
|
385
385
|
const node = this.navigateToPath(this.node, path);
|
|
386
|
-
return
|
|
386
|
+
return new Promise((resolve, reject) => {
|
|
387
|
+
node.put(data, (ack) => {
|
|
388
|
+
if (ack && ack.err) {
|
|
389
|
+
reject(new Error(ack.err));
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
resolve(ack);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
});
|
|
387
396
|
}
|
|
388
397
|
/**
|
|
389
398
|
* Sets data at the specified path
|
|
@@ -393,7 +402,16 @@ class DataBase {
|
|
|
393
402
|
*/
|
|
394
403
|
async set(path, data) {
|
|
395
404
|
const node = this.navigateToPath(this.node, path);
|
|
396
|
-
return
|
|
405
|
+
return new Promise((resolve, reject) => {
|
|
406
|
+
node.set(data, (ack) => {
|
|
407
|
+
if (ack && ack.err) {
|
|
408
|
+
reject(new Error(ack.err));
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
resolve(ack);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
});
|
|
397
415
|
}
|
|
398
416
|
/**
|
|
399
417
|
* Removes data at the specified path
|
|
@@ -402,7 +420,16 @@ class DataBase {
|
|
|
402
420
|
*/
|
|
403
421
|
async remove(path) {
|
|
404
422
|
const node = this.navigateToPath(this.node, path);
|
|
405
|
-
return
|
|
423
|
+
return new Promise((resolve, reject) => {
|
|
424
|
+
node.put(null, (ack) => {
|
|
425
|
+
if (ack && ack.err) {
|
|
426
|
+
reject(new Error(ack.err));
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
resolve(ack);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
});
|
|
406
433
|
}
|
|
407
434
|
/**
|
|
408
435
|
* Checks if a user is currently logged in
|
|
@@ -932,7 +959,11 @@ class DataBase {
|
|
|
932
959
|
if (normalizedUsername.length === 0) {
|
|
933
960
|
throw new Error("Username cannot be empty");
|
|
934
961
|
}
|
|
935
|
-
const existingUser = await
|
|
962
|
+
const existingUser = await new Promise((resolve) => {
|
|
963
|
+
this.gun.get(userPub).once((data) => {
|
|
964
|
+
resolve(data);
|
|
965
|
+
});
|
|
966
|
+
});
|
|
936
967
|
const isNewUser = !existingUser || !existingUser.alias;
|
|
937
968
|
// const isNewUser = true;
|
|
938
969
|
// Get user's encryption public key (epub) for comprehensive tracking
|
|
@@ -1025,14 +1056,17 @@ class DataBase {
|
|
|
1025
1056
|
const aliasNode = this.gun.get(`~@${username}`);
|
|
1026
1057
|
// For Gun.js alias validation to pass, the data must be exactly equal to the key
|
|
1027
1058
|
// The key is `~@${username}`, so we store that as the data
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1059
|
+
return new Promise((resolve) => {
|
|
1060
|
+
aliasNode.put(`~@${username}`, (ack) => {
|
|
1061
|
+
if (ack && ack.err) {
|
|
1062
|
+
console.error(`Error creating alias index: ${ack.err}`);
|
|
1063
|
+
resolve(false);
|
|
1064
|
+
}
|
|
1065
|
+
else {
|
|
1066
|
+
resolve(true);
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
});
|
|
1036
1070
|
}
|
|
1037
1071
|
catch (error) {
|
|
1038
1072
|
console.error(`Error creating alias index: ${error}`);
|
|
@@ -1044,18 +1078,20 @@ class DataBase {
|
|
|
1044
1078
|
*/
|
|
1045
1079
|
async createUsernameMapping(username, userPub) {
|
|
1046
1080
|
try {
|
|
1047
|
-
|
|
1048
|
-
.
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1081
|
+
return new Promise((resolve) => {
|
|
1082
|
+
this.node
|
|
1083
|
+
.get("usernames")
|
|
1084
|
+
.get(username)
|
|
1085
|
+
.put(userPub, (ack) => {
|
|
1086
|
+
if (ack && ack.err) {
|
|
1087
|
+
console.error(`Error creating username mapping: ${ack.err}`);
|
|
1088
|
+
resolve(false);
|
|
1089
|
+
}
|
|
1090
|
+
else {
|
|
1091
|
+
resolve(true);
|
|
1092
|
+
}
|
|
1093
|
+
});
|
|
1094
|
+
});
|
|
1059
1095
|
}
|
|
1060
1096
|
catch (error) {
|
|
1061
1097
|
console.error(`Error creating username mapping: ${error}`);
|
|
@@ -1074,18 +1110,20 @@ class DataBase {
|
|
|
1074
1110
|
registeredAt: Date.now().toString(),
|
|
1075
1111
|
lastSeen: Date.now().toString(),
|
|
1076
1112
|
};
|
|
1077
|
-
|
|
1078
|
-
.
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1113
|
+
return new Promise((resolve) => {
|
|
1114
|
+
this.node
|
|
1115
|
+
.get("users")
|
|
1116
|
+
.get(userPub)
|
|
1117
|
+
.put(userData, (ack) => {
|
|
1118
|
+
if (ack && ack.err) {
|
|
1119
|
+
console.error(`Error creating user registry: ${ack.err}`);
|
|
1120
|
+
resolve(false);
|
|
1121
|
+
}
|
|
1122
|
+
else {
|
|
1123
|
+
resolve(true);
|
|
1124
|
+
}
|
|
1125
|
+
});
|
|
1126
|
+
});
|
|
1089
1127
|
}
|
|
1090
1128
|
catch (error) {
|
|
1091
1129
|
console.error(`Error creating user registry: ${error}`);
|
|
@@ -1097,18 +1135,20 @@ class DataBase {
|
|
|
1097
1135
|
*/
|
|
1098
1136
|
async createReverseLookup(username, userPub) {
|
|
1099
1137
|
try {
|
|
1100
|
-
|
|
1101
|
-
.
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1138
|
+
return new Promise((resolve) => {
|
|
1139
|
+
this.node
|
|
1140
|
+
.get("userAliases")
|
|
1141
|
+
.get(userPub)
|
|
1142
|
+
.put(username, (ack) => {
|
|
1143
|
+
if (ack && ack.err) {
|
|
1144
|
+
console.error(`Error creating reverse lookup: ${ack.err}`);
|
|
1145
|
+
resolve(false);
|
|
1146
|
+
}
|
|
1147
|
+
else {
|
|
1148
|
+
resolve(true);
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
1151
|
+
});
|
|
1112
1152
|
}
|
|
1113
1153
|
catch (error) {
|
|
1114
1154
|
console.error(`Error creating reverse lookup: ${error}`);
|
|
@@ -1120,14 +1160,20 @@ class DataBase {
|
|
|
1120
1160
|
*/
|
|
1121
1161
|
async createEpubIndex(epub, userPub) {
|
|
1122
1162
|
try {
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1163
|
+
return new Promise((resolve) => {
|
|
1164
|
+
this.node
|
|
1165
|
+
.get("epubKeys")
|
|
1166
|
+
.get(epub)
|
|
1167
|
+
.put(userPub, (ack) => {
|
|
1168
|
+
if (ack && ack.err) {
|
|
1169
|
+
console.error(`Error creating epub index: ${ack.err}`);
|
|
1170
|
+
resolve(false);
|
|
1171
|
+
}
|
|
1172
|
+
else {
|
|
1173
|
+
resolve(true);
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
});
|
|
1131
1177
|
}
|
|
1132
1178
|
catch (error) {
|
|
1133
1179
|
console.error(`Error creating epub index: ${error}`);
|
|
@@ -1145,14 +1191,17 @@ class DataBase {
|
|
|
1145
1191
|
registeredAt: Date.now(),
|
|
1146
1192
|
lastSeen: Date.now(),
|
|
1147
1193
|
};
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1194
|
+
return new Promise((resolve) => {
|
|
1195
|
+
this.gun.get(userPub).put(userMetadata, (ack) => {
|
|
1196
|
+
if (ack && ack.err) {
|
|
1197
|
+
console.error(`Error creating user metadata: ${ack.err}`);
|
|
1198
|
+
resolve(false);
|
|
1199
|
+
}
|
|
1200
|
+
else {
|
|
1201
|
+
resolve(true);
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
});
|
|
1156
1205
|
}
|
|
1157
1206
|
catch (error) {
|
|
1158
1207
|
console.error(`Error creating user metadata: ${error}`);
|
|
@@ -1172,9 +1221,14 @@ class DataBase {
|
|
|
1172
1221
|
}
|
|
1173
1222
|
// Method 1: Try GunDB standard alias lookup (~@alias)
|
|
1174
1223
|
try {
|
|
1175
|
-
const aliasData =
|
|
1176
|
-
|
|
1177
|
-
|
|
1224
|
+
const aliasData = this.gun.get(`~@${normalizedAlias}`);
|
|
1225
|
+
const aliasDataObj = await new Promise((resolve) => {
|
|
1226
|
+
aliasData.once((data) => {
|
|
1227
|
+
resolve(data);
|
|
1228
|
+
});
|
|
1229
|
+
});
|
|
1230
|
+
if (aliasDataObj && aliasDataObj["~pubKeyOfUser"]) {
|
|
1231
|
+
const userPub = aliasDataObj["~pubKeyOfUser"]["#"] || aliasDataObj["~pubKeyOfUser"];
|
|
1178
1232
|
if (userPub) {
|
|
1179
1233
|
const userData = await this.getUserDataByPub(userPub);
|
|
1180
1234
|
if (userData) {
|
|
@@ -1188,10 +1242,14 @@ class DataBase {
|
|
|
1188
1242
|
}
|
|
1189
1243
|
// Method 2: Try username mapping (usernames/alias -> userPub)
|
|
1190
1244
|
try {
|
|
1191
|
-
const userPub = await
|
|
1192
|
-
.
|
|
1193
|
-
|
|
1194
|
-
|
|
1245
|
+
const userPub = await new Promise((resolve) => {
|
|
1246
|
+
this.node
|
|
1247
|
+
.get("usernames")
|
|
1248
|
+
.get(normalizedAlias)
|
|
1249
|
+
.once((data) => {
|
|
1250
|
+
resolve(data);
|
|
1251
|
+
});
|
|
1252
|
+
});
|
|
1195
1253
|
if (userPub) {
|
|
1196
1254
|
const userData = await this.getUserDataByPub(userPub);
|
|
1197
1255
|
if (userData) {
|
|
@@ -1221,7 +1279,14 @@ class DataBase {
|
|
|
1221
1279
|
}
|
|
1222
1280
|
// Method 1: Try user registry (users/userPub -> user data)
|
|
1223
1281
|
try {
|
|
1224
|
-
const userData = await
|
|
1282
|
+
const userData = await new Promise((resolve) => {
|
|
1283
|
+
this.node
|
|
1284
|
+
.get("users")
|
|
1285
|
+
.get(userPub)
|
|
1286
|
+
.once((data) => {
|
|
1287
|
+
resolve(data);
|
|
1288
|
+
});
|
|
1289
|
+
});
|
|
1225
1290
|
if (userData && userData.username) {
|
|
1226
1291
|
return {
|
|
1227
1292
|
userPub: userData.userPub || userPub,
|
|
@@ -1237,7 +1302,11 @@ class DataBase {
|
|
|
1237
1302
|
}
|
|
1238
1303
|
// Method 2: Try user's own node
|
|
1239
1304
|
try {
|
|
1240
|
-
const userNodeData = await
|
|
1305
|
+
const userNodeData = await new Promise((resolve) => {
|
|
1306
|
+
this.gun.get(userPub).once((data) => {
|
|
1307
|
+
resolve(data);
|
|
1308
|
+
});
|
|
1309
|
+
});
|
|
1241
1310
|
if (userNodeData && userNodeData.username) {
|
|
1242
1311
|
return {
|
|
1243
1312
|
userPub: userPub,
|
|
@@ -1268,7 +1337,14 @@ class DataBase {
|
|
|
1268
1337
|
if (!epub || typeof epub !== "string") {
|
|
1269
1338
|
return null;
|
|
1270
1339
|
}
|
|
1271
|
-
const userPub = await
|
|
1340
|
+
const userPub = await new Promise((resolve) => {
|
|
1341
|
+
this.node
|
|
1342
|
+
.get("epubKeys")
|
|
1343
|
+
.get(epub)
|
|
1344
|
+
.once((data) => {
|
|
1345
|
+
resolve(data);
|
|
1346
|
+
});
|
|
1347
|
+
});
|
|
1272
1348
|
return userPub || null;
|
|
1273
1349
|
}
|
|
1274
1350
|
catch (error) {
|
|
@@ -1286,7 +1362,14 @@ class DataBase {
|
|
|
1286
1362
|
if (!userPub || typeof userPub !== "string") {
|
|
1287
1363
|
return null;
|
|
1288
1364
|
}
|
|
1289
|
-
const alias = await
|
|
1365
|
+
const alias = await new Promise((resolve) => {
|
|
1366
|
+
this.node
|
|
1367
|
+
.get("userAliases")
|
|
1368
|
+
.get(userPub)
|
|
1369
|
+
.once((data) => {
|
|
1370
|
+
resolve(data);
|
|
1371
|
+
});
|
|
1372
|
+
});
|
|
1290
1373
|
return alias || null;
|
|
1291
1374
|
}
|
|
1292
1375
|
catch (error) {
|
|
@@ -1325,19 +1408,39 @@ class DataBase {
|
|
|
1325
1408
|
const timestamp = Date.now();
|
|
1326
1409
|
// Update in user registry
|
|
1327
1410
|
try {
|
|
1328
|
-
await
|
|
1329
|
-
.
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1411
|
+
await new Promise((resolve, reject) => {
|
|
1412
|
+
this.node
|
|
1413
|
+
.get("users")
|
|
1414
|
+
.get(userPub)
|
|
1415
|
+
.get("lastSeen")
|
|
1416
|
+
.put(timestamp, (ack) => {
|
|
1417
|
+
if (ack && ack.err) {
|
|
1418
|
+
reject(new Error(ack.err));
|
|
1419
|
+
}
|
|
1420
|
+
else {
|
|
1421
|
+
resolve();
|
|
1422
|
+
}
|
|
1423
|
+
});
|
|
1424
|
+
});
|
|
1334
1425
|
}
|
|
1335
1426
|
catch (error) {
|
|
1336
1427
|
console.error(`Failed to update lastSeen in user registry:`, error);
|
|
1337
1428
|
}
|
|
1338
1429
|
// Update in user's own node
|
|
1339
1430
|
try {
|
|
1340
|
-
await
|
|
1431
|
+
await new Promise((resolve, reject) => {
|
|
1432
|
+
this.gun
|
|
1433
|
+
.get(userPub)
|
|
1434
|
+
.get("lastSeen")
|
|
1435
|
+
.put(timestamp, (ack) => {
|
|
1436
|
+
if (ack && ack.err) {
|
|
1437
|
+
reject(new Error(ack.err));
|
|
1438
|
+
}
|
|
1439
|
+
else {
|
|
1440
|
+
resolve();
|
|
1441
|
+
}
|
|
1442
|
+
});
|
|
1443
|
+
});
|
|
1341
1444
|
}
|
|
1342
1445
|
catch (error) {
|
|
1343
1446
|
console.error(`Failed to update lastSeen in user node:`, error);
|
|
@@ -1588,10 +1691,19 @@ class DataBase {
|
|
|
1588
1691
|
questions: JSON.stringify(securityQuestions),
|
|
1589
1692
|
hint: encryptedHint,
|
|
1590
1693
|
};
|
|
1591
|
-
const ack = await
|
|
1592
|
-
.
|
|
1593
|
-
|
|
1594
|
-
|
|
1694
|
+
const ack = await new Promise((resolve, reject) => {
|
|
1695
|
+
this.node
|
|
1696
|
+
.get(userPub)
|
|
1697
|
+
.get("security")
|
|
1698
|
+
.put(securityPayload, (ack) => {
|
|
1699
|
+
if (ack && ack.err) {
|
|
1700
|
+
reject(new Error(ack.err));
|
|
1701
|
+
}
|
|
1702
|
+
else {
|
|
1703
|
+
resolve(ack);
|
|
1704
|
+
}
|
|
1705
|
+
});
|
|
1706
|
+
});
|
|
1595
1707
|
if (ack.err) {
|
|
1596
1708
|
console.error("Error saving security data to public graph:", ack.err);
|
|
1597
1709
|
throw new Error(ack.err);
|
|
@@ -1614,15 +1726,26 @@ class DataBase {
|
|
|
1614
1726
|
try {
|
|
1615
1727
|
// Find the user's data using direct lookup
|
|
1616
1728
|
const normalizedUsername = username.trim().toLowerCase();
|
|
1617
|
-
const userPub =
|
|
1618
|
-
|
|
1729
|
+
const userPub = await new Promise((resolve) => {
|
|
1730
|
+
this.node
|
|
1731
|
+
.get("usernames")
|
|
1732
|
+
.get(normalizedUsername)
|
|
1733
|
+
.once((data) => {
|
|
1734
|
+
resolve(data);
|
|
1735
|
+
});
|
|
1736
|
+
});
|
|
1619
1737
|
if (!userPub) {
|
|
1620
1738
|
return { success: false, error: "User not found" };
|
|
1621
1739
|
}
|
|
1622
1740
|
// Access the user's security data directly from their public key node
|
|
1623
|
-
const securityData = await
|
|
1624
|
-
.
|
|
1625
|
-
|
|
1741
|
+
const securityData = await new Promise((resolve) => {
|
|
1742
|
+
this.node
|
|
1743
|
+
.get(userPub)
|
|
1744
|
+
.get("security")
|
|
1745
|
+
.once((data) => {
|
|
1746
|
+
resolve(data);
|
|
1747
|
+
});
|
|
1748
|
+
});
|
|
1626
1749
|
if (!securityData || !securityData.hint) {
|
|
1627
1750
|
return {
|
|
1628
1751
|
success: false,
|