shogun-core 2.0.0 → 2.0.1
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 +74126 -91893
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/core.js +32 -36
- package/dist/gundb/crypto.js +17 -32
- package/dist/gundb/db.js +35 -82
- package/dist/gundb/derive.js +16 -19
- package/dist/gundb/errors.js +7 -17
- package/dist/gundb/index.js +1 -17
- package/dist/gundb/restricted-put.js +5 -11
- package/dist/gundb/rxjs.js +15 -19
- package/dist/gundb/types.js +1 -2
- package/dist/index.js +9 -34
- package/dist/plugins/base.js +2 -6
- package/dist/plugins/index.js +10 -36
- package/dist/plugins/nostr/index.js +4 -20
- package/dist/plugins/nostr/nostrConnector.js +22 -29
- package/dist/plugins/nostr/nostrConnectorPlugin.js +24 -28
- package/dist/plugins/nostr/nostrSigner.js +8 -15
- package/dist/plugins/nostr/types.js +1 -2
- package/dist/plugins/oauth/index.js +2 -7
- package/dist/plugins/oauth/oauthConnector.js +9 -16
- package/dist/plugins/oauth/oauthPlugin.js +21 -25
- package/dist/plugins/oauth/types.js +1 -2
- package/dist/plugins/web3/index.js +4 -20
- package/dist/plugins/web3/types.js +1 -2
- package/dist/plugins/web3/web3Connector.js +21 -27
- package/dist/plugins/web3/web3ConnectorPlugin.js +17 -21
- package/dist/plugins/web3/web3Signer.js +15 -22
- package/dist/plugins/webauthn/index.js +3 -19
- package/dist/plugins/webauthn/types.js +2 -5
- package/dist/plugins/webauthn/webauthn.js +21 -29
- package/dist/plugins/webauthn/webauthnPlugin.js +9 -13
- package/dist/plugins/webauthn/webauthnSigner.js +12 -19
- package/dist/storage/storage.js +1 -5
- package/dist/types/common.js +1 -2
- package/dist/types/events.js +2 -6
- package/dist/types/gundb/db.d.ts +2 -0
- package/dist/types/plugin.js +1 -2
- package/dist/types/shogun.js +4 -7
- package/dist/utils/errorHandler.js +4 -9
- package/dist/utils/eventEmitter.js +1 -5
- package/dist/utils/validation.js +7 -14
- package/package.json +1 -3
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const web3Connector_1 = require("./web3Connector");
|
|
6
|
-
const web3Signer_1 = require("./web3Signer");
|
|
7
|
-
const errorHandler_1 = require("../../utils/errorHandler");
|
|
1
|
+
import { BasePlugin } from "../base";
|
|
2
|
+
import { Web3Connector } from "./web3Connector";
|
|
3
|
+
import { Web3Signer } from "./web3Signer";
|
|
4
|
+
import { ErrorHandler, ErrorType, createError } from "../../utils/errorHandler";
|
|
8
5
|
/**
|
|
9
6
|
* Plugin per la gestione delle funzionalità Web3 in ShogunCore
|
|
10
7
|
*/
|
|
11
|
-
class Web3ConnectorPlugin extends
|
|
8
|
+
export class Web3ConnectorPlugin extends BasePlugin {
|
|
12
9
|
name = "web3";
|
|
13
10
|
version = "1.0.0";
|
|
14
11
|
description = "Provides Ethereum wallet connection and authentication for ShogunCore";
|
|
@@ -20,8 +17,8 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
20
17
|
initialize(core) {
|
|
21
18
|
super.initialize(core);
|
|
22
19
|
// Inizializziamo il modulo Web3
|
|
23
|
-
this.Web3 = new
|
|
24
|
-
this.signer = new
|
|
20
|
+
this.Web3 = new Web3Connector();
|
|
21
|
+
this.signer = new Web3Signer(this.Web3);
|
|
25
22
|
// Rimuovo i console.log superflui
|
|
26
23
|
}
|
|
27
24
|
/**
|
|
@@ -319,10 +316,10 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
319
316
|
try {
|
|
320
317
|
const core = this.assertInitialized();
|
|
321
318
|
if (!address) {
|
|
322
|
-
throw
|
|
319
|
+
throw createError(ErrorType.VALIDATION, "ADDRESS_REQUIRED", "Ethereum address required for Web3 login");
|
|
323
320
|
}
|
|
324
321
|
if (!this.isAvailable()) {
|
|
325
|
-
throw
|
|
322
|
+
throw createError(ErrorType.ENVIRONMENT, "WEB3_UNAVAILABLE", "Web3 is not available in the browser");
|
|
326
323
|
}
|
|
327
324
|
console.log(`🔧 Web3 login - starting login for address:`, address);
|
|
328
325
|
// FIX: Use deterministic pair instead of generating new credentials
|
|
@@ -369,7 +366,7 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
369
366
|
address,
|
|
370
367
|
});
|
|
371
368
|
if (!gunUser.success) {
|
|
372
|
-
throw
|
|
369
|
+
throw createError(ErrorType.AUTHENTICATION, "WEB3_LOGIN_FAILED", gunUser.error || "Failed to log in with Web3 credentials");
|
|
373
370
|
}
|
|
374
371
|
console.log(`🔧 Web3 login - gunUser success, userPub:`, gunUser.userPub ? gunUser.userPub.slice(0, 8) + "..." : "null");
|
|
375
372
|
// Set authentication method to web3
|
|
@@ -400,10 +397,10 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
400
397
|
}
|
|
401
398
|
catch (error) {
|
|
402
399
|
// Handle both ShogunError and generic errors
|
|
403
|
-
const errorType = error?.type ||
|
|
400
|
+
const errorType = error?.type || ErrorType.AUTHENTICATION;
|
|
404
401
|
const errorCode = error?.code || "WEB3_LOGIN_ERROR";
|
|
405
402
|
const errorMessage = error?.message || "Unknown error during Web3 login";
|
|
406
|
-
|
|
403
|
+
ErrorHandler.handle(errorType, errorCode, errorMessage, error);
|
|
407
404
|
return { success: false, error: errorMessage };
|
|
408
405
|
}
|
|
409
406
|
}
|
|
@@ -416,15 +413,15 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
416
413
|
try {
|
|
417
414
|
const core = this.assertInitialized();
|
|
418
415
|
if (!address) {
|
|
419
|
-
throw
|
|
416
|
+
throw createError(ErrorType.VALIDATION, "ADDRESS_REQUIRED", "Ethereum address required for Web3 registration");
|
|
420
417
|
}
|
|
421
418
|
if (!this.isAvailable()) {
|
|
422
|
-
throw
|
|
419
|
+
throw createError(ErrorType.ENVIRONMENT, "WEB3_UNAVAILABLE", "Web3 is not available in the browser");
|
|
423
420
|
}
|
|
424
421
|
// Use setupConsistentOneshotSigning for signup
|
|
425
422
|
const { gunUser } = await this.setupConsistentOneshotSigning(address);
|
|
426
423
|
if (!gunUser.success) {
|
|
427
|
-
throw
|
|
424
|
+
throw createError(ErrorType.AUTHENTICATION, "WEB3_SIGNUP_FAILED", gunUser.error || "Failed to sign up with Web3 credentials");
|
|
428
425
|
}
|
|
429
426
|
// Set authentication method to web3
|
|
430
427
|
core.setAuthMethod("web3");
|
|
@@ -441,12 +438,11 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
441
438
|
}
|
|
442
439
|
catch (error) {
|
|
443
440
|
// Handle both ShogunError and generic errors
|
|
444
|
-
const errorType = error?.type ||
|
|
441
|
+
const errorType = error?.type || ErrorType.AUTHENTICATION;
|
|
445
442
|
const errorCode = error?.code || "WEB3_SIGNUP_ERROR";
|
|
446
443
|
const errorMessage = error?.message || "Unknown error during Web3 registration";
|
|
447
|
-
|
|
444
|
+
ErrorHandler.handle(errorType, errorCode, errorMessage, error);
|
|
448
445
|
return { success: false, error: errorMessage };
|
|
449
446
|
}
|
|
450
447
|
}
|
|
451
448
|
}
|
|
452
|
-
exports.Web3ConnectorPlugin = Web3ConnectorPlugin;
|
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.Web3Signer = void 0;
|
|
7
|
-
const web3Connector_1 = require("./web3Connector");
|
|
8
|
-
const ethers_1 = require("ethers");
|
|
9
|
-
const derive_1 = __importDefault(require("../../gundb/derive"));
|
|
1
|
+
import { Web3Connector } from "./web3Connector";
|
|
2
|
+
import { ethers } from "ethers";
|
|
3
|
+
import derive from "../../gundb/derive";
|
|
10
4
|
/**
|
|
11
5
|
* Web3 Signer - Provides oneshot signing functionality
|
|
12
6
|
* Similar to webauthn.js but for Web3/MetaMask
|
|
13
7
|
* CONSISTENT with normal Web3 approach
|
|
14
8
|
*/
|
|
15
|
-
class Web3Signer {
|
|
9
|
+
export class Web3Signer {
|
|
16
10
|
web3Connector;
|
|
17
11
|
credentials = new Map();
|
|
18
12
|
MESSAGE_TO_SIGN = "I Love Shogun!"; // Same as normal approach
|
|
19
13
|
constructor(web3Connector) {
|
|
20
|
-
this.web3Connector = web3Connector || new
|
|
14
|
+
this.web3Connector = web3Connector || new Web3Connector();
|
|
21
15
|
}
|
|
22
16
|
/**
|
|
23
17
|
* Creates a new Web3 signing credential
|
|
@@ -26,14 +20,14 @@ class Web3Signer {
|
|
|
26
20
|
async createSigningCredential(address) {
|
|
27
21
|
try {
|
|
28
22
|
// Validate address
|
|
29
|
-
const validAddress =
|
|
23
|
+
const validAddress = ethers.getAddress(address.toLowerCase());
|
|
30
24
|
// Request signature using the same approach as normal Web3
|
|
31
25
|
const signature = await this.requestSignature(validAddress);
|
|
32
26
|
// Generate credentials using the SAME logic as normal approach
|
|
33
27
|
const username = `${validAddress.toLowerCase()}`;
|
|
34
28
|
// FIX: Use only address for password generation to ensure consistency
|
|
35
29
|
// The signature changes each time, causing different passwords for same user
|
|
36
|
-
const password =
|
|
30
|
+
const password = ethers.keccak256(ethers.toUtf8Bytes(`${validAddress.toLowerCase()}:shogun-web3`));
|
|
37
31
|
const signingCredential = {
|
|
38
32
|
address: validAddress,
|
|
39
33
|
signature,
|
|
@@ -143,11 +137,11 @@ class Web3Signer {
|
|
|
143
137
|
async createDerivedKeyPairFromAddress(address, extra) {
|
|
144
138
|
try {
|
|
145
139
|
// Generate deterministic password from address (same as createSigningCredential)
|
|
146
|
-
const validAddress =
|
|
147
|
-
const password =
|
|
140
|
+
const validAddress = ethers.getAddress(address.toLowerCase());
|
|
141
|
+
const password = ethers.keccak256(ethers.toUtf8Bytes(`${validAddress.toLowerCase()}:shogun-web3`));
|
|
148
142
|
console.log(`🔧 Web3Signer - generating deterministic pair for address:`, validAddress);
|
|
149
143
|
// Use the same derive function as normal approach
|
|
150
|
-
const derivedKeys = await (
|
|
144
|
+
const derivedKeys = await derive(password, // Deterministic password from address
|
|
151
145
|
extra, { includeP256: true });
|
|
152
146
|
return {
|
|
153
147
|
pub: derivedKeys.pub,
|
|
@@ -226,9 +220,9 @@ class Web3Signer {
|
|
|
226
220
|
const keyPair = await this.createDerivedKeyPair(address, extra);
|
|
227
221
|
// Create signature using the same approach as SEA
|
|
228
222
|
const message = JSON.stringify(data);
|
|
229
|
-
const messageHash =
|
|
223
|
+
const messageHash = ethers.keccak256(ethers.toUtf8Bytes(message));
|
|
230
224
|
// Use ethers for signing (compatible with SEA)
|
|
231
|
-
const wallet = new
|
|
225
|
+
const wallet = new ethers.Wallet(keyPair.priv);
|
|
232
226
|
const signature = await wallet.signMessage(message);
|
|
233
227
|
// Format like SEA signature
|
|
234
228
|
const seaSignature = {
|
|
@@ -263,8 +257,8 @@ class Web3Signer {
|
|
|
263
257
|
getPassword(address) {
|
|
264
258
|
try {
|
|
265
259
|
// Generate deterministic password from address (same as createSigningCredential)
|
|
266
|
-
const validAddress =
|
|
267
|
-
const password =
|
|
260
|
+
const validAddress = ethers.getAddress(address.toLowerCase());
|
|
261
|
+
const password = ethers.keccak256(ethers.toUtf8Bytes(`${validAddress.toLowerCase()}:shogun-web3`));
|
|
268
262
|
return password;
|
|
269
263
|
}
|
|
270
264
|
catch (error) {
|
|
@@ -311,5 +305,4 @@ class Web3Signer {
|
|
|
311
305
|
return this.credentials.delete(address.toLowerCase());
|
|
312
306
|
}
|
|
313
307
|
}
|
|
314
|
-
|
|
315
|
-
exports.default = Web3Signer;
|
|
308
|
+
export default Web3Signer;
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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("./webauthnPlugin"), exports);
|
|
18
|
-
__exportStar(require("./types"), exports);
|
|
19
|
-
__exportStar(require("./webauthn"), exports);
|
|
1
|
+
export * from "./webauthnPlugin";
|
|
2
|
+
export * from "./types";
|
|
3
|
+
export * from "./webauthn";
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WebAuthnEventType = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* WebAuthn event types
|
|
6
3
|
*/
|
|
7
|
-
var WebAuthnEventType;
|
|
4
|
+
export var WebAuthnEventType;
|
|
8
5
|
(function (WebAuthnEventType) {
|
|
9
6
|
WebAuthnEventType["DEVICE_REGISTERED"] = "deviceRegistered";
|
|
10
7
|
WebAuthnEventType["DEVICE_REMOVED"] = "deviceRemoved";
|
|
11
8
|
WebAuthnEventType["AUTHENTICATION_SUCCESS"] = "authenticationSuccess";
|
|
12
9
|
WebAuthnEventType["AUTHENTICATION_FAILED"] = "authenticationFailed";
|
|
13
10
|
WebAuthnEventType["ERROR"] = "error";
|
|
14
|
-
})(WebAuthnEventType || (
|
|
11
|
+
})(WebAuthnEventType || (WebAuthnEventType = {}));
|
|
@@ -1,20 +1,13 @@
|
|
|
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.Webauthn = void 0;
|
|
7
|
-
exports.deriveWebauthnKeys = deriveWebauthnKeys;
|
|
8
1
|
/**
|
|
9
2
|
* Constants for WebAuthn configuration
|
|
10
3
|
*/
|
|
11
4
|
const MIN_USERNAME_LENGTH = 3;
|
|
12
5
|
const MAX_USERNAME_LENGTH = 64;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
import { ethers } from "ethers";
|
|
7
|
+
import { ErrorHandler, ErrorType } from "../../utils/errorHandler";
|
|
8
|
+
import { EventEmitter } from "../../utils/eventEmitter";
|
|
9
|
+
import { WebAuthnEventType, } from "./types";
|
|
10
|
+
import derive from "../../gundb/derive";
|
|
18
11
|
/**
|
|
19
12
|
* Constants for WebAuthn configuration
|
|
20
13
|
*/
|
|
@@ -29,7 +22,7 @@ const DEFAULT_CONFIG = {
|
|
|
29
22
|
/**
|
|
30
23
|
* Main WebAuthn class for authentication management
|
|
31
24
|
*/
|
|
32
|
-
class Webauthn extends
|
|
25
|
+
export class Webauthn extends EventEmitter {
|
|
33
26
|
config;
|
|
34
27
|
gunInstance;
|
|
35
28
|
credential;
|
|
@@ -80,8 +73,8 @@ class Webauthn extends eventEmitter_1.EventEmitter {
|
|
|
80
73
|
try {
|
|
81
74
|
const result = await this.generateCredentials(username, credentials, isNewDevice);
|
|
82
75
|
if (result.success) {
|
|
83
|
-
this.emit(
|
|
84
|
-
type:
|
|
76
|
+
this.emit(WebAuthnEventType.DEVICE_REGISTERED, {
|
|
77
|
+
type: WebAuthnEventType.DEVICE_REGISTERED,
|
|
85
78
|
data: { username },
|
|
86
79
|
timestamp: Date.now(),
|
|
87
80
|
});
|
|
@@ -100,8 +93,8 @@ class Webauthn extends eventEmitter_1.EventEmitter {
|
|
|
100
93
|
throw lastError || new Error("Failed to create account after retries");
|
|
101
94
|
}
|
|
102
95
|
catch (error) {
|
|
103
|
-
this.emit(
|
|
104
|
-
type:
|
|
96
|
+
this.emit(WebAuthnEventType.ERROR, {
|
|
97
|
+
type: WebAuthnEventType.ERROR,
|
|
105
98
|
data: { error: error.message },
|
|
106
99
|
timestamp: Date.now(),
|
|
107
100
|
});
|
|
@@ -116,7 +109,7 @@ class Webauthn extends eventEmitter_1.EventEmitter {
|
|
|
116
109
|
this.validateUsername(username);
|
|
117
110
|
if (!salt) {
|
|
118
111
|
const error = new Error("No WebAuthn credentials found for this username");
|
|
119
|
-
|
|
112
|
+
ErrorHandler.handle(ErrorType.WEBAUTHN, "NO_CREDENTIALS", error.message, error);
|
|
120
113
|
return { success: false, error: error.message };
|
|
121
114
|
}
|
|
122
115
|
// Cancel any existing authentication attempt
|
|
@@ -150,8 +143,8 @@ class Webauthn extends eventEmitter_1.EventEmitter {
|
|
|
150
143
|
credentialId: this.bufferToBase64(assertion.rawId),
|
|
151
144
|
deviceInfo,
|
|
152
145
|
};
|
|
153
|
-
this.emit(
|
|
154
|
-
type:
|
|
146
|
+
this.emit(WebAuthnEventType.AUTHENTICATION_SUCCESS, {
|
|
147
|
+
type: WebAuthnEventType.AUTHENTICATION_SUCCESS,
|
|
155
148
|
data: { username, deviceInfo },
|
|
156
149
|
timestamp: Date.now(),
|
|
157
150
|
});
|
|
@@ -164,12 +157,12 @@ class Webauthn extends eventEmitter_1.EventEmitter {
|
|
|
164
157
|
}
|
|
165
158
|
catch (error) {
|
|
166
159
|
const errorMessage = error instanceof Error ? error.message : "Unknown WebAuthn error";
|
|
167
|
-
this.emit(
|
|
168
|
-
type:
|
|
160
|
+
this.emit(WebAuthnEventType.AUTHENTICATION_FAILED, {
|
|
161
|
+
type: WebAuthnEventType.AUTHENTICATION_FAILED,
|
|
169
162
|
data: { username, error: errorMessage },
|
|
170
163
|
timestamp: Date.now(),
|
|
171
164
|
});
|
|
172
|
-
|
|
165
|
+
ErrorHandler.handle(ErrorType.WEBAUTHN, "AUTH_ERROR", errorMessage, error);
|
|
173
166
|
return { success: false, error: errorMessage };
|
|
174
167
|
}
|
|
175
168
|
}
|
|
@@ -262,9 +255,9 @@ class Webauthn extends eventEmitter_1.EventEmitter {
|
|
|
262
255
|
* Generates credentials from username and salt
|
|
263
256
|
*/
|
|
264
257
|
generateCredentialsFromSalt(username, salt) {
|
|
265
|
-
const data =
|
|
258
|
+
const data = ethers.toUtf8Bytes(username + salt);
|
|
266
259
|
return {
|
|
267
|
-
password:
|
|
260
|
+
password: ethers.sha256(data),
|
|
268
261
|
};
|
|
269
262
|
}
|
|
270
263
|
/**
|
|
@@ -468,7 +461,6 @@ class Webauthn extends eventEmitter_1.EventEmitter {
|
|
|
468
461
|
return signature;
|
|
469
462
|
}
|
|
470
463
|
}
|
|
471
|
-
exports.Webauthn = Webauthn;
|
|
472
464
|
// Add to global scope if available
|
|
473
465
|
if (typeof window !== "undefined") {
|
|
474
466
|
window.Webauthn = Webauthn;
|
|
@@ -477,10 +469,10 @@ else if (typeof global !== "undefined") {
|
|
|
477
469
|
global.Webauthn = Webauthn;
|
|
478
470
|
}
|
|
479
471
|
// Funzione helper per derivare chiavi WebAuthn (come per Web3)
|
|
480
|
-
async function deriveWebauthnKeys(username, credentialId) {
|
|
481
|
-
const hashedCredentialId =
|
|
472
|
+
export async function deriveWebauthnKeys(username, credentialId) {
|
|
473
|
+
const hashedCredentialId = ethers.keccak256(ethers.toUtf8Bytes(credentialId));
|
|
482
474
|
const salt = `${username}_${credentialId}`;
|
|
483
|
-
return await (
|
|
475
|
+
return await derive(hashedCredentialId, salt, {
|
|
484
476
|
includeP256: true,
|
|
485
477
|
});
|
|
486
478
|
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const webauthn_1 = require("./webauthn");
|
|
6
|
-
const webauthnSigner_1 = require("./webauthnSigner");
|
|
7
|
-
const errorHandler_1 = require("../../utils/errorHandler");
|
|
1
|
+
import { BasePlugin } from "../base";
|
|
2
|
+
import { Webauthn } from "./webauthn";
|
|
3
|
+
import { WebAuthnSigner } from "./webauthnSigner";
|
|
4
|
+
import { ErrorHandler, ErrorType } from "../../utils/errorHandler";
|
|
8
5
|
/**
|
|
9
6
|
* Plugin per la gestione delle funzionalità WebAuthn in ShogunCore
|
|
10
7
|
*/
|
|
11
|
-
class WebauthnPlugin extends
|
|
8
|
+
export class WebauthnPlugin extends BasePlugin {
|
|
12
9
|
name = "webauthn";
|
|
13
10
|
version = "1.0.0";
|
|
14
11
|
description = "Provides WebAuthn authentication functionality for ShogunCore";
|
|
@@ -30,8 +27,8 @@ class WebauthnPlugin extends base_1.BasePlugin {
|
|
|
30
27
|
return;
|
|
31
28
|
}
|
|
32
29
|
// Inizializziamo il modulo WebAuthn
|
|
33
|
-
this.webauthn = new
|
|
34
|
-
this.signer = new
|
|
30
|
+
this.webauthn = new Webauthn(core.gun);
|
|
31
|
+
this.signer = new WebAuthnSigner(this.webauthn);
|
|
35
32
|
console.log("[webauthnPlugin] WebAuthn plugin initialized with signer support");
|
|
36
33
|
}
|
|
37
34
|
/**
|
|
@@ -345,7 +342,7 @@ class WebauthnPlugin extends base_1.BasePlugin {
|
|
|
345
342
|
catch (error) {
|
|
346
343
|
console.error(`Error during WebAuthn login: ${error}`);
|
|
347
344
|
// Log but do not depend on handler return value
|
|
348
|
-
|
|
345
|
+
ErrorHandler.handle(ErrorType.WEBAUTHN, "WEBAUTHN_LOGIN_ERROR", error.message || "Error during WebAuthn login", error);
|
|
349
346
|
return {
|
|
350
347
|
success: false,
|
|
351
348
|
error: error.message || "Error during WebAuthn login",
|
|
@@ -391,7 +388,7 @@ class WebauthnPlugin extends base_1.BasePlugin {
|
|
|
391
388
|
}
|
|
392
389
|
catch (error) {
|
|
393
390
|
console.error(`Error during WebAuthn registration: ${error}`);
|
|
394
|
-
|
|
391
|
+
ErrorHandler.handle(ErrorType.WEBAUTHN, "WEBAUTHN_SIGNUP_ERROR", error.message || "Error during WebAuthn registration", error);
|
|
395
392
|
return {
|
|
396
393
|
success: false,
|
|
397
394
|
error: error.message || "Error during WebAuthn registration",
|
|
@@ -399,4 +396,3 @@ class WebauthnPlugin extends base_1.BasePlugin {
|
|
|
399
396
|
}
|
|
400
397
|
}
|
|
401
398
|
}
|
|
402
|
-
exports.WebauthnPlugin = WebauthnPlugin;
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
exports.WebAuthnSigner = void 0;
|
|
7
|
-
const webauthn_1 = require("./webauthn");
|
|
8
|
-
const p256_1 = require("@noble/curves/p256");
|
|
9
|
-
const sha256_1 = require("@noble/hashes/sha256");
|
|
10
|
-
const derive_1 = __importDefault(require("../../gundb/derive"));
|
|
11
|
-
const ethers_1 = require("ethers");
|
|
1
|
+
import { Webauthn } from "./webauthn";
|
|
2
|
+
import { p256 } from "@noble/curves/p256";
|
|
3
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
4
|
+
import derive from "../../gundb/derive";
|
|
5
|
+
import { ethers } from "ethers";
|
|
12
6
|
/**
|
|
13
7
|
* Base64URL encoding utilities
|
|
14
8
|
*/
|
|
@@ -33,11 +27,11 @@ const base64url = {
|
|
|
33
27
|
* Similar to webauthn.js but integrated with our architecture
|
|
34
28
|
* CONSISTENT with normal WebAuthn approach
|
|
35
29
|
*/
|
|
36
|
-
class WebAuthnSigner {
|
|
30
|
+
export class WebAuthnSigner {
|
|
37
31
|
webauthn;
|
|
38
32
|
credentials = new Map();
|
|
39
33
|
constructor(webauthn) {
|
|
40
|
-
this.webauthn = webauthn || new
|
|
34
|
+
this.webauthn = webauthn || new Webauthn();
|
|
41
35
|
}
|
|
42
36
|
/**
|
|
43
37
|
* Creates a new WebAuthn credential for signing
|
|
@@ -89,7 +83,7 @@ class WebAuthnSigner {
|
|
|
89
83
|
const y = base64url.encode(yCoord);
|
|
90
84
|
const pub = `${x}.${y}`;
|
|
91
85
|
// CONSISTENCY: Use the same hashing approach as normal WebAuthn
|
|
92
|
-
const hashedCredentialId =
|
|
86
|
+
const hashedCredentialId = ethers.keccak256(ethers.toUtf8Bytes(credential.id));
|
|
93
87
|
const signingCredential = {
|
|
94
88
|
id: credential.id,
|
|
95
89
|
rawId: credential.rawId,
|
|
@@ -158,7 +152,7 @@ class WebAuthnSigner {
|
|
|
158
152
|
try {
|
|
159
153
|
// CONSISTENCY: Use the same approach as normal WebAuthn
|
|
160
154
|
// Use hashedCredentialId as password (same as normal approach)
|
|
161
|
-
const derivedKeys = await (
|
|
155
|
+
const derivedKeys = await derive(credential.hashedCredentialId, // This is the key change!
|
|
162
156
|
extra, { includeP256: true });
|
|
163
157
|
return {
|
|
164
158
|
pub: derivedKeys.pub,
|
|
@@ -240,11 +234,11 @@ class WebAuthnSigner {
|
|
|
240
234
|
const keyPair = await this.createDerivedKeyPair(credentialId, username, extra);
|
|
241
235
|
// Create signature using P-256 (same as SEA)
|
|
242
236
|
const message = JSON.stringify(data);
|
|
243
|
-
const messageHash =
|
|
237
|
+
const messageHash = sha256(new TextEncoder().encode(message));
|
|
244
238
|
// Convert base64url private key to bytes
|
|
245
239
|
const privKeyBytes = base64url.decode(keyPair.priv);
|
|
246
240
|
// Sign with P-256
|
|
247
|
-
const signature =
|
|
241
|
+
const signature = p256.sign(messageHash, privKeyBytes);
|
|
248
242
|
// Format like SEA signature
|
|
249
243
|
const seaSignature = {
|
|
250
244
|
m: message,
|
|
@@ -307,5 +301,4 @@ class WebAuthnSigner {
|
|
|
307
301
|
return this.credentials.delete(credentialId);
|
|
308
302
|
}
|
|
309
303
|
}
|
|
310
|
-
|
|
311
|
-
exports.default = WebAuthnSigner;
|
|
304
|
+
export default WebAuthnSigner;
|
package/dist/storage/storage.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ShogunStorage = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Storage implementation based on StorageMock
|
|
6
3
|
* Provides a unified storage interface that works in both browser and non-browser environments
|
|
7
4
|
* In browser environments, data is persisted to localStorage as a backup
|
|
8
5
|
*/
|
|
9
|
-
class ShogunStorage {
|
|
6
|
+
export class ShogunStorage {
|
|
10
7
|
store;
|
|
11
8
|
isTestMode;
|
|
12
9
|
useLocalStorage;
|
|
@@ -148,4 +145,3 @@ class ShogunStorage {
|
|
|
148
145
|
}
|
|
149
146
|
}
|
|
150
147
|
}
|
|
151
|
-
exports.ShogunStorage = ShogunStorage;
|
package/dist/types/common.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/types/events.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ShogunEventEmitter = void 0;
|
|
4
|
-
const eventEmitter_1 = require("../utils/eventEmitter");
|
|
1
|
+
import { EventEmitter } from "../utils/eventEmitter";
|
|
5
2
|
/**
|
|
6
3
|
* Extended EventEmitter class with typed events for Shogun
|
|
7
4
|
* @class ShogunEventEmitter
|
|
8
5
|
* @extends EventEmitter
|
|
9
6
|
*/
|
|
10
|
-
class ShogunEventEmitter extends
|
|
7
|
+
export class ShogunEventEmitter extends EventEmitter {
|
|
11
8
|
/**
|
|
12
9
|
* Emit a typed Shogun event
|
|
13
10
|
* @template K - Event key type
|
|
@@ -37,4 +34,3 @@ class ShogunEventEmitter extends eventEmitter_1.EventEmitter {
|
|
|
37
34
|
super.off(event, listener);
|
|
38
35
|
}
|
|
39
36
|
}
|
|
40
|
-
exports.ShogunEventEmitter = ShogunEventEmitter;
|
package/dist/types/gundb/db.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ import "gun/lib/radisk";
|
|
|
14
14
|
import "gun/lib/store";
|
|
15
15
|
import "gun/lib/rindexed";
|
|
16
16
|
import "gun/lib/webrtc";
|
|
17
|
+
import "gun/lib/evict";
|
|
18
|
+
import "gun/lib/les";
|
|
17
19
|
import { restrictedPut } from "./restricted-put";
|
|
18
20
|
import derive, { DeriveOptions } from "./derive";
|
|
19
21
|
import type { IGunUserInstance, IGunInstance, IGunChain, ISEAPair } from "gun/types";
|
package/dist/types/plugin.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/dist/types/shogun.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CorePlugins = exports.PluginCategory = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Standard plugin categories in ShogunCore
|
|
6
3
|
*/
|
|
7
|
-
var PluginCategory;
|
|
4
|
+
export var PluginCategory;
|
|
8
5
|
(function (PluginCategory) {
|
|
9
6
|
/** Authentication plugins (WebAuthn, MetaMask, Bitcoin) */
|
|
10
7
|
PluginCategory["Authentication"] = "authentication";
|
|
@@ -20,11 +17,11 @@ var PluginCategory;
|
|
|
20
17
|
PluginCategory["Messages"] = "messages";
|
|
21
18
|
/** Messaging plugins */
|
|
22
19
|
PluginCategory["Other"] = "other";
|
|
23
|
-
})(PluginCategory || (
|
|
20
|
+
})(PluginCategory || (PluginCategory = {}));
|
|
24
21
|
/**
|
|
25
22
|
* Standard names for built-in plugins
|
|
26
23
|
*/
|
|
27
|
-
var CorePlugins;
|
|
24
|
+
export var CorePlugins;
|
|
28
25
|
(function (CorePlugins) {
|
|
29
26
|
/** WebAuthn plugin */
|
|
30
27
|
CorePlugins["WebAuthn"] = "webauthn";
|
|
@@ -34,4 +31,4 @@ var CorePlugins;
|
|
|
34
31
|
CorePlugins["Nostr"] = "nostr";
|
|
35
32
|
/** OAuth plugin */
|
|
36
33
|
CorePlugins["OAuth"] = "oauth";
|
|
37
|
-
})(CorePlugins || (
|
|
34
|
+
})(CorePlugins || (CorePlugins = {}));
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ErrorHandler = exports.ErrorType = void 0;
|
|
4
|
-
exports.createError = createError;
|
|
5
1
|
/**
|
|
6
2
|
* Types of errors that can occur in the application
|
|
7
3
|
*/
|
|
8
|
-
var ErrorType;
|
|
4
|
+
export var ErrorType;
|
|
9
5
|
(function (ErrorType) {
|
|
10
6
|
ErrorType["AUTHENTICATION"] = "AuthenticationError";
|
|
11
7
|
ErrorType["AUTHORIZATION"] = "AuthorizationError";
|
|
@@ -29,7 +25,7 @@ var ErrorType;
|
|
|
29
25
|
ErrorType["BIP32"] = "BIP32Error";
|
|
30
26
|
ErrorType["ETHEREUM"] = "EthereumError";
|
|
31
27
|
ErrorType["BITCOIN"] = "BitcoinError";
|
|
32
|
-
})(ErrorType || (
|
|
28
|
+
})(ErrorType || (ErrorType = {}));
|
|
33
29
|
/**
|
|
34
30
|
* Wrapper to standardize errors
|
|
35
31
|
* @param type - Error type
|
|
@@ -38,7 +34,7 @@ var ErrorType;
|
|
|
38
34
|
* @param originalError - Original error
|
|
39
35
|
* @returns A structured error object
|
|
40
36
|
*/
|
|
41
|
-
function createError(type, code, message, originalError) {
|
|
37
|
+
export function createError(type, code, message, originalError) {
|
|
42
38
|
return {
|
|
43
39
|
type,
|
|
44
40
|
code,
|
|
@@ -50,7 +46,7 @@ function createError(type, code, message, originalError) {
|
|
|
50
46
|
/**
|
|
51
47
|
* Centralized error handler
|
|
52
48
|
*/
|
|
53
|
-
class ErrorHandler {
|
|
49
|
+
export class ErrorHandler {
|
|
54
50
|
static errors = [];
|
|
55
51
|
static maxErrors = 100;
|
|
56
52
|
static listeners = [];
|
|
@@ -243,4 +239,3 @@ class ErrorHandler {
|
|
|
243
239
|
this.errors = [];
|
|
244
240
|
}
|
|
245
241
|
}
|
|
246
|
-
exports.ErrorHandler = ErrorHandler;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EventEmitter = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Simple event emitter implementation with generic event types
|
|
6
3
|
*/
|
|
7
|
-
class EventEmitter {
|
|
4
|
+
export class EventEmitter {
|
|
8
5
|
events;
|
|
9
6
|
constructor() {
|
|
10
7
|
this.events = new Map();
|
|
@@ -77,4 +74,3 @@ class EventEmitter {
|
|
|
77
74
|
}
|
|
78
75
|
}
|
|
79
76
|
}
|
|
80
|
-
exports.EventEmitter = EventEmitter;
|