Skip to content

feat: Express/Fastify/Koa middleware for route-level email verification #9

Description

@mdesoto

Context

Most developers will use BurnerGuard in a web signup route. Today, they need to manually wire up verify() in their handler. A one-liner middleware that rejects disposable emails before the handler runs would be a significant adoption driver — it meets developers exactly where they are.

Proposed API

Express

import {BurnerGuard} from '@quarg/burnerguard';
import {createMiddleware} from '@quarg/burnerguard/express';

const guard = await BurnerGuard.create();

app.post('/signup', createMiddleware(guard, {field: 'email'}), (req, res) => {
    // Only reached if the email passed verification
});

Fastify

import {createPlugin} from '@quarg/burnerguard/fastify';

fastify.register(createPlugin(guard, {field: 'email'}));

Configuration

createMiddleware(guard, {
    field: 'email',                          // request body field to check
    source: 'body',                          // 'body' | 'query' | 'params' (default: 'body')
    onMatch: (req, res, result) => {         // custom rejection handler
        res.status(422).json({
            error: 'Disposable email addresses are not allowed',
            domain: result.domain
        });
    },
    statusCode: 422,                         // default rejection status (if no custom handler)
    message: 'Disposable email not allowed'  // default rejection message
});

Design decisions

  • Separate entry points (@quarg/burnerguard/express, @quarg/burnerguard/fastify) to avoid pulling Express types into non-Express projects
  • Framework types as peer dependencies — @types/express etc. should be peerDependencies, not dependencies
  • Zero new runtime dependencies — middleware is just a thin wrapper around guard.verify()
  • Guard instance passed in, not created internally — the developer controls initialization and can reuse across routes

Open questions

  • Should middleware be in the core package (@quarg/burnerguard/express) or separate packages (@quarg/burnerguard-express)?
  • Should there be a generic/framework-agnostic middleware factory that works with any (req, res, next) pattern?
  • Should Koa get its own adapter or is a generic one sufficient?

Acceptance criteria

  • Express middleware with configurable field extraction and rejection behavior
  • Fastify plugin equivalent
  • Custom rejection handler support
  • Framework types as peer dependencies only
  • Tests for each framework adapter
  • README section with framework integration examples

Priority: 🔴 High — biggest adoption lever, meets developers where they are

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions