npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@outloud/adonis-auth

v1.0.0

Published

Session and access token guards for AdonisJS 7.

Readme

AdonisJS Auth

Session and access token guards for AdonisJS 7, built on top of @adonisjs/auth.

typescript-image npm-image npm-download-image license-image


Features

  • Database backed sessions with per-platform sliding expiry, sent as a cookie or a bearer token.
  • Access tokens with static or per-row prefixes.
  • Tokens are checksummed, so tokens with a typo are rejected without a DB lookup.
  • Generic TokenService for one-time tokens (password resets, invitations, ...).
  • Middleware for auth, guest, silent auth and guard restriction.

Getting Started

Install the package and make sure @adonisjs/auth and @adonisjs/lucid are configured.

npm i @outloud/adonis-auth

Tokens

Tokens are stored as a sha256 hash, the plain value is available only right after creation. Token models must have id (uuid), hash, createdAt, updatedAt and optional expiresAt columns.

The token value has the format <prefix>_<id>.<secret><checksum>, the prefix is optional.

import { Secret } from '@adonisjs/core/helpers'
import { TokenService } from '@outloud/adonis-auth'
import PasswordReset from '#models/password_reset'

const tokens = new TokenService(PasswordReset, { prefix: 'pr' })

const { token, row } = await tokens.create({ userId: user.id, expiresAt })
token.value?.release() // plain token, send it to the user

const result = await tokens.verify(new Secret(value)) // { token, row } | null

// verify, run the callback and delete the token, throws errors.E_INVALID_TOKEN when invalid
await tokens.consume(new Secret(value), async (row) => {})

Options:

  • prefix - static prefix, or a function resolving it from the row.
  • secretLength - length of the random secret, defaults to 16.
  • query - modify the lookup query, e.g. to preload relations.
  • validate - additional validation of a verified token.

Guards

Session guard

Sessions are stored in a database table. Each session belongs to a platform, which defines its lifetime:

  • age - idle lifetime, extended on every use.
  • maxAge - absolute lifetime counted from session creation.

The session model must implement SessionContract: platform, data (json), userAgent, ipAddress, lastActivityAt and expiresAt columns on top of the token columns.

// config/auth.ts
import { defineConfig } from '@adonisjs/auth'
import { sessionGuard, sessionUserProvider } from '@outloud/adonis-auth/guards/session'

const authConfig = defineConfig({
  default: 'session',
  guards: {
    session: sessionGuard({
      cookie: {
        name: 'app.session',
        path: '/',
        httpOnly: true,
        sameSite: 'lax',
      },
      platforms: {
        web: { age: '7d', maxAge: '30d' },
        ios: { age: '30d', maxAge: '365d' },
      },
      provider: sessionUserProvider({
        model: () => import('#models/user'),
        session: () => import('#models/session'),
        foreignKey: 'userId',
        prefix: 'ses',
      }),
    }),
  },
})

Login creates a session. With cookie transport (default) the session cookie is set, with header transport the token is returned and the client sends it as a bearer token.

const { token } = await auth.use('session').login(user, { platform: 'web', transport: 'header' })

The current session is available as auth.session. Changes to auth.session.data are persisted at the end of the request by the silent auth middleware, or manually using auth.use('session').commit().

Expired sessions are deleted in the background, at most once per 10 minutes per process.

Access token guard

// config/auth.ts
import { defineConfig } from '@adonisjs/auth'
import { accessTokenGuard, accessTokenUserProvider } from '@outloud/adonis-auth/guards/access_token'

const authConfig = defineConfig({
  default: 'api',
  guards: {
    api: accessTokenGuard({
      provider: accessTokenUserProvider({
        model: () => import('#models/user'),
        token: () => import('#models/access_token'),
        foreignKey: 'userId',
        prefix: 'tok',
      }),
    }),
  },
})

The current token is available as auth.accessToken. When the token model has a lastActivityAt column, it is updated at most once per minute.

Middleware

Register the middleware in start/kernel.ts.

router.use([
  () => import('@adonisjs/auth/initialize_auth_middleware'),
  () => import('@outloud/adonis-auth/middleware/silent_auth'),
])

export const middleware = router.named({
  guest: () => import('@outloud/adonis-auth/middleware/guest'),
  auth: () => import('@outloud/adonis-auth/middleware/auth'),
  guard: () => import('@outloud/adonis-auth/middleware/guard'),
})
  • silent_auth - attempts to authenticate the request without failing it, commits guard changes (e.g. session data) once the request is handled.
  • auth - denies the request unless it is authenticated by one of the guards.
  • guest - denies the request when it is authenticated, throws errors.E_GUEST_ACCESS.
  • guard - denies the request unless it was authenticated by one of the given guards, throws errors.E_GUARD_REQUIRED with code E_<GUARD>_REQUIRED for a single guard.

auth, guest and silent_auth use all configured guards unless specified.

router.post('/account/delete', handler).use([middleware.auth(), middleware.guard(['session'])])