@setu-ts/auth-plugin — authenticate requests and guard routes
Add it: setu add auth prints the registration for setu.config.ts; configure
AuthPlugin({ jwt: { secret: process.env.JWT_SECRET! }, rbac: { roles: { user: { permissions: ['orders:read'] } } } }).
It provides CAPABILITIES.AUTH (IAuthService), CAPABILITIES.JWT (IJwtService) with jwt, and
CAPABILITIES.AUTHORIZATION (IAuthorizationService) with rbac.
Protect an order route
import type { IRouterApi } from '@setu-ts/common';
import { requireAuth, requirePermission } from '@setu-ts/auth-plugin';
export function registerOrderRoutes(router: IRouterApi): void {
router.get('/orders', {
middleware: [requireAuth(), requirePermission('orders:read')],
handler: (ctx) => ctx.response.json({ userId: ctx.request.user?.id }),
});
}
Sign after verifying credentials
Configure local.verify to check credentials first.
import { CAPABILITIES } from '@setu-ts/common';
import type { IAuthService, IJwtService } from '@setu-ts/common';
const auth = ctx.services.get<IAuthService>(CAPABILITIES.AUTH);
const principal = await auth.verifyCredentials(await ctx.request.json<{ identifier: string; secret: string }>());
if (principal === null) {
ctx.response.status(401).json({ error: 'Invalid credentials' });
} else {
const jwt = ctx.services.get<IJwtService>(CAPABILITIES.JWT);
const token = await jwt.sign({ sub: principal.id, roles: principal.roles }, { expiresIn: '1h' });
ctx.response.json({ token });
}
Behaviour the types do not show
- Passive authentication defaults to priority 300; put guards on routes.
- Missing principal: 401; denied role/permission: 403; no
rbac: those guards return 501. requireAuth({ signInPage })redirects unauthenticated browser navigations there withreturnTo(except that page itself); APIs keep 401.- Tokens expire at
exp, with no tolerance.localneeds a passive strategy for later requests.
Other options
apiKey,session,issuersandstrategiessupply other passive authentication paths.definePolicyandrequirePolicyevaluate application policies; scoped guards usescopedRbac.signIn.mfaandsignIn.passkeysadd factors;RefreshTokenServiceandrateLimitMiddlewareare standalone helpers.signInwithproviders: []is password-only;signIn.sessionStampreads the user record’s stamp. Changing it ends every session of that user.