shogun-core 4.2.3 → 4.2.5
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 +120 -161
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/core.js +11 -0
- package/dist/gundb/db.js +109 -161
- package/dist/types/core.d.ts +5 -0
- package/dist/types/interfaces/shogun.d.ts +1 -0
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -41,6 +41,17 @@ class ShogunCore {
|
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Manually initialize the Shogun SDK (for testing or delayed initialization)
|
|
46
|
+
* @returns Promise that resolves when initialization is complete
|
|
47
|
+
*/
|
|
48
|
+
async initialize() {
|
|
49
|
+
// If already initialized, just wait a bit for any pending initialization
|
|
50
|
+
if (this._gun) {
|
|
51
|
+
return Promise.resolve();
|
|
52
|
+
}
|
|
53
|
+
return this.coreInitializer.initialize(this.config);
|
|
54
|
+
}
|
|
44
55
|
/**
|
|
45
56
|
* Access to the Gun instance
|
|
46
57
|
* @returns The Gun instance
|
package/dist/gundb/db.js
CHANGED
|
@@ -82,6 +82,7 @@ class DataBase {
|
|
|
82
82
|
constructor(gun, appScope = "shogun") {
|
|
83
83
|
this.user = null;
|
|
84
84
|
this.onAuthCallbacks = [];
|
|
85
|
+
console.log("[DB] Initializing DataBase");
|
|
85
86
|
// Initialize event emitter
|
|
86
87
|
this.eventEmitter = new eventEmitter_1.EventEmitter();
|
|
87
88
|
// Validate Gun instance
|
|
@@ -101,31 +102,38 @@ class DataBase {
|
|
|
101
102
|
throw new Error(`Gun instance is invalid: gun.on is not a function. Received gun.on type: ${typeof gun.on}`);
|
|
102
103
|
}
|
|
103
104
|
this.gun = gun;
|
|
105
|
+
console.log("[DB] Gun instance validated");
|
|
104
106
|
// Recall only if NOT disabled and there's a "pair" in sessionStorage
|
|
105
107
|
this.user = this.gun.user().recall({ sessionStorage: true });
|
|
108
|
+
console.log("[DB] User recall completed");
|
|
106
109
|
this.subscribeToAuthEvents();
|
|
110
|
+
console.log("[DB] Auth events subscribed");
|
|
107
111
|
this.crypto = crypto;
|
|
108
112
|
this.sea = sea_1.default;
|
|
109
113
|
this._rxjs = new rxjs_1.RxJS(this.gun);
|
|
110
114
|
this.node = null;
|
|
115
|
+
console.log("[DB] DataBase initialization completed");
|
|
111
116
|
}
|
|
112
117
|
/**
|
|
113
118
|
* Initialize the GunInstance asynchronously
|
|
114
119
|
* This method should be called after construction to perform async operations
|
|
115
120
|
*/
|
|
116
121
|
initialize(appScope = "shogun") {
|
|
122
|
+
console.log(`[DB] Initializing with appScope: ${appScope}`);
|
|
117
123
|
try {
|
|
118
124
|
const sessionResult = this.restoreSession();
|
|
125
|
+
console.log(`[DB] Session restore result: ${sessionResult.success ? "success" : "failed"}`);
|
|
119
126
|
this.node = this.gun.get(appScope);
|
|
127
|
+
console.log("[DB] App scope node initialized");
|
|
120
128
|
if (sessionResult.success) {
|
|
121
|
-
|
|
129
|
+
console.log("[DB] Session automatically restored");
|
|
122
130
|
}
|
|
123
131
|
else {
|
|
124
|
-
|
|
132
|
+
console.log("[DB] No previous session to restore");
|
|
125
133
|
}
|
|
126
134
|
}
|
|
127
135
|
catch (error) {
|
|
128
|
-
console.error("Error during automatic session restoration:", error);
|
|
136
|
+
console.error("[DB] Error during automatic session restoration:", error);
|
|
129
137
|
}
|
|
130
138
|
}
|
|
131
139
|
subscribeToAuthEvents() {
|
|
@@ -148,13 +156,16 @@ class DataBase {
|
|
|
148
156
|
* @param peer URL of the peer to add
|
|
149
157
|
*/
|
|
150
158
|
addPeer(peer) {
|
|
159
|
+
console.log(`[PEER] Adding peer: ${peer}`);
|
|
151
160
|
this.gun.opt({ peers: [peer] });
|
|
161
|
+
console.log(`[PEER] Peer added successfully`);
|
|
152
162
|
}
|
|
153
163
|
/**
|
|
154
164
|
* Removes a peer from the network
|
|
155
165
|
* @param peer URL of the peer to remove
|
|
156
166
|
*/
|
|
157
167
|
removePeer(peer) {
|
|
168
|
+
console.log(`[PEER] Removing peer: ${peer}`);
|
|
158
169
|
try {
|
|
159
170
|
// Get current peers from Gun instance
|
|
160
171
|
const gunOpts = this.gun._.opt;
|
|
@@ -166,13 +177,14 @@ class DataBase {
|
|
|
166
177
|
if (peerConnection && typeof peerConnection.close === "function") {
|
|
167
178
|
peerConnection.close();
|
|
168
179
|
}
|
|
180
|
+
console.log(`[PEER] Peer removed successfully`);
|
|
169
181
|
}
|
|
170
182
|
else {
|
|
171
|
-
console.error(`Peer not found in current connections: ${peer}`);
|
|
183
|
+
console.error(`[PEER] Peer not found in current connections: ${peer}`);
|
|
172
184
|
}
|
|
173
185
|
}
|
|
174
186
|
catch (error) {
|
|
175
|
-
console.error(`Error removing peer ${peer}:`, error);
|
|
187
|
+
console.error(`[PEER] Error removing peer ${peer}:`, error);
|
|
176
188
|
}
|
|
177
189
|
}
|
|
178
190
|
/**
|
|
@@ -383,16 +395,7 @@ class DataBase {
|
|
|
383
395
|
*/
|
|
384
396
|
async put(path, data) {
|
|
385
397
|
const node = this.navigateToPath(this.node, path);
|
|
386
|
-
return
|
|
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
|
-
});
|
|
398
|
+
return await node.put(data).then();
|
|
396
399
|
}
|
|
397
400
|
/**
|
|
398
401
|
* Sets data at the specified path
|
|
@@ -402,16 +405,7 @@ class DataBase {
|
|
|
402
405
|
*/
|
|
403
406
|
async set(path, data) {
|
|
404
407
|
const node = this.navigateToPath(this.node, path);
|
|
405
|
-
return
|
|
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
|
-
});
|
|
408
|
+
return await node.set(data).then();
|
|
415
409
|
}
|
|
416
410
|
/**
|
|
417
411
|
* Removes data at the specified path
|
|
@@ -420,16 +414,7 @@ class DataBase {
|
|
|
420
414
|
*/
|
|
421
415
|
async remove(path) {
|
|
422
416
|
const node = this.navigateToPath(this.node, path);
|
|
423
|
-
return
|
|
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
|
-
});
|
|
417
|
+
return await node.put(null).then();
|
|
433
418
|
}
|
|
434
419
|
/**
|
|
435
420
|
* Checks if a user is currently logged in
|
|
@@ -931,18 +916,20 @@ class DataBase {
|
|
|
931
916
|
});
|
|
932
917
|
}
|
|
933
918
|
async runPostAuthOnAuthResult(username, userPub, authResult) {
|
|
934
|
-
|
|
919
|
+
console.log(`[POSTAUTH] Starting post-auth setup for user: ${username}, userPub: ${userPub}`);
|
|
935
920
|
try {
|
|
921
|
+
console.log(`[POSTAUTH] Validating parameters for user: ${username}`);
|
|
936
922
|
// Validate required parameters
|
|
937
923
|
if (!username ||
|
|
938
924
|
typeof username !== "string" ||
|
|
939
925
|
username.trim().length === 0) {
|
|
926
|
+
console.error(`[POSTAUTH] Invalid username provided: ${username}`);
|
|
940
927
|
throw new Error("Invalid username provided");
|
|
941
928
|
}
|
|
942
929
|
if (!userPub ||
|
|
943
930
|
typeof userPub !== "string" ||
|
|
944
931
|
userPub.trim().length === 0) {
|
|
945
|
-
console.error("Invalid userPub provided:", {
|
|
932
|
+
console.error("[POSTAUTH] Invalid userPub provided:", {
|
|
946
933
|
userPub,
|
|
947
934
|
type: typeof userPub,
|
|
948
935
|
authResult,
|
|
@@ -951,34 +938,46 @@ class DataBase {
|
|
|
951
938
|
}
|
|
952
939
|
// Additional validation for userPub format
|
|
953
940
|
if (!userPub.includes(".") || userPub.length < 10) {
|
|
954
|
-
console.error(
|
|
941
|
+
console.error(`[POSTAUTH] Invalid userPub format: ${userPub}`);
|
|
955
942
|
throw new Error("Invalid userPub format");
|
|
956
943
|
}
|
|
944
|
+
console.log(`[POSTAUTH] Parameters validated for user: ${username}`);
|
|
957
945
|
// Normalize username to prevent path issues
|
|
958
946
|
const normalizedUsername = username.trim().toLowerCase();
|
|
959
947
|
if (normalizedUsername.length === 0) {
|
|
948
|
+
console.error(`[POSTAUTH] Normalized username is empty for user: ${username}`);
|
|
960
949
|
throw new Error("Username cannot be empty");
|
|
961
950
|
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
951
|
+
console.log(`[POSTAUTH] Normalized username: ${normalizedUsername}`);
|
|
952
|
+
console.log(`[POSTAUTH] Checking if user exists: ${userPub}`);
|
|
953
|
+
// Add timeout to prevent hanging
|
|
954
|
+
const existingUser = await Promise.race([
|
|
955
|
+
this.gun.get(userPub).then(),
|
|
956
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout checking user existence")), 5000)),
|
|
957
|
+
]).catch((error) => {
|
|
958
|
+
console.error(`[POSTAUTH] Error or timeout checking user existence:`, error);
|
|
959
|
+
return null;
|
|
966
960
|
});
|
|
961
|
+
console.log(`[POSTAUTH] User existence check completed, existingUser:`, existingUser);
|
|
967
962
|
const isNewUser = !existingUser || !existingUser.alias;
|
|
968
|
-
|
|
963
|
+
console.log(`[POSTAUTH] User is ${isNewUser ? "NEW" : "EXISTING"}: ${userPub}`);
|
|
969
964
|
// Get user's encryption public key (epub) for comprehensive tracking
|
|
970
965
|
const userInstance = this.gun.user();
|
|
971
966
|
const userSea = userInstance?._?.sea;
|
|
972
967
|
const epub = userSea?.epub;
|
|
968
|
+
console.log(`[POSTAUTH] User epub retrieved: ${epub ? "yes" : "no"}`);
|
|
973
969
|
// Enhanced user tracking system
|
|
970
|
+
console.log(`[POSTAUTH] Setting up comprehensive user tracking for: ${normalizedUsername}`);
|
|
974
971
|
const trackingResult = await this.setupComprehensiveUserTracking(normalizedUsername, userPub, epub);
|
|
975
972
|
if (!trackingResult) {
|
|
973
|
+
console.error(`[POSTAUTH] Comprehensive user tracking setup failed for: ${normalizedUsername}`);
|
|
976
974
|
return {
|
|
977
975
|
success: false,
|
|
978
976
|
error: "Comprehensive user tracking setup failed",
|
|
979
977
|
};
|
|
980
978
|
}
|
|
981
|
-
|
|
979
|
+
console.log(`[POSTAUTH] User tracking setup completed successfully for: ${normalizedUsername}`);
|
|
980
|
+
const result = {
|
|
982
981
|
success: true,
|
|
983
982
|
userPub: userPub,
|
|
984
983
|
username: normalizedUsername,
|
|
@@ -993,9 +992,11 @@ class DataBase {
|
|
|
993
992
|
}
|
|
994
993
|
: undefined,
|
|
995
994
|
};
|
|
995
|
+
console.log(`[POSTAUTH] Post-auth setup completed successfully for user: ${username}`);
|
|
996
|
+
return result;
|
|
996
997
|
}
|
|
997
998
|
catch (error) {
|
|
998
|
-
console.error(`Error in post-authentication setup
|
|
999
|
+
console.error(`[POSTAUTH] Error in post-authentication setup for ${username}:`, error);
|
|
999
1000
|
return {
|
|
1000
1001
|
success: false,
|
|
1001
1002
|
error: `Post-authentication setup failed: ${error}`,
|
|
@@ -1007,43 +1008,66 @@ class DataBase {
|
|
|
1007
1008
|
* Creates multiple indexes for efficient user discovery
|
|
1008
1009
|
*/
|
|
1009
1010
|
async setupComprehensiveUserTracking(username, userPub, epub) {
|
|
1011
|
+
console.log(`[TRACKING] Starting comprehensive user tracking setup for: ${username}, userPub: ${userPub}`);
|
|
1010
1012
|
try {
|
|
1011
1013
|
// 1. Create alias index: ~@alias -> userPub (for GunDB compatibility)
|
|
1014
|
+
console.log(`[TRACKING] Step 1: Creating alias index for ${username}`);
|
|
1012
1015
|
const aliasIndexResult = await this.createAliasIndex(username, userPub);
|
|
1013
1016
|
if (!aliasIndexResult) {
|
|
1017
|
+
console.error(`[TRACKING] Failed to create alias index for ${username}`);
|
|
1014
1018
|
return false;
|
|
1015
1019
|
}
|
|
1020
|
+
console.log(`[TRACKING] Step 1 completed: Alias index created for ${username}`);
|
|
1016
1021
|
// 2. Create username mapping: usernames/alias -> userPub
|
|
1022
|
+
console.log(`[TRACKING] Step 2: Creating username mapping for ${username}`);
|
|
1017
1023
|
const usernameMappingResult = await this.createUsernameMapping(username, userPub);
|
|
1018
1024
|
if (!usernameMappingResult) {
|
|
1025
|
+
console.error(`[TRACKING] Failed to create username mapping for ${username}`);
|
|
1019
1026
|
return false;
|
|
1020
1027
|
}
|
|
1028
|
+
console.log(`[TRACKING] Step 2 completed: Username mapping created for ${username}`);
|
|
1021
1029
|
// 3. Create user registry: users/userPub -> user data
|
|
1030
|
+
console.log(`[TRACKING] Step 3: Creating user registry for ${username}`);
|
|
1022
1031
|
const userRegistryResult = await this.createUserRegistry(username, userPub, epub);
|
|
1023
1032
|
if (!userRegistryResult) {
|
|
1033
|
+
console.error(`[TRACKING] Failed to create user registry for ${username}`);
|
|
1024
1034
|
return false;
|
|
1025
1035
|
}
|
|
1036
|
+
console.log(`[TRACKING] Step 3 completed: User registry created for ${username}`);
|
|
1026
1037
|
// 4. Create reverse lookup: userPub -> alias
|
|
1038
|
+
console.log(`[TRACKING] Step 4: Creating reverse lookup for ${username}`);
|
|
1027
1039
|
const reverseLookupResult = await this.createReverseLookup(username, userPub);
|
|
1028
1040
|
if (!reverseLookupResult) {
|
|
1041
|
+
console.error(`[TRACKING] Failed to create reverse lookup for ${username}`);
|
|
1029
1042
|
return false;
|
|
1030
1043
|
}
|
|
1044
|
+
console.log(`[TRACKING] Step 4 completed: Reverse lookup created for ${username}`);
|
|
1031
1045
|
// 5. Create epub index: epubKeys/epub -> userPub (for encryption lookups)
|
|
1032
1046
|
if (epub) {
|
|
1047
|
+
console.log(`[TRACKING] Step 5: Creating epub index for ${username}`);
|
|
1033
1048
|
const epubIndexResult = await this.createEpubIndex(epub, userPub);
|
|
1034
1049
|
if (!epubIndexResult) {
|
|
1050
|
+
console.error(`[TRACKING] Failed to create epub index for ${username}`);
|
|
1035
1051
|
return false;
|
|
1036
1052
|
}
|
|
1053
|
+
console.log(`[TRACKING] Step 5 completed: Epub index created for ${username}`);
|
|
1054
|
+
}
|
|
1055
|
+
else {
|
|
1056
|
+
console.log(`[TRACKING] Step 5 skipped: No epub available for ${username}`);
|
|
1037
1057
|
}
|
|
1038
1058
|
// 6. Create user metadata in user's own node
|
|
1059
|
+
console.log(`[TRACKING] Step 6: Creating user metadata for ${username}`);
|
|
1039
1060
|
const userMetadataResult = await this.createUserMetadata(username, userPub, epub);
|
|
1040
1061
|
if (!userMetadataResult) {
|
|
1062
|
+
console.error(`[TRACKING] Failed to create user metadata for ${username}`);
|
|
1041
1063
|
return false;
|
|
1042
1064
|
}
|
|
1065
|
+
console.log(`[TRACKING] Step 6 completed: User metadata created for ${username}`);
|
|
1066
|
+
console.log(`[TRACKING] Comprehensive user tracking setup completed successfully for: ${username}`);
|
|
1043
1067
|
return true;
|
|
1044
1068
|
}
|
|
1045
1069
|
catch (error) {
|
|
1046
|
-
console.error(`Error in comprehensive user tracking setup
|
|
1070
|
+
console.error(`[TRACKING] Error in comprehensive user tracking setup for ${username}:`, error);
|
|
1047
1071
|
// Don't throw - continue with other operations
|
|
1048
1072
|
return false;
|
|
1049
1073
|
}
|
|
@@ -1135,20 +1159,18 @@ class DataBase {
|
|
|
1135
1159
|
*/
|
|
1136
1160
|
async createReverseLookup(username, userPub) {
|
|
1137
1161
|
try {
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
});
|
|
1151
|
-
});
|
|
1162
|
+
const ack = await this.node
|
|
1163
|
+
.get("userAliases")
|
|
1164
|
+
.get(userPub)
|
|
1165
|
+
.put(username)
|
|
1166
|
+
.then();
|
|
1167
|
+
if (ack.err) {
|
|
1168
|
+
console.error(`Error creating reverse lookup: ${ack.err}`);
|
|
1169
|
+
return false;
|
|
1170
|
+
}
|
|
1171
|
+
else {
|
|
1172
|
+
return true;
|
|
1173
|
+
}
|
|
1152
1174
|
}
|
|
1153
1175
|
catch (error) {
|
|
1154
1176
|
console.error(`Error creating reverse lookup: ${error}`);
|
|
@@ -1221,14 +1243,9 @@ class DataBase {
|
|
|
1221
1243
|
}
|
|
1222
1244
|
// Method 1: Try GunDB standard alias lookup (~@alias)
|
|
1223
1245
|
try {
|
|
1224
|
-
const aliasData = this.gun.get(`~@${normalizedAlias}`);
|
|
1225
|
-
|
|
1226
|
-
aliasData
|
|
1227
|
-
resolve(data);
|
|
1228
|
-
});
|
|
1229
|
-
});
|
|
1230
|
-
if (aliasDataObj && aliasDataObj["~pubKeyOfUser"]) {
|
|
1231
|
-
const userPub = aliasDataObj["~pubKeyOfUser"]["#"] || aliasDataObj["~pubKeyOfUser"];
|
|
1246
|
+
const aliasData = await this.gun.get(`~@${normalizedAlias}`).then();
|
|
1247
|
+
if (aliasData && aliasData["~pubKeyOfUser"]) {
|
|
1248
|
+
const userPub = aliasData["~pubKeyOfUser"]["#"] || aliasData["~pubKeyOfUser"];
|
|
1232
1249
|
if (userPub) {
|
|
1233
1250
|
const userData = await this.getUserDataByPub(userPub);
|
|
1234
1251
|
if (userData) {
|
|
@@ -1242,14 +1259,10 @@ class DataBase {
|
|
|
1242
1259
|
}
|
|
1243
1260
|
// Method 2: Try username mapping (usernames/alias -> userPub)
|
|
1244
1261
|
try {
|
|
1245
|
-
const userPub = await
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
.once((data) => {
|
|
1250
|
-
resolve(data);
|
|
1251
|
-
});
|
|
1252
|
-
});
|
|
1262
|
+
const userPub = await this.node
|
|
1263
|
+
.get("usernames")
|
|
1264
|
+
.get(normalizedAlias)
|
|
1265
|
+
.then();
|
|
1253
1266
|
if (userPub) {
|
|
1254
1267
|
const userData = await this.getUserDataByPub(userPub);
|
|
1255
1268
|
if (userData) {
|
|
@@ -1279,14 +1292,7 @@ class DataBase {
|
|
|
1279
1292
|
}
|
|
1280
1293
|
// Method 1: Try user registry (users/userPub -> user data)
|
|
1281
1294
|
try {
|
|
1282
|
-
const userData = await
|
|
1283
|
-
this.node
|
|
1284
|
-
.get("users")
|
|
1285
|
-
.get(userPub)
|
|
1286
|
-
.once((data) => {
|
|
1287
|
-
resolve(data);
|
|
1288
|
-
});
|
|
1289
|
-
});
|
|
1295
|
+
const userData = await this.node.get("users").get(userPub).then();
|
|
1290
1296
|
if (userData && userData.username) {
|
|
1291
1297
|
return {
|
|
1292
1298
|
userPub: userData.userPub || userPub,
|
|
@@ -1302,11 +1308,7 @@ class DataBase {
|
|
|
1302
1308
|
}
|
|
1303
1309
|
// Method 2: Try user's own node
|
|
1304
1310
|
try {
|
|
1305
|
-
const userNodeData = await
|
|
1306
|
-
this.gun.get(userPub).once((data) => {
|
|
1307
|
-
resolve(data);
|
|
1308
|
-
});
|
|
1309
|
-
});
|
|
1311
|
+
const userNodeData = await this.gun.get(userPub).then();
|
|
1310
1312
|
if (userNodeData && userNodeData.username) {
|
|
1311
1313
|
return {
|
|
1312
1314
|
userPub: userPub,
|
|
@@ -1337,14 +1339,7 @@ class DataBase {
|
|
|
1337
1339
|
if (!epub || typeof epub !== "string") {
|
|
1338
1340
|
return null;
|
|
1339
1341
|
}
|
|
1340
|
-
const userPub = await
|
|
1341
|
-
this.node
|
|
1342
|
-
.get("epubKeys")
|
|
1343
|
-
.get(epub)
|
|
1344
|
-
.once((data) => {
|
|
1345
|
-
resolve(data);
|
|
1346
|
-
});
|
|
1347
|
-
});
|
|
1342
|
+
const userPub = await this.node.get("epubKeys").get(epub).then();
|
|
1348
1343
|
return userPub || null;
|
|
1349
1344
|
}
|
|
1350
1345
|
catch (error) {
|
|
@@ -1362,14 +1357,7 @@ class DataBase {
|
|
|
1362
1357
|
if (!userPub || typeof userPub !== "string") {
|
|
1363
1358
|
return null;
|
|
1364
1359
|
}
|
|
1365
|
-
const alias = await
|
|
1366
|
-
this.node
|
|
1367
|
-
.get("userAliases")
|
|
1368
|
-
.get(userPub)
|
|
1369
|
-
.once((data) => {
|
|
1370
|
-
resolve(data);
|
|
1371
|
-
});
|
|
1372
|
-
});
|
|
1360
|
+
const alias = await this.node.get("userAliases").get(userPub).then();
|
|
1373
1361
|
return alias || null;
|
|
1374
1362
|
}
|
|
1375
1363
|
catch (error) {
|
|
@@ -1408,39 +1396,19 @@ class DataBase {
|
|
|
1408
1396
|
const timestamp = Date.now();
|
|
1409
1397
|
// Update in user registry
|
|
1410
1398
|
try {
|
|
1411
|
-
await
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
if (ack && ack.err) {
|
|
1418
|
-
reject(new Error(ack.err));
|
|
1419
|
-
}
|
|
1420
|
-
else {
|
|
1421
|
-
resolve();
|
|
1422
|
-
}
|
|
1423
|
-
});
|
|
1424
|
-
});
|
|
1399
|
+
await this.node
|
|
1400
|
+
.get("users")
|
|
1401
|
+
.get(userPub)
|
|
1402
|
+
.get("lastSeen")
|
|
1403
|
+
.put(timestamp)
|
|
1404
|
+
.then();
|
|
1425
1405
|
}
|
|
1426
1406
|
catch (error) {
|
|
1427
1407
|
console.error(`Failed to update lastSeen in user registry:`, error);
|
|
1428
1408
|
}
|
|
1429
1409
|
// Update in user's own node
|
|
1430
1410
|
try {
|
|
1431
|
-
await
|
|
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
|
-
});
|
|
1411
|
+
await this.gun.get(userPub).get("lastSeen").put(timestamp).then();
|
|
1444
1412
|
}
|
|
1445
1413
|
catch (error) {
|
|
1446
1414
|
console.error(`Failed to update lastSeen in user node:`, error);
|
|
@@ -1691,19 +1659,10 @@ class DataBase {
|
|
|
1691
1659
|
questions: JSON.stringify(securityQuestions),
|
|
1692
1660
|
hint: encryptedHint,
|
|
1693
1661
|
};
|
|
1694
|
-
const ack = await
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
.put(securityPayload, (ack) => {
|
|
1699
|
-
if (ack && ack.err) {
|
|
1700
|
-
reject(new Error(ack.err));
|
|
1701
|
-
}
|
|
1702
|
-
else {
|
|
1703
|
-
resolve(ack);
|
|
1704
|
-
}
|
|
1705
|
-
});
|
|
1706
|
-
});
|
|
1662
|
+
const ack = await this.node.get(userPub)
|
|
1663
|
+
.get("security")
|
|
1664
|
+
.put(securityPayload)
|
|
1665
|
+
.then();
|
|
1707
1666
|
if (ack.err) {
|
|
1708
1667
|
console.error("Error saving security data to public graph:", ack.err);
|
|
1709
1668
|
throw new Error(ack.err);
|
|
@@ -1726,26 +1685,15 @@ class DataBase {
|
|
|
1726
1685
|
try {
|
|
1727
1686
|
// Find the user's data using direct lookup
|
|
1728
1687
|
const normalizedUsername = username.trim().toLowerCase();
|
|
1729
|
-
const userPub = await
|
|
1730
|
-
|
|
1731
|
-
.get("usernames")
|
|
1732
|
-
.get(normalizedUsername)
|
|
1733
|
-
.once((data) => {
|
|
1734
|
-
resolve(data);
|
|
1735
|
-
});
|
|
1736
|
-
});
|
|
1688
|
+
const userPub = (await this.node.get("usernames").get(normalizedUsername).then()) ||
|
|
1689
|
+
null;
|
|
1737
1690
|
if (!userPub) {
|
|
1738
1691
|
return { success: false, error: "User not found" };
|
|
1739
1692
|
}
|
|
1740
1693
|
// Access the user's security data directly from their public key node
|
|
1741
|
-
const securityData = await
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
.get("security")
|
|
1745
|
-
.once((data) => {
|
|
1746
|
-
resolve(data);
|
|
1747
|
-
});
|
|
1748
|
-
});
|
|
1694
|
+
const securityData = await this.node.get(userPub)
|
|
1695
|
+
.get("security")
|
|
1696
|
+
.then();
|
|
1749
1697
|
if (!securityData || !securityData.hint) {
|
|
1750
1698
|
return {
|
|
1751
1699
|
success: false,
|
package/dist/types/core.d.ts
CHANGED
|
@@ -40,6 +40,11 @@ export declare class ShogunCore implements IShogunCore {
|
|
|
40
40
|
* and plugin system.
|
|
41
41
|
*/
|
|
42
42
|
constructor(config: ShogunCoreConfig);
|
|
43
|
+
/**
|
|
44
|
+
* Manually initialize the Shogun SDK (for testing or delayed initialization)
|
|
45
|
+
* @returns Promise that resolves when initialization is complete
|
|
46
|
+
*/
|
|
47
|
+
initialize(): Promise<void>;
|
|
43
48
|
/**
|
|
44
49
|
* Access to the Gun instance
|
|
45
50
|
* @returns The Gun instance
|
|
@@ -123,6 +123,7 @@ export interface IShogunCore extends PluginManager {
|
|
|
123
123
|
removeAllListeners(eventName?: string | symbol): this;
|
|
124
124
|
emit<K extends keyof ShogunEventMap>(eventName: K, data?: ShogunEventMap[K] extends void ? never : ShogunEventMap[K]): boolean;
|
|
125
125
|
getRecentErrors(count?: number): ShogunError[];
|
|
126
|
+
initialize(): Promise<void>;
|
|
126
127
|
login(username: string, password: string, pair?: ISEAPair | null): Promise<AuthResult>;
|
|
127
128
|
loginWithPair(username: string, pair: ISEAPair): Promise<AuthResult>;
|
|
128
129
|
signUp(username: string, password?: string, pair?: ISEAPair | null): Promise<SignUpResult>;
|