shogun-core 1.2.7 → 1.2.8

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.
Files changed (67) hide show
  1. package/README.md +0 -1
  2. package/dist/browser/shogun-core.js +1 -1
  3. package/dist/browser/shogun-core.js.LICENSE.txt +2 -0
  4. package/dist/browser/shogun-core.light.js +1 -1
  5. package/dist/browser/shogun-core.vendors.light.js +1 -1
  6. package/dist/core.js +31 -71
  7. package/dist/gundb/{instance.js → gunInstance.js} +135 -115
  8. package/dist/gundb/index.js +3 -20
  9. package/dist/plugins/index.js +23 -1
  10. package/dist/plugins/nostr/index.js +1 -0
  11. package/dist/plugins/nostr/nostrChain.js +128 -0
  12. package/dist/plugins/nostr/nostrConnector.js +42 -7
  13. package/dist/plugins/nostr/nostrConnectorPlugin.js +157 -1
  14. package/dist/plugins/nostr/nostrSigner.js +343 -0
  15. package/dist/plugins/oauth/index.js +13 -0
  16. package/dist/plugins/oauth/oauthChain.js +161 -0
  17. package/dist/plugins/oauth/oauthConnector.js +542 -0
  18. package/dist/plugins/oauth/oauthPlugin.js +302 -0
  19. package/dist/plugins/oauth/types.js +2 -0
  20. package/dist/plugins/web3/index.js +1 -0
  21. package/dist/plugins/web3/web3Chain.js +77 -2
  22. package/dist/plugins/web3/web3Connector.js +159 -37
  23. package/dist/plugins/web3/web3ConnectorPlugin.js +157 -1
  24. package/dist/plugins/web3/web3Signer.js +268 -0
  25. package/dist/plugins/webauthn/webauthnChain.js +78 -0
  26. package/dist/plugins/webauthn/webauthnPlugin.js +154 -1
  27. package/dist/plugins/webauthn/webauthnSigner.js +318 -0
  28. package/dist/storage/storage.js +0 -8
  29. package/dist/types/core.d.ts +10 -34
  30. package/dist/types/gundb/gun-es/gun-es.d.ts +1 -0
  31. package/dist/types/gundb/{instance.d.ts → gunInstance.d.ts} +2 -2
  32. package/dist/types/gundb/index.d.ts +1 -4
  33. package/dist/types/plugins/index.d.ts +4 -0
  34. package/dist/types/plugins/nostr/index.d.ts +1 -0
  35. package/dist/types/plugins/nostr/nostrConnector.d.ts +3 -2
  36. package/dist/types/plugins/nostr/nostrConnectorPlugin.d.ts +82 -0
  37. package/dist/types/plugins/nostr/nostrSigner.d.ts +104 -0
  38. package/dist/types/plugins/oauth/index.d.ts +4 -0
  39. package/dist/types/plugins/oauth/oauthChain.d.ts +2 -0
  40. package/dist/types/plugins/oauth/oauthConnector.d.ts +100 -0
  41. package/dist/types/plugins/oauth/oauthPlugin.d.ts +89 -0
  42. package/dist/types/plugins/oauth/types.d.ts +106 -0
  43. package/dist/types/plugins/web3/index.d.ts +1 -0
  44. package/dist/types/plugins/web3/types.d.ts +1 -0
  45. package/dist/types/plugins/web3/web3Connector.d.ts +8 -2
  46. package/dist/types/plugins/web3/web3ConnectorPlugin.d.ts +82 -0
  47. package/dist/types/plugins/web3/web3Signer.d.ts +93 -0
  48. package/dist/types/plugins/webauthn/webauthnPlugin.d.ts +81 -0
  49. package/dist/types/plugins/webauthn/webauthnSigner.d.ts +90 -0
  50. package/dist/types/shogun.js +1 -28
  51. package/dist/types/types/events.d.ts +2 -2
  52. package/dist/types/types/shogun.d.ts +13 -49
  53. package/package.json +2 -1
  54. package/dist/browser.js +0 -107
  55. package/dist/contracts/base.js +0 -152
  56. package/dist/contracts/entryPoint.js +0 -407
  57. package/dist/contracts/index.js +0 -47
  58. package/dist/contracts/registry.js +0 -259
  59. package/dist/contracts/relay.js +0 -494
  60. package/dist/contracts/utils.js +0 -582
  61. package/dist/types/browser.d.ts +0 -27
  62. package/dist/types/contracts/base.d.ts +0 -82
  63. package/dist/types/contracts/entryPoint.d.ts +0 -138
  64. package/dist/types/contracts/index.d.ts +0 -17
  65. package/dist/types/contracts/registry.d.ts +0 -97
  66. package/dist/types/contracts/relay.d.ts +0 -165
  67. package/dist/types/contracts/utils.d.ts +0 -173
@@ -0,0 +1,542 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OAuthConnector = void 0;
4
+ /**
5
+ * OAuth Connector - Simple version for GunDB user creation
6
+ */
7
+ const ethers_1 = require("ethers");
8
+ const logger_1 = require("../../utils/logger");
9
+ const eventEmitter_1 = require("../../utils/eventEmitter");
10
+ /**
11
+ * OAuth Connector
12
+ */
13
+ class OAuthConnector extends eventEmitter_1.EventEmitter {
14
+ DEFAULT_CONFIG = {
15
+ providers: {
16
+ google: {
17
+ clientId: "",
18
+ clientSecret: "",
19
+ redirectUri: `${this.getOrigin()}/auth/callback`,
20
+ scope: ["openid", "email", "profile"],
21
+ authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
22
+ tokenUrl: "https://oauth2.googleapis.com/token",
23
+ userInfoUrl: "https://www.googleapis.com/oauth2/v2/userinfo",
24
+ },
25
+ github: {
26
+ clientId: "",
27
+ clientSecret: "",
28
+ redirectUri: `${this.getOrigin()}/auth/callback`,
29
+ scope: ["user:email"],
30
+ authUrl: "https://github.com/login/oauth/authorize",
31
+ tokenUrl: "https://github.com/login/oauth/access_token",
32
+ userInfoUrl: "https://api.github.com/user",
33
+ },
34
+ discord: {
35
+ clientId: "",
36
+ clientSecret: "",
37
+ redirectUri: `${this.getOrigin()}/auth/callback`,
38
+ scope: ["identify", "email"],
39
+ authUrl: "https://discord.com/api/oauth2/authorize",
40
+ tokenUrl: "https://discord.com/api/oauth2/token",
41
+ userInfoUrl: "https://discord.com/api/users/@me",
42
+ },
43
+ twitter: {
44
+ clientId: "",
45
+ clientSecret: "",
46
+ redirectUri: `${this.getOrigin()}/auth/callback`,
47
+ scope: ["tweet.read", "users.read"],
48
+ authUrl: "https://twitter.com/i/oauth2/authorize",
49
+ tokenUrl: "https://api.twitter.com/2/oauth2/token",
50
+ userInfoUrl: "https://api.twitter.com/2/users/me",
51
+ },
52
+ custom: {
53
+ clientId: "",
54
+ clientSecret: "",
55
+ redirectUri: "",
56
+ scope: [],
57
+ authUrl: "",
58
+ tokenUrl: "",
59
+ userInfoUrl: "",
60
+ },
61
+ },
62
+ usePKCE: true,
63
+ cacheDuration: 24 * 60 * 60 * 1000, // 24 hours
64
+ timeout: 60000,
65
+ maxRetries: 3,
66
+ retryDelay: 1000,
67
+ };
68
+ config;
69
+ userCache = new Map();
70
+ // Fallback storage for Node.js environment
71
+ memoryStorage = new Map();
72
+ constructor(config = {}) {
73
+ super();
74
+ this.config = {
75
+ ...this.DEFAULT_CONFIG,
76
+ ...config,
77
+ providers: {
78
+ ...(this.DEFAULT_CONFIG.providers || {}),
79
+ ...(config.providers || {}),
80
+ },
81
+ };
82
+ }
83
+ /**
84
+ * Update the connector configuration
85
+ * @param config - New configuration options
86
+ */
87
+ updateConfig(config) {
88
+ this.config = {
89
+ ...this.config,
90
+ ...config,
91
+ providers: {
92
+ ...(this.config.providers || {}),
93
+ ...(config.providers || {}),
94
+ },
95
+ };
96
+ (0, logger_1.logDebug)("OAuthConnector configuration updated", this.config);
97
+ }
98
+ /**
99
+ * Get origin URL (browser or Node.js compatible)
100
+ */
101
+ getOrigin() {
102
+ if (typeof window !== "undefined" && window.location) {
103
+ return window.location.origin;
104
+ }
105
+ // Fallback for Node.js environment
106
+ return "http://localhost:3000";
107
+ }
108
+ /**
109
+ * Storage abstraction (browser sessionStorage or Node.js Map)
110
+ */
111
+ setItem(key, value) {
112
+ if (typeof sessionStorage !== "undefined") {
113
+ sessionStorage.setItem(key, value);
114
+ }
115
+ else {
116
+ this.memoryStorage.set(key, value);
117
+ }
118
+ }
119
+ getItem(key) {
120
+ if (typeof sessionStorage !== "undefined") {
121
+ return sessionStorage.getItem(key);
122
+ }
123
+ else {
124
+ return this.memoryStorage.get(key) || null;
125
+ }
126
+ }
127
+ removeItem(key) {
128
+ if (typeof sessionStorage !== "undefined") {
129
+ sessionStorage.removeItem(key);
130
+ }
131
+ else {
132
+ this.memoryStorage.delete(key);
133
+ }
134
+ }
135
+ /**
136
+ * Check if OAuth is supported
137
+ */
138
+ isSupported() {
139
+ // In Node.js, we can still demonstrate the functionality
140
+ return typeof URLSearchParams !== "undefined";
141
+ }
142
+ /**
143
+ * Get available OAuth providers
144
+ */
145
+ getAvailableProviders() {
146
+ return Object.keys(this.config.providers || {}).filter((provider) => this.config.providers[provider]?.clientId);
147
+ }
148
+ /**
149
+ * Generate PKCE challenge for secure OAuth flow
150
+ */
151
+ async generatePKCEChallenge() {
152
+ const codeVerifier = this.generateRandomString(128);
153
+ const codeChallenge = await this.calculatePKCECodeChallenge(codeVerifier);
154
+ return { codeVerifier, codeChallenge };
155
+ }
156
+ /**
157
+ * Calculate the PKCE code challenge from a code verifier.
158
+ * Hashes the verifier using SHA-256 and then base64url encodes it.
159
+ * @param verifier The code verifier string.
160
+ * @returns The base64url-encoded SHA-256 hash of the verifier.
161
+ */
162
+ async calculatePKCECodeChallenge(verifier) {
163
+ if (typeof window !== "undefined" &&
164
+ window.crypto &&
165
+ window.crypto.subtle) {
166
+ // Browser environment
167
+ const encoder = new TextEncoder();
168
+ const data = encoder.encode(verifier);
169
+ const hashBuffer = await window.crypto.subtle.digest("SHA-256", data);
170
+ return this.base64urlEncode(hashBuffer);
171
+ }
172
+ else {
173
+ // Node.js environment
174
+ const crypto = require("crypto");
175
+ const hash = crypto.createHash("sha256").update(verifier).digest();
176
+ return this.base64urlEncode(hash);
177
+ }
178
+ }
179
+ /**
180
+ * Encodes a buffer into a Base64URL-encoded string.
181
+ * @param buffer The buffer to encode.
182
+ * @returns The Base64URL-encoded string.
183
+ */
184
+ base64urlEncode(buffer) {
185
+ let base64string;
186
+ // In Node.js, we can use the Buffer object. In the browser, we need a different approach.
187
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(buffer)) {
188
+ // Node.js path
189
+ base64string = buffer.toString("base64");
190
+ }
191
+ else {
192
+ // Browser path (assuming ArrayBuffer)
193
+ const bytes = new Uint8Array(buffer);
194
+ let binary = "";
195
+ for (let i = 0; i < bytes.length; i++) {
196
+ binary += String.fromCharCode(bytes[i]);
197
+ }
198
+ base64string = window.btoa(binary);
199
+ }
200
+ return base64string
201
+ .replace(/\+/g, "-")
202
+ .replace(/\//g, "_")
203
+ .replace(/=/g, "");
204
+ }
205
+ /**
206
+ * Generate cryptographically secure random string
207
+ */
208
+ generateRandomString(length) {
209
+ const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
210
+ let randomValues;
211
+ if (typeof window !== "undefined" && window.crypto) {
212
+ // Browser environment
213
+ randomValues = new Uint8Array(length);
214
+ window.crypto.getRandomValues(randomValues);
215
+ }
216
+ else {
217
+ // Node.js environment
218
+ const crypto = require("crypto");
219
+ randomValues = new Uint8Array(crypto.randomBytes(length));
220
+ }
221
+ return Array.from(randomValues)
222
+ .map((value) => charset[value % charset.length])
223
+ .join("");
224
+ }
225
+ /**
226
+ * Initiate OAuth flow with a provider
227
+ */
228
+ async initiateOAuth(provider) {
229
+ try {
230
+ (0, logger_1.logDebug)(`Initiating OAuth flow with ${provider}`);
231
+ const providerConfig = this.config.providers[provider];
232
+ if (!providerConfig || !providerConfig.clientId) {
233
+ throw new Error(`Provider ${provider} not configured`);
234
+ }
235
+ // Generate state for CSRF protection
236
+ const state = this.generateRandomString(32);
237
+ this.setItem(`oauth_state_${provider}`, state);
238
+ // Generate PKCE challenge if enabled
239
+ let pkceParams = {};
240
+ if (this.config.usePKCE) {
241
+ const { codeVerifier, codeChallenge } = await this.generatePKCEChallenge();
242
+ this.setItem(`oauth_verifier_${provider}`, codeVerifier);
243
+ pkceParams = {
244
+ code_challenge: codeChallenge,
245
+ code_challenge_method: "S256",
246
+ };
247
+ }
248
+ // Build authorization URL
249
+ const authParams = new URLSearchParams({
250
+ client_id: providerConfig.clientId,
251
+ redirect_uri: providerConfig.redirectUri,
252
+ scope: providerConfig.scope.join(" "),
253
+ response_type: "code",
254
+ state,
255
+ ...pkceParams,
256
+ });
257
+ // Handle the authorization URL that might already contain query parameters
258
+ let authUrl = providerConfig.authUrl || "";
259
+ if (!authUrl) {
260
+ throw new Error(`Auth URL not configured for provider ${provider}`);
261
+ }
262
+ // If the authorization URL already contains query parameters, add the new parameters
263
+ if (authUrl.includes("?")) {
264
+ authUrl = `${authUrl}&${authParams.toString()}`;
265
+ }
266
+ else {
267
+ authUrl = `${authUrl}?${authParams.toString()}`;
268
+ }
269
+ this.emit("oauth_initiated", { provider, authUrl });
270
+ return {
271
+ success: true,
272
+ provider,
273
+ authUrl,
274
+ };
275
+ }
276
+ catch (error) {
277
+ (0, logger_1.logError)(`Error initiating OAuth with ${provider}:`, error);
278
+ return {
279
+ success: false,
280
+ error: error.message,
281
+ };
282
+ }
283
+ }
284
+ /**
285
+ * Complete OAuth flow
286
+ */
287
+ async completeOAuth(provider, authCode, state) {
288
+ const providerConfig = this.config.providers?.[provider];
289
+ if (!providerConfig) {
290
+ const errorMsg = `Provider '${provider}' is not configured.`;
291
+ (0, logger_1.logError)(errorMsg);
292
+ return { success: false, error: errorMsg };
293
+ }
294
+ try {
295
+ const tokenData = await this.exchangeCodeForToken(provider, providerConfig, authCode, state);
296
+ if (!tokenData.access_token) {
297
+ const errorMsg = "No access token received from provider";
298
+ (0, logger_1.logError)(errorMsg, tokenData);
299
+ return { success: false, error: errorMsg };
300
+ }
301
+ const userInfo = await this.fetchUserInfo(provider, providerConfig, tokenData.access_token);
302
+ // Cache user info
303
+ this.cacheUserInfo(userInfo.id, provider, userInfo);
304
+ // Generate credentials
305
+ const credentials = await this.generateCredentials(userInfo, provider);
306
+ this.emit("oauth_completed", { provider, userInfo, credentials });
307
+ return {
308
+ success: true,
309
+ provider,
310
+ userInfo,
311
+ };
312
+ }
313
+ catch (error) {
314
+ (0, logger_1.logError)(`Error completing OAuth with ${provider}:`, error);
315
+ return {
316
+ success: false,
317
+ error: error.message,
318
+ };
319
+ }
320
+ }
321
+ /**
322
+ * Generate credentials from OAuth user info
323
+ */
324
+ async generateCredentials(userInfo, provider) {
325
+ const providerConfig = this.config.providers?.[provider];
326
+ if (!providerConfig) {
327
+ throw new Error(`Provider ${provider} is not configured.`);
328
+ }
329
+ const salt = `${provider}@${userInfo.id}`;
330
+ const username = userInfo.email || `${userInfo.id}@${provider}.shogun`;
331
+ try {
332
+ (0, logger_1.logDebug)(`Generating credentials for ${provider} user: ${userInfo.id}`);
333
+ // Generate deterministic password
334
+ const password = await this.generateDeterministicPassword(userInfo, provider);
335
+ const credentials = {
336
+ username,
337
+ password,
338
+ provider,
339
+ };
340
+ // Cache the user info
341
+ this.cacheUserInfo(userInfo.id, provider, userInfo);
342
+ (0, logger_1.logDebug)("OAuth credentials generated successfully");
343
+ return credentials;
344
+ }
345
+ catch (error) {
346
+ (0, logger_1.logError)("Error generating OAuth credentials:", error);
347
+ throw error;
348
+ }
349
+ }
350
+ /**
351
+ * Generate deterministic password
352
+ */
353
+ async generateDeterministicPassword(userInfo, provider) {
354
+ const passwordBase = `${userInfo.id}_${provider}_${userInfo.email || ""}_shogun_oauth`;
355
+ const passwordHash = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(passwordBase));
356
+ return passwordHash.slice(2, 34); // 32 character hex string
357
+ }
358
+ /**
359
+ * Exchange authorization code for access token
360
+ */
361
+ async exchangeCodeForToken(provider, providerConfig, code, state) {
362
+ const storedState = await this.getItem(`oauth_state_${provider}`);
363
+ if (state && storedState !== state) {
364
+ throw new Error("Invalid state parameter");
365
+ }
366
+ const tokenParams = {
367
+ client_id: providerConfig.clientId,
368
+ code: code,
369
+ redirect_uri: providerConfig.redirectUri,
370
+ grant_type: "authorization_code",
371
+ };
372
+ // Add client secret if available
373
+ if (providerConfig.clientSecret) {
374
+ tokenParams.client_secret = providerConfig.clientSecret;
375
+ }
376
+ if (this.config.usePKCE) {
377
+ const verifier = await this.getItem(`oauth_verifier_${provider}`);
378
+ if (verifier) {
379
+ tokenParams.code_verifier = verifier;
380
+ this.removeItem(`oauth_verifier_${provider}`);
381
+ }
382
+ else {
383
+ (0, logger_1.logWarn)(`PKCE is enabled, but no code verifier was found for ${provider}.`);
384
+ }
385
+ }
386
+ const response = await fetch(providerConfig.tokenUrl, {
387
+ method: "POST",
388
+ headers: {
389
+ "Content-Type": "application/x-www-form-urlencoded",
390
+ Accept: "application/json",
391
+ },
392
+ body: new URLSearchParams(tokenParams),
393
+ });
394
+ if (!response.ok) {
395
+ const errorData = await response
396
+ .json()
397
+ .catch(() => ({ error: response.statusText }));
398
+ throw new Error(`Token exchange failed: ${response.status} ${response.statusText} - ${JSON.stringify(errorData)}`);
399
+ }
400
+ return await response.json();
401
+ }
402
+ /**
403
+ * Get user info from OAuth provider
404
+ */
405
+ async fetchUserInfo(provider, providerConfig, accessToken) {
406
+ const response = await fetch(providerConfig.userInfoUrl, {
407
+ headers: {
408
+ Authorization: `Bearer ${accessToken}`,
409
+ Accept: "application/json",
410
+ },
411
+ });
412
+ if (!response.ok) {
413
+ throw new Error(`Failed to get user info: ${response.statusText}`);
414
+ }
415
+ const userData = await response.json();
416
+ return this.normalizeUserInfo(userData, provider);
417
+ }
418
+ /**
419
+ * Normalize user info across different providers
420
+ */
421
+ normalizeUserInfo(userData, provider) {
422
+ switch (provider) {
423
+ case "google":
424
+ return {
425
+ id: userData.id,
426
+ email: userData.email,
427
+ name: userData.name,
428
+ picture: userData.picture,
429
+ verified_email: userData.verified_email,
430
+ provider,
431
+ };
432
+ case "github":
433
+ return {
434
+ id: userData.id.toString(),
435
+ email: userData.email,
436
+ name: userData.name || userData.login,
437
+ picture: userData.avatar_url,
438
+ provider,
439
+ };
440
+ default:
441
+ return {
442
+ id: userData.id?.toString() || userData.sub,
443
+ email: userData.email,
444
+ name: userData.name || userData.username,
445
+ picture: userData.picture || userData.avatar_url,
446
+ provider,
447
+ };
448
+ }
449
+ }
450
+ /**
451
+ * Cache user info
452
+ */
453
+ cacheUserInfo(userId, provider, userInfo) {
454
+ const cacheKey = `${provider}_${userId}`;
455
+ const cacheEntry = {
456
+ data: userInfo,
457
+ timestamp: Date.now(),
458
+ provider,
459
+ userId,
460
+ };
461
+ this.userCache.set(cacheKey, cacheEntry);
462
+ // Also store in localStorage for persistence
463
+ try {
464
+ localStorage.setItem(`shogun_oauth_user_${cacheKey}`, JSON.stringify(cacheEntry));
465
+ }
466
+ catch (error) {
467
+ (0, logger_1.logError)("Error caching user info:", error);
468
+ }
469
+ }
470
+ /**
471
+ * Get cached user info
472
+ */
473
+ getCachedUserInfo(userId, provider) {
474
+ const cacheKey = `${provider}_${userId}`;
475
+ // Check memory cache first
476
+ const cached = this.userCache.get(cacheKey);
477
+ if (cached &&
478
+ cached.data &&
479
+ Date.now() - cached.timestamp <= this.config.cacheDuration) {
480
+ return cached.data;
481
+ }
482
+ // Check localStorage
483
+ try {
484
+ const localCached = localStorage.getItem(`shogun_oauth_user_${cacheKey}`);
485
+ if (localCached) {
486
+ const parsedCache = JSON.parse(localCached);
487
+ if (parsedCache.data &&
488
+ Date.now() - parsedCache.timestamp <= this.config.cacheDuration) {
489
+ this.userCache.set(cacheKey, parsedCache);
490
+ return parsedCache.data;
491
+ }
492
+ else {
493
+ localStorage.removeItem(`shogun_oauth_user_${cacheKey}`);
494
+ }
495
+ }
496
+ }
497
+ catch (error) {
498
+ (0, logger_1.logError)("Error reading cached user info:", error);
499
+ }
500
+ return null;
501
+ }
502
+ /**
503
+ * Clear user info cache
504
+ */
505
+ clearUserCache(userId, provider) {
506
+ if (userId && provider) {
507
+ const cacheKey = `${provider}_${userId}`;
508
+ this.userCache.delete(cacheKey);
509
+ try {
510
+ localStorage.removeItem(`shogun_oauth_user_${cacheKey}`);
511
+ }
512
+ catch (error) {
513
+ (0, logger_1.logError)("Error clearing user cache:", error);
514
+ }
515
+ }
516
+ else {
517
+ // Clear all caches
518
+ this.userCache.clear();
519
+ try {
520
+ const keysToRemove = [];
521
+ for (let i = 0; i < localStorage.length; i++) {
522
+ const key = localStorage.key(i);
523
+ if (key && key.startsWith("shogun_oauth_user_")) {
524
+ keysToRemove.push(key);
525
+ }
526
+ }
527
+ keysToRemove.forEach((key) => localStorage.removeItem(key));
528
+ }
529
+ catch (error) {
530
+ (0, logger_1.logError)("Error clearing all user caches:", error);
531
+ }
532
+ }
533
+ }
534
+ /**
535
+ * Cleanup resources
536
+ */
537
+ cleanup() {
538
+ this.removeAllListeners();
539
+ this.userCache.clear();
540
+ }
541
+ }
542
+ exports.OAuthConnector = OAuthConnector;