Skip to content

Auth Helpers

@nomadahq/sm-ui/auth exports worker-side helpers for CF Worker _worker.js files. These run server-side only — never import them in browser/React code.

js
// In _worker.js — CF Worker (server side)
import { verifyJWT, signJWT, requireAuth, generateToken, generateId, getSession } from '@nomadahq/sm-ui/auth'

verifyJWT(token, secret)

Verify and decode a JWT signed with HMAC-SHA256.

js
const payload = await verifyJWT(token, env.SESSION_SECRET)
// Returns decoded payload object, or null if invalid/expired

Returns: Object | null

Checks:

  • HMAC-SHA256 signature validity
  • exp claim — returns null if expired

signJWT(payload, secret)

Sign a payload as a JWT.

js
const jwt = await signJWT({
  id: contact.id,
  email: contact.email,
  name: contact.full_name,
  products: ['studios'],
  iat: Math.floor(Date.now() / 1000),
  exp: Math.floor(Date.now() / 1000) + 7 * 24 * 3600  // 7 days
}, env.SESSION_SECRET)

Returns: string — signed JWT


getSession(request)

Extract the sm_client JWT value from the cookie header.

js
const token = getSession(request)
// Returns the raw JWT string or null if cookie not present

requireAuth(request, env)

Full auth check — extract cookie + verify JWT in one call.

js
const session = await requireAuth(request, env)
if (!session) {
  return new Response(JSON.stringify({ error: 'Unauthorized' }), {
    status: 401,
    headers: { 'Content-Type': 'application/json' }
  })
}
// session.email, session.id, session.products, etc.

env.JWT_SECRET

requireAuth reads env.JWT_SECRET. SM portals use SESSION_SECRET as the env var name. Make sure the env var name matches or pass the correct env object.


generateToken()

Generate a 48-character random token for magic links.

js
const token = generateToken()
// 'k7mxp3r9q2...' (48 chars, alphanumeric)

generateId(prefix)

Generate a prefixed random hex ID.

js
const id = generateId('ct')
// 'ct_a1b2c3d4e5f6g7h8'

Complete Worker Auth Example

js
// _worker.js

import { getSession, verifyJWT, signJWT } from '@nomadahq/sm-ui/auth'

const SESSION_SECRET = env.SESSION_SECRET

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url)

    // Public routes
    if (url.pathname === '/auth/login' || url.pathname.startsWith('/auth/')) {
      return handleAuth(request, env)
    }

    // Protected routes — verify session
    const token = getSession(request)
    if (!token) {
      return Response.redirect('/auth/login?redirect=' + encodeURIComponent(url.pathname))
    }

    const session = await verifyJWT(token, env.SESSION_SECRET)
    if (!session) {
      return Response.redirect('/auth/login')
    }

    // Attach session to request context and serve app
    return env.ASSETS.fetch(request)
  }
}

Sprint Mode LLC — Internal Platform Documentation