shogun-core 3.3.4 → 3.3.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.
@@ -168632,7 +168632,7 @@ function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf
168632
168632
  var fs = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'fs'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
168633
168633
  var path = __webpack_require__(/*! path */ "./node_modules/path-browserify/index.js");
168634
168634
  var asyncSeries = __webpack_require__(/*! async/series */ "./node_modules/shogun-ipfs/node_modules/async/series.js");
168635
- var zlib = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'zlib'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
168635
+ var zlib = __webpack_require__(/*! zlib */ "?25c3");
168636
168636
  var _require = __webpack_require__(/*! triple-beam */ "./node_modules/shogun-ipfs/node_modules/triple-beam/index.js"),
168637
168637
  MESSAGE = _require.MESSAGE;
168638
168638
  var _require2 = __webpack_require__(/*! readable-stream */ "./node_modules/shogun-ipfs/node_modules/readable-stream/readable-browser.js"),
@@ -208850,356 +208850,642 @@ SHIP_05.NODES = {
208850
208850
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
208851
208851
 
208852
208852
  "use strict";
208853
+ /* provided dependency */ var Buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js")["Buffer"];
208853
208854
 
208854
208855
  /**
208855
- * SHIP-06: Ephemeral P2P Messaging Implementation
208856
+ * SHIP-06: Secure Vault Implementation
208856
208857
  *
208857
- * Two modes:
208858
- * 1. Standalone: new SHIP_06(gunPeers[], roomId) - NO authentication!
208859
- * - Uses ShogunCore internally with silent: true, disableAutoRecall: true
208860
- * - Zero logs, zero storage, pure relay communication
208861
- * - Room hashed with Web Crypto API SHA-256 for deterministic IDs
208858
+ * Vault crittografato decentralizzato che dipende da SHIP-00 per l'identità.
208862
208859
  *
208863
- * 2. With Identity: new SHIP_06(ISHIP_00, roomId) - Authenticated sessions
208864
- * - Uses existing Gun instance from SHIP-00
208865
- * - All ShogunCore features available
208860
+ * Dipendenze:
208861
+ * - SHIP-00 (Identity & Authentication) - per gestione utenti e chiavi
208862
+ * - GunDB - per storage decentralizzato P2P
208863
+ * - SEA - per crittografia AES-256-GCM
208866
208864
  *
208867
- * Architecture:
208868
- * - Gun Relay for P2P communication (no WebRTC complexity!)
208869
- * - SEA for ephemeral key generation and ECDH encryption
208870
- * - Pure relay mode: radisk: false, localStorage: false, multicast: false
208865
+ * Ispirato a: https://github.com/draeder/gunsafe
208871
208866
  */
208872
208867
  Object.defineProperty(exports, "__esModule", ({ value: true }));
208873
208868
  exports.SHIP_06 = void 0;
208874
- const core_1 = __webpack_require__(/*! ../../src/core */ "./src/core.ts"); // ← Import diretto, NON da index!
208875
208869
  // ============================================================================
208876
- // IMPLEMENTATION - STANDALONE VERSION (No ShogunCore dependency!)
208870
+ // IMPLEMENTATION
208877
208871
  // ============================================================================
208872
+ /**
208873
+ * SHIP-06 Reference Implementation
208874
+ *
208875
+ * Questa implementazione dipende da ISHIP_00 per tutte le operazioni di identità.
208876
+ * Si concentra esclusivamente sulla logica del vault crittografato.
208877
+ */
208878
208878
  class SHIP_06 {
208879
- // Constructor overload: with identity OR standalone
208880
- constructor(identityOrPeers, roomId, config) {
208881
- this.identity = null;
208882
- // State
208883
- this.connected = false;
208884
- this.swarmId = "";
208885
- this.myAddress = "";
208886
- this.myPair = null;
208879
+ /**
208880
+ * Constructor
208881
+ * @param identity ISHIP_00 instance for identity operations
208882
+ * @param vaultNodeName Optional custom vault node name
208883
+ */
208884
+ constructor(identity, vaultNodeName) {
208885
+ this.initialized = false;
208887
208886
  // Gun nodes
208888
- this.gun = null;
208889
- this.sea = null;
208890
- this.roomNode = null;
208891
- this.presenceNode = null;
208892
- this.messagesNode = null;
208893
- // Peers
208894
- this.peers = new Map();
208895
- // Event handlers
208896
- this.messageHandlers = [];
208897
- this.encryptedMessageHandlers = [];
208898
- this.peerSeenHandlers = [];
208899
- this.peerLeftHandlers = [];
208900
- // Heartbeat & cleanup
208901
- this.heartbeatInterval = null;
208902
- this.processedMessages = new Set();
208903
- this.roomId = roomId;
208904
- this.config = {
208905
- debug: config?.debug || false,
208906
- timeout: 30000,
208907
- };
208908
- if (Array.isArray(identityOrPeers)) {
208909
- // STANDALONE MODE - ShogunCore with silent mode
208910
- const shogunCore = new core_1.ShogunCore({
208911
- gunOptions: {
208912
- peers: identityOrPeers,
208913
- radisk: false,
208914
- localStorage: false,
208915
- multicast: false,
208916
- axe: false,
208917
- },
208918
- silent: true,
208919
- disableAutoRecall: true,
208920
- });
208921
- this.gun = shogunCore.db.gun;
208922
- this.sea = shogunCore.db.sea;
208923
- this.identity = null;
208924
- }
208925
- else {
208926
- // WITH IDENTITY MODE - use existing Gun from SHIP-00
208927
- if (!identityOrPeers.isLoggedIn()) {
208928
- throw new Error("User must be authenticated via SHIP-00");
208929
- }
208930
- this.identity = identityOrPeers;
208931
- const shogun = identityOrPeers.getShogun();
208932
- this.gun = shogun.db.gun;
208887
+ this.vaultNode = null;
208888
+ this.recordsNode = null;
208889
+ this.metadataNode = null;
208890
+ if (!identity.isLoggedIn()) {
208891
+ throw new Error("User must be authenticated via SHIP-00 before using SHIP-06");
208933
208892
  }
208893
+ this.identity = identity;
208894
+ this.vaultNodeName = vaultNodeName || SHIP_06.DEFAULT_NODE_NAME;
208895
+ console.log("✅ SHIP-06 initialized");
208934
208896
  }
208897
+ /**
208898
+ * Get identity provider
208899
+ */
208935
208900
  getIdentity() {
208936
- if (!this.identity) {
208937
- throw new Error("No identity - SHIP-06 running in standalone mode");
208938
- }
208939
208901
  return this.identity;
208940
208902
  }
208941
- async connect() {
208942
- if (this.connected)
208903
+ // ========================================================================
208904
+ // INITIALIZATION
208905
+ // ========================================================================
208906
+ /**
208907
+ * Initialize vault
208908
+ */
208909
+ async initialize() {
208910
+ if (this.initialized) {
208911
+ console.warn("⚠️ Vault already initialized");
208943
208912
  return;
208944
- // Generate ephemeral pair
208945
- this.myPair = await this.sea.pair();
208946
- if (!this.myPair) {
208947
- throw new Error("Failed to generate SEA pair");
208948
- }
208949
- this.myAddress = this.myPair.pub.substring(0, 16);
208950
- // Hash room ID DETERMINISTICAMENTE - Simple SHA256 hash
208951
- if (this.identity) {
208952
- const shogun = this.identity.getShogun();
208953
- this.swarmId = await shogun.db.crypto.hashText(this.roomId);
208954
208913
  }
208955
- else {
208956
- // Standalone: use simple deterministic hash
208957
- // SEA.work with different calls produces different results, so we use a simple hash
208958
- const encoder = new TextEncoder();
208959
- const data = encoder.encode(this.roomId);
208960
- // Use Web Crypto API for deterministic SHA-256 hash
208961
- if (typeof crypto !== "undefined" && crypto.subtle) {
208962
- const hashBuffer = await crypto.subtle.digest("SHA-256", data);
208963
- const hashArray = Array.from(new Uint8Array(hashBuffer));
208964
- this.swarmId = hashArray
208965
- .map((b) => b.toString(16).padStart(2, "0"))
208966
- .join("");
208914
+ try {
208915
+ // Get Gun instance from identity
208916
+ const shogun = this.identity.getShogun();
208917
+ if (!shogun || !shogun.db) {
208918
+ throw new Error("Cannot access ShogunCore from identity");
208919
+ }
208920
+ const gun = shogun.db.gun;
208921
+ if (!gun) {
208922
+ throw new Error("Cannot access GunDB");
208923
+ }
208924
+ // Get user node
208925
+ const userNode = gun.user();
208926
+ if (!userNode || !userNode.is) {
208927
+ throw new Error("User not authenticated in Gun");
208928
+ }
208929
+ // Setup vault nodes
208930
+ this.vaultNode = userNode.get(this.vaultNodeName);
208931
+ this.recordsNode = this.vaultNode.get("records");
208932
+ this.metadataNode = this.vaultNode.get("metadata");
208933
+ // Initialize metadata
208934
+ const existingMetadata = await this.metadataNode.then();
208935
+ if (!existingMetadata || !existingMetadata.version) {
208936
+ await this.metadataNode.put({
208937
+ version: SHIP_06.VAULT_VERSION,
208938
+ created: Date.now().toString(),
208939
+ recordCount: "0",
208940
+ }).then();
208941
+ console.log("📦 Vault metadata initialized");
208967
208942
  }
208968
208943
  else {
208969
- // Fallback: simple deterministic hash
208970
- let hash = "";
208971
- for (let i = 0; i < this.roomId.length; i++) {
208972
- hash += this.roomId.charCodeAt(i).toString(16);
208973
- }
208974
- this.swarmId = hash;
208944
+ console.log("📦 Existing vault found");
208975
208945
  }
208946
+ this.initialized = true;
208947
+ console.log("✅ Vault initialized successfully");
208976
208948
  }
208977
- if (this.config.debug) {
208978
- console.log(`🔑 Room ID: "${this.roomId}"`);
208979
- console.log(`🔒 Swarm ID (hashed): ${this.swarmId.substring(0, 32)}...`);
208980
- }
208981
- // Setup Gun nodes
208982
- this.roomNode = this.gun.get("ephemeral").get(this.swarmId);
208983
- this.presenceNode = this.roomNode.get("presence");
208984
- this.messagesNode = this.roomNode.get("messages");
208985
- // Announce presence
208986
- await this.announcePresence();
208987
- // Start listening
208988
- this.listenForPeers();
208989
- this.listenForMessages();
208990
- // Start heartbeat
208991
- this.startHeartbeat();
208992
- this.connected = true;
208993
- }
208994
- disconnect() {
208995
- if (this.heartbeatInterval) {
208996
- clearInterval(this.heartbeatInterval);
208997
- }
208998
- if (this.presenceNode && this.myAddress) {
208999
- this.presenceNode.get(this.myAddress).put(null);
208949
+ catch (error) {
208950
+ console.error("❌ Error initializing vault:", error);
208951
+ throw error;
209000
208952
  }
209001
- this.connected = false;
209002
- }
209003
- isConnected() {
209004
- return this.connected;
209005
208953
  }
209006
- getSwarmId() {
209007
- return this.swarmId;
209008
- }
209009
- getAddress() {
209010
- return this.myAddress;
208954
+ /**
208955
+ * Check if vault is initialized
208956
+ */
208957
+ isInitialized() {
208958
+ return this.initialized;
209011
208959
  }
209012
208960
  // ========================================================================
209013
- // PRESENCE
208961
+ // CRUD OPERATIONS
209014
208962
  // ========================================================================
209015
- async announcePresence() {
209016
- if (!this.myPair)
209017
- return;
209018
- const presenceData = {
209019
- address: this.myAddress,
209020
- pub: this.myPair.pub,
209021
- epub: this.myPair.epub,
209022
- timestamp: Date.now(),
209023
- };
209024
- if (this.config.debug) {
209025
- console.log(`📡 Announcing presence: ${this.myAddress}`);
209026
- }
209027
- await this.presenceNode.get(this.myAddress).put(presenceData);
209028
- }
209029
- startHeartbeat() {
209030
- this.heartbeatInterval = setInterval(() => {
209031
- if (this.myPair) {
209032
- this.presenceNode.get(this.myAddress).put({
209033
- address: this.myAddress,
209034
- pub: this.myPair.pub,
209035
- epub: this.myPair.epub,
209036
- timestamp: Date.now(),
209037
- });
209038
- }
209039
- }, 3000);
208963
+ /**
208964
+ * Store encrypted record in vault
208965
+ */
208966
+ async put(name, data, metadata) {
208967
+ if (!this.initialized) {
208968
+ return { success: false, error: "Vault not initialized" };
208969
+ }
208970
+ if (!name || name.trim() === "") {
208971
+ return { success: false, error: "Record name cannot be empty" };
208972
+ }
208973
+ try {
208974
+ // Get crypto and key pair
208975
+ const shogun = this.identity.getShogun();
208976
+ const crypto = shogun?.db?.crypto;
208977
+ const pair = this.identity.getKeyPair();
208978
+ if (!crypto || !pair) {
208979
+ return { success: false, error: "Cannot access encryption" };
208980
+ }
208981
+ // Encrypt data
208982
+ const dataString = JSON.stringify(data);
208983
+ const encryptedData = await crypto.encrypt(dataString, pair.epriv);
208984
+ // Encrypt metadata if provided
208985
+ let encryptedMetadata;
208986
+ if (metadata) {
208987
+ const metadataString = JSON.stringify(metadata);
208988
+ encryptedMetadata = await crypto.encrypt(metadataString, pair.epriv);
208989
+ }
208990
+ // Create encrypted record
208991
+ const record = {
208992
+ data: encryptedData,
208993
+ created: Date.now().toString(),
208994
+ updated: Date.now().toString(),
208995
+ deleted: false,
208996
+ metadata: encryptedMetadata,
208997
+ };
208998
+ // Store in vault
208999
+ await this.recordsNode.get(name).put(record).then();
209000
+ // Update vault metadata
209001
+ await this.updateRecordCount();
209002
+ console.log(`✅ Record stored: ${name}`);
209003
+ return {
209004
+ success: true,
209005
+ recordName: name,
209006
+ };
209007
+ }
209008
+ catch (error) {
209009
+ console.error("❌ Error storing record:", error);
209010
+ return {
209011
+ success: false,
209012
+ error: error.message,
209013
+ };
209014
+ }
209040
209015
  }
209041
- listenForPeers() {
209042
- if (this.config.debug) {
209043
- console.log(`👂 Listening for peers on: ephemeral/${this.swarmId.substring(0, 20)}...`);
209016
+ /**
209017
+ * Retrieve and decrypt record from vault
209018
+ */
209019
+ async get(name, options) {
209020
+ if (!this.initialized) {
209021
+ console.error("❌ Vault not initialized");
209022
+ return null;
209044
209023
  }
209045
- this.presenceNode.map().on((data, address) => {
209046
- if (!data || !address || address === "_" || address === this.myAddress) {
209047
- return;
209024
+ try {
209025
+ // Retrieve encrypted record
209026
+ const encryptedRecord = await this.recordsNode.get(name).then();
209027
+ if (!encryptedRecord || !encryptedRecord.data) {
209028
+ return null;
209048
209029
  }
209049
- if (!data.pub || !data.epub || !data.timestamp) {
209050
- return;
209030
+ // Check if deleted (unless includeDeleted)
209031
+ if (encryptedRecord.deleted && !options?.includeDeleted) {
209032
+ return null;
209051
209033
  }
209052
- const age = Date.now() - (data.timestamp || 0);
209053
- const isOnline = age < 10000;
209054
- if (!this.peers.has(address)) {
209055
- this.peers.set(address, {
209056
- address,
209057
- pubKey: data.pub,
209058
- epub: data.epub,
209059
- pub: data.pub,
209060
- connectedAt: data.timestamp,
209061
- });
209062
- if (isOnline) {
209063
- this.peerSeenHandlers.forEach((h) => h(address));
209034
+ // Get crypto and key pair
209035
+ const shogun = this.identity.getShogun();
209036
+ const crypto = shogun?.db?.crypto;
209037
+ const pair = this.identity.getKeyPair();
209038
+ if (!crypto || !pair) {
209039
+ console.error("❌ Cannot access encryption");
209040
+ return null;
209041
+ }
209042
+ // Decrypt data
209043
+ const decryptedDataString = await crypto.decrypt(encryptedRecord.data, pair.epriv);
209044
+ // Try to parse JSON, if it fails, use the string as-is
209045
+ let decryptedData;
209046
+ try {
209047
+ decryptedData = JSON.parse(decryptedDataString);
209048
+ }
209049
+ catch (parseError) {
209050
+ // If JSON.parse fails, the data is likely a plain string
209051
+ // This can happen if the data was already a string value
209052
+ decryptedData = decryptedDataString;
209053
+ }
209054
+ // Decrypt metadata if present
209055
+ let decryptedMetadata;
209056
+ if (encryptedRecord.metadata) {
209057
+ try {
209058
+ const metadataString = await crypto.decrypt(encryptedRecord.metadata, pair.epriv);
209059
+ decryptedMetadata = JSON.parse(metadataString);
209064
209060
  }
209061
+ catch (error) {
209062
+ // Metadata decryption failed, continue without it
209063
+ console.warn("⚠️ Could not decrypt metadata");
209064
+ }
209065
+ }
209066
+ // Create vault record
209067
+ const vaultRecord = {
209068
+ name,
209069
+ data: decryptedData,
209070
+ created: parseInt(encryptedRecord.created),
209071
+ updated: parseInt(encryptedRecord.updated),
209072
+ deleted: encryptedRecord.deleted,
209073
+ metadata: decryptedMetadata,
209074
+ };
209075
+ return vaultRecord;
209076
+ }
209077
+ catch (error) {
209078
+ console.error("❌ Error retrieving record:", error);
209079
+ return null;
209080
+ }
209081
+ }
209082
+ /**
209083
+ * Delete record from vault (soft delete)
209084
+ */
209085
+ async delete(name) {
209086
+ if (!this.initialized) {
209087
+ return { success: false, error: "Vault not initialized" };
209088
+ }
209089
+ try {
209090
+ if (name) {
209091
+ // Delete specific record (soft delete)
209092
+ const existingRecord = await this.recordsNode.get(name).then();
209093
+ if (!existingRecord) {
209094
+ return { success: false, error: `Record ${name} not found` };
209095
+ }
209096
+ // Mark as deleted
209097
+ await this.recordsNode.get(name).get("deleted").put(true).then();
209098
+ await this.recordsNode.get(name).get("updated").put(Date.now().toString()).then();
209099
+ console.log(`🗑️ Record soft-deleted: ${name}`);
209100
+ return {
209101
+ success: true,
209102
+ recordName: name,
209103
+ };
209065
209104
  }
209066
209105
  else {
209067
- const peer = this.peers.get(address);
209068
- if (peer && data.timestamp > peer.connectedAt) {
209069
- peer.connectedAt = data.timestamp;
209070
- peer.pubKey = data.pub;
209071
- peer.epub = data.epub;
209072
- peer.pub = data.pub;
209106
+ // Delete all records (soft delete)
209107
+ const allRecords = await this.list({ includeDeleted: false });
209108
+ let deletedCount = 0;
209109
+ for (const recordName of allRecords) {
209110
+ const result = await this.delete(recordName);
209111
+ if (result.success) {
209112
+ deletedCount++;
209113
+ }
209073
209114
  }
209115
+ console.log(`🗑️ ${deletedCount} records soft-deleted`);
209116
+ return {
209117
+ success: true,
209118
+ recordCount: deletedCount,
209119
+ };
209074
209120
  }
209075
- });
209121
+ }
209122
+ catch (error) {
209123
+ console.error("❌ Error deleting record:", error);
209124
+ return {
209125
+ success: false,
209126
+ error: error.message,
209127
+ };
209128
+ }
209129
+ }
209130
+ /**
209131
+ * List all record names in vault
209132
+ */
209133
+ async list(options) {
209134
+ if (!this.initialized) {
209135
+ console.error("❌ Vault not initialized");
209136
+ return [];
209137
+ }
209138
+ try {
209139
+ return new Promise((resolve) => {
209140
+ const recordNames = [];
209141
+ this.recordsNode.map().once(async (record, key) => {
209142
+ // Skip metadata
209143
+ if (!record || typeof record !== "object" || key === "_") {
209144
+ return;
209145
+ }
209146
+ // Skip deleted records (unless includeDeleted)
209147
+ if (record.deleted && !options?.includeDeleted) {
209148
+ return;
209149
+ }
209150
+ // Apply filters if provided
209151
+ if (options?.filterByType || options?.filterByTag) {
209152
+ try {
209153
+ // Need to decrypt metadata to filter
209154
+ const shogun = this.identity.getShogun();
209155
+ const crypto = shogun?.db?.crypto;
209156
+ const pair = this.identity.getKeyPair();
209157
+ if (crypto && pair && record.metadata) {
209158
+ const metadataString = await crypto.decrypt(record.metadata, pair.epriv);
209159
+ const metadata = JSON.parse(metadataString);
209160
+ // Filter by type
209161
+ if (options.filterByType && metadata.type !== options.filterByType) {
209162
+ return;
209163
+ }
209164
+ // Filter by tag
209165
+ if (options.filterByTag) {
209166
+ if (!metadata.tags || !metadata.tags.includes(options.filterByTag)) {
209167
+ return;
209168
+ }
209169
+ }
209170
+ }
209171
+ }
209172
+ catch (error) {
209173
+ // Decryption failed, skip
209174
+ return;
209175
+ }
209176
+ }
209177
+ recordNames.push(key);
209178
+ });
209179
+ // Wait for Gun to return all records
209180
+ setTimeout(() => {
209181
+ // Sort if requested
209182
+ if (options?.sortBy) {
209183
+ // For now, just sort by name
209184
+ recordNames.sort();
209185
+ if (options.sortDesc) {
209186
+ recordNames.reverse();
209187
+ }
209188
+ }
209189
+ resolve(recordNames);
209190
+ }, 1000);
209191
+ });
209192
+ }
209193
+ catch (error) {
209194
+ console.error("❌ Error listing records:", error);
209195
+ return [];
209196
+ }
209197
+ }
209198
+ /**
209199
+ * Check if record exists
209200
+ */
209201
+ async exists(name) {
209202
+ const record = await this.get(name);
209203
+ return record !== null;
209204
+ }
209205
+ /**
209206
+ * Update existing record
209207
+ */
209208
+ async update(name, data) {
209209
+ if (!this.initialized) {
209210
+ return { success: false, error: "Vault not initialized" };
209211
+ }
209212
+ try {
209213
+ // Check if record exists
209214
+ const existingRecord = await this.get(name);
209215
+ if (!existingRecord) {
209216
+ return { success: false, error: `Record ${name} not found` };
209217
+ }
209218
+ // Keep existing metadata
209219
+ return await this.put(name, data, existingRecord.metadata);
209220
+ }
209221
+ catch (error) {
209222
+ console.error("❌ Error updating record:", error);
209223
+ return {
209224
+ success: false,
209225
+ error: error.message,
209226
+ };
209227
+ }
209076
209228
  }
209077
209229
  // ========================================================================
209078
- // MESSAGING
209230
+ // BACKUP & RESTORE
209079
209231
  // ========================================================================
209080
- async sendBroadcast(message) {
209081
- if (!this.connected || !this.myPair) {
209082
- throw new Error("Not connected");
209083
- }
209084
- if (this.peers.size === 0) {
209085
- console.warn("⚠️ No peers connected");
209086
- return;
209232
+ /**
209233
+ * Export entire vault (encrypted)
209234
+ */
209235
+ async export(password, options) {
209236
+ if (!this.initialized) {
209237
+ throw new Error("Vault not initialized");
209087
209238
  }
209088
- for (const [address, peer] of this.peers.entries()) {
209089
- try {
209090
- const secret = await this.sea.secret(peer.epub, this.myPair);
209091
- const encrypted = await this.sea.encrypt(message, secret);
209092
- const msgId = `${Date.now()}-${this.myAddress}-${Math.random().toString(36).substring(2, 9)}`;
209093
- await this.messagesNode.get(msgId).put({
209094
- from: this.myAddress,
209095
- fromPub: this.myPair.pub,
209096
- fromEpub: this.myPair.epub,
209097
- to: address,
209098
- content: encrypted,
209099
- timestamp: Date.now(),
209100
- type: "broadcast",
209239
+ try {
209240
+ // Get all records
209241
+ const recordNames = await this.list({
209242
+ includeDeleted: options?.includeDeleted || false,
209243
+ filterByTag: options?.filterByTag,
209244
+ filterByType: options?.filterByType,
209245
+ });
209246
+ const records = {};
209247
+ for (const name of recordNames) {
209248
+ const record = await this.get(name, {
209249
+ includeDeleted: options?.includeDeleted || false,
209101
209250
  });
209251
+ if (record) {
209252
+ records[name] = record;
209253
+ }
209102
209254
  }
209103
- catch (error) {
209104
- console.error(` ❌ Error sending to ${address.substring(0, 8)}:`, error);
209105
- }
209106
- }
209107
- }
209108
- async sendDirect(peerAddress, message) {
209109
- const peer = this.peers.get(peerAddress);
209110
- if (!peer)
209111
- throw new Error(`Peer ${peerAddress} not found`);
209112
- if (!this.myPair)
209113
- throw new Error("No SEA pair");
209114
- const secret = await this.sea.secret(peer.epub, this.myPair);
209115
- const encrypted = await this.sea.encrypt(message, secret);
209116
- const msgId = `${Date.now()}-${this.myAddress}-${Math.random().toString(36).substring(2, 9)}`;
209117
- await this.messagesNode.get(msgId).put({
209118
- from: this.myAddress,
209119
- fromPub: this.myPair.pub,
209120
- fromEpub: this.myPair.epub,
209121
- to: peerAddress,
209122
- content: encrypted,
209123
- timestamp: Date.now(),
209124
- type: "direct",
209125
- });
209255
+ // Create export data
209256
+ const exportData = {
209257
+ version: SHIP_06.VAULT_VERSION,
209258
+ exportedAt: Date.now(),
209259
+ exportedBy: this.identity.getCurrentUser()?.pub,
209260
+ recordCount: Object.keys(records).length,
209261
+ records,
209262
+ };
209263
+ // Serialize to JSON
209264
+ const jsonString = options?.pretty
209265
+ ? JSON.stringify(exportData, null, 2)
209266
+ : JSON.stringify(exportData);
209267
+ // Optionally encrypt with password
209268
+ if (password) {
209269
+ const crypto = this.identity.shogun?.db?.crypto;
209270
+ if (!crypto) {
209271
+ throw new Error("Cannot access crypto");
209272
+ }
209273
+ const encryptedJson = await crypto.encrypt(jsonString, password);
209274
+ const base64 = Buffer.from(encryptedJson).toString("base64");
209275
+ console.log(`✅ Vault exported (encrypted, ${base64.length} chars)`);
209276
+ return base64;
209277
+ }
209278
+ // Otherwise, return as base64
209279
+ const base64 = Buffer.from(jsonString).toString("base64");
209280
+ console.log(`✅ Vault exported (${base64.length} chars)`);
209281
+ return base64;
209282
+ }
209283
+ catch (error) {
209284
+ console.error("❌ Error exporting vault:", error);
209285
+ throw error;
209286
+ }
209126
209287
  }
209127
- listenForMessages() {
209128
- this.messagesNode.map().on(async (data, msgId) => {
209129
- if (!data || msgId === "_" || this.processedMessages.has(msgId))
209130
- return;
209131
- if (data.to !== this.myAddress || data.from === this.myAddress)
209132
- return;
209133
- this.processedMessages.add(msgId);
209134
- console.log(`\n📬 MESSAGE RECEIVED!`);
209135
- console.log(` From: ${data.from.substring(0, 12)}...`);
209136
- try {
209137
- let peer = this.peers.get(data.from);
209138
- if (!peer && data.fromPub && data.fromEpub) {
209139
- peer = {
209140
- address: data.from,
209141
- pubKey: data.fromPub,
209142
- epub: data.fromEpub,
209143
- pub: data.fromPub,
209144
- connectedAt: data.timestamp,
209145
- };
209146
- this.peers.set(data.from, peer);
209288
+ /**
209289
+ * Import vault from backup
209290
+ */
209291
+ async import(backupData, password, options) {
209292
+ if (!this.initialized) {
209293
+ return { success: false, error: "Vault not initialized" };
209294
+ }
209295
+ try {
209296
+ // Decode base64
209297
+ let jsonString = Buffer.from(backupData, "base64").toString("utf-8");
209298
+ // Decrypt if password provided
209299
+ if (password) {
209300
+ const crypto = this.identity.shogun?.db?.crypto;
209301
+ if (!crypto) {
209302
+ return { success: false, error: "Cannot access crypto" };
209303
+ }
209304
+ jsonString = await crypto.decrypt(jsonString, password);
209305
+ }
209306
+ // Parse JSON
209307
+ const importData = JSON.parse(jsonString);
209308
+ // Validate version
209309
+ if (importData.version !== SHIP_06.VAULT_VERSION) {
209310
+ console.warn(`⚠️ Version mismatch: ${importData.version} vs ${SHIP_06.VAULT_VERSION}`);
209311
+ }
209312
+ // Import records
209313
+ let importedCount = 0;
209314
+ let skippedCount = 0;
209315
+ for (const [name, record] of Object.entries(importData.records)) {
209316
+ const vaultRecord = record;
209317
+ // Skip deleted records if requested
209318
+ if (options?.skipDeleted && vaultRecord.deleted) {
209319
+ skippedCount++;
209320
+ continue;
209147
209321
  }
209148
- if (!peer || !this.myPair)
209149
- return;
209150
- const senderEpub = data.fromEpub || peer.epub;
209151
- const secret = await this.sea.secret(senderEpub, this.myPair);
209152
- const decrypted = await this.sea.decrypt(data.content, secret);
209153
- if (!decrypted)
209154
- return;
209155
- console.log(` Content: "${decrypted}"`);
209156
- const ephemeralMsg = {
209157
- from: data.from,
209158
- fromPubKey: data.fromPub || peer.pubKey || "",
209159
- content: decrypted,
209160
- timestamp: data.timestamp,
209161
- type: data.type,
209162
- };
209163
- this.messageHandlers.forEach((h) => h(ephemeralMsg));
209164
- }
209165
- catch (error) {
209166
- if (this.config.debug) {
209167
- console.error(` ❌ Error:`, error);
209322
+ // Check if exists (if merge mode)
209323
+ const exists = await this.exists(name);
209324
+ if (exists) {
209325
+ if (options?.overwrite) {
209326
+ // Overwrite existing
209327
+ await this.put(name, vaultRecord.data, vaultRecord.metadata);
209328
+ importedCount++;
209329
+ }
209330
+ else if (!options?.merge) {
209331
+ // Skip if not merge and not overwrite
209332
+ skippedCount++;
209333
+ continue;
209334
+ }
209335
+ else {
209336
+ // Merge mode: skip existing
209337
+ skippedCount++;
209338
+ continue;
209339
+ }
209340
+ }
209341
+ else {
209342
+ // Import new record
209343
+ await this.put(name, vaultRecord.data, vaultRecord.metadata);
209344
+ importedCount++;
209168
209345
  }
209169
209346
  }
209170
- });
209347
+ console.log(`✅ Vault imported: ${importedCount} records (${skippedCount} skipped)`);
209348
+ return {
209349
+ success: true,
209350
+ recordCount: importedCount,
209351
+ };
209352
+ }
209353
+ catch (error) {
209354
+ console.error("❌ Error importing vault:", error);
209355
+ return {
209356
+ success: false,
209357
+ error: error.message,
209358
+ };
209359
+ }
209171
209360
  }
209172
209361
  // ========================================================================
209173
- // EVENT HANDLERS
209362
+ // UTILITIES
209174
209363
  // ========================================================================
209175
- onMessage(callback) {
209176
- this.messageHandlers.push(callback);
209177
- }
209178
- onPeerSeen(callback) {
209179
- this.peerSeenHandlers.push(callback);
209180
- }
209181
- onPeerLeft(callback) {
209182
- this.peerLeftHandlers.push(callback);
209183
- }
209184
- onEncryptedMessage(callback) {
209185
- this.encryptedMessageHandlers.push(callback);
209364
+ /**
209365
+ * Get vault statistics
209366
+ */
209367
+ async getStats() {
209368
+ if (!this.initialized) {
209369
+ throw new Error("Vault not initialized");
209370
+ }
209371
+ try {
209372
+ const allRecords = await this.list({ includeDeleted: true });
209373
+ const activeRecords = await this.list({ includeDeleted: false });
209374
+ // Get metadata
209375
+ const metadata = await this.metadataNode.then();
209376
+ const stats = {
209377
+ totalRecords: allRecords.length,
209378
+ activeRecords: activeRecords.length,
209379
+ deletedRecords: allRecords.length - activeRecords.length,
209380
+ totalSize: 0, // TODO: Calculate actual size
209381
+ created: metadata?.created ? parseInt(metadata.created) : Date.now(),
209382
+ lastModified: Date.now(),
209383
+ recordsByType: {},
209384
+ };
209385
+ // Count by type
209386
+ for (const name of activeRecords) {
209387
+ const record = await this.get(name);
209388
+ if (record && record.metadata?.type) {
209389
+ const type = record.metadata.type;
209390
+ stats.recordsByType[type] = (stats.recordsByType[type] || 0) + 1;
209391
+ }
209392
+ }
209393
+ return stats;
209394
+ }
209395
+ catch (error) {
209396
+ console.error("❌ Error getting stats:", error);
209397
+ throw error;
209398
+ }
209186
209399
  }
209187
- getPeers() {
209188
- return Array.from(this.peers.keys());
209400
+ /**
209401
+ * Clear all records (soft delete all)
209402
+ */
209403
+ async clear() {
209404
+ return await this.delete(); // Delete without name = delete all
209189
209405
  }
209190
- getPeerInfo(address) {
209191
- return this.peers.get(address) || null;
209406
+ /**
209407
+ * Compact vault (remove deleted records permanently)
209408
+ */
209409
+ async compact() {
209410
+ if (!this.initialized) {
209411
+ return { success: false, error: "Vault not initialized" };
209412
+ }
209413
+ try {
209414
+ // Get all deleted records
209415
+ const allRecords = await this.list({ includeDeleted: true });
209416
+ let compactedCount = 0;
209417
+ for (const name of allRecords) {
209418
+ const record = await this.get(name, { includeDeleted: true });
209419
+ if (record && record.deleted) {
209420
+ // Permanently remove
209421
+ await this.recordsNode.get(name).put(null).then();
209422
+ compactedCount++;
209423
+ }
209424
+ }
209425
+ // Update metadata
209426
+ await this.updateRecordCount();
209427
+ console.log(`✅ Vault compacted: ${compactedCount} records permanently removed`);
209428
+ return {
209429
+ success: true,
209430
+ recordCount: compactedCount,
209431
+ };
209432
+ }
209433
+ catch (error) {
209434
+ console.error("❌ Error compacting vault:", error);
209435
+ return {
209436
+ success: false,
209437
+ error: error.message,
209438
+ };
209439
+ }
209192
209440
  }
209193
- async getEphemeralPair() {
209194
- if (!this.myPair)
209195
- throw new Error("No ephemeral pair");
209196
- return this.myPair;
209441
+ /**
209442
+ * Search records by content
209443
+ */
209444
+ async search(query) {
209445
+ if (!this.initialized) {
209446
+ return [];
209447
+ }
209448
+ try {
209449
+ const allRecords = await this.list({ includeDeleted: false });
209450
+ const matches = [];
209451
+ for (const name of allRecords) {
209452
+ const record = await this.get(name);
209453
+ if (record) {
209454
+ // Search in data (converted to string)
209455
+ const dataString = JSON.stringify(record.data).toLowerCase();
209456
+ const queryLower = query.toLowerCase();
209457
+ if (dataString.includes(queryLower) || name.toLowerCase().includes(queryLower)) {
209458
+ matches.push(name);
209459
+ }
209460
+ }
209461
+ }
209462
+ return matches;
209463
+ }
209464
+ catch (error) {
209465
+ console.error("❌ Error searching records:", error);
209466
+ return [];
209467
+ }
209197
209468
  }
209198
- async setEphemeralPair(pair) {
209199
- this.myPair = pair;
209469
+ // ========================================================================
209470
+ // PRIVATE HELPERS
209471
+ // ========================================================================
209472
+ /**
209473
+ * Update record count in metadata
209474
+ */
209475
+ async updateRecordCount() {
209476
+ try {
209477
+ const activeRecords = await this.list({ includeDeleted: false });
209478
+ await this.metadataNode.get("recordCount").put(activeRecords.length.toString()).then();
209479
+ }
209480
+ catch (error) {
209481
+ console.error("❌ Error updating record count:", error);
209482
+ }
209200
209483
  }
209201
209484
  }
209202
209485
  exports.SHIP_06 = SHIP_06;
209486
+ // Constants
209487
+ SHIP_06.VAULT_VERSION = "1.0.0";
209488
+ SHIP_06.DEFAULT_NODE_NAME = "vault";
209203
209489
 
209204
209490
 
209205
209491
  /***/ }),
@@ -211002,9 +211288,6 @@ class DataBase {
211002
211288
  this.user = this.gun.user().recall({ sessionStorage: true });
211003
211289
  }
211004
211290
  else {
211005
- if (!this.silent && !this.disableAutoRecall) {
211006
- console.log("No pair found in sessionStorage, using gun.user()");
211007
- }
211008
211291
  this.user = this.gun.user();
211009
211292
  }
211010
211293
  this.subscribeToAuthEvents();
@@ -211053,7 +211336,6 @@ class DataBase {
211053
211336
  */
211054
211337
  addPeer(peer) {
211055
211338
  this.gun.opt({ peers: [peer] });
211056
- console.log(`Added new peer: ${peer}`);
211057
211339
  }
211058
211340
  /**
211059
211341
  * Removes a peer from the network
@@ -211071,10 +211353,9 @@ class DataBase {
211071
211353
  if (peerConnection && typeof peerConnection.close === "function") {
211072
211354
  peerConnection.close();
211073
211355
  }
211074
- console.log(`Removed peer: ${peer}`);
211075
211356
  }
211076
211357
  else {
211077
- console.log(`Peer not found in current connections: ${peer}`);
211358
+ console.error(`Peer not found in current connections: ${peer}`);
211078
211359
  }
211079
211360
  }
211080
211361
  catch (error) {
@@ -211159,7 +211440,6 @@ class DataBase {
211159
211440
  this.removePeer(peer);
211160
211441
  // Add it back immediately instead of with timeout
211161
211442
  this.addPeer(peer);
211162
- console.log(`Reconnected to peer: ${peer}`);
211163
211443
  }
211164
211444
  catch (error) {
211165
211445
  console.error(`Error reconnecting to peer ${peer}:`, error);
@@ -211183,7 +211463,6 @@ class DataBase {
211183
211463
  this.addPeer(peer);
211184
211464
  });
211185
211465
  }
211186
- console.log(`Gun database reset with ${newPeers ? newPeers.length : 0} peers: ${newPeers ? newPeers.join(", ") : "none"}`);
211187
211466
  }
211188
211467
  }
211189
211468
  catch (error) {
@@ -211420,7 +211699,6 @@ class DataBase {
211420
211699
  else {
211421
211700
  const recallResult = userInstance;
211422
211701
  }
211423
- // console.log("recallResult", recallResult);
211424
211702
  }
211425
211703
  catch (recallError) {
211426
211704
  console.error("Error during recall:", recallError);
@@ -211464,7 +211742,6 @@ class DataBase {
211464
211742
  try {
211465
211743
  const currentUser = this.gun.user();
211466
211744
  if (!currentUser || !currentUser.is) {
211467
- console.log("No user logged in, skipping logout");
211468
211745
  return;
211469
211746
  }
211470
211747
  // Log out user
@@ -211623,7 +211900,6 @@ class DataBase {
211623
211900
  });
211624
211901
  }
211625
211902
  else {
211626
- console.log(`User created successfully with userPub: ${userPub}`);
211627
211903
  resolve({ success: true, userPub: userPub });
211628
211904
  }
211629
211905
  }
@@ -211659,7 +211935,6 @@ class DataBase {
211659
211935
  }
211660
211936
  if (pair) {
211661
211937
  this.gun.user().auth(pair, (ack) => {
211662
- console.log(`Pair authentication after creation result:`, ack);
211663
211938
  if (ack.err) {
211664
211939
  console.error(`Authentication after creation failed: ${ack.err}`);
211665
211940
  resolve({ success: false, error: ack.err });
@@ -211669,9 +211944,6 @@ class DataBase {
211669
211944
  setTimeout(() => {
211670
211945
  // Extract userPub from multiple possible sources
211671
211946
  const userPub = ack.pub || this.gun.user().is?.pub || ack.user?.pub;
211672
- console.log(`Extracted userPub after pair auth: ${userPub}`);
211673
- console.log(`User object after pair auth:`, this.gun.user());
211674
- console.log(`User.is after pair auth:`, this.gun.user().is);
211675
211947
  if (!userPub) {
211676
211948
  console.error("Authentication successful but no userPub found");
211677
211949
  resolve({
@@ -211688,7 +211960,6 @@ class DataBase {
211688
211960
  }
211689
211961
  else {
211690
211962
  this.gun.user().auth(normalizedUsername, password, (ack) => {
211691
- console.log(`Password authentication after creation result:`, ack);
211692
211963
  if (ack.err) {
211693
211964
  console.error(`Authentication after creation failed: ${ack.err}`);
211694
211965
  resolve({ success: false, error: ack.err });
@@ -211698,9 +211969,6 @@ class DataBase {
211698
211969
  setTimeout(() => {
211699
211970
  // Extract userPub from multiple possible sources
211700
211971
  const userPub = ack.pub || this.gun.user().is?.pub || ack.user?.pub;
211701
- console.log(`Extracted userPub after password auth: ${userPub}`);
211702
- console.log(`User object after password auth:`, this.gun.user());
211703
- console.log(`User.is after password auth:`, this.gun.user().is);
211704
211972
  if (!userPub) {
211705
211973
  console.error("Authentication successful but no userPub found");
211706
211974
  resolve({
@@ -211764,7 +212032,6 @@ class DataBase {
211764
212032
  this.user = this.gun.user();
211765
212033
  // Run post-authentication tasks
211766
212034
  try {
211767
- console.log(`Running post-auth setup with userPub: ${authResult.userPub}`);
211768
212035
  const postAuthResult = await this.runPostAuthOnAuthResult(username, authResult.userPub, authResult);
211769
212036
  // Return the post-auth result which includes the complete user data
211770
212037
  return postAuthResult;
@@ -211821,7 +212088,6 @@ class DataBase {
211821
212088
  // For pair-based authentication, we don't need to call gun.user().create()
211822
212089
  // because the pair already contains the cryptographic credentials
211823
212090
  // We just need to validate that the pair is valid and return success
211824
- console.log(`User created successfully with pair for: ${normalizedUsername}`);
211825
212091
  resolve({ success: true, userPub: pair.pub });
211826
212092
  });
211827
212093
  }
@@ -211854,7 +212120,6 @@ class DataBase {
211854
212120
  if (normalizedUsername.length === 0) {
211855
212121
  throw new Error("Username cannot be empty");
211856
212122
  }
211857
- console.log(`Setting up user profile for ${normalizedUsername} with userPub: ${userPub}`);
211858
212123
  const existingUser = await this.gun.get(userPub).then();
211859
212124
  const isNewUser = !existingUser || !existingUser.alias;
211860
212125
  // const isNewUser = true;
@@ -211932,7 +212197,6 @@ class DataBase {
211932
212197
  if (!userMetadataResult) {
211933
212198
  return false;
211934
212199
  }
211935
- console.log(`Comprehensive user tracking setup completed for ${username}`);
211936
212200
  return true;
211937
212201
  }
211938
212202
  catch (error) {
@@ -211955,7 +212219,6 @@ class DataBase {
211955
212219
  return false;
211956
212220
  }
211957
212221
  else {
211958
- console.log(`Alias index created: ~@${username} -> ${userPub}`);
211959
212222
  return true;
211960
212223
  }
211961
212224
  }
@@ -211979,7 +212242,6 @@ class DataBase {
211979
212242
  return false;
211980
212243
  }
211981
212244
  else {
211982
- console.log(`Username mapping created: ${username} -> ${userPub}`);
211983
212245
  return true;
211984
212246
  }
211985
212247
  }
@@ -212010,7 +212272,6 @@ class DataBase {
212010
212272
  return false;
212011
212273
  }
212012
212274
  else {
212013
- console.log(`User registry created: ${userPub}`);
212014
212275
  return true;
212015
212276
  }
212016
212277
  }
@@ -212034,7 +212295,6 @@ class DataBase {
212034
212295
  return false;
212035
212296
  }
212036
212297
  else {
212037
- console.log(`Reverse lookup created: ${userPub} -> ${username}`);
212038
212298
  return true;
212039
212299
  }
212040
212300
  }
@@ -212054,7 +212314,6 @@ class DataBase {
212054
212314
  return false;
212055
212315
  }
212056
212316
  else {
212057
- console.log(`Epub index created: ${epub} -> ${userPub}`);
212058
212317
  return true;
212059
212318
  }
212060
212319
  }
@@ -212080,7 +212339,6 @@ class DataBase {
212080
212339
  return false;
212081
212340
  }
212082
212341
  else {
212083
- console.log(`User metadata created for ${userPub}`);
212084
212342
  return true;
212085
212343
  }
212086
212344
  }
@@ -212114,7 +212372,7 @@ class DataBase {
212114
212372
  }
212115
212373
  }
212116
212374
  catch (error) {
212117
- console.log(`GunDB alias lookup failed for ${normalizedAlias}:`, error);
212375
+ console.error(`GunDB alias lookup failed for ${normalizedAlias}:`, error);
212118
212376
  }
212119
212377
  // Method 2: Try username mapping (usernames/alias -> userPub)
212120
212378
  try {
@@ -212130,7 +212388,7 @@ class DataBase {
212130
212388
  }
212131
212389
  }
212132
212390
  catch (error) {
212133
- console.log(`Username mapping lookup failed for ${normalizedAlias}:`, error);
212391
+ console.error(`Username mapping lookup failed for ${normalizedAlias}:`, error);
212134
212392
  }
212135
212393
  return null;
212136
212394
  }
@@ -212163,7 +212421,7 @@ class DataBase {
212163
212421
  }
212164
212422
  }
212165
212423
  catch (error) {
212166
- console.log(`User registry lookup failed for ${userPub}:`, error);
212424
+ console.error(`User registry lookup failed for ${userPub}:`, error);
212167
212425
  }
212168
212426
  // Method 2: Try user's own node
212169
212427
  try {
@@ -212179,7 +212437,7 @@ class DataBase {
212179
212437
  }
212180
212438
  }
212181
212439
  catch (error) {
212182
- console.log(`User node lookup failed for ${userPub}:`, error);
212440
+ console.error(`User node lookup failed for ${userPub}:`, error);
212183
212441
  }
212184
212442
  return null;
212185
212443
  }
@@ -212263,14 +212521,14 @@ class DataBase {
212263
212521
  .then();
212264
212522
  }
212265
212523
  catch (error) {
212266
- console.log(`Failed to update lastSeen in user registry:`, error);
212524
+ console.error(`Failed to update lastSeen in user registry:`, error);
212267
212525
  }
212268
212526
  // Update in user's own node
212269
212527
  try {
212270
212528
  await this.gun.get(userPub).get("lastSeen").put(timestamp).then();
212271
212529
  }
212272
212530
  catch (error) {
212273
- console.log(`Failed to update lastSeen in user node:`, error);
212531
+ console.error(`Failed to update lastSeen in user node:`, error);
212274
212532
  }
212275
212533
  }
212276
212534
  catch (error) {
@@ -212282,10 +212540,8 @@ class DataBase {
212282
212540
  */
212283
212541
  async performAuthentication(username, password, pair) {
212284
212542
  return new Promise((resolve) => {
212285
- console.log(`Attempting authentication for user: ${username}`);
212286
212543
  if (pair) {
212287
212544
  this.gun.user().auth(pair, (ack) => {
212288
- console.log(`Pair authentication result:`, ack);
212289
212545
  if (ack.err) {
212290
212546
  console.error(`Login error for ${username}: ${ack.err}`);
212291
212547
  resolve({ success: false, error: ack.err });
@@ -212297,7 +212553,6 @@ class DataBase {
212297
212553
  }
212298
212554
  else {
212299
212555
  this.gun.user().auth(username, password, (ack) => {
212300
- console.log(`Password authentication result:`, ack);
212301
212556
  if (ack.err) {
212302
212557
  console.error(`Login error for ${username}: ${ack.err}`);
212303
212558
  resolve({ success: false, error: ack.err });
@@ -212346,9 +212601,6 @@ class DataBase {
212346
212601
  if (!alias) {
212347
212602
  alias = username;
212348
212603
  }
212349
- console.log(`Login authentication successful, extracted userPub: ${userPub}`);
212350
- console.log(`User object:`, this.gun.user());
212351
- console.log(`User.is:`, this.gun.user().is);
212352
212604
  if (!userPub) {
212353
212605
  return {
212354
212606
  success: false,
@@ -212514,7 +212766,6 @@ class DataBase {
212514
212766
  if (!userPub) {
212515
212767
  return { success: false, error: "User not found" };
212516
212768
  }
212517
- // console.log(`Found user public key for password recovery: ${userPub}`);
212518
212769
  // Access the user's security data directly from their public key node
212519
212770
  const securityData = await this.node.get(userPub)
212520
212771
  .get("security")
@@ -212730,14 +212981,7 @@ exports.DataBase = DataBase;
212730
212981
  // Errors
212731
212982
  DataBase.Errors = GunErrors;
212732
212983
  const createGun = (config, silent) => {
212733
- if (!silent) {
212734
- console.log("Creating Gun instance with config:", config);
212735
- console.log("Config peers:", config?.peers);
212736
- }
212737
212984
  const gunInstance = (0, gun_1.default)(config);
212738
- if (!silent) {
212739
- console.log("Created Gun instance:", gunInstance);
212740
- }
212741
212985
  return gunInstance;
212742
212986
  };
212743
212987
  exports.createGun = createGun;
@@ -220391,6 +220635,16 @@ function generateDeterministicPassword(salt) {
220391
220635
 
220392
220636
  /***/ }),
220393
220637
 
220638
+ /***/ "?25c3":
220639
+ /*!**********************!*\
220640
+ !*** zlib (ignored) ***!
220641
+ \**********************/
220642
+ /***/ (() => {
220643
+
220644
+ /* (ignored) */
220645
+
220646
+ /***/ }),
220647
+
220394
220648
  /***/ "?3fc0":
220395
220649
  /*!************************!*\
220396
220650
  !*** crypto (ignored) ***!