@leanmcp/auth 0.3.2 → 0.4.0
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 +148 -661
- package/dist/{auth0-DMNC3QWJ.mjs → auth0-UTD4QBG6.mjs} +4 -2
- package/dist/chunk-LPEX4YW6.mjs +13 -0
- package/dist/{chunk-ESHQ6BRM.mjs → chunk-P4HFKA5R.mjs} +7 -7
- package/dist/chunk-RGCCBQWG.mjs +113 -0
- package/dist/chunk-ZOPKMOPV.mjs +53 -0
- package/dist/{clerk-7PVVTTC7.mjs → clerk-3SDKGD6C.mjs} +4 -2
- package/dist/client/index.d.mts +499 -0
- package/dist/client/index.d.ts +499 -0
- package/dist/client/index.js +1039 -0
- package/dist/client/index.mjs +869 -0
- package/dist/{cognito-5Q5HGYMA.mjs → cognito-QQT7LK2Y.mjs} +4 -2
- package/dist/index.mjs +2 -1
- package/dist/{leanmcp-X6BD6HOJ.mjs → leanmcp-Y7TXNSTD.mjs} +4 -2
- package/dist/proxy/index.d.mts +376 -0
- package/dist/proxy/index.d.ts +376 -0
- package/dist/proxy/index.js +536 -0
- package/dist/proxy/index.mjs +480 -0
- package/dist/server/index.d.mts +496 -0
- package/dist/server/index.d.ts +496 -0
- package/dist/server/index.js +882 -0
- package/dist/server/index.mjs +847 -0
- package/dist/storage/index.d.mts +181 -0
- package/dist/storage/index.d.ts +181 -0
- package/dist/storage/index.js +499 -0
- package/dist/storage/index.mjs +372 -0
- package/dist/types-DMpGN530.d.mts +122 -0
- package/dist/types-DMpGN530.d.ts +122 -0
- package/package.json +40 -7
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/storage/index.ts
|
|
22
|
+
var storage_exports = {};
|
|
23
|
+
__export(storage_exports, {
|
|
24
|
+
FileStorage: () => FileStorage,
|
|
25
|
+
KeychainStorage: () => KeychainStorage,
|
|
26
|
+
MemoryStorage: () => MemoryStorage,
|
|
27
|
+
isKeychainAvailable: () => isKeychainAvailable,
|
|
28
|
+
isTokenExpired: () => isTokenExpired,
|
|
29
|
+
withExpiresAt: () => withExpiresAt
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(storage_exports);
|
|
32
|
+
|
|
33
|
+
// src/storage/types.ts
|
|
34
|
+
function isTokenExpired(tokens, bufferSeconds = 60) {
|
|
35
|
+
if (!tokens.expires_at && !tokens.expires_in) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const expiresAt = tokens.expires_at ?? Date.now() / 1e3 + (tokens.expires_in ?? 0);
|
|
39
|
+
const now = Date.now() / 1e3;
|
|
40
|
+
return expiresAt <= now + bufferSeconds;
|
|
41
|
+
}
|
|
42
|
+
__name(isTokenExpired, "isTokenExpired");
|
|
43
|
+
function withExpiresAt(tokens) {
|
|
44
|
+
if (tokens.expires_at || !tokens.expires_in) {
|
|
45
|
+
return tokens;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
...tokens,
|
|
49
|
+
expires_at: Math.floor(Date.now() / 1e3) + tokens.expires_in
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
__name(withExpiresAt, "withExpiresAt");
|
|
53
|
+
|
|
54
|
+
// src/storage/memory.ts
|
|
55
|
+
var MemoryStorage = class {
|
|
56
|
+
static {
|
|
57
|
+
__name(this, "MemoryStorage");
|
|
58
|
+
}
|
|
59
|
+
tokens = /* @__PURE__ */ new Map();
|
|
60
|
+
clients = /* @__PURE__ */ new Map();
|
|
61
|
+
/**
|
|
62
|
+
* Normalize server URL for consistent key lookup
|
|
63
|
+
*/
|
|
64
|
+
normalizeUrl(serverUrl) {
|
|
65
|
+
return serverUrl.replace(/\/+$/, "").toLowerCase();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if an entry is expired
|
|
69
|
+
*/
|
|
70
|
+
isExpired(entry) {
|
|
71
|
+
if (!entry) return true;
|
|
72
|
+
if (!entry.expiresAt) return false;
|
|
73
|
+
return Date.now() / 1e3 >= entry.expiresAt;
|
|
74
|
+
}
|
|
75
|
+
async getTokens(serverUrl) {
|
|
76
|
+
const key = this.normalizeUrl(serverUrl);
|
|
77
|
+
const entry = this.tokens.get(key);
|
|
78
|
+
if (this.isExpired(entry)) {
|
|
79
|
+
this.tokens.delete(key);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return entry?.value ?? null;
|
|
83
|
+
}
|
|
84
|
+
async setTokens(serverUrl, tokens) {
|
|
85
|
+
const key = this.normalizeUrl(serverUrl);
|
|
86
|
+
const enrichedTokens = withExpiresAt(tokens);
|
|
87
|
+
this.tokens.set(key, {
|
|
88
|
+
value: enrichedTokens,
|
|
89
|
+
expiresAt: enrichedTokens.expires_at
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async clearTokens(serverUrl) {
|
|
93
|
+
const key = this.normalizeUrl(serverUrl);
|
|
94
|
+
this.tokens.delete(key);
|
|
95
|
+
}
|
|
96
|
+
async getClientInfo(serverUrl) {
|
|
97
|
+
const key = this.normalizeUrl(serverUrl);
|
|
98
|
+
const entry = this.clients.get(key);
|
|
99
|
+
if (this.isExpired(entry)) {
|
|
100
|
+
this.clients.delete(key);
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
return entry?.value ?? null;
|
|
104
|
+
}
|
|
105
|
+
async setClientInfo(serverUrl, info) {
|
|
106
|
+
const key = this.normalizeUrl(serverUrl);
|
|
107
|
+
this.clients.set(key, {
|
|
108
|
+
value: info,
|
|
109
|
+
expiresAt: info.client_secret_expires_at
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
async clearClientInfo(serverUrl) {
|
|
113
|
+
const key = this.normalizeUrl(serverUrl);
|
|
114
|
+
this.clients.delete(key);
|
|
115
|
+
}
|
|
116
|
+
async clearAll() {
|
|
117
|
+
this.tokens.clear();
|
|
118
|
+
this.clients.clear();
|
|
119
|
+
}
|
|
120
|
+
async getAllSessions() {
|
|
121
|
+
const sessions = [];
|
|
122
|
+
for (const [url, entry] of this.tokens.entries()) {
|
|
123
|
+
if (!this.isExpired(entry)) {
|
|
124
|
+
sessions.push({
|
|
125
|
+
serverUrl: url,
|
|
126
|
+
tokens: entry.value,
|
|
127
|
+
clientInfo: this.clients.get(url)?.value,
|
|
128
|
+
createdAt: Date.now(),
|
|
129
|
+
updatedAt: Date.now()
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return sessions;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// src/storage/file.ts
|
|
138
|
+
var import_fs = require("fs");
|
|
139
|
+
var import_path = require("path");
|
|
140
|
+
var import_crypto = require("crypto");
|
|
141
|
+
var CURRENT_VERSION = 1;
|
|
142
|
+
var ALGORITHM = "aes-256-gcm";
|
|
143
|
+
var FileStorage = class {
|
|
144
|
+
static {
|
|
145
|
+
__name(this, "FileStorage");
|
|
146
|
+
}
|
|
147
|
+
filePath;
|
|
148
|
+
encryptionKey;
|
|
149
|
+
prettyPrint;
|
|
150
|
+
cache = null;
|
|
151
|
+
writePromise = null;
|
|
152
|
+
constructor(options) {
|
|
153
|
+
if (typeof options === "string") {
|
|
154
|
+
this.filePath = this.expandPath(options);
|
|
155
|
+
this.prettyPrint = false;
|
|
156
|
+
} else {
|
|
157
|
+
this.filePath = this.expandPath(options.filePath);
|
|
158
|
+
this.prettyPrint = options.prettyPrint ?? false;
|
|
159
|
+
if (options.encryptionKey) {
|
|
160
|
+
this.encryptionKey = (0, import_crypto.scryptSync)(options.encryptionKey, "leanmcp-salt", 32);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Expand ~ to home directory
|
|
166
|
+
*/
|
|
167
|
+
expandPath(filePath) {
|
|
168
|
+
if (filePath.startsWith("~")) {
|
|
169
|
+
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
170
|
+
return filePath.replace("~", home);
|
|
171
|
+
}
|
|
172
|
+
return filePath;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Normalize server URL for consistent key lookup
|
|
176
|
+
*/
|
|
177
|
+
normalizeUrl(serverUrl) {
|
|
178
|
+
return serverUrl.replace(/\/+$/, "").toLowerCase();
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Encrypt data
|
|
182
|
+
*/
|
|
183
|
+
encrypt(data) {
|
|
184
|
+
if (!this.encryptionKey) return data;
|
|
185
|
+
const iv = (0, import_crypto.randomBytes)(16);
|
|
186
|
+
const cipher = (0, import_crypto.createCipheriv)(ALGORITHM, this.encryptionKey, iv);
|
|
187
|
+
let encrypted = cipher.update(data, "utf8", "hex");
|
|
188
|
+
encrypted += cipher.final("hex");
|
|
189
|
+
const authTag = cipher.getAuthTag();
|
|
190
|
+
return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}`;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Decrypt data
|
|
194
|
+
*/
|
|
195
|
+
decrypt(data) {
|
|
196
|
+
if (!this.encryptionKey) return data;
|
|
197
|
+
const [ivHex, authTagHex, encrypted] = data.split(":");
|
|
198
|
+
const iv = Buffer.from(ivHex, "hex");
|
|
199
|
+
const authTag = Buffer.from(authTagHex, "hex");
|
|
200
|
+
const decipher = (0, import_crypto.createDecipheriv)(ALGORITHM, this.encryptionKey, iv);
|
|
201
|
+
decipher.setAuthTag(authTag);
|
|
202
|
+
let decrypted = decipher.update(encrypted, "hex", "utf8");
|
|
203
|
+
decrypted += decipher.final("utf8");
|
|
204
|
+
return decrypted;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Read data from file
|
|
208
|
+
*/
|
|
209
|
+
async readFile() {
|
|
210
|
+
if (this.cache) return this.cache;
|
|
211
|
+
try {
|
|
212
|
+
const raw = await import_fs.promises.readFile(this.filePath, "utf8");
|
|
213
|
+
const decrypted = this.decrypt(raw);
|
|
214
|
+
this.cache = JSON.parse(decrypted);
|
|
215
|
+
return this.cache;
|
|
216
|
+
} catch (error) {
|
|
217
|
+
if (error.code === "ENOENT") {
|
|
218
|
+
this.cache = {
|
|
219
|
+
version: CURRENT_VERSION,
|
|
220
|
+
sessions: {}
|
|
221
|
+
};
|
|
222
|
+
return this.cache;
|
|
223
|
+
}
|
|
224
|
+
throw error;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Write data to file (coalesced to avoid race conditions)
|
|
229
|
+
*/
|
|
230
|
+
async writeFile(data) {
|
|
231
|
+
this.cache = data;
|
|
232
|
+
if (this.writePromise) {
|
|
233
|
+
return this.writePromise;
|
|
234
|
+
}
|
|
235
|
+
this.writePromise = (async () => {
|
|
236
|
+
try {
|
|
237
|
+
await import_fs.promises.mkdir((0, import_path.dirname)(this.filePath), {
|
|
238
|
+
recursive: true
|
|
239
|
+
});
|
|
240
|
+
const json = this.prettyPrint ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
241
|
+
const encrypted = this.encrypt(json);
|
|
242
|
+
await import_fs.promises.writeFile(this.filePath, encrypted, "utf8");
|
|
243
|
+
} finally {
|
|
244
|
+
this.writePromise = null;
|
|
245
|
+
}
|
|
246
|
+
})();
|
|
247
|
+
return this.writePromise;
|
|
248
|
+
}
|
|
249
|
+
async getTokens(serverUrl) {
|
|
250
|
+
const key = this.normalizeUrl(serverUrl);
|
|
251
|
+
const data = await this.readFile();
|
|
252
|
+
const session = data.sessions[key];
|
|
253
|
+
if (!session) return null;
|
|
254
|
+
if (isTokenExpired(session.tokens)) {
|
|
255
|
+
return session.tokens;
|
|
256
|
+
}
|
|
257
|
+
return session.tokens;
|
|
258
|
+
}
|
|
259
|
+
async setTokens(serverUrl, tokens) {
|
|
260
|
+
const key = this.normalizeUrl(serverUrl);
|
|
261
|
+
const data = await this.readFile();
|
|
262
|
+
const now = Date.now();
|
|
263
|
+
const existing = data.sessions[key];
|
|
264
|
+
data.sessions[key] = {
|
|
265
|
+
tokens: withExpiresAt(tokens),
|
|
266
|
+
clientInfo: existing?.clientInfo,
|
|
267
|
+
createdAt: existing?.createdAt ?? now,
|
|
268
|
+
updatedAt: now
|
|
269
|
+
};
|
|
270
|
+
await this.writeFile(data);
|
|
271
|
+
}
|
|
272
|
+
async clearTokens(serverUrl) {
|
|
273
|
+
const key = this.normalizeUrl(serverUrl);
|
|
274
|
+
const data = await this.readFile();
|
|
275
|
+
const session = data.sessions[key];
|
|
276
|
+
if (session) {
|
|
277
|
+
if (session.clientInfo) {
|
|
278
|
+
data.sessions[key] = {
|
|
279
|
+
tokens: {
|
|
280
|
+
access_token: "",
|
|
281
|
+
token_type: "bearer"
|
|
282
|
+
},
|
|
283
|
+
clientInfo: session.clientInfo,
|
|
284
|
+
createdAt: session.createdAt,
|
|
285
|
+
updatedAt: Date.now()
|
|
286
|
+
};
|
|
287
|
+
} else {
|
|
288
|
+
const { [key]: _, ...remaining } = data.sessions;
|
|
289
|
+
data.sessions = remaining;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
await this.writeFile(data);
|
|
293
|
+
}
|
|
294
|
+
async getClientInfo(serverUrl) {
|
|
295
|
+
const key = this.normalizeUrl(serverUrl);
|
|
296
|
+
const data = await this.readFile();
|
|
297
|
+
return data.sessions[key]?.clientInfo ?? null;
|
|
298
|
+
}
|
|
299
|
+
async setClientInfo(serverUrl, info) {
|
|
300
|
+
const key = this.normalizeUrl(serverUrl);
|
|
301
|
+
const data = await this.readFile();
|
|
302
|
+
const now = Date.now();
|
|
303
|
+
const existing = data.sessions[key];
|
|
304
|
+
data.sessions[key] = {
|
|
305
|
+
tokens: existing?.tokens ?? {
|
|
306
|
+
access_token: "",
|
|
307
|
+
token_type: "bearer"
|
|
308
|
+
},
|
|
309
|
+
clientInfo: info,
|
|
310
|
+
createdAt: existing?.createdAt ?? now,
|
|
311
|
+
updatedAt: now
|
|
312
|
+
};
|
|
313
|
+
await this.writeFile(data);
|
|
314
|
+
}
|
|
315
|
+
async clearClientInfo(serverUrl) {
|
|
316
|
+
const key = this.normalizeUrl(serverUrl);
|
|
317
|
+
const data = await this.readFile();
|
|
318
|
+
const session = data.sessions[key];
|
|
319
|
+
if (session) {
|
|
320
|
+
if (session.tokens?.access_token) {
|
|
321
|
+
data.sessions[key] = {
|
|
322
|
+
tokens: session.tokens,
|
|
323
|
+
createdAt: session.createdAt,
|
|
324
|
+
updatedAt: Date.now()
|
|
325
|
+
};
|
|
326
|
+
} else {
|
|
327
|
+
const { [key]: _, ...remaining } = data.sessions;
|
|
328
|
+
data.sessions = remaining;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
await this.writeFile(data);
|
|
332
|
+
}
|
|
333
|
+
async clearAll() {
|
|
334
|
+
await this.writeFile({
|
|
335
|
+
version: CURRENT_VERSION,
|
|
336
|
+
sessions: {}
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
async getAllSessions() {
|
|
340
|
+
const data = await this.readFile();
|
|
341
|
+
return Object.entries(data.sessions).map(([url, session]) => ({
|
|
342
|
+
serverUrl: url,
|
|
343
|
+
tokens: session.tokens,
|
|
344
|
+
clientInfo: session.clientInfo,
|
|
345
|
+
createdAt: session.createdAt,
|
|
346
|
+
updatedAt: session.updatedAt
|
|
347
|
+
}));
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
// src/storage/keychain.ts
|
|
352
|
+
var SERVICE_NAME = "leanmcp-auth";
|
|
353
|
+
var KeychainStorage = class {
|
|
354
|
+
static {
|
|
355
|
+
__name(this, "KeychainStorage");
|
|
356
|
+
}
|
|
357
|
+
serviceName;
|
|
358
|
+
keytar = null;
|
|
359
|
+
initPromise = null;
|
|
360
|
+
constructor(options = {}) {
|
|
361
|
+
this.serviceName = options.serviceName ?? SERVICE_NAME;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Initialize keytar (lazy load)
|
|
365
|
+
*/
|
|
366
|
+
async init() {
|
|
367
|
+
if (this.keytar) return;
|
|
368
|
+
if (this.initPromise) {
|
|
369
|
+
await this.initPromise;
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
this.initPromise = (async () => {
|
|
373
|
+
try {
|
|
374
|
+
this.keytar = require("keytar");
|
|
375
|
+
} catch (error) {
|
|
376
|
+
throw new Error('KeychainStorage requires the "keytar" package. Install it with: npm install keytar');
|
|
377
|
+
}
|
|
378
|
+
})();
|
|
379
|
+
await this.initPromise;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Normalize server URL for consistent key lookup
|
|
383
|
+
*/
|
|
384
|
+
normalizeUrl(serverUrl) {
|
|
385
|
+
return serverUrl.replace(/\/+$/, "").toLowerCase();
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Get account key for tokens
|
|
389
|
+
*/
|
|
390
|
+
getTokensAccount(serverUrl) {
|
|
391
|
+
return `tokens:${this.normalizeUrl(serverUrl)}`;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Get account key for client info
|
|
395
|
+
*/
|
|
396
|
+
getClientAccount(serverUrl) {
|
|
397
|
+
return `client:${this.normalizeUrl(serverUrl)}`;
|
|
398
|
+
}
|
|
399
|
+
async getTokens(serverUrl) {
|
|
400
|
+
await this.init();
|
|
401
|
+
const account = this.getTokensAccount(serverUrl);
|
|
402
|
+
const stored = await this.keytar.getPassword(this.serviceName, account);
|
|
403
|
+
if (!stored) return null;
|
|
404
|
+
try {
|
|
405
|
+
return JSON.parse(stored);
|
|
406
|
+
} catch {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
async setTokens(serverUrl, tokens) {
|
|
411
|
+
await this.init();
|
|
412
|
+
const account = this.getTokensAccount(serverUrl);
|
|
413
|
+
const enrichedTokens = withExpiresAt(tokens);
|
|
414
|
+
await this.keytar.setPassword(this.serviceName, account, JSON.stringify(enrichedTokens));
|
|
415
|
+
}
|
|
416
|
+
async clearTokens(serverUrl) {
|
|
417
|
+
await this.init();
|
|
418
|
+
const account = this.getTokensAccount(serverUrl);
|
|
419
|
+
await this.keytar.deletePassword(this.serviceName, account);
|
|
420
|
+
}
|
|
421
|
+
async getClientInfo(serverUrl) {
|
|
422
|
+
await this.init();
|
|
423
|
+
const account = this.getClientAccount(serverUrl);
|
|
424
|
+
const stored = await this.keytar.getPassword(this.serviceName, account);
|
|
425
|
+
if (!stored) return null;
|
|
426
|
+
try {
|
|
427
|
+
return JSON.parse(stored);
|
|
428
|
+
} catch {
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
async setClientInfo(serverUrl, info) {
|
|
433
|
+
await this.init();
|
|
434
|
+
const account = this.getClientAccount(serverUrl);
|
|
435
|
+
await this.keytar.setPassword(this.serviceName, account, JSON.stringify(info));
|
|
436
|
+
}
|
|
437
|
+
async clearClientInfo(serverUrl) {
|
|
438
|
+
await this.init();
|
|
439
|
+
const account = this.getClientAccount(serverUrl);
|
|
440
|
+
await this.keytar.deletePassword(this.serviceName, account);
|
|
441
|
+
}
|
|
442
|
+
async clearAll() {
|
|
443
|
+
await this.init();
|
|
444
|
+
const credentials = await this.keytar.findCredentials(this.serviceName);
|
|
445
|
+
for (const cred of credentials) {
|
|
446
|
+
await this.keytar.deletePassword(this.serviceName, cred.account);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
async getAllSessions() {
|
|
450
|
+
await this.init();
|
|
451
|
+
const credentials = await this.keytar.findCredentials(this.serviceName);
|
|
452
|
+
const sessions = [];
|
|
453
|
+
const tokensMap = /* @__PURE__ */ new Map();
|
|
454
|
+
const clientMap = /* @__PURE__ */ new Map();
|
|
455
|
+
for (const cred of credentials) {
|
|
456
|
+
if (cred.account.startsWith("tokens:")) {
|
|
457
|
+
const url = cred.account.replace("tokens:", "");
|
|
458
|
+
try {
|
|
459
|
+
tokensMap.set(url, JSON.parse(cred.password));
|
|
460
|
+
} catch {
|
|
461
|
+
}
|
|
462
|
+
} else if (cred.account.startsWith("client:")) {
|
|
463
|
+
const url = cred.account.replace("client:", "");
|
|
464
|
+
try {
|
|
465
|
+
clientMap.set(url, JSON.parse(cred.password));
|
|
466
|
+
} catch {
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
for (const [url, tokens] of tokensMap) {
|
|
471
|
+
sessions.push({
|
|
472
|
+
serverUrl: url,
|
|
473
|
+
tokens,
|
|
474
|
+
clientInfo: clientMap.get(url),
|
|
475
|
+
createdAt: Date.now(),
|
|
476
|
+
updatedAt: Date.now()
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
return sessions;
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
async function isKeychainAvailable() {
|
|
483
|
+
try {
|
|
484
|
+
require("keytar");
|
|
485
|
+
return true;
|
|
486
|
+
} catch {
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
__name(isKeychainAvailable, "isKeychainAvailable");
|
|
491
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
492
|
+
0 && (module.exports = {
|
|
493
|
+
FileStorage,
|
|
494
|
+
KeychainStorage,
|
|
495
|
+
MemoryStorage,
|
|
496
|
+
isKeychainAvailable,
|
|
497
|
+
isTokenExpired,
|
|
498
|
+
withExpiresAt
|
|
499
|
+
});
|