mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-12 14:14:47 +00:00
fix(cursor): redact daemon token from dashboard start (#1540)
Redacts the Cursor daemon token from dashboard start output.
This commit is contained in:
1 parent
74dd2f38cc
commit
b85a3de26e
2 files changed
+40
-30
No files matched your search
@@ -234,7 +234,9 @@ router.post('/daemon/start', async (_req: Request, res: Response): Promise<void>
|
|||||||
port: cursorConfig.port,
|
port: cursorConfig.port,
|
||||||
ghost_mode: cursorConfig.ghost_mode,
|
ghost_mode: cursorConfig.ghost_mode,
|
||||||
});
|
});
|
||||||
res.json(result);
|
const { daemonToken: _redactedDaemonToken, ...publicResult } = result;
|
||||||
|
void _redactedDaemonToken;
|
||||||
|
res.json(publicResult);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ error: (error as Error).message });
|
res.status(500).json({ error: (error as Error).message });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,9 +52,11 @@ let checkAuthStatus: () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
let getTokenStoragePath: () => string;
|
let getTokenStoragePath: () => string;
|
||||||
let getDaemonStartPreconditionError: (
|
let getDaemonStartPreconditionError: (input: {
|
||||||
input: { enabled: boolean; authenticated: boolean; tokenExpired?: boolean }
|
enabled: boolean;
|
||||||
) => { status: number; error: string } | null;
|
authenticated: boolean;
|
||||||
|
tokenExpired?: boolean;
|
||||||
|
}) => { status: number; error: string } | null;
|
||||||
let getAutoDetectFailureStatus: (
|
let getAutoDetectFailureStatus: (
|
||||||
reason?:
|
reason?:
|
||||||
| 'db_not_found'
|
| 'db_not_found'
|
||||||
@@ -65,13 +67,15 @@ let getAutoDetectFailureStatus: (
|
|||||||
| 'invalid_token_format'
|
| 'invalid_token_format'
|
||||||
) => number;
|
) => number;
|
||||||
|
|
||||||
function seedCursorConfig(overrides: {
|
function seedCursorConfig(
|
||||||
enabled?: boolean;
|
overrides: {
|
||||||
port?: number;
|
enabled?: boolean;
|
||||||
auto_start?: boolean;
|
port?: number;
|
||||||
ghost_mode?: boolean;
|
auto_start?: boolean;
|
||||||
model?: string;
|
ghost_mode?: boolean;
|
||||||
} = {}): void {
|
model?: string;
|
||||||
|
} = {}
|
||||||
|
): void {
|
||||||
const config = loadOrCreateUnifiedConfig();
|
const config = loadOrCreateUnifiedConfig();
|
||||||
config.cursor = {
|
config.cursor = {
|
||||||
enabled: overrides.enabled ?? true,
|
enabled: overrides.enabled ?? true,
|
||||||
@@ -329,7 +333,10 @@ describe('Cursor Routes Logic', () => {
|
|||||||
try {
|
try {
|
||||||
const dbPath = getTokenStoragePath();
|
const dbPath = getTokenStoragePath();
|
||||||
fs.mkdirSync(path.dirname(dbPath), { recursive: true });
|
fs.mkdirSync(path.dirname(dbPath), { recursive: true });
|
||||||
execFileSync('sqlite3', [dbPath, 'CREATE TABLE IF NOT EXISTS itemTable (key TEXT PRIMARY KEY, value TEXT);']);
|
execFileSync('sqlite3', [
|
||||||
|
dbPath,
|
||||||
|
'CREATE TABLE IF NOT EXISTS itemTable (key TEXT PRIMARY KEY, value TEXT);',
|
||||||
|
]);
|
||||||
execFileSync('sqlite3', [
|
execFileSync('sqlite3', [
|
||||||
dbPath,
|
dbPath,
|
||||||
`INSERT OR REPLACE INTO itemTable (key, value) VALUES ('cursorAuth/accessToken', '${token}');`,
|
`INSERT OR REPLACE INTO itemTable (key, value) VALUES ('cursorAuth/accessToken', '${token}');`,
|
||||||
@@ -471,27 +478,28 @@ describe('Cursor Routes Logic', () => {
|
|||||||
expect(json.error).toContain('expired');
|
expect(json.error).toContain('expired');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it('POST /api/cursor/daemon/start starts daemon and /daemon/stop stops it', async () => {
|
||||||
'POST /api/cursor/daemon/start starts daemon and /daemon/stop stops it',
|
const port = 15000 + Math.floor(Math.random() * 20000);
|
||||||
async () => {
|
seedCursorConfig({ enabled: true, port });
|
||||||
const port = 15000 + Math.floor(Math.random() * 20000);
|
seedCredentials(false);
|
||||||
seedCursorConfig({ enabled: true, port });
|
|
||||||
seedCredentials(false);
|
|
||||||
|
|
||||||
const startRes = await fetch(`${baseUrl}/api/cursor/daemon/start`, { method: 'POST' });
|
const startRes = await fetch(`${baseUrl}/api/cursor/daemon/start`, { method: 'POST' });
|
||||||
expect(startRes.status).toBe(200);
|
expect(startRes.status).toBe(200);
|
||||||
|
|
||||||
const startJson = (await startRes.json()) as { success?: boolean; pid?: number };
|
const startJson = (await startRes.json()) as {
|
||||||
expect(startJson.success).toBe(true);
|
success?: boolean;
|
||||||
expect(typeof startJson.pid).toBe('number');
|
pid?: number;
|
||||||
|
daemonToken?: string;
|
||||||
|
};
|
||||||
|
expect(startJson.success).toBe(true);
|
||||||
|
expect(typeof startJson.pid).toBe('number');
|
||||||
|
expect(startJson.daemonToken).toBeUndefined();
|
||||||
|
|
||||||
const stopRes = await fetch(`${baseUrl}/api/cursor/daemon/stop`, { method: 'POST' });
|
const stopRes = await fetch(`${baseUrl}/api/cursor/daemon/stop`, { method: 'POST' });
|
||||||
expect(stopRes.status).toBe(200);
|
expect(stopRes.status).toBe(200);
|
||||||
const stopJson = (await stopRes.json()) as { success?: boolean };
|
const stopJson = (await stopRes.json()) as { success?: boolean };
|
||||||
expect(stopJson.success).toBe(true);
|
expect(stopJson.success).toBe(true);
|
||||||
},
|
}, 35000);
|
||||||
35000
|
|
||||||
);
|
|
||||||
|
|
||||||
it('POST /api/cursor/daemon/stop returns success when daemon is not running', async () => {
|
it('POST /api/cursor/daemon/stop returns success when daemon is not running', async () => {
|
||||||
const res = await fetch(`${baseUrl}/api/cursor/daemon/stop`, { method: 'POST' });
|
const res = await fetch(`${baseUrl}/api/cursor/daemon/stop`, { method: 'POST' });
|
||||||
|
|||||||
Reference in new issue
Block a user