-
Notifications
You must be signed in to change notification settings - Fork 3
refactor(middleware): enhance subdomain handling and URL rewriting logic #66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| 'use client' | ||
|
|
||
| import { useParams } from 'next/navigation' | ||
|
|
||
| export default function StorePage() { | ||
| const params = useParams() | ||
| const store = params.store | ||
|
|
||
| return ( | ||
| <div> | ||
| <h1>Tienda: {store}</h1> | ||
| </div> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,6 +8,42 @@ import { handleCollectionOwnershipMiddleware } from './middlewares/ownership/col | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export async function middleware(request: NextRequest) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const path = request.nextUrl.pathname | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hostname = request.headers.get('host') || '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Configuración de dominios | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const isProduction = process.env.NODE_ENV === 'production' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Detectar subdominios | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let subdomain = '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isProduction) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // En producción: verificar si hay un subdominio (ej: tienda.fasttify.com) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const allowedDomains = ['fasttify.com', 'www.fasttify.com']; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const parts = hostname.split('.'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const domain = parts.slice(-2).join('.'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (parts.length > 2 && allowedDomains.includes(domain)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| subdomain = parts[0]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // En desarrollo: usar el formato subdominio.localhost:3000 o localhost:3000 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (hostname.includes('.localhost')) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| subdomain = hostname.split('.')[0] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Si hay un subdominio y estamos en la raíz, reescribir a la ruta de la tienda | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (subdomain && subdomain !== 'www' && path === '/') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Reescribir la URL para mostrar la página de la tienda | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const url = request.nextUrl.clone() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url.pathname = `/${subdomain}` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.rewrite(url) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Si hay un subdominio y la ruta no empieza con el subdominio, agregar el prefijo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (subdomain && subdomain !== 'www' && !path.startsWith(`/${subdomain}`)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const url = request.nextUrl.clone() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url.pathname = `/${subdomain}${path}` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.rewrite(url) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+33
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consolidate URL rewriting logic to eliminate duplication. Both conditional blocks check for subdomain existence and perform similar URL rewriting. This can be simplified into a single block. Apply this diff to consolidate the logic: - // Si hay un subdominio y estamos en la raíz, reescribir a la ruta de la tienda
- if (subdomain && subdomain !== 'www' && path === '/') {
- // Reescribir la URL para mostrar la página de la tienda
- const url = request.nextUrl.clone()
- url.pathname = `/${subdomain}`
- return NextResponse.rewrite(url)
- }
-
- // Si hay un subdominio y la ruta no empieza con el subdominio, agregar el prefijo
- if (subdomain && subdomain !== 'www' && !path.startsWith(`/${subdomain}`)) {
- const url = request.nextUrl.clone()
- url.pathname = `/${subdomain}${path}`
- return NextResponse.rewrite(url)
- }
+ // Reescribir URLs basadas en subdominios
+ if (subdomain && subdomain !== 'www') {
+ const url = request.nextUrl.clone()
+
+ if (path === '/') {
+ // Si estamos en la raíz, reescribir a la ruta de la tienda
+ url.pathname = `/${subdomain}`
+ } else if (!path.startsWith(`/${subdomain}`)) {
+ // Si la ruta no empieza con el subdominio, agregar el prefijo
+ url.pathname = `/${subdomain}${path}`
+ } else {
+ // La ruta ya tiene el prefijo correcto
+ return NextResponse.next()
+ }
+
+ return NextResponse.rewrite(url)
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Verificar propiedad de productos específicos | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -45,12 +81,5 @@ export async function middleware(request: NextRequest) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const config = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matcher: [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '/subscription-success', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '/account-settings', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '/first-steps', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '/my-store', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '/login', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '/store/:path*', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate the hostname to prevent header spoofing.
The hostname is retrieved directly from request headers without validation, which could be manipulated by clients. This poses a security risk as attackers could potentially bypass subdomain-based access controls.
Apply this diff to add hostname validation:
📝 Committable suggestion
🤖 Prompt for AI Agents