Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
13 changes: 9 additions & 4 deletions src/commands/setup-nextjs-app-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,15 @@ export default async function setupNextJsAppRouter(targetDir: string): Promise<v
log.success(`✓ Created authentication routes`)
await sleep(500)

const middlewareContent = await loadTemplateResource('nextjs', 'middleware.ts')
const middlewareFilePath = path.join(targetPath, isUsingSrcDir ? 'src/middleware.ts' : 'middleware.ts')
await overwriteFileWithConfirmation(middlewareFilePath, middlewareContent, 'Middleware file')
log.success('✓ Created middleware')
const useProxy = nextMajor >= 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')
Expand Down
41 changes: 41 additions & 0 deletions templates/nextjs/proxy.ts
Original file line number Diff line number Diff line change
@@ -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
],
}