Skip to content

Instantly share code, notes, and snippets.

@finom
Last active June 20, 2023 11:23
Show Gist options
  • Save finom/d9c0fe6497148f8f81a0f7c83294d214 to your computer and use it in GitHub Desktop.
Save finom/d9c0fe6497148f8f81a0f7c83294d214 to your computer and use it in GitHub Desktop.
A beautiful way to add NestJS decorator vibes for NextJS app API route to check for authorisation or anything else
import { NextRequest, NextResponse } from 'next/server';
import { checkAuth } from './checkAuth'; // define it by yourself
const httpMethods = ['GET', 'POST', 'PUT', 'DELETE'] as const;
type MethodMap<T> = { GET?: T; POST?: T; PUT?: T; DELETE?: T };
export default function authGuard(options?: MethodMap<boolean>) {
return function AuthGuard(given: Function) {
const ctr = given as Omit<Function, 'prototype'> & {
prototype: MethodMap<(req: NextRequest) => NextResponse | Promise<NextResponse>>;
};
for (const method of httpMethods) {
if (options && options?.[method] === false) {
continue;
}
const originalMethod = ctr.prototype[method];
if (originalMethod) {
ctr.prototype[method] = function (req: NextRequest) {
if (!(await checkAuth(req))) return new NextResponse('Unauthorised', { status: 401 });
return originalMethod.call(this, req);
};
}
}
};
}
// app/api/.../route.ts
import { NextRequest, NextResponse } from 'next/server';
import authGuard from './authGuard';
// define your class with HTTP methods and authGuard decorator
@authGuard({ GET: false }) // disable auth check for GET HTTP method
class Route {
#hello = 'World';
GET = (req: NextRequest) => {
return NextResponse.json({ hello: 'World 1' });
};
POST = (req: NextRequest) => {
return NextResponse.json({ hello: this.#hello });
};
}
// export your HTTP methods
export const { GET, POST } = new Route();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment