@sinequa/atomic

Impersonation

Running requests as another user — the two configuration keys, the headers they produce, and what it changes about signing out.

An administrator can run requests as another user, to see what that person sees. Support does it to reproduce a report of missing results; an administrator does it to verify a rights change.

Two configuration keys, and the second is the switch:

acting as someone else
client.configure({
  userOverride: { username: "alice", domain: "corp" },
  userOverrideActive: true,
});

This is an administrative capability

The server decides whether the signed-in user may impersonate. Setting these keys on an account without the right produces a distinctive failure — see the pitfalls. Gate the control on principal.isAdministrator or isDelegatedAdmin rather than offering it to everyone.

What it changes on the wire

While active, every request carries two headers:

on each request
sinequa-override-user: alice
sinequa-override-domain: corp

And the request body says noUserOverride: false — the flag is the negation of userOverrideActive, so the body and the headers agree. They used to disagree: the body sent a hard-coded true while the headers asked for an override on the same request.

Results then come back as Alice would see them: her rights, her documents, her counts.

Turning it on and off

An impersonation banner, with a way out
src/impersonate.ts
import { createAtomicClient } from "@sinequa/atomic";

const client = createAtomicClient({
  app: "<your-app>",
  backendUrl: "https://<your-sinequa-server>",
});

await client.initializeConfig();
await client.auth.login();

const me = await client.api.principal.get();

/** Only offer this where the server would allow it. */
export const mayImpersonate = me.isAdministrator || me.isDelegatedAdmin;

export function startImpersonating(username: string, domain: string) {
  if (!mayImpersonate) throw new Error("You may not impersonate.");

  client.configure({
    userOverride: { username, domain },
    userOverrideActive: true,
  });
}

/** Clearing the flag is enough; the headers stop being sent immediately. */
export function stopImpersonating() {
  client.configure({ userOverrideActive: false, userOverride: undefined });
}

/** What the banner should read. `config` is a live view, so this is current. */
export function impersonating() {
  return client.config.userOverrideActive === true
    ? (client.config.userOverride as { username: string } | undefined)?.username
    : undefined;
}

Use Finding principals to pick who to impersonate rather than typing a username.

Pitfalls

What's next

On this page