Augment Koa.Context automatically for routes with a certain middleware

101 Views Asked by At

I have a web app that I've written using TypeScript and Koa. All requests from the frontend to the backend pass an optional JWT via HTTP headers if, and only if, the user of the web app is signed in. On the backend I have a middleware that looks for and verifies the JWT, if available, and stores the data in an object in Koa.Context. This is solved by augmenting Context the following way:

// context.d.ts

import "koa";

declare module "koa" {
    interface Context {
        account?: {
            accountId: number;
            // more stuff here
        };
    }
}

Then in my routers I have a couple of anonymous routes not requiring any authentication whatsoever, as well as some routes that require authentication. For this I have a simple requireAuthentication middleware:

// middleware.ts

import { Context, Next } from "koa";

export function requireAuthentication() {
    return async (ctx: Context, next: Next) => {
        if (!ctx.account) {
            ctx.status = 401;
            return;
        }

        await next();
    };
}

A couple of routes demonstrating this:

// myRoutes.ts 

class MyRoutes extends KoaRouter {
    public constructor() {
        this.get("/anonymous-route", ctx => this.anonymousRoute(ctx));
        this.get("/authenticated-route", requireAuthentication(), ctx => this.authenticatedRoute(ctx));
    }

    private async anonymousRoute(ctx: Koa.Context) {
        // ctx.account may be undefined here which is fine
    }

    private async authenticatedRoute(ctx: Koa.Context) {
        // ctx.account may be undefined here as well, even though we only reach this if it isn't
    }
}

The problem may be resolved simply by defining a custom context and use it instead of Koa.Context in authenticatedRoute. However, since requireAuthentication already guarantees that ctx.account is distinct from undefined, I'm looking for a way to automatically augment Koa.Context for route handlers that are run after that particular middleware.

Is there a way to achieve this, or am I better of using a custom context type instead of Koa.Context in all of my method declarations?

0

There are 0 best solutions below