diff --git a/package.json b/package.json index e714c33..e2ce7aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@propelauth/cli", - "version": "0.0.2", + "version": "0.0.3", "description": "PropelAuth CLI tool", "homepage": "https://www.propelauth.com", "type": "module", diff --git a/src/commands/setup-nextjs-app-router.ts b/src/commands/setup-nextjs-app-router.ts index 64dbb61..ba806f6 100644 --- a/src/commands/setup-nextjs-app-router.ts +++ b/src/commands/setup-nextjs-app-router.ts @@ -72,10 +72,15 @@ export default async function setupNextJsAppRouter(targetDir: string): Promise= 16 + let middlewareOrProxy = 'proxy' + if (!useProxy) { + middlewareOrProxy = 'middleware' + } + let middlewareContent = await loadTemplateResource('nextjs', `${middlewareOrProxy}.ts`) + let middlewareFilePath = path.join(targetPath, isUsingSrcDir ? `src/${middlewareOrProxy}.ts` : `${middlewareOrProxy}.ts`) + await overwriteFileWithConfirmation(middlewareFilePath, middlewareContent, `${middlewareOrProxy} file`) + log.success(`✓ Created ${middlewareOrProxy}`) await sleep(500) const layoutPath = path.join(appRouterDir, 'layout.tsx') diff --git a/templates/nextjs/proxy.ts b/templates/nextjs/proxy.ts new file mode 100644 index 0000000..a499065 --- /dev/null +++ b/templates/nextjs/proxy.ts @@ -0,0 +1,41 @@ +import { AuthHookResponse, buildAuthMiddleware, UserFromToken } from '@propelauth/nextjs/server' +import { NextRequest, NextResponse } from 'next/server' + +// Note: Before 2025-03-22, Next.js recommended adding authentication and authorization checks in middleware. +// +// At PropelAuth, we're honestly not big fans of Next middleware in general, given how hard it is to compose +// more than one, and quite frankly, relying on a regex matcher for when it runs feels a bit dubious. +// +// The examples in our docs and output from the CLI show how to use functions like +// getUserOrRedirect() in your server components / route handlers to protect your application, +// and that is the approach we typically recommend. +// +// That being said, below we have an example where you could use the `afterAuthHook` to reject requests +// that are unauthenticated. This can be valuable to reject unauthorized requests early in the request, +// but, you should always prefer protecting routes explicitly in your server components / route handlers, +// and reach out at support@propelauth.com with any questions you have! +export const proxy = buildAuthMiddleware({ + afterAuthHook: async (req: NextRequest, res: NextResponse, user?: UserFromToken) => { + if (!user && isProtectedRoute(req.nextUrl.pathname)) { + return AuthHookResponse.reject(new NextResponse(undefined, { status: 401 })) + } else { + return AuthHookResponse.continue() + } + }, +}) + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const isProtectedRoute = (_path: string) => { + // compare with regex or a list, really whatever + return false +} + +export const config = { + matcher: [ + // REQUIRED: Match all request paths that start with /api/auth/ + '/api/auth/(.*)', + // OPTIONAL: Exclude static assets + '/((?!_next/static|_next/image|favicon.ico).*)', + // TODO: Add any other paths that should be protected + ], +}