MCPcopy Create free account
hub / github.com/CreminiAI/skillpack / ConfigFileAuthBackend

Class ConfigFileAuthBackend

src/runtime/config.ts:367–425  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

365// ---------------------------------------------------------------------------
366// ConfigFileAuthBackend – stores OAuth credentials inside config.json._auth
367// ---------------------------------------------------------------------------
368
369/**
370 * Custom AuthStorageBackend that persists OAuth credentials to the `_auth`
371 * field of config.json, keeping all configuration in a single file.
372 */
373export class ConfigFileAuthBackend implements AuthStorageBackend {
374 constructor(private configPath: string) {}
375
376 private ensureFile(): void {
377 const dir = path.dirname(this.configPath);
378 if (!fs.existsSync(dir)) {
379 fs.mkdirSync(dir, { recursive: true });
380 }
381 if (!fs.existsSync(this.configPath)) {
382 fs.writeFileSync(this.configPath, "{}", "utf-8");
383 }
384 }
385
386 private readAuthJson(): string | undefined {
387 this.ensureFile();
388 try {
389 const raw = fs.readFileSync(this.configPath, "utf-8");
390 const config = JSON.parse(raw);
391 if (config._auth && typeof config._auth === "object") {
392 return JSON.stringify(config._auth);
393 }
394 return undefined;
395 } catch {
396 return undefined;
397 }
398 }
399
400 private writeAuthJson(authJson: string): void {
401 this.ensureFile();
402 try {
403 const raw = fs.readFileSync(this.configPath, "utf-8");
404 const config = JSON.parse(raw);
405 config._auth = JSON.parse(authJson);
406 fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), "utf-8");
407 } catch {
408 // If config.json is unreadable, write a minimal file
409 const config = { _auth: JSON.parse(authJson) };
410 fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), "utf-8");
411 }
412 }
413
414 withLock<T>(fn: (current: string | undefined) => LockResult<T>): T {
415 const current = this.readAuthJson();
416 const { result, next } = fn(current);
417 if (next !== undefined) {
418 this.writeAuthJson(next);
419 }
420 return result;
421 }
422
423 async withLockAsync<T>(fn: (current: string | undefined) => Promise<LockResult<T>>): Promise<T> {
424 const current = this.readAuthJson();

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected