mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-16 03:01:56 +00:00
- Add /login and /logout commands for OAuth flow - OAuth tokens stored in ~/.pi/agent/oauth.json with 0600 permissions - Auto-refresh tokens when expired (5min buffer) - Priority: OAuth > ANTHROPIC_OAUTH_TOKEN env > ANTHROPIC_API_KEY env - Fix model selector async loading and re-render - Add bracketed paste support to Input component for long codes - Update README.md with OAuth documentation - Add implementation docs and testing checklist
95 lines
2.2 KiB
TypeScript
95 lines
2.2 KiB
TypeScript
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
import { homedir } from "os";
|
|
import { join } from "path";
|
|
|
|
export interface OAuthCredentials {
|
|
type: "oauth";
|
|
refresh: string;
|
|
access: string;
|
|
expires: number;
|
|
}
|
|
|
|
interface OAuthStorageFormat {
|
|
[provider: string]: OAuthCredentials;
|
|
}
|
|
|
|
/**
|
|
* Get path to oauth.json
|
|
*/
|
|
function getOAuthFilePath(): string {
|
|
const configDir = join(homedir(), ".pi", "agent");
|
|
return join(configDir, "oauth.json");
|
|
}
|
|
|
|
/**
|
|
* Ensure the config directory exists
|
|
*/
|
|
function ensureConfigDir(): void {
|
|
const configDir = join(homedir(), ".pi", "agent");
|
|
if (!existsSync(configDir)) {
|
|
mkdirSync(configDir, { recursive: true, mode: 0o700 });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load all OAuth credentials from oauth.json
|
|
*/
|
|
function loadStorage(): OAuthStorageFormat {
|
|
const filePath = getOAuthFilePath();
|
|
if (!existsSync(filePath)) {
|
|
return {};
|
|
}
|
|
|
|
try {
|
|
const content = readFileSync(filePath, "utf-8");
|
|
return JSON.parse(content);
|
|
} catch (error) {
|
|
console.error(`Warning: Failed to load OAuth credentials: ${error}`);
|
|
return {};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save all OAuth credentials to oauth.json
|
|
*/
|
|
function saveStorage(storage: OAuthStorageFormat): void {
|
|
ensureConfigDir();
|
|
const filePath = getOAuthFilePath();
|
|
writeFileSync(filePath, JSON.stringify(storage, null, 2), "utf-8");
|
|
// Set permissions to owner read/write only
|
|
chmodSync(filePath, 0o600);
|
|
}
|
|
|
|
/**
|
|
* Load OAuth credentials for a specific provider
|
|
*/
|
|
export function loadOAuthCredentials(provider: string): OAuthCredentials | null {
|
|
const storage = loadStorage();
|
|
return storage[provider] || null;
|
|
}
|
|
|
|
/**
|
|
* Save OAuth credentials for a specific provider
|
|
*/
|
|
export function saveOAuthCredentials(provider: string, creds: OAuthCredentials): void {
|
|
const storage = loadStorage();
|
|
storage[provider] = creds;
|
|
saveStorage(storage);
|
|
}
|
|
|
|
/**
|
|
* Remove OAuth credentials for a specific provider
|
|
*/
|
|
export function removeOAuthCredentials(provider: string): void {
|
|
const storage = loadStorage();
|
|
delete storage[provider];
|
|
saveStorage(storage);
|
|
}
|
|
|
|
/**
|
|
* List all providers with OAuth credentials
|
|
*/
|
|
export function listOAuthProviders(): string[] {
|
|
const storage = loadStorage();
|
|
return Object.keys(storage);
|
|
}
|