Skip to the content
Krizaka TS
Krizaka TS

@krizaka/auth

Accounts and roles: profile, e-mail change by link, password, sessions, roles as data.

Install

bashTerminal
npm install @krizaka/auth

The account of a Krizaka product, behind a port: a display name, language, theme and avatar seed; the e-mail change by a link mailed to the new address (the verified flag is set by that very act); the password (checked before anything sensitive, other sessions signed out on change); the live sessions with sign-out of the others; the data export; the deletion. Each product keeps its own accounts — the package brings an adapter over the product's PostgreSQL and the migration it needs, nothing central.

import { accountsMigration, postgresAccounts } from "@krizaka/auth";

await db.query(accountsMigration({ backfillVerified: true })); // once, in your migrations (idempotent)
const accounts = postgresAccounts({ query, mail, baseUrl: "https://www.akinaza.com", product: "Akinaza", tokenPrefix: "ae", passwords: { hash, verify }, tokenHash });
await accounts.updateProfile(id, { name: "Éric", theme: "dark" });
await accounts.sessions(id, new Date(), currentSessionId);

The product keeps what is its own: its session cookie and token hashing (tokenHash), its password hashing, its mailer, its rate limits and its HTTP answers (AccountError carries a status and a stable code). Time is passed in (now); nothing here reads the clock.

Roles per scope

A role model is data: defineRoles({ roles, permissions, manages }) says which roles exist, what each may do and who may hand which role to whom. createRoles keeps memberships (one person, several scopes, a role in each) and invitations (an e-mail invited with a role, a link used once, only its hash kept, never demoting), refuses to remove or demote the last owner, and answers authorize(account, scope, "invoices") with the role or a stable refusal (NOT_A_MEMBER 404, FORBIDDEN 403). rolesMigration(roles, { scopeTable }) makes the tables.

Exports

The 28 names the package exports, read from its types.

NameKindWhat it is
AccountDepstype
AccountErrorclass
AccountProfiletype
AccountServicetype
accountsMigrationfunctionWhat the account adapter needs from a product's database, safe to run on a database that already has accounts and sessions: a display name, a theme, an a…
canfunction
createRolesfunctionWho may do what in a scope, over the product's PostgreSQL.
defineRolesfunction
EMAIL_CHANGE_TTL_HOURSconstant
emailChangeMailfunction
emailChangeTokenfunction
Invitationtype
isEmailChangeTokenfunction
Mailtype
Membertype
postgresAccountsfunctionThe adapter over the product's own PostgreSQL (accounts, sessions, email_changes; see accountsMigration).
ProfilePatchtype
QuerytypeA SQL executor: the rows of a statement and its parameters (the product's pool).
RoleModeltypeRoles per scope (a shop, a workspace), as DATA: a model says which roles exist, which permissions each holds and who may hand which role to whom.
Rolestype
ROLES_CODEconstant
RolesCodetype
RolesDepstype
RolesErrorclass
rolesMigrationfunctionMemberships (who has which role in which scope) and invitations (an e-mail address invited with a role, by a link used once), from the product's role model.
RolesQuerytype
SessionSummarytypeA sign-in of the person: where from and when.
ThemetypeThe account PORT (ADR-0008 of Yomizaka, now shared).

Package

Version on npm0.3.0 (npm)
LicenceApache-2.0
Node.js>=22
Dependenciesdate-fns ^4.4.0
Sourceauth

Changelog

0.3.0

Minor changes

  • Roles per scope as data: the role model, memberships, invitations by e-mail, authorize, the last owner protected, and rolesMigration.

0.2.0

Minor changes

  • The mail handed to the product carries locale (the person's), so an outbox can store it.

0.1.0

Minor changes

  • First release: the account port, its PostgreSQL adapter and migration (profile, theme, e-mail change by link, password, sessions, export, deletion).

On this page