(req, apiKey = '', body = null)
| 67 | } |
| 68 | |
| 69 | export function callerKeyFromRequest(req, apiKey = '', body = null) { |
| 70 | const bodySubKey = body ? extractBodyCallerSubKey(body) : ''; |
| 71 | const hasUserInBody = !!(body && typeof body.user === 'string'); |
| 72 | log.info('[caller-key] body.user=%s subKey=%s', hasUserInBody ? body.user : '(none)', bodySubKey || '(none)'); |
| 73 | if (apiKey) { |
| 74 | const base = `api:${sha256Hex(apiKey).slice(0, 32)}`; |
| 75 | if (bodySubKey) return `${base}:user:${bodySubKey}`; |
| 76 | const ipua = ipUaFingerprint(req); |
| 77 | return ipua ? `${base}:client:${ipua}` : base; |
| 78 | } |
| 79 | const sessionId = req?.headers?.['x-dashboard-session'] || req?.headers?.['x-session-id'] || ''; |
| 80 | if (sessionId) { |
| 81 | const base = `session:${sha256Hex(sessionId).slice(0, 32)}`; |
| 82 | return bodySubKey ? `${base}:user:${bodySubKey}` : base; |
| 83 | } |
| 84 | const ip = clientIp(req); |
| 85 | const ua = req?.headers?.['user-agent'] || ''; |
| 86 | const base = `client:${sha256Hex(`${ip}\0${ua}`).slice(0, 32)}`; |
| 87 | return bodySubKey ? `${base}:user:${bodySubKey}` : base; |
| 88 | } |
| 89 | |
| 90 | // Returns true if we have any per-user signal beyond the bare API key. |
| 91 | // chat.js consults this to decide whether to allow conversation reuse for a |
no test coverage detected