env.auth.user
Returns the signed-in user associated with a request, or null if the request has no authenticated session.
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const user = await env.auth.user(request);
if (!user) return Response.redirect(new URL("/__runlot/auth/sign-in", request.url));
return Response.json({ email: user.email });
},
};user(). The session lives in the request's cookies or headers, and env outlives any single request. If you omit the argument you get the error env.auth.user(request): pass the request object. Next.js is the exception: with @runlot/next the adapter tracks the current request, so you can call it with no arguments.User
export interface User {
id: string; // uuid
email: string | null;
emailVerified: boolean;
name: string | null;
avatarUrl: string | null;
providers: string[]; // e.g. ["password", "github"]
createdAt: string; // ISO 8601
lastSignInAt: string | null;
}id is the primary key of runlot_auth.users. Use it to link user-owned rows in your own tables.
create table posts (
id bigserial primary key,
owner_id uuid not null,
title text not null
);const user = await env.auth.user(request);
await env.db.exec("insert into posts (owner_id, title) values ($1, $2)", [user.id, title]);Logging out
if (url.pathname === "/logout") {
return new Response(null, {
status: 302,
headers: { location: "/", ...(await env.auth.signOut(request)) },
});
}signOut deletes the server-side session and returns a headers object that clears the cookie. From a browser form you can also post to POST /__runlot/auth/sign-out.
Managing users
const u = await env.auth.users.get(id);
const byEmail = await env.auth.users.getByEmail("[email protected]");
const page = await env.auth.users.list({ limit: 50, cursor });
await env.auth.users.update(id, { name: "New name" });
await env.auth.users.delete(id);
await env.auth.sessions.revokeAll(userId);list returns 50 records by default and 200 at most. An empty cursor means you are on the last page.
Browser helpers
import { config, session, signInUrl, signOutUrl } from "@runlot/auth/client";
const { user } = await session(); // { user: null } when not logged in
const { providers, password, allowSignup } = await config();
location.href = signInUrl("github", { next: "/app" });config() reads /__runlot/auth/config: the brand, the providers that are on (OIDC providers with their name and icon), whether password and magic-link login are on, and allowSignup. It holds no secrets; providers() returns the list alone. Draw a custom login page from it instead of hard-coding buttons. This module has no external dependencies. If you pass an external URL to next, it is ignored for security.
Calling without a request
env.auth.user() without a request argument is a feature of the framework adapters. Today the only adapter is @runlot/next for Next.js. Everywhere else, always pass the request object.