mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-17 04:17:11 +00:00
fix(dashboard): read accounts from unified config
Dashboard accounts page was only reading from profiles.json, ignoring accounts stored in config.yaml when in unified mode. This caused accounts created via CLI to be invisible in the dashboard. - Use ProfileRegistry instead of direct file access - Merge legacy and unified accounts (unified takes precedence) - Set default via unified config when in unified mode Fixes #203
This commit is contained in:
@@ -1,38 +1,57 @@
|
||||
/**
|
||||
* Account Routes - CRUD operations for Claude accounts (profiles.json)
|
||||
* Account Routes - CRUD operations for Claude accounts
|
||||
*
|
||||
* Separated from profile-routes.ts to avoid dual-mounting conflicts.
|
||||
* Uses ProfileRegistry to read from both legacy (profiles.json)
|
||||
* and unified config (config.yaml) for consistent data with CLI.
|
||||
*/
|
||||
|
||||
import { Router, Request, Response } from 'express';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { getCcsDir } from '../../utils/config-manager';
|
||||
import ProfileRegistry from '../../auth/profile-registry';
|
||||
import { isUnifiedMode } from '../../config/unified-config-loader';
|
||||
|
||||
const router = Router();
|
||||
const registry = new ProfileRegistry();
|
||||
|
||||
/**
|
||||
* GET /api/accounts - List accounts from profiles.json
|
||||
* GET /api/accounts - List accounts from both profiles.json and config.yaml
|
||||
*/
|
||||
router.get('/', (_req: Request, res: Response): void => {
|
||||
try {
|
||||
const profilesPath = path.join(getCcsDir(), 'profiles.json');
|
||||
// Get profiles from both legacy and unified config (same logic as CLI)
|
||||
const legacyProfiles = registry.getAllProfiles();
|
||||
const unifiedAccounts = registry.getAllAccountsUnified();
|
||||
|
||||
if (!fs.existsSync(profilesPath)) {
|
||||
res.json({ accounts: [], default: null });
|
||||
return;
|
||||
// Merge profiles: unified config takes precedence
|
||||
const merged: Record<string, { type: string; created: string; last_used: string | null }> = {};
|
||||
|
||||
// Add legacy profiles first
|
||||
for (const [name, meta] of Object.entries(legacyProfiles)) {
|
||||
merged[name] = {
|
||||
type: meta.type || 'account',
|
||||
created: meta.created,
|
||||
last_used: meta.last_used || null,
|
||||
};
|
||||
}
|
||||
|
||||
const data = JSON.parse(fs.readFileSync(profilesPath, 'utf8'));
|
||||
const accounts = Object.entries(data.profiles || {}).map(([name, meta]) => {
|
||||
const metadata = meta as Record<string, unknown>;
|
||||
return {
|
||||
name,
|
||||
...metadata,
|
||||
// Override with unified config accounts (takes precedence)
|
||||
for (const [name, account] of Object.entries(unifiedAccounts)) {
|
||||
merged[name] = {
|
||||
type: 'account',
|
||||
created: account.created,
|
||||
last_used: account.last_used,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
res.json({ accounts, default: data.default || null });
|
||||
// Convert to array format
|
||||
const accounts = Object.entries(merged).map(([name, meta]) => ({
|
||||
name,
|
||||
...meta,
|
||||
}));
|
||||
|
||||
// Get default from unified config first, fallback to legacy
|
||||
const defaultProfile = registry.getDefaultUnified() ?? registry.getDefaultProfile() ?? null;
|
||||
|
||||
res.json({ accounts, default: defaultProfile });
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: (error as Error).message });
|
||||
}
|
||||
@@ -50,14 +69,12 @@ router.post('/default', (req: Request, res: Response): void => {
|
||||
return;
|
||||
}
|
||||
|
||||
const profilesPath = path.join(getCcsDir(), 'profiles.json');
|
||||
|
||||
const data = fs.existsSync(profilesPath)
|
||||
? JSON.parse(fs.readFileSync(profilesPath, 'utf8'))
|
||||
: { profiles: {} };
|
||||
|
||||
data.default = name;
|
||||
fs.writeFileSync(profilesPath, JSON.stringify(data, null, 2) + '\n');
|
||||
// Use unified config if in unified mode, otherwise use legacy
|
||||
if (isUnifiedMode()) {
|
||||
registry.setDefaultUnified(name);
|
||||
} else {
|
||||
registry.setDefaultProfile(name);
|
||||
}
|
||||
|
||||
res.json({ default: name });
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user