Skip to content

auth-server-ts quickstart

Install

Terminal window
pnpm add @vendidit/auth-server-ts

Env

AUTH_SERVER_URL=https://auth.vendidit.com
AUTH_APP_CODE=my-service
JWT_ACCESS_SECRET=<shared with auth-server>

Construct the client

import {
AuthClient,
HttpTransport,
JwtValidator,
InMemorySessionStore,
SystemClock,
resolveConfig,
} from '@vendidit/auth-server-ts';
const config = resolveConfig({
authServerUrl: process.env.AUTH_SERVER_URL!,
appCode: process.env.AUTH_APP_CODE,
jwtAccessSecret: process.env.JWT_ACCESS_SECRET,
jwtIssuer: 'ven-auth',
jwtAudience: 'ven-platform',
});
const auth = new AuthClient({
config,
transport: new HttpTransport({ baseUrl: `${config.authServerUrl}/api/v1` }),
validator: new JwtValidator({
secret: config.jwtAccessSecret!,
issuer: config.jwtIssuer,
audience: config.jwtAudience,
}),
session: new InMemorySessionStore(),
clock: new SystemClock(),
});

Express middleware

import type { Request, Response, NextFunction } from 'express';
import { VenAuthException } from '@vendidit/auth-server-ts';
export async function jwtMiddleware(req: Request, res: Response, next: NextFunction) {
try {
const principal = await auth.validateBearer(req.headers.authorization ?? '');
(req as any).user = principal;
next();
} catch (err) {
if (err instanceof VenAuthException) {
res.status(err.statusCode ?? 401).json({ error: err.code, message: err.message });
} else {
res.status(500).json({ error: 'internal_error' });
}
}
}

Fastify hook

import type { FastifyInstance } from 'fastify';
export function registerAuth(app: FastifyInstance) {
app.addHook('onRequest', async (req, reply) => {
const principal = await auth.validateBearer(req.headers.authorization ?? '');
(req as any).user = principal;
});
}

Calling other auth-server endpoints

// As the current user
const me = await auth.me(accessToken);
// As a service (m2m)
import { ServiceAuthClient } from '@vendidit/auth-server-ts';
const m2m = new ServiceAuthClient({
transport: new HttpTransport({ baseUrl: `${config.authServerUrl}/api/v1` }),
credentials: {
clientId: process.env.AUTH_CLIENT_ID!,
clientSecret: process.env.AUTH_CLIENT_SECRET!,
},
});
const serviceToken = await m2m.getToken(); // cached + auto-refreshed

Permission registration on boot

import { Flows } from '@vendidit/auth-server-ts';
await new Flows({ transport, config }).registerPermissions(serviceToken, {
service: 'orders',
permissions: [
{ code: 'orders:read', resource: 'orders', action: 'read', name: 'Read orders' },
{ code: 'orders:create', resource: 'orders', action: 'create', name: 'Create order' },
],
});

Idempotent — safe to call every boot.