Merge branch 'codex/feishu-remote-v2'
This commit is contained in:
commit
1420c05cd9
28 files changed
+3525
-1149
No files matched your search
@@ -5,7 +5,11 @@ export const runtime = 'nodejs';
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
/**
|
||||
* GET /api/bridge — Return bridge status (pure query, no side effects)
|
||||
* GET /api/bridge — Return bridge status (pure query, no side effects).
|
||||
*
|
||||
* Does NOT run probe — probe is an explicit action via the per-channel
|
||||
* status endpoint (e.g. /api/channels/feishu/status?probe=true).
|
||||
* This endpoint is polled every 5s by useBridgeStatus so it must stay cheap.
|
||||
*/
|
||||
export async function GET() {
|
||||
try {
|
||||
|
||||
@@ -14,7 +14,7 @@ import type { MCPServerConfig } from '@/types';
|
||||
export const runtime = 'nodejs';
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
/** Read MCP server configs from ~/.claude.json and ~/.claude/settings.json */
|
||||
/** Read MCP server configs from ~/.claude.json, ~/.claude/settings.json, and project .mcp.json */
|
||||
function loadMcpServers(): Record<string, MCPServerConfig> | undefined {
|
||||
try {
|
||||
const readJson = (p: string): Record<string, unknown> => {
|
||||
@@ -23,10 +23,25 @@ function loadMcpServers(): Record<string, MCPServerConfig> | undefined {
|
||||
};
|
||||
const userConfig = readJson(path.join(os.homedir(), '.claude.json'));
|
||||
const settings = readJson(path.join(os.homedir(), '.claude', 'settings.json'));
|
||||
// Also read project-level .mcp.json
|
||||
const projectMcp = readJson(path.join(process.cwd(), '.mcp.json'));
|
||||
const merged = {
|
||||
...((userConfig.mcpServers || {}) as Record<string, MCPServerConfig>),
|
||||
...((settings.mcpServers || {}) as Record<string, MCPServerConfig>),
|
||||
...((projectMcp.mcpServers || {}) as Record<string, MCPServerConfig>),
|
||||
};
|
||||
// Resolve ${...} placeholders in env values against DB settings
|
||||
for (const server of Object.values(merged)) {
|
||||
if (server.env) {
|
||||
for (const [key, value] of Object.entries(server.env)) {
|
||||
if (typeof value === 'string' && value.startsWith('${') && value.endsWith('}')) {
|
||||
const settingKey = value.slice(2, -1);
|
||||
const resolved = getSetting(settingKey);
|
||||
server.env[key] = resolved || '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Object.keys(merged).length > 0 ? merged : undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
|
||||
@@ -11,7 +11,9 @@ const FEISHU_KEYS = [
|
||||
'bridge_feishu_app_id',
|
||||
'bridge_feishu_app_secret',
|
||||
'bridge_feishu_domain',
|
||||
'bridge_feishu_allowed_users',
|
||||
'bridge_feishu_allow_from',
|
||||
'bridge_feishu_dm_policy',
|
||||
'bridge_feishu_thread_session',
|
||||
'bridge_feishu_group_policy',
|
||||
'bridge_feishu_group_allow_from',
|
||||
'bridge_feishu_require_mention',
|
||||
@@ -23,7 +25,7 @@ export async function GET() {
|
||||
for (const key of FEISHU_KEYS) {
|
||||
const value = getSetting(key);
|
||||
if (value !== undefined) {
|
||||
// Mask app secret for security
|
||||
// Mask sensitive fields for security
|
||||
if (key === 'bridge_feishu_app_secret' && value.length > 8) {
|
||||
result[key] = '***' + value.slice(-8);
|
||||
} else {
|
||||
@@ -52,7 +54,7 @@ export async function PUT(request: NextRequest) {
|
||||
if (!FEISHU_KEYS.includes(key as typeof FEISHU_KEYS[number])) continue;
|
||||
const strValue = String(value ?? '').trim();
|
||||
|
||||
// Don't overwrite secret if user sent the masked version back
|
||||
// Don't overwrite secrets if user sent the masked version back
|
||||
if (key === 'bridge_feishu_app_secret' && strValue.startsWith('***')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user