@sinequa/atomic

The current user

Reading who is signed in, their administrative flags, and understanding why security never needs checking client-side.

One call gives you the signed-in identity:

one call
const principal = await client.api.principal.get();

It is also the call the library uses as its authentication probe, which is why it is the cheapest way to confirm a session is real — see Prerequisites.

Concept — a principal

A principal is an identity known to the security layer: a user or a group. The signed-in user is one, and so is every group they belong to. Documents carry access lists of principals, which is how the engine decides who sees what.

What you get

Prop

Type

Reading it once, at start-up

Load the user, warn on an expiring password
src/user.ts
import { createAtomicClient, expiresSoon, isExpired } from "@sinequa/atomic";
import type { Principal } from "@sinequa/atomic";

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

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

// Fetch once and keep it: the identity does not change during a session.
const principal: Principal = await client.api.principal.get();

console.log(`signed in as ${principal.name} (${principal.email})`);

if (principal.isAdministrator) enableAdministration();

// Both helpers are exported, and both tolerate an undefined date.
if (isExpired(principal.passwordExpirationDate ?? undefined)) {
  console.warn("Your password has expired.");
} else if (expiresSoon(principal.passwordExpirationDate ?? undefined, 7)) {
  console.warn("Your password expires within a week.");
}

function enableAdministration() {
  console.log("administration available");
}

Security is not your job

This is the part worth internalising: access rights are enforced in the index, per document, from the access lists captured when the document was crawled. Two consequences:

  • Results are already filtered. A document the user may not see never appears in records, and is not counted in rowCount. There is nothing to check, and nothing to hide client-side.
  • Two users legitimately get different counts for the identical query. That is not a caching bug.

A record's accesslists field describes those rights when you need to display them — an "who can see this" panel — but never to decide whether to render a result.

Looking up other people

principal.get() is the signed-in user. For anyone else there are two different calls, and picking the wrong one is a common mistake:

CallFor
principal.userid(id) / principal.userids(ids)Resolving known identifiers to principals
principal.list({ search, isuser, isgroup })Browsing the directory
principal.search({ offset, limit, search })Search-as-you-type, with pagination and cancellation

The last one is the one an owner-picker wants; see Finding principals.

Pitfalls

What's next

On this page