Auth client SDK for AccountMaker (Am)
npm install @softwarepatterns/am@softwarepatterns/amAuthentication client SDK for AccountMaker (Am).
This package provides a small, stable client for interacting with the AccountMaker authentication API. It is designed with explicit support for both ESM and CommonJS consumers.
---
* Automatic access-token refresh
* TypeScript-first API with bundled .d.ts
* Explicit error modeling via RFC 9457 Problem Details
* Automatic access-token refresh
* No runtime dependencies or side effects on import
* ESM and CommonJS support
---
* Node.js ≥ 18
* A runtime with a global fetch implementation
(Node 18+, Bun, Deno, or a custom fetchFn)
---
``bash`
npm install @softwarepatterns/am
---
`ts`
import { Am } from "@softwarepatterns/am";
`js`
const { Am } = require("@softwarepatterns/am");
---
`ts
import { Am } from "@softwarepatterns/am";
const am = new Am();
`
---
`ts`
const session = await am.signIn({
clientId: "your-client-id",
email: "user@example.com",
password: "password"
});
`ts`
const session = await am.signUp({
clientId: "your-client-id",
email: "user@example.com",
password: "password"
});
`ts`
const session = await am.acceptInvite({
clientId: "your-client-id",
token: "token-from-email",
});
`ts`
const session = await am.signInWithToken({
clientId: "your-client-id",
token: "token-from-email",
});
A session represents an authenticated user and handles token refresh automatically.
`ts`
// Automatically adds Authorization header, will refresh tokens as needed,
const res = await session.fetch("https://yourdomain.com/some/protected/resource");
You can also use the access token yourself.
`tsBearer ${session.accessToken()}
if (session.isExpired()) {
await session.refresh();
}
await fetch("https://yourdomain.com/your/own/protected/api", {
headers: {
Authorization: `
}
});
Your own services can validate the access token using AM's public keys.
`ts
import * as jose from 'jose';
// Will auto fetch, cache, and rotate keys as needed
const jwksUrl = new URL('https://auth.yourdomain.com/.well-known/jwks.json');
// if not using a custom auth domain:
// const jwksUrl = new URL('https://api.accountmaker.com/.well-known/jwks.json?client_id=your-client-id');
const JWKS = jose.createRemoteJWKSet(jwksUrl);
export const validateAccessToken = async (token: string) => {
const { payload } = await jose.jwtVerify(token, JWKS);
console.log('Account Id:', payload.acc);
console.log('User Id:', payload.uid);
console.log('User Account Role:', payload.role);
}
`
By default, tokens are saved in memory only.
`ts`
const am = new Am({
storage: null // disable storage, default is in-memory
});
Set to "localStorage" to persist sessions across reloads.
`ts`
const am = new Am({
storage: "localStorage"
});
const session = am.restoreSession();
Or implement your own storage mechanism by implementing the Storage interface.
---
All API errors throw as AuthError.
`ts
import { AuthError } from "@softwarepatterns/am";
try {
await am.signIn({ email, password });
} catch (err) {
if (err instanceof AuthError) {
console.log(err.status);
console.log(err.title);
console.log(err.detail);
}
}
`
Errors follow RFC 9457 Problem Details format (application/problem+json).
Unknown or unsupported error responses are converted into a generic problem shape without exposing raw response bodies. All non-HTTP errors (such as network or parsing errors) are left alone to bubble up.
---
For mocking or for custom fetch implementations, you can provide your own.
`ts`
const am = new Am({
fetchFn: fetch,
});
---
The following are guaranteed:
* Stable ESM and CommonJS entry points
* Stable TypeScript types for exported symbols
* Compatibility with Node 18, 20, and 22
This package follows semantic versioning.
* 0.x releases may introduce breaking changes1.0.0
* will mark a frozen public API
---
Integration tests require credentials stored in .env. The encrypted version .env.enc is committed to the repository.
`bash`
sops -d .env.enc > .env
`bashUnit tests
npm run test:unit
$3
`bash
sops -e .env > .env.enc
``---
MIT