shogun-core 3.0.13 → 3.0.15
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/README.md +27 -1
- package/dist/browser/shogun-core.js +103157 -84871
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/config/simplified-config.js +22 -16
- package/dist/core.js +18 -26
- package/dist/examples/api-test.js +273 -0
- package/dist/examples/simple-api-test.js +89 -0
- package/dist/gundb/api.js +126 -189
- package/dist/gundb/crypto.js +32 -17
- package/dist/gundb/db.js +89 -137
- package/dist/gundb/derive.js +20 -17
- package/dist/gundb/errors.js +17 -7
- package/dist/gundb/index.js +19 -3
- package/dist/gundb/rxjs.js +19 -17
- package/dist/gundb/types.js +2 -1
- package/dist/index.js +43 -12
- package/dist/interfaces/common.js +2 -1
- package/dist/interfaces/events.js +6 -2
- package/dist/interfaces/plugin.js +2 -1
- package/dist/interfaces/shogun.js +7 -4
- package/dist/managers/AuthManager.js +9 -7
- package/dist/managers/CoreInitializer.js +23 -20
- package/dist/managers/EventManager.js +7 -4
- package/dist/managers/PluginManager.js +6 -3
- package/dist/migration-test.js +13 -8
- package/dist/plugins/base.js +11 -8
- package/dist/plugins/index.js +36 -10
- package/dist/plugins/nostr/index.js +20 -4
- package/dist/plugins/nostr/nostrConnector.js +42 -36
- package/dist/plugins/nostr/nostrConnectorPlugin.js +36 -29
- package/dist/plugins/nostr/nostrSigner.js +17 -11
- package/dist/plugins/nostr/types.js +2 -1
- package/dist/plugins/oauth/index.js +7 -2
- package/dist/plugins/oauth/oauthConnector.js +75 -69
- package/dist/plugins/oauth/oauthPlugin.js +31 -27
- package/dist/plugins/oauth/types.js +2 -1
- package/dist/plugins/web3/index.js +20 -4
- package/dist/plugins/web3/types.js +2 -1
- package/dist/plugins/web3/web3Connector.js +38 -33
- package/dist/plugins/web3/web3ConnectorPlugin.js +29 -22
- package/dist/plugins/web3/web3Signer.js +24 -18
- package/dist/plugins/webauthn/index.js +19 -3
- package/dist/plugins/webauthn/types.js +5 -2
- package/dist/plugins/webauthn/webauthn.js +30 -25
- package/dist/plugins/webauthn/webauthnPlugin.js +21 -14
- package/dist/plugins/webauthn/webauthnSigner.js +20 -14
- package/dist/storage/storage.js +5 -4
- package/dist/types/events.js +8 -2
- package/dist/types/examples/api-test.d.ts +12 -0
- package/dist/types/examples/simple-api-test.d.ts +5 -0
- package/dist/types/gundb/api.d.ts +0 -26
- package/dist/types/gundb/db.d.ts +2 -35
- package/dist/types/shogun.js +7 -4
- package/dist/utils/errorHandler.js +13 -8
- package/dist/utils/eventEmitter.js +5 -2
- package/dist/utils/validation.js +14 -7
- package/package.json +2 -1
package/dist/plugins/index.js
CHANGED
|
@@ -1,15 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.OAuthPlugin = exports.OAuthConnector = exports.NostrConnectorPlugin = exports.NostrConnector = exports.Web3ConnectorPlugin = exports.Web3Connector = exports.WebauthnPlugin = exports.Webauthn = exports.BasePlugin = void 0;
|
|
1
18
|
// Base plugin interface and types
|
|
2
|
-
|
|
19
|
+
var base_1 = require("./base");
|
|
20
|
+
Object.defineProperty(exports, "BasePlugin", { enumerable: true, get: function () { return base_1.BasePlugin; } });
|
|
3
21
|
// WebAuthn plugin exports
|
|
4
|
-
|
|
5
|
-
|
|
22
|
+
var webauthn_1 = require("./webauthn/webauthn");
|
|
23
|
+
Object.defineProperty(exports, "Webauthn", { enumerable: true, get: function () { return webauthn_1.Webauthn; } });
|
|
24
|
+
var webauthnPlugin_1 = require("./webauthn/webauthnPlugin");
|
|
25
|
+
Object.defineProperty(exports, "WebauthnPlugin", { enumerable: true, get: function () { return webauthnPlugin_1.WebauthnPlugin; } });
|
|
6
26
|
// Ethereum plugin exports
|
|
7
|
-
|
|
8
|
-
|
|
27
|
+
var web3Connector_1 = require("./web3/web3Connector");
|
|
28
|
+
Object.defineProperty(exports, "Web3Connector", { enumerable: true, get: function () { return web3Connector_1.Web3Connector; } });
|
|
29
|
+
var web3ConnectorPlugin_1 = require("./web3/web3ConnectorPlugin");
|
|
30
|
+
Object.defineProperty(exports, "Web3ConnectorPlugin", { enumerable: true, get: function () { return web3ConnectorPlugin_1.Web3ConnectorPlugin; } });
|
|
9
31
|
// Bitcoin plugin exports
|
|
10
|
-
|
|
11
|
-
|
|
32
|
+
var nostrConnector_1 = require("./nostr/nostrConnector");
|
|
33
|
+
Object.defineProperty(exports, "NostrConnector", { enumerable: true, get: function () { return nostrConnector_1.NostrConnector; } });
|
|
34
|
+
var nostrConnectorPlugin_1 = require("./nostr/nostrConnectorPlugin");
|
|
35
|
+
Object.defineProperty(exports, "NostrConnectorPlugin", { enumerable: true, get: function () { return nostrConnectorPlugin_1.NostrConnectorPlugin; } });
|
|
12
36
|
// OAuth plugin exports
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
37
|
+
var oauthConnector_1 = require("./oauth/oauthConnector");
|
|
38
|
+
Object.defineProperty(exports, "OAuthConnector", { enumerable: true, get: function () { return oauthConnector_1.OAuthConnector; } });
|
|
39
|
+
var oauthPlugin_1 = require("./oauth/oauthPlugin");
|
|
40
|
+
Object.defineProperty(exports, "OAuthPlugin", { enumerable: true, get: function () { return oauthPlugin_1.OAuthPlugin; } });
|
|
41
|
+
__exportStar(require("./oauth/types"), exports);
|
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./nostrConnectorPlugin"), exports);
|
|
18
|
+
__exportStar(require("./nostrConnector"), exports);
|
|
19
|
+
__exportStar(require("./nostrSigner"), exports);
|
|
20
|
+
__exportStar(require("./types"), exports);
|
|
@@ -1,33 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.NostrConnector = exports.MESSAGE_TO_SIGN = void 0;
|
|
7
|
+
exports.deriveNostrKeys = deriveNostrKeys;
|
|
1
8
|
/**
|
|
2
9
|
* The BitcoinWallet class provides functionality for connecting, signing up, and logging in using Bitcoin wallets.
|
|
3
10
|
* Supports Alby and Nostr extensions, as well as manual key management.
|
|
4
11
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
const ethers_1 = require("ethers");
|
|
13
|
+
const nostr_tools_1 = require("nostr-tools");
|
|
14
|
+
const eventEmitter_1 = require("../../utils/eventEmitter");
|
|
15
|
+
const derive_1 = __importDefault(require("../../gundb/derive"));
|
|
16
|
+
const validation_1 = require("../../utils/validation");
|
|
17
|
+
exports.MESSAGE_TO_SIGN = "I Love Shogun!";
|
|
11
18
|
/**
|
|
12
19
|
* Class for Bitcoin wallet connections and operations
|
|
13
20
|
*/
|
|
14
|
-
class NostrConnector extends EventEmitter {
|
|
15
|
-
DEFAULT_CONFIG = {
|
|
16
|
-
cacheDuration: 24 * 60 * 60 * 1000, // 24 hours instead of 30 minutes for better UX
|
|
17
|
-
maxRetries: 3,
|
|
18
|
-
retryDelay: 1000,
|
|
19
|
-
timeout: 60000,
|
|
20
|
-
network: "mainnet",
|
|
21
|
-
useApi: false,
|
|
22
|
-
};
|
|
23
|
-
config;
|
|
24
|
-
signatureCache = new Map();
|
|
25
|
-
// Connection state
|
|
26
|
-
connectedAddress = null;
|
|
27
|
-
connectedType = null;
|
|
28
|
-
manualKeyPair = null;
|
|
21
|
+
class NostrConnector extends eventEmitter_1.EventEmitter {
|
|
29
22
|
constructor(config = {}) {
|
|
30
23
|
super();
|
|
24
|
+
this.DEFAULT_CONFIG = {
|
|
25
|
+
cacheDuration: 24 * 60 * 60 * 1000, // 24 hours instead of 30 minutes for better UX
|
|
26
|
+
maxRetries: 3,
|
|
27
|
+
retryDelay: 1000,
|
|
28
|
+
timeout: 60000,
|
|
29
|
+
network: "mainnet",
|
|
30
|
+
useApi: false,
|
|
31
|
+
};
|
|
32
|
+
this.signatureCache = new Map();
|
|
33
|
+
// Connection state
|
|
34
|
+
this.connectedAddress = null;
|
|
35
|
+
this.connectedType = null;
|
|
36
|
+
this.manualKeyPair = null;
|
|
31
37
|
this.config = { ...this.DEFAULT_CONFIG, ...config };
|
|
32
38
|
this.setupEventListeners();
|
|
33
39
|
}
|
|
@@ -211,12 +217,12 @@ class NostrConnector extends EventEmitter {
|
|
|
211
217
|
* Generate credentials using Nostr: username deterministico e chiave GunDB derivata dall'address
|
|
212
218
|
*/
|
|
213
219
|
async generateCredentials(address, signature, message) {
|
|
214
|
-
const username = generateUsernameFromIdentity("nostr", { id: address });
|
|
220
|
+
const username = (0, validation_1.generateUsernameFromIdentity)("nostr", { id: address });
|
|
215
221
|
// Usa un hashing robusto di address con keccak256
|
|
216
|
-
const hashedAddress = ethers.keccak256(ethers.toUtf8Bytes(address));
|
|
222
|
+
const hashedAddress = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(address));
|
|
217
223
|
// Include la signature nel salt per aggiungere un ulteriore livello di sicurezza
|
|
218
224
|
const salt = `${username}_${address}_${message}_${signature}`;
|
|
219
|
-
const key = await
|
|
225
|
+
const key = await (0, derive_1.default)(hashedAddress, salt, { includeP256: true });
|
|
220
226
|
return { username, key, message, signature };
|
|
221
227
|
}
|
|
222
228
|
/**
|
|
@@ -229,7 +235,7 @@ class NostrConnector extends EventEmitter {
|
|
|
229
235
|
try {
|
|
230
236
|
// Create a deterministic hash from the signature using a secure algorithm
|
|
231
237
|
const normalizedSig = signature.toLowerCase().replace(/[^a-f0-9]/g, "");
|
|
232
|
-
const passwordHash = ethers.sha256(ethers.toUtf8Bytes(normalizedSig));
|
|
238
|
+
const passwordHash = ethers_1.ethers.sha256(ethers_1.ethers.toUtf8Bytes(normalizedSig));
|
|
233
239
|
return passwordHash;
|
|
234
240
|
}
|
|
235
241
|
catch (error) {
|
|
@@ -264,10 +270,10 @@ class NostrConnector extends EventEmitter {
|
|
|
264
270
|
};
|
|
265
271
|
const event = {
|
|
266
272
|
...eventData,
|
|
267
|
-
id: getEventHash(eventData),
|
|
273
|
+
id: (0, nostr_tools_1.getEventHash)(eventData),
|
|
268
274
|
sig: signature,
|
|
269
275
|
};
|
|
270
|
-
return verifyEvent(event);
|
|
276
|
+
return (0, nostr_tools_1.verifyEvent)(event);
|
|
271
277
|
}
|
|
272
278
|
catch (verifyError) {
|
|
273
279
|
console.error("Error in Nostr signature verification:", verifyError);
|
|
@@ -291,10 +297,10 @@ class NostrConnector extends EventEmitter {
|
|
|
291
297
|
};
|
|
292
298
|
const event = {
|
|
293
299
|
...eventData,
|
|
294
|
-
id: getEventHash(eventData),
|
|
300
|
+
id: (0, nostr_tools_1.getEventHash)(eventData),
|
|
295
301
|
sig: signature,
|
|
296
302
|
};
|
|
297
|
-
return verifyEvent(event);
|
|
303
|
+
return (0, nostr_tools_1.verifyEvent)(event);
|
|
298
304
|
}
|
|
299
305
|
catch (manualVerifyError) {
|
|
300
306
|
console.error("Error in manual signature verification:", manualVerifyError);
|
|
@@ -349,7 +355,7 @@ class NostrConnector extends EventEmitter {
|
|
|
349
355
|
};
|
|
350
356
|
const nostrEvent = {
|
|
351
357
|
...eventData,
|
|
352
|
-
id: getEventHash(eventData),
|
|
358
|
+
id: (0, nostr_tools_1.getEventHash)(eventData),
|
|
353
359
|
sig: "", // This will be filled by window.nostr.signEvent
|
|
354
360
|
};
|
|
355
361
|
const signedEvent = await window.nostr.signEvent(nostrEvent);
|
|
@@ -370,11 +376,11 @@ class NostrConnector extends EventEmitter {
|
|
|
370
376
|
};
|
|
371
377
|
const eventTemplate = {
|
|
372
378
|
...manualEventData,
|
|
373
|
-
id: getEventHash(manualEventData),
|
|
379
|
+
id: (0, nostr_tools_1.getEventHash)(manualEventData),
|
|
374
380
|
sig: "", // This will be filled by finalizeEvent
|
|
375
381
|
};
|
|
376
|
-
const privateKeyBytes =
|
|
377
|
-
const signedEventManual = await finalizeEvent(eventTemplate, privateKeyBytes);
|
|
382
|
+
const privateKeyBytes = nostr_tools_1.utils.hexToBytes(this.manualKeyPair.privateKey);
|
|
383
|
+
const signedEventManual = await (0, nostr_tools_1.finalizeEvent)(eventTemplate, privateKeyBytes);
|
|
378
384
|
console.log("Generated manual signature:", signedEventManual.sig.substring(0, 20) + "...");
|
|
379
385
|
return signedEventManual.sig;
|
|
380
386
|
default:
|
|
@@ -396,11 +402,12 @@ class NostrConnector extends EventEmitter {
|
|
|
396
402
|
this.manualKeyPair = null;
|
|
397
403
|
}
|
|
398
404
|
}
|
|
405
|
+
exports.NostrConnector = NostrConnector;
|
|
399
406
|
// Funzione helper per derivare chiavi Nostr/Bitcoin (come per Web3/WebAuthn)
|
|
400
|
-
|
|
407
|
+
async function deriveNostrKeys(address, signature, message) {
|
|
401
408
|
// Usa solo l'address per rendere le credenziali deterministiche
|
|
402
409
|
const salt = `${address}_${message}`;
|
|
403
|
-
return await
|
|
410
|
+
return await (0, derive_1.default)(address, salt, {
|
|
404
411
|
includeP256: true,
|
|
405
412
|
});
|
|
406
413
|
}
|
|
@@ -410,4 +417,3 @@ if (typeof window !== "undefined") {
|
|
|
410
417
|
else if (typeof global !== "undefined") {
|
|
411
418
|
global.NostrConnector = NostrConnector;
|
|
412
419
|
}
|
|
413
|
-
export { NostrConnector };
|
|
@@ -1,25 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NostrConnectorPlugin = void 0;
|
|
4
|
+
const base_1 = require("../base");
|
|
5
|
+
const nostrConnector_1 = require("./nostrConnector");
|
|
6
|
+
const nostrSigner_1 = require("./nostrSigner");
|
|
7
|
+
const errorHandler_1 = require("../../utils/errorHandler");
|
|
5
8
|
/**
|
|
6
9
|
* Plugin for managing Bitcoin wallet functionality in ShogunCore
|
|
7
10
|
* Supports Alby, Nostr extensions, or direct key management
|
|
8
11
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
class NostrConnectorPlugin extends base_1.BasePlugin {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.name = "nostr";
|
|
16
|
+
this.version = "1.0.0";
|
|
17
|
+
this.description = "Provides Bitcoin wallet connection and authentication for ShogunCore";
|
|
18
|
+
this.bitcoinConnector = null;
|
|
19
|
+
this.signer = null;
|
|
20
|
+
}
|
|
15
21
|
/**
|
|
16
22
|
* @inheritdoc
|
|
17
23
|
*/
|
|
18
24
|
initialize(core) {
|
|
19
25
|
super.initialize(core);
|
|
20
26
|
// Initialize the Bitcoin wallet module
|
|
21
|
-
this.bitcoinConnector = new NostrConnector();
|
|
22
|
-
this.signer = new NostrSigner(this.bitcoinConnector);
|
|
27
|
+
this.bitcoinConnector = new nostrConnector_1.NostrConnector();
|
|
28
|
+
this.signer = new nostrSigner_1.NostrSigner(this.bitcoinConnector);
|
|
23
29
|
}
|
|
24
30
|
/**
|
|
25
31
|
* @inheritdoc
|
|
@@ -315,33 +321,33 @@ export class NostrConnectorPlugin extends BasePlugin {
|
|
|
315
321
|
try {
|
|
316
322
|
const core = this.assertInitialized();
|
|
317
323
|
if (!address) {
|
|
318
|
-
throw createError(ErrorType.VALIDATION, "ADDRESS_REQUIRED", "Bitcoin address required for login");
|
|
324
|
+
throw (0, errorHandler_1.createError)(errorHandler_1.ErrorType.VALIDATION, "ADDRESS_REQUIRED", "Bitcoin address required for login");
|
|
319
325
|
}
|
|
320
326
|
if (!this.isAvailable()) {
|
|
321
|
-
throw createError(ErrorType.ENVIRONMENT, "BITCOIN_WALLET_UNAVAILABLE", "No Bitcoin wallet available in the browser");
|
|
327
|
+
throw (0, errorHandler_1.createError)(errorHandler_1.ErrorType.ENVIRONMENT, "BITCOIN_WALLET_UNAVAILABLE", "No Bitcoin wallet available in the browser");
|
|
322
328
|
}
|
|
323
|
-
const message = MESSAGE_TO_SIGN;
|
|
329
|
+
const message = nostrConnector_1.MESSAGE_TO_SIGN;
|
|
324
330
|
const signature = await this.assertBitcoinConnector().requestSignature(address, message);
|
|
325
331
|
const credentials = await this.generateCredentials(address, signature, message);
|
|
326
332
|
if (!credentials?.username ||
|
|
327
333
|
!credentials?.key ||
|
|
328
334
|
!credentials.message ||
|
|
329
335
|
!credentials.signature) {
|
|
330
|
-
throw createError(ErrorType.AUTHENTICATION, "CREDENTIAL_GENERATION_FAILED", "Bitcoin wallet credentials not generated correctly or signature missing");
|
|
336
|
+
throw (0, errorHandler_1.createError)(errorHandler_1.ErrorType.AUTHENTICATION, "CREDENTIAL_GENERATION_FAILED", "Bitcoin wallet credentials not generated correctly or signature missing");
|
|
331
337
|
}
|
|
332
338
|
const isValid = await this.verifySignature(credentials.message, credentials.signature, address);
|
|
333
339
|
if (!isValid) {
|
|
334
340
|
console.error(`Signature verification failed for address: ${address}`);
|
|
335
|
-
throw createError(ErrorType.SECURITY, "SIGNATURE_VERIFICATION_FAILED", "Bitcoin wallet signature verification failed");
|
|
341
|
+
throw (0, errorHandler_1.createError)(errorHandler_1.ErrorType.SECURITY, "SIGNATURE_VERIFICATION_FAILED", "Bitcoin wallet signature verification failed");
|
|
336
342
|
}
|
|
337
343
|
// Deriva le chiavi da address, signature, message
|
|
338
|
-
const k = await deriveNostrKeys(address, signature, message);
|
|
344
|
+
const k = await (0, nostrConnector_1.deriveNostrKeys)(address, signature, message);
|
|
339
345
|
// Set authentication method to nostr before login
|
|
340
346
|
core.setAuthMethod("nostr");
|
|
341
347
|
// Usa le chiavi derivate per login
|
|
342
348
|
const loginResult = await core.login(credentials.username, "", k);
|
|
343
349
|
if (!loginResult.success) {
|
|
344
|
-
throw createError(ErrorType.AUTHENTICATION, "BITCOIN_LOGIN_FAILED", loginResult.error || "Failed to log in with Bitcoin credentials");
|
|
350
|
+
throw (0, errorHandler_1.createError)(errorHandler_1.ErrorType.AUTHENTICATION, "BITCOIN_LOGIN_FAILED", loginResult.error || "Failed to log in with Bitcoin credentials");
|
|
345
351
|
}
|
|
346
352
|
// Emit login event
|
|
347
353
|
core.emit("auth:login", {
|
|
@@ -353,10 +359,10 @@ export class NostrConnectorPlugin extends BasePlugin {
|
|
|
353
359
|
}
|
|
354
360
|
catch (error) {
|
|
355
361
|
// Handle both ShogunError and generic errors
|
|
356
|
-
const errorType = error?.type || ErrorType.AUTHENTICATION;
|
|
362
|
+
const errorType = error?.type || errorHandler_1.ErrorType.AUTHENTICATION;
|
|
357
363
|
const errorCode = error?.code || "BITCOIN_LOGIN_ERROR";
|
|
358
364
|
const errorMessage = error?.message || "Unknown error during Bitcoin wallet login";
|
|
359
|
-
ErrorHandler.handle(errorType, errorCode, errorMessage, error);
|
|
365
|
+
errorHandler_1.ErrorHandler.handle(errorType, errorCode, errorMessage, error);
|
|
360
366
|
return { success: false, error: errorMessage };
|
|
361
367
|
}
|
|
362
368
|
}
|
|
@@ -369,28 +375,28 @@ export class NostrConnectorPlugin extends BasePlugin {
|
|
|
369
375
|
try {
|
|
370
376
|
const core = this.assertInitialized();
|
|
371
377
|
if (!address) {
|
|
372
|
-
throw createError(ErrorType.VALIDATION, "ADDRESS_REQUIRED", "Bitcoin address required for signup");
|
|
378
|
+
throw (0, errorHandler_1.createError)(errorHandler_1.ErrorType.VALIDATION, "ADDRESS_REQUIRED", "Bitcoin address required for signup");
|
|
373
379
|
}
|
|
374
380
|
if (!this.isAvailable()) {
|
|
375
|
-
throw createError(ErrorType.ENVIRONMENT, "BITCOIN_WALLET_UNAVAILABLE", "No Bitcoin wallet available in the browser");
|
|
381
|
+
throw (0, errorHandler_1.createError)(errorHandler_1.ErrorType.ENVIRONMENT, "BITCOIN_WALLET_UNAVAILABLE", "No Bitcoin wallet available in the browser");
|
|
376
382
|
}
|
|
377
|
-
const message = MESSAGE_TO_SIGN;
|
|
383
|
+
const message = nostrConnector_1.MESSAGE_TO_SIGN;
|
|
378
384
|
const signature = await this.assertBitcoinConnector().requestSignature(address, message);
|
|
379
385
|
const credentials = await this.generateCredentials(address, signature, message);
|
|
380
386
|
if (!credentials?.username ||
|
|
381
387
|
!credentials?.key ||
|
|
382
388
|
!credentials.message ||
|
|
383
389
|
!credentials.signature) {
|
|
384
|
-
throw createError(ErrorType.AUTHENTICATION, "CREDENTIAL_GENERATION_FAILED", "Bitcoin wallet credentials not generated correctly or signature missing");
|
|
390
|
+
throw (0, errorHandler_1.createError)(errorHandler_1.ErrorType.AUTHENTICATION, "CREDENTIAL_GENERATION_FAILED", "Bitcoin wallet credentials not generated correctly or signature missing");
|
|
385
391
|
}
|
|
386
392
|
// Verify signature
|
|
387
393
|
const isValid = await this.verifySignature(credentials.message, credentials.signature, address);
|
|
388
394
|
if (!isValid) {
|
|
389
395
|
console.error(`Signature verification failed for address: ${address}`);
|
|
390
|
-
throw createError(ErrorType.SECURITY, "SIGNATURE_VERIFICATION_FAILED", "Bitcoin wallet signature verification failed");
|
|
396
|
+
throw (0, errorHandler_1.createError)(errorHandler_1.ErrorType.SECURITY, "SIGNATURE_VERIFICATION_FAILED", "Bitcoin wallet signature verification failed");
|
|
391
397
|
}
|
|
392
398
|
// Deriva le chiavi da address, signature, message
|
|
393
|
-
const k = await deriveNostrKeys(address, signature, message);
|
|
399
|
+
const k = await (0, nostrConnector_1.deriveNostrKeys)(address, signature, message);
|
|
394
400
|
// Set authentication method to nostr before signup
|
|
395
401
|
core.setAuthMethod("nostr");
|
|
396
402
|
// Usa le chiavi derivate per signup
|
|
@@ -424,10 +430,10 @@ export class NostrConnectorPlugin extends BasePlugin {
|
|
|
424
430
|
}
|
|
425
431
|
catch (error) {
|
|
426
432
|
// Handle both ShogunError and generic errors
|
|
427
|
-
const errorType = error?.type || ErrorType.AUTHENTICATION;
|
|
433
|
+
const errorType = error?.type || errorHandler_1.ErrorType.AUTHENTICATION;
|
|
428
434
|
const errorCode = error?.code || "BITCOIN_SIGNUP_ERROR";
|
|
429
435
|
const errorMessage = error?.message || "Unknown error during Bitcoin wallet signup";
|
|
430
|
-
ErrorHandler.handle(errorType, errorCode, errorMessage, error);
|
|
436
|
+
errorHandler_1.ErrorHandler.handle(errorType, errorCode, errorMessage, error);
|
|
431
437
|
return { success: false, error: errorMessage };
|
|
432
438
|
}
|
|
433
439
|
}
|
|
@@ -444,3 +450,4 @@ export class NostrConnectorPlugin extends BasePlugin {
|
|
|
444
450
|
return this.signUp(address);
|
|
445
451
|
}
|
|
446
452
|
}
|
|
453
|
+
exports.NostrConnectorPlugin = NostrConnectorPlugin;
|
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.NostrSigner = void 0;
|
|
7
|
+
const nostrConnector_1 = require("./nostrConnector");
|
|
8
|
+
const derive_1 = __importDefault(require("../../gundb/derive"));
|
|
9
|
+
const ethers_1 = require("ethers");
|
|
4
10
|
/**
|
|
5
11
|
* Nostr Signer - Provides oneshot signing functionality
|
|
6
12
|
* Similar to webauthn.js but for Nostr/Bitcoin wallets
|
|
7
13
|
* CONSISTENT with normal Nostr approach
|
|
8
14
|
*/
|
|
9
|
-
|
|
10
|
-
nostrConnector;
|
|
11
|
-
credentials = new Map();
|
|
12
|
-
MESSAGE_TO_SIGN = "I Love Shogun!"; // Same as normal approach
|
|
15
|
+
class NostrSigner {
|
|
13
16
|
constructor(nostrConnector) {
|
|
14
|
-
this.
|
|
17
|
+
this.credentials = new Map();
|
|
18
|
+
this.MESSAGE_TO_SIGN = "I Love Shogun!"; // Same as normal approach
|
|
19
|
+
this.nostrConnector = nostrConnector || new nostrConnector_1.NostrConnector();
|
|
15
20
|
}
|
|
16
21
|
/**
|
|
17
22
|
* Creates a new Nostr signing credential
|
|
@@ -112,7 +117,7 @@ export class NostrSigner {
|
|
|
112
117
|
try {
|
|
113
118
|
// SAME LOGIC as NostrConnector.generatePassword
|
|
114
119
|
const normalizedSig = signature.toLowerCase().replace(/[^a-f0-9]/g, "");
|
|
115
|
-
const passwordHash = ethers.sha256(ethers.toUtf8Bytes(normalizedSig));
|
|
120
|
+
const passwordHash = ethers_1.ethers.sha256(ethers_1.ethers.toUtf8Bytes(normalizedSig));
|
|
116
121
|
return passwordHash;
|
|
117
122
|
}
|
|
118
123
|
catch (error) {
|
|
@@ -164,7 +169,7 @@ export class NostrSigner {
|
|
|
164
169
|
try {
|
|
165
170
|
// CONSISTENCY: Use the same approach as normal Nostr
|
|
166
171
|
// Use password as seed (same as normal approach)
|
|
167
|
-
const derivedKeys = await
|
|
172
|
+
const derivedKeys = await (0, derive_1.default)(credential.password, // This is the key consistency point!
|
|
168
173
|
extra, { includeP256: true });
|
|
169
174
|
return {
|
|
170
175
|
pub: derivedKeys.pub,
|
|
@@ -310,4 +315,5 @@ export class NostrSigner {
|
|
|
310
315
|
return this.credentials.delete(address.toLowerCase());
|
|
311
316
|
}
|
|
312
317
|
}
|
|
313
|
-
|
|
318
|
+
exports.NostrSigner = NostrSigner;
|
|
319
|
+
exports.default = NostrSigner;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OAuthPlugin = exports.OAuthConnector = void 0;
|
|
1
4
|
// OAuth plugin exports
|
|
2
|
-
|
|
3
|
-
|
|
5
|
+
var oauthConnector_1 = require("./oauthConnector");
|
|
6
|
+
Object.defineProperty(exports, "OAuthConnector", { enumerable: true, get: function () { return oauthConnector_1.OAuthConnector; } });
|
|
7
|
+
var oauthPlugin_1 = require("./oauthPlugin");
|
|
8
|
+
Object.defineProperty(exports, "OAuthPlugin", { enumerable: true, get: function () { return oauthPlugin_1.OAuthPlugin; } });
|
|
@@ -1,76 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OAuthConnector = void 0;
|
|
1
7
|
/**
|
|
2
8
|
* OAuth Connector - Secure version for GunDB user creation
|
|
3
9
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
const eventEmitter_1 = require("../../utils/eventEmitter");
|
|
11
|
+
const derive_1 = __importDefault(require("../../gundb/derive"));
|
|
12
|
+
const validation_1 = require("../../utils/validation");
|
|
13
|
+
const ethers_1 = require("ethers");
|
|
8
14
|
/**
|
|
9
15
|
* OAuth Connector
|
|
10
16
|
*/
|
|
11
|
-
|
|
12
|
-
DEFAULT_CONFIG = {
|
|
13
|
-
providers: {
|
|
14
|
-
google: {
|
|
15
|
-
clientId: "",
|
|
16
|
-
redirectUri: `${this.getOrigin()}/auth/callback`,
|
|
17
|
-
scope: ["openid", "email", "profile"],
|
|
18
|
-
authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
19
|
-
tokenUrl: "https://oauth2.googleapis.com/token",
|
|
20
|
-
userInfoUrl: "https://www.googleapis.com/oauth2/v2/userinfo",
|
|
21
|
-
usePKCE: true, // Forza PKCE per Google
|
|
22
|
-
},
|
|
23
|
-
github: {
|
|
24
|
-
clientId: "",
|
|
25
|
-
redirectUri: `${this.getOrigin()}/auth/callback`,
|
|
26
|
-
scope: ["user:email"],
|
|
27
|
-
authUrl: "https://github.com/login/oauth/authorize",
|
|
28
|
-
tokenUrl: "https://github.com/login/oauth/access_token",
|
|
29
|
-
userInfoUrl: "https://api.github.com/user",
|
|
30
|
-
usePKCE: true,
|
|
31
|
-
},
|
|
32
|
-
discord: {
|
|
33
|
-
clientId: "",
|
|
34
|
-
redirectUri: `${this.getOrigin()}/auth/callback`,
|
|
35
|
-
scope: ["identify", "email"],
|
|
36
|
-
authUrl: "https://discord.com/api/oauth2/authorize",
|
|
37
|
-
tokenUrl: "https://discord.com/api/oauth2/token",
|
|
38
|
-
userInfoUrl: "https://discord.com/api/users/@me",
|
|
39
|
-
usePKCE: true,
|
|
40
|
-
},
|
|
41
|
-
twitter: {
|
|
42
|
-
clientId: "",
|
|
43
|
-
redirectUri: `${this.getOrigin()}/auth/callback`,
|
|
44
|
-
scope: ["tweet.read", "users.read"],
|
|
45
|
-
authUrl: "https://twitter.com/i/oauth2/authorize",
|
|
46
|
-
tokenUrl: "https://api.twitter.com/2/oauth2/token",
|
|
47
|
-
userInfoUrl: "https://api.twitter.com/2/users/me",
|
|
48
|
-
usePKCE: true,
|
|
49
|
-
},
|
|
50
|
-
custom: {
|
|
51
|
-
clientId: "",
|
|
52
|
-
redirectUri: "",
|
|
53
|
-
scope: [],
|
|
54
|
-
authUrl: "",
|
|
55
|
-
tokenUrl: "",
|
|
56
|
-
userInfoUrl: "",
|
|
57
|
-
usePKCE: true,
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
usePKCE: true, // PKCE abilitato di default per sicurezza
|
|
61
|
-
cacheDuration: 24 * 60 * 60 * 1000, // 24 hours
|
|
62
|
-
timeout: 60000,
|
|
63
|
-
maxRetries: 3,
|
|
64
|
-
retryDelay: 1000,
|
|
65
|
-
allowUnsafeClientSecret: false, // Disabilitato per sicurezza
|
|
66
|
-
stateTimeout: 10 * 60 * 1000, // 10 minuti per il timeout dello state
|
|
67
|
-
};
|
|
68
|
-
config;
|
|
69
|
-
userCache = new Map();
|
|
70
|
-
// Fallback storage for Node.js environment
|
|
71
|
-
memoryStorage = new Map();
|
|
17
|
+
class OAuthConnector extends eventEmitter_1.EventEmitter {
|
|
72
18
|
constructor(config = {}) {
|
|
73
19
|
super();
|
|
20
|
+
this.DEFAULT_CONFIG = {
|
|
21
|
+
providers: {
|
|
22
|
+
google: {
|
|
23
|
+
clientId: "",
|
|
24
|
+
redirectUri: `${this.getOrigin()}/auth/callback`,
|
|
25
|
+
scope: ["openid", "email", "profile"],
|
|
26
|
+
authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
27
|
+
tokenUrl: "https://oauth2.googleapis.com/token",
|
|
28
|
+
userInfoUrl: "https://www.googleapis.com/oauth2/v2/userinfo",
|
|
29
|
+
usePKCE: true, // Forza PKCE per Google
|
|
30
|
+
},
|
|
31
|
+
github: {
|
|
32
|
+
clientId: "",
|
|
33
|
+
redirectUri: `${this.getOrigin()}/auth/callback`,
|
|
34
|
+
scope: ["user:email"],
|
|
35
|
+
authUrl: "https://github.com/login/oauth/authorize",
|
|
36
|
+
tokenUrl: "https://github.com/login/oauth/access_token",
|
|
37
|
+
userInfoUrl: "https://api.github.com/user",
|
|
38
|
+
usePKCE: true,
|
|
39
|
+
},
|
|
40
|
+
discord: {
|
|
41
|
+
clientId: "",
|
|
42
|
+
redirectUri: `${this.getOrigin()}/auth/callback`,
|
|
43
|
+
scope: ["identify", "email"],
|
|
44
|
+
authUrl: "https://discord.com/api/oauth2/authorize",
|
|
45
|
+
tokenUrl: "https://discord.com/api/oauth2/token",
|
|
46
|
+
userInfoUrl: "https://discord.com/api/users/@me",
|
|
47
|
+
usePKCE: true,
|
|
48
|
+
},
|
|
49
|
+
twitter: {
|
|
50
|
+
clientId: "",
|
|
51
|
+
redirectUri: `${this.getOrigin()}/auth/callback`,
|
|
52
|
+
scope: ["tweet.read", "users.read"],
|
|
53
|
+
authUrl: "https://twitter.com/i/oauth2/authorize",
|
|
54
|
+
tokenUrl: "https://api.twitter.com/2/oauth2/token",
|
|
55
|
+
userInfoUrl: "https://api.twitter.com/2/users/me",
|
|
56
|
+
usePKCE: true,
|
|
57
|
+
},
|
|
58
|
+
custom: {
|
|
59
|
+
clientId: "",
|
|
60
|
+
redirectUri: "",
|
|
61
|
+
scope: [],
|
|
62
|
+
authUrl: "",
|
|
63
|
+
tokenUrl: "",
|
|
64
|
+
userInfoUrl: "",
|
|
65
|
+
usePKCE: true,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
usePKCE: true, // PKCE abilitato di default per sicurezza
|
|
69
|
+
cacheDuration: 24 * 60 * 60 * 1000, // 24 hours
|
|
70
|
+
timeout: 60000,
|
|
71
|
+
maxRetries: 3,
|
|
72
|
+
retryDelay: 1000,
|
|
73
|
+
allowUnsafeClientSecret: false, // Disabilitato per sicurezza
|
|
74
|
+
stateTimeout: 10 * 60 * 1000, // 10 minuti per il timeout dello state
|
|
75
|
+
};
|
|
76
|
+
this.userCache = new Map();
|
|
77
|
+
// Fallback storage for Node.js environment
|
|
78
|
+
this.memoryStorage = new Map();
|
|
74
79
|
this.config = {
|
|
75
80
|
...this.DEFAULT_CONFIG,
|
|
76
81
|
...config,
|
|
@@ -388,15 +393,15 @@ export class OAuthConnector extends EventEmitter {
|
|
|
388
393
|
throw new Error(`Provider ${provider} is not configured.`);
|
|
389
394
|
}
|
|
390
395
|
// Username uniforme
|
|
391
|
-
const username = generateUsernameFromIdentity(provider, userInfo);
|
|
396
|
+
const username = (0, validation_1.generateUsernameFromIdentity)(provider, userInfo);
|
|
392
397
|
try {
|
|
393
398
|
console.log(`Generating credentials for ${provider} user: ${userInfo.id}`);
|
|
394
399
|
const saltData = `${userInfo.id}_${provider}_${userInfo.email || "no-email"}`;
|
|
395
|
-
const salt = ethers.keccak256(ethers.toUtf8Bytes(saltData));
|
|
400
|
+
const salt = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(saltData));
|
|
396
401
|
// Password deterministica (compatibilità)
|
|
397
|
-
const password = generateDeterministicPassword(salt);
|
|
402
|
+
const password = (0, validation_1.generateDeterministicPassword)(salt);
|
|
398
403
|
// Deriva la chiave GunDB
|
|
399
|
-
const key = await
|
|
404
|
+
const key = await (0, derive_1.default)(password, salt, { includeP256: true });
|
|
400
405
|
const credentials = {
|
|
401
406
|
username,
|
|
402
407
|
password,
|
|
@@ -751,3 +756,4 @@ export class OAuthConnector extends EventEmitter {
|
|
|
751
756
|
}
|
|
752
757
|
}
|
|
753
758
|
}
|
|
759
|
+
exports.OAuthConnector = OAuthConnector;
|