shogun-core 0.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/README.md +71 -0
- package/dist/auth/credentialAuth.js +154 -0
- package/dist/auth/metamaskAuth.js +264 -0
- package/dist/auth/webauthnAuth.js +267 -0
- package/dist/config.js +39 -0
- package/dist/connector/metamask.js +262 -0
- package/dist/events.js +12 -0
- package/dist/gun/auth.js +523 -0
- package/dist/gun/errors.js +66 -0
- package/dist/gun/gun.js +331 -0
- package/dist/index.js +440 -0
- package/dist/mom/MOMClient.js +1253 -0
- package/dist/stealth/stealth.js +289 -0
- package/dist/storage/storage.js +93 -0
- package/dist/types/auth/credentialAuth.d.ts +56 -0
- package/dist/types/auth/metamaskAuth.d.ts +74 -0
- package/dist/types/auth/webauthnAuth.d.ts +83 -0
- package/dist/types/auth.js +1 -0
- package/dist/types/config.d.ts +39 -0
- package/dist/types/connector/metamask.d.ts +112 -0
- package/dist/types/events.d.ts +27 -0
- package/dist/types/gun/auth.d.ts +219 -0
- package/dist/types/gun/errors.d.ts +42 -0
- package/dist/types/gun/gun.d.ts +124 -0
- package/dist/types/gun.js +4 -0
- package/dist/types/index.d.ts +173 -0
- package/dist/types/mom/MOMClient.d.ts +217 -0
- package/dist/types/mom.js +29 -0
- package/dist/types/shogun.js +1 -0
- package/dist/types/stealth/stealth.d.ts +67 -0
- package/dist/types/storage/storage.d.ts +11 -0
- package/dist/types/token.js +1 -0
- package/dist/types/types/auth.d.ts +47 -0
- package/dist/types/types/gun.d.ts +73 -0
- package/dist/types/types/mom.d.ts +147 -0
- package/dist/types/types/shogun.d.ts +90 -0
- package/dist/types/types/token.d.ts +12 -0
- package/dist/types/utils/eventEmitter.d.ts +9 -0
- package/dist/types/utils/logger.d.ts +24 -0
- package/dist/types/utils/storageMock.d.ts +12 -0
- package/dist/types/utils/utility.d.ts +20 -0
- package/dist/types/utils/wait.d.ts +24 -0
- package/dist/types/wallet/gunWallet.d.ts +14 -0
- package/dist/types/wallet/hdWallet.d.ts +154 -0
- package/dist/types/wallet/walletManager-old.d.ts +70 -0
- package/dist/types/wallet/walletManager.d.ts +188 -0
- package/dist/types/webauthn/webauthn-gun.d.ts +1 -0
- package/dist/types/webauthn/webauthn.d.ts +52 -0
- package/dist/utils/eventEmitter.js +29 -0
- package/dist/utils/logger.js +39 -0
- package/dist/utils/storageMock.js +27 -0
- package/dist/utils/utility.js +32 -0
- package/dist/utils/wait.js +78 -0
- package/dist/wallet/gunWallet.js +14 -0
- package/dist/wallet/hdWallet.js +619 -0
- package/dist/wallet/walletManager-old.js +473 -0
- package/dist/wallet/walletManager.js +1226 -0
- package/dist/webauthn/webauthn-gun.js +115 -0
- package/dist/webauthn/webauthn.js +313 -0
- package/package.json +48 -0
package/dist/gun/auth.js
ADDED
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modulo di autenticazione OAuth per GunDB
|
|
3
|
+
*
|
|
4
|
+
* Implementa un sistema di autenticazione minimale ma completo
|
|
5
|
+
* compatibile con GunDB e il suo sistema SEA (Security, Encryption, Authorization).
|
|
6
|
+
*
|
|
7
|
+
* Fornisce funzionalità essenziali come:
|
|
8
|
+
* - Creazione di utenti
|
|
9
|
+
* - Login/Logout
|
|
10
|
+
* - Gestione delle sessioni
|
|
11
|
+
* - Recupero delle informazioni utente
|
|
12
|
+
* - Modifica delle credenziali
|
|
13
|
+
*/
|
|
14
|
+
import { logDebug, logWarning } from "../utils/logger";
|
|
15
|
+
/**
|
|
16
|
+
* Errori specifici per l'autenticazione
|
|
17
|
+
*/
|
|
18
|
+
export class AuthError extends Error {
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "AuthError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export class InvalidCredentials extends AuthError {
|
|
25
|
+
constructor(message = "Credenziali non valide") {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = "InvalidCredentials";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class UserExists extends AuthError {
|
|
31
|
+
constructor(message = "Utente già esistente") {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "UserExists";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export class TimeoutError extends AuthError {
|
|
37
|
+
constructor(message = "Operazione scaduta") {
|
|
38
|
+
super(message);
|
|
39
|
+
this.name = "TimeoutError";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export class MultipleAuthError extends AuthError {
|
|
43
|
+
constructor(message = "Operazione di autenticazione già in corso") {
|
|
44
|
+
super(message);
|
|
45
|
+
this.name = "MultipleAuthError";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Utilità per verificare se si è in un ambiente web
|
|
50
|
+
*/
|
|
51
|
+
const isPlatformWeb = () => {
|
|
52
|
+
return typeof window !== "undefined";
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Attende il completamento di una promessa con timeout
|
|
56
|
+
*/
|
|
57
|
+
async function timeoutAfter(promise, ms, error) {
|
|
58
|
+
if (ms <= 0)
|
|
59
|
+
return promise;
|
|
60
|
+
const timeout = new Promise((_, reject) => {
|
|
61
|
+
setTimeout(() => {
|
|
62
|
+
reject(error || new TimeoutError());
|
|
63
|
+
}, ms);
|
|
64
|
+
});
|
|
65
|
+
return Promise.race([promise, timeout]);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Core di autenticazione GUN
|
|
69
|
+
* Gestisce le operazioni di autenticazione a basso livello con GUN
|
|
70
|
+
*/
|
|
71
|
+
export class GunAuthCore {
|
|
72
|
+
/**
|
|
73
|
+
* @param gun - Istanza GUN di riferimento
|
|
74
|
+
*/
|
|
75
|
+
constructor(gun) {
|
|
76
|
+
/** Flag per indicare se è iscritto agli eventi di autenticazione */
|
|
77
|
+
this._subscribed = false;
|
|
78
|
+
/** Callback di autenticazione */
|
|
79
|
+
this._authCallbacks = [];
|
|
80
|
+
this.gun = gun;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Ottiene l'istanza predefinita di GunAuthCore
|
|
84
|
+
* @param gun - Istanza GUN opzionale
|
|
85
|
+
* @returns Istanza predefinita di GunAuthCore
|
|
86
|
+
*/
|
|
87
|
+
static default(gun) {
|
|
88
|
+
if (!GunAuthCore._default) {
|
|
89
|
+
if (!gun && !GunAuthCore.defaultGun) {
|
|
90
|
+
throw new Error("Nessuna istanza GUN disponibile");
|
|
91
|
+
}
|
|
92
|
+
GunAuthCore._default = new GunAuthCore(gun || GunAuthCore.defaultGun);
|
|
93
|
+
}
|
|
94
|
+
return GunAuthCore._default;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Reimposta l'istanza predefinita
|
|
98
|
+
*/
|
|
99
|
+
static resetDefault() {
|
|
100
|
+
GunAuthCore._default = undefined;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Effettua il logout dell'utente corrente
|
|
104
|
+
*/
|
|
105
|
+
logout() {
|
|
106
|
+
const user = this.gun.user();
|
|
107
|
+
if (user && typeof user.leave === "function") {
|
|
108
|
+
user.leave();
|
|
109
|
+
}
|
|
110
|
+
this._authPromise = undefined;
|
|
111
|
+
if (this.delegate && typeof this.delegate.onLogout === 'function') {
|
|
112
|
+
this.delegate.onLogout();
|
|
113
|
+
}
|
|
114
|
+
logDebug("Utente disconnesso con successo");
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Ottiene l'utente correntemente autenticato
|
|
118
|
+
*/
|
|
119
|
+
user() {
|
|
120
|
+
const user = this.gun.user();
|
|
121
|
+
// Accesso alla proprietà 'is' attraverso cast
|
|
122
|
+
const is = user.is;
|
|
123
|
+
if (!is)
|
|
124
|
+
return undefined;
|
|
125
|
+
return user;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Ottiene la chiave pubblica dell'utente corrente
|
|
129
|
+
*/
|
|
130
|
+
pub() {
|
|
131
|
+
// Accesso alla proprietà '_' attraverso cast
|
|
132
|
+
return this.user()?._?.sea?.pub;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Ottiene la coppia di chiavi dell'utente corrente
|
|
136
|
+
*/
|
|
137
|
+
pair() {
|
|
138
|
+
// Accesso alla proprietà '_' attraverso cast
|
|
139
|
+
return this.user()?._?.sea;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Crea un nuovo utente
|
|
143
|
+
* @param creds Credenziali utente
|
|
144
|
+
* @param options Opzioni aggiuntive
|
|
145
|
+
*/
|
|
146
|
+
async create(creds, options = {}) {
|
|
147
|
+
return this._executeAuthOperation(() => this._createUser(creds, options));
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Effettua il login di un utente
|
|
151
|
+
* @param creds Credenziali utente o coppia di chiavi
|
|
152
|
+
* @param options Opzioni aggiuntive
|
|
153
|
+
*/
|
|
154
|
+
async login(creds, options = {}) {
|
|
155
|
+
return this._executeAuthOperation(() => this._loginUser(creds, options));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Verifica se un utente esiste
|
|
159
|
+
* @param alias Nome utente da verificare
|
|
160
|
+
* @param options Opzioni aggiuntive
|
|
161
|
+
*/
|
|
162
|
+
async exists(alias, options = {}) {
|
|
163
|
+
const pub = await this.getPub(alias, options);
|
|
164
|
+
return !!pub;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Ottiene la chiave pubblica associata a un nome utente
|
|
168
|
+
* @param alias Nome utente
|
|
169
|
+
* @param options Opzioni aggiuntive
|
|
170
|
+
*/
|
|
171
|
+
async getPub(alias, options = {}) {
|
|
172
|
+
const { timeout = GunAuthCore.defaultExistsTimeout } = options;
|
|
173
|
+
const user = this.gun.user();
|
|
174
|
+
return new Promise((resolve, reject) => {
|
|
175
|
+
let resolved = false;
|
|
176
|
+
let timer = null;
|
|
177
|
+
const callback = (at) => {
|
|
178
|
+
if (resolved)
|
|
179
|
+
return;
|
|
180
|
+
resolved = true;
|
|
181
|
+
try {
|
|
182
|
+
if (!at) {
|
|
183
|
+
if (timer) {
|
|
184
|
+
clearTimeout(timer);
|
|
185
|
+
timer = null;
|
|
186
|
+
}
|
|
187
|
+
return resolve(undefined);
|
|
188
|
+
}
|
|
189
|
+
const pubs = Object.values(at);
|
|
190
|
+
if (!pubs.length) {
|
|
191
|
+
return resolve(undefined);
|
|
192
|
+
}
|
|
193
|
+
if (timer) {
|
|
194
|
+
clearTimeout(timer);
|
|
195
|
+
timer = null;
|
|
196
|
+
}
|
|
197
|
+
resolve(pubs[0]);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
reject(err instanceof Error ? err : new Error("Errore nel recupero della chiave pubblica"));
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
user.get("~@" + alias).once(callback);
|
|
204
|
+
if (timeout > 0) {
|
|
205
|
+
timer = setTimeout(() => {
|
|
206
|
+
if (!resolved) {
|
|
207
|
+
resolved = true;
|
|
208
|
+
resolve(undefined);
|
|
209
|
+
}
|
|
210
|
+
}, timeout);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Recupera un utente precedentemente autenticato dalla sessione
|
|
216
|
+
* @param options Opzioni aggiuntive
|
|
217
|
+
*/
|
|
218
|
+
async recall(options = {}) {
|
|
219
|
+
return this._executeAuthOperation(() => this._recallSession(options));
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Si sottoscrive agli eventi di autenticazione
|
|
223
|
+
* @param callback Funzione da chiamare quando l'utente viene autenticato
|
|
224
|
+
*/
|
|
225
|
+
async on(callback) {
|
|
226
|
+
if (callback) {
|
|
227
|
+
this._addAuthCallback(callback);
|
|
228
|
+
}
|
|
229
|
+
if (this._authPromise) {
|
|
230
|
+
return this._authPromise;
|
|
231
|
+
}
|
|
232
|
+
return this._executeAuthOperation(() => this._handleAuthEvent());
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Cambia la password di un utente
|
|
236
|
+
* @param creds Credenziali con la nuova password
|
|
237
|
+
* @param options Opzioni aggiuntive
|
|
238
|
+
*/
|
|
239
|
+
async changePassword(creds, options = {}) {
|
|
240
|
+
return this._executeAuthOperation(() => this._createUser(creds, { ...options, changePass: true }));
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Elimina un utente
|
|
244
|
+
* @param creds Credenziali dell'utente
|
|
245
|
+
* @param options Opzioni aggiuntive
|
|
246
|
+
*/
|
|
247
|
+
async delete(creds, options = {}) {
|
|
248
|
+
return this._executeAuthOperation(() => this._deleteUser(creds, options));
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Implementazione interna per la creazione di un utente
|
|
252
|
+
*/
|
|
253
|
+
async _createUser({ alias, pass, newPass }, options) {
|
|
254
|
+
const { timeout = GunAuthCore.defaultTimeout, existsTimeout = GunAuthCore.defaultExistsTimeout } = options;
|
|
255
|
+
// Verifica se l'utente esiste già
|
|
256
|
+
if (alias) {
|
|
257
|
+
const exists = await this.exists(alias, { timeout: existsTimeout });
|
|
258
|
+
if (exists && !options.changePass) {
|
|
259
|
+
throw new UserExists();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return new Promise((resolve, reject) => {
|
|
263
|
+
const createOp = (callback) => {
|
|
264
|
+
try {
|
|
265
|
+
if (newPass && options.changePass) {
|
|
266
|
+
// Cambio password: dobbiamo fare un cast a any per evitare errori di tipo
|
|
267
|
+
const userRef = this.gun.user();
|
|
268
|
+
userRef.auth(alias, pass, (ack) => {
|
|
269
|
+
if (ack.err) {
|
|
270
|
+
return callback({ err: ack.err });
|
|
271
|
+
}
|
|
272
|
+
// Una volta autenticati, cambiamo la password
|
|
273
|
+
// Il secondo argomento è la nuova password, non è un callback
|
|
274
|
+
userRef.auth(newPass, (ack) => {
|
|
275
|
+
callback(ack);
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// Creazione utente standard
|
|
281
|
+
this.gun.user().create(alias, pass, callback);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
callback({ err: err instanceof Error ? err.message : String(err) });
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
try {
|
|
289
|
+
createOp((ack) => {
|
|
290
|
+
if (ack.err) {
|
|
291
|
+
return reject(this._parseGunError(ack.err));
|
|
292
|
+
}
|
|
293
|
+
// Utilizziamo un cast a any per accedere alla proprietà is
|
|
294
|
+
const userRef = this.gun.user();
|
|
295
|
+
const pub = ack.pub || (userRef.is?.pub);
|
|
296
|
+
if (!pub) {
|
|
297
|
+
return reject(new AuthError("Impossibile ottenere la chiave pubblica"));
|
|
298
|
+
}
|
|
299
|
+
// Se richiesto, memorizziamo la coppia di chiavi
|
|
300
|
+
if (options.storePair && this.delegate?.storePair) {
|
|
301
|
+
const pair = this.pair();
|
|
302
|
+
if (pair) {
|
|
303
|
+
this.delegate.storePair(this, pair).catch(err => {
|
|
304
|
+
logWarning("Errore durante il salvataggio delle chiavi: " + err.message);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
resolve(pub);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
catch (err) {
|
|
312
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Implementazione interna per il login di un utente
|
|
318
|
+
*/
|
|
319
|
+
async _loginUser(creds, options) {
|
|
320
|
+
const { timeout = GunAuthCore.defaultTimeout } = options;
|
|
321
|
+
const loginPromise = new Promise((resolve, reject) => {
|
|
322
|
+
try {
|
|
323
|
+
// Determina se stiamo usando credenziali o una coppia di chiavi
|
|
324
|
+
const isPair = 'pub' in creds && 'priv' in creds && !('alias' in creds);
|
|
325
|
+
const authCallback = (ack) => {
|
|
326
|
+
if (ack.err) {
|
|
327
|
+
reject(this._parseGunError(ack.err));
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
const pub = ack.sea?.pub || this.pub();
|
|
331
|
+
if (!pub) {
|
|
332
|
+
reject(new AuthError("Login riuscito ma impossibile ottenere la chiave pubblica"));
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
resolve(pub);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
if (isPair) {
|
|
340
|
+
this.gun.user().auth(creds, authCallback);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
const { alias, pass } = creds;
|
|
344
|
+
this.gun.user().auth(alias, pass, authCallback);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
catch (err) {
|
|
348
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
return timeout > 0 ? timeoutAfter(loginPromise, timeout) : loginPromise;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Implementazione interna per l'eliminazione di un utente
|
|
355
|
+
*/
|
|
356
|
+
async _deleteUser({ alias, pass }, options) {
|
|
357
|
+
const { timeout = GunAuthCore.defaultTimeout } = options;
|
|
358
|
+
return new Promise((resolve, reject) => {
|
|
359
|
+
try {
|
|
360
|
+
this.gun.user().delete(alias, pass, (ack) => {
|
|
361
|
+
if (ack.err) {
|
|
362
|
+
reject(this._parseGunError(ack.err));
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
resolve();
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
catch (err) {
|
|
370
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Implementazione interna per il recupero della sessione
|
|
376
|
+
*/
|
|
377
|
+
async _recallSession(options) {
|
|
378
|
+
const { timeout = GunAuthCore.defaultTimeout } = options;
|
|
379
|
+
// Se il delegato può recuperare la coppia di chiavi
|
|
380
|
+
if (this.delegate?.recallPair) {
|
|
381
|
+
const pair = await this.delegate.recallPair(this, options);
|
|
382
|
+
if (pair) {
|
|
383
|
+
// Autentica con la coppia di chiavi
|
|
384
|
+
return await this.login(pair, options);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
// Altrimenti prova a recuperare la sessione dal browser
|
|
388
|
+
if (isPlatformWeb()) {
|
|
389
|
+
const recallAction = new Promise((resolve, reject) => {
|
|
390
|
+
try {
|
|
391
|
+
this.gun.user().recall({ sessionStorage: true }, (ack) => {
|
|
392
|
+
if (ack.err) {
|
|
393
|
+
reject(this._parseGunError(ack.err));
|
|
394
|
+
}
|
|
395
|
+
else if (ack.sea) {
|
|
396
|
+
resolve(ack.sea.pub);
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
resolve(undefined);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
catch (err) {
|
|
404
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
return timeout > 0 ?
|
|
408
|
+
timeoutAfter(recallAction, timeout, new TimeoutError("Timeout durante il recupero della sessione")) :
|
|
409
|
+
recallAction;
|
|
410
|
+
}
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Gestisce gli eventi di autenticazione
|
|
415
|
+
*/
|
|
416
|
+
async _handleAuthEvent() {
|
|
417
|
+
if (!this._subscribed) {
|
|
418
|
+
this._subscribeToAuthEvents();
|
|
419
|
+
}
|
|
420
|
+
// Se siamo già autenticati, restituisci subito la chiave pubblica
|
|
421
|
+
const currentPub = this.pub();
|
|
422
|
+
if (currentPub) {
|
|
423
|
+
return Promise.resolve(currentPub);
|
|
424
|
+
}
|
|
425
|
+
// Altrimenti crea una nuova promise che verrà risolta quando l'autenticazione avviene
|
|
426
|
+
return new Promise((resolve) => {
|
|
427
|
+
this._beginAuthPromise(resolve);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Si sottoscrive agli eventi di autenticazione
|
|
432
|
+
*/
|
|
433
|
+
_subscribeToAuthEvents() {
|
|
434
|
+
if (this._subscribed)
|
|
435
|
+
return;
|
|
436
|
+
// Callback interno che risolve la promise di autenticazione
|
|
437
|
+
const callback = () => this._completeAuthPromise();
|
|
438
|
+
// Sottoscrizione all'evento 'auth' di GUN
|
|
439
|
+
this.gun.on('auth', callback);
|
|
440
|
+
this._subscribed = true;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Aggiunge un callback agli eventi di autenticazione
|
|
444
|
+
*/
|
|
445
|
+
_addAuthCallback(callback) {
|
|
446
|
+
this._authCallbacks.push(callback);
|
|
447
|
+
// Se siamo già autenticati, esegui subito il callback
|
|
448
|
+
if (this.pub()) {
|
|
449
|
+
setTimeout(callback, 0);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Inizializza la promise di autenticazione
|
|
454
|
+
*/
|
|
455
|
+
_beginAuthPromise(resolver) {
|
|
456
|
+
this._authResolver = resolver;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Completa la promise di autenticazione
|
|
460
|
+
*/
|
|
461
|
+
_completeAuthPromise(pub) {
|
|
462
|
+
if (this._authResolver) {
|
|
463
|
+
const actualPub = pub || this.pub();
|
|
464
|
+
if (actualPub) {
|
|
465
|
+
this._authResolver(actualPub);
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
this._authResolver("");
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
this._authResolver = undefined;
|
|
472
|
+
this._authPromise = undefined;
|
|
473
|
+
// Se disponiamo di un delegato, salviamo la coppia di chiavi
|
|
474
|
+
if (pub) {
|
|
475
|
+
if (this.delegate && typeof this.delegate.storePair === "function") {
|
|
476
|
+
const pair = this.pair();
|
|
477
|
+
if (pair) {
|
|
478
|
+
this.delegate.storePair(this, pair);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// Esegui tutti i callback di autenticazione
|
|
483
|
+
this._authCallbacks.forEach(cb => setTimeout(cb, 0));
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Esegue un'operazione di autenticazione, impedendo operazioni simultanee
|
|
487
|
+
*/
|
|
488
|
+
async _executeAuthOperation(operation) {
|
|
489
|
+
if (this._authOperation) {
|
|
490
|
+
throw new MultipleAuthError();
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
const promise = operation();
|
|
494
|
+
this._authOperation = promise;
|
|
495
|
+
return await promise;
|
|
496
|
+
}
|
|
497
|
+
finally {
|
|
498
|
+
this._authOperation = undefined;
|
|
499
|
+
this._completeAuthPromise();
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Converte gli errori di GUN in errori tipizzati
|
|
504
|
+
*/
|
|
505
|
+
_parseGunError(error) {
|
|
506
|
+
switch (error) {
|
|
507
|
+
case "User already created!":
|
|
508
|
+
return new UserExists(error);
|
|
509
|
+
case "Wrong user or password.":
|
|
510
|
+
return new InvalidCredentials(error);
|
|
511
|
+
case "User is already being created or authenticated!":
|
|
512
|
+
return new MultipleAuthError(error);
|
|
513
|
+
default:
|
|
514
|
+
return new AuthError(error);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
/** Timeout predefinito per le operazioni di autenticazione */
|
|
519
|
+
GunAuthCore.defaultTimeout = 10000;
|
|
520
|
+
/** Timeout predefinito per verificare l'esistenza di un utente */
|
|
521
|
+
GunAuthCore.defaultExistsTimeout = 3000;
|
|
522
|
+
// Per compatibilità retroattiva, manteniamo un alias
|
|
523
|
+
export const Auth = GunAuthCore;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classi di errore per Gun e Auth
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Errore di base per Gun
|
|
6
|
+
*/
|
|
7
|
+
export class GunError extends Error {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = 'GunError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Errore di autenticazione generico
|
|
15
|
+
*/
|
|
16
|
+
export class AuthError extends GunError {
|
|
17
|
+
constructor(message) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = 'AuthError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Errore di credenziali non valide
|
|
24
|
+
*/
|
|
25
|
+
export class InvalidCredentials extends AuthError {
|
|
26
|
+
constructor(message = 'Credenziali non valide') {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = 'InvalidCredentials';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Errore di utente già esistente
|
|
33
|
+
*/
|
|
34
|
+
export class UserExists extends AuthError {
|
|
35
|
+
constructor(message = 'Utente già esistente') {
|
|
36
|
+
super(message);
|
|
37
|
+
this.name = 'UserExists';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Errore di timeout
|
|
42
|
+
*/
|
|
43
|
+
export class TimeoutError extends GunError {
|
|
44
|
+
constructor(message = 'Timeout durante l\'operazione') {
|
|
45
|
+
super(message);
|
|
46
|
+
this.name = 'TimeoutError';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Errore di multiple autenticazioni
|
|
51
|
+
*/
|
|
52
|
+
export class MultipleAuthError extends AuthError {
|
|
53
|
+
constructor(message = 'Autenticazione multipla in corso') {
|
|
54
|
+
super(message);
|
|
55
|
+
this.name = 'MultipleAuthError';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Base error related to the network. */
|
|
59
|
+
export class NetworkError extends GunError {
|
|
60
|
+
}
|
|
61
|
+
const withDefaultMessage = (args, defaultMessage) => {
|
|
62
|
+
if (args.length === 0 || args.length === 1 && !args[0]) {
|
|
63
|
+
args = [defaultMessage];
|
|
64
|
+
}
|
|
65
|
+
return args;
|
|
66
|
+
};
|