TausiDocs

Node.js and Express

@tausi-auth/node has no dependencies and needs Node 18+. TausiBackend (secret key) protects your API and manages users; TausiClient (publishable key) signs users in from Node, Electron, React Native or a CLI.

Install

@tausi-auth/node on npmRequires Node 18.17+, Bun or Deno; no dependencies
Shell
npm install @tausi-auth/node
tausi.tsTypeScript
import { TausiBackend } from "@tausi-auth/node";

export const tausi = new TausiBackend({
  baseUrl: process.env.TAUSI_URL ?? "https://auth.tausi.app",
  secretKey: process.env.TAUSI_SECRET_KEY!,
});

await tausi.getProject(); // optional startup check that the key works

Protect your API

Your frontend sends Authorization: Bearer <sessionToken>. Check it on every request:

verifyTypeScript
const auth = await tausi.authenticateRequest(request);   // any Request, Headers or Node IncomingMessage
if (!auth) return unauthorized();                         // invalid, expired, revoked, banned or another project
auth.user.id; auth.user.email; auth.session.expiresAt;

// or with a token you already have:
const result = await tausi.verifySession(token);

These return null for any bad token and only throw TausiError for problems on your side (wrong secret key, Tausi unreachable, 5xx). Answer those with 503, not 401, so users aren't signed out by an outage.

Express

server.tsTypeScript
import express from "express";
import { optionalAuth, requireAuth } from "@tausi-auth/node/express";
import { tausi } from "./tausi";

const app = express();

app.get("/api/me", requireAuth(tausi), (req, res) => res.json(req.auth.user));          // 401 without a valid token
app.get("/api/feed", optionalAuth(tausi), (req, res) => res.json({ personal: Boolean(req.auth) }));

app.use((err, _req, res, _next) => res.status(503).json({ error: "Authentication unavailable" }));

Hono, Fastify, Bun, Deno

hono.tsTypeScript
import { Hono } from "hono";

const app = new Hono();
app.use("/api/*", async (c, next) => {
  const auth = await tausi.authenticateRequest(c.req.raw);
  if (!auth) return c.json({ error: "Unauthorized" }, 401);
  c.set("auth", auth);
  await next();
});
fastify.tsTypeScript
fastify.addHook("preHandler", async (request, reply) => {
  const auth = await tausi.authenticateRequest(request.raw);
  if (!auth) return reply.code(401).send({ error: "Unauthorized" });
  request.auth = auth;
});

Manage users

adminTypeScript
const page = await tausi.users.list({ q: "asha", access: "active", page: 1, pageSize: 50 });
// each item: status ("signed_in" / "signed_out"), activeSessions, lastSignInAt, lastActiveAt, access, ...

const detail = await tausi.users.get(userId);      // user, sessions (devices), signInHistory, recentAudit
await tausi.users.update(userId, { emailVerified: true, publicMetadata: { plan: "pro" }, privateMetadata: { stripeId: "cus_123" } });
await tausi.users.suspend(userId, { durationHours: 24, reason: "Chargeback" });
await tausi.users.ban(userId, { reason: "Spam" });
await tausi.users.unban(userId);
await tausi.users.bulk("revoke_sessions", [idA, idB]);
await tausi.users.revokeSessions(userId);
await tausi.users.delete(userId);

Everything is in Managing users.

Sign users in (Node, Electron, React Native, CLIs)

client.tsTypeScript
import { TausiClient, randomDeviceId } from "@tausi-auth/node";

const tausi = new TausiClient({
  baseUrl: "https://auth.tausi.app",
  publishableKey: "pk_…",
  tokenStore: { get: () => store.get("token"), set: (t) => store.set("token", t) }, // may be async (AsyncStorage, Keychain)
  deviceId: savedDeviceId ?? randomDeviceId(),                                       // persist one per install
});

await tausi.signIn({ email, password });
const token = await tausi.getToken();      // send as Authorization: Bearer
await tausi.updateUser({ username: "asha" });

// Social sign-in with PKCE
const { url, codeVerifier } = await tausi.startOAuth("google", { redirectTo: "https://app.example.com/auth/callback" });
// open url in a browser ... then, with the URL it came back to:
await tausi.handleOAuthRedirect(callbackUrl, codeVerifier);

Errors

errorsTypeScript
import { isTausiError } from "@tausi-auth/node";

try { /* ... */ } catch (e) {
  if (isTausiError(e)) {
    e.code;        // "INVALID_CREDENTIALS", "ACCOUNT_BANNED", "RATE_LIMITED", ...
    e.status;      // HTTP status, 0 for network errors
    e.retryAfter;  // seconds, for RATE_LIMITED
    e.requestId;   // quote it when reporting a problem
    e.details;     // e.g. { issues: [{ path, message }] } for VALIDATION_ERROR
  }
}
See also
All error codesEvery code with its HTTP status and meaning.