every proxied request carries who is asking
Officer's session is the only place the acting user is known, and fofos writes it into its own change history. An email in X-Actor, because that database has no users to point at. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -48,6 +48,14 @@ type RequestOptions = {
|
|||||||
/** Already-serialised. Forwarded as given so what fofos receives is what the caller sent. */
|
/** Already-serialised. Forwarded as given so what fofos receives is what the caller sent. */
|
||||||
body?: string | FormData | null;
|
body?: string | FormData | null;
|
||||||
contentType?: string | null;
|
contentType?: string | null;
|
||||||
|
/**
|
||||||
|
* Who is asking, as an email — sent as `X-Actor`, and written into fofos's own change history.
|
||||||
|
*
|
||||||
|
* fofos has no users, so it cannot work this out and cannot check it: the header is as trustworthy
|
||||||
|
* as the token that carried it. That is enough for what it is for, which is telling two colleagues
|
||||||
|
* apart rather than proving anything.
|
||||||
|
*/
|
||||||
|
actor?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FofosResponse = { status: number; body: string; contentType: string | null };
|
export type FofosResponse = { status: number; body: string; contentType: string | null };
|
||||||
@@ -70,6 +78,7 @@ export async function fofosRequest(
|
|||||||
// Left unset for FormData: fetch has to write its own, including the multipart boundary, and a
|
// Left unset for FormData: fetch has to write its own, including the multipart boundary, and a
|
||||||
// hand-set Content-Type here produces a body the other end cannot parse.
|
// hand-set Content-Type here produces a body the other end cannot parse.
|
||||||
if (options.contentType) headers['Content-Type'] = options.contentType;
|
if (options.contentType) headers['Content-Type'] = options.contentType;
|
||||||
|
if (options.actor) headers['X-Actor'] = options.actor;
|
||||||
|
|
||||||
let response: Response;
|
let response: Response;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -762,6 +762,9 @@ router.all('/*', async (ctx) => {
|
|||||||
search: url.search,
|
search: url.search,
|
||||||
body,
|
body,
|
||||||
contentType: body ? 'application/json' : null,
|
contentType: body ? 'application/json' : null,
|
||||||
|
// Officer's session is the only place the acting user is known. fofos writes it into its own
|
||||||
|
// history — see its record.ts, and the note on `actor` in fofos-client.
|
||||||
|
actor: ctx.get('user')?.email ?? null,
|
||||||
});
|
});
|
||||||
return passThrough(response);
|
return passThrough(response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user