fix sidebar menu redirect in production
Build & Deploy / Build & Push Docker Image (push) Successful in 3m15s
Test / Type Check (all packages) (push) Successful in 55s
Build & Deploy / Deploy to VPS (push) Successful in 4s
Test / API Unit Tests (push) Successful in 47s
Test / Homepage Unit Tests (push) Successful in 42s
Test / Carplace Unit Tests (push) Successful in 44s
Test / Admin Unit Tests (push) Successful in 42s
Test / Dashboard Unit Tests (push) Successful in 40s
Test / API Integration Tests (push) Successful in 59s
Build & Deploy / Build & Push Docker Image (push) Successful in 3m15s
Test / Type Check (all packages) (push) Successful in 55s
Build & Deploy / Deploy to VPS (push) Successful in 4s
Test / API Unit Tests (push) Successful in 47s
Test / Homepage Unit Tests (push) Successful in 42s
Test / Carplace Unit Tests (push) Successful in 44s
Test / Admin Unit Tests (push) Successful in 42s
Test / Dashboard Unit Tests (push) Successful in 40s
Test / API Integration Tests (push) Successful in 59s
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { describe, expect, it } from 'vitest'
|
import { describe, expect, it } from 'vitest'
|
||||||
import { resolveDashboardRoutePolicy, roleCanAccessPolicy } from '@/lib/dashboardRoutePolicies'
|
import { resolveDashboardRoutePolicy, roleCanAccessPolicy } from '@/lib/dashboardRoutePolicies'
|
||||||
import { flattenInternalRoutes, getBaselineInternalRoutes, isAllowedRoute, resolveAccessRedirect, resolveAllowedRoutes } from './DashboardAccessGuard'
|
import { buildSignInRedirect, flattenInternalRoutes, getBaselineInternalRoutes, isAllowedRoute, resolveAccessRedirect, resolveAllowedRoutes } from './DashboardAccessGuard'
|
||||||
|
|
||||||
describe('DashboardAccessGuard route helpers', () => {
|
describe('DashboardAccessGuard route helpers', () => {
|
||||||
it('normalizes dashboard-prefixed menu routes before checking access', () => {
|
it('normalizes dashboard-prefixed menu routes before checking access', () => {
|
||||||
@@ -108,6 +108,11 @@ describe('DashboardAccessGuard route helpers', () => {
|
|||||||
expect(resolveAccessRedirect('/fleet/123', ['/', '/fleet'])).toBeNull()
|
expect(resolveAccessRedirect('/fleet/123', ['/', '/fleet'])).toBeNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('builds sign-in redirects with public dashboard return paths', () => {
|
||||||
|
expect(buildSignInRedirect('/reservations')).toBe('/sign-in?redirect=%2Fdashboard%2Freservations')
|
||||||
|
expect(buildSignInRedirect('/dashboard/fleet')).toBe('/sign-in?redirect=%2Fdashboard%2Ffleet')
|
||||||
|
})
|
||||||
|
|
||||||
it('treats subscription as an owner-only recovery route independent of menu registration', () => {
|
it('treats subscription as an owner-only recovery route independent of menu registration', () => {
|
||||||
const policy = resolveDashboardRoutePolicy('/subscription')
|
const policy = resolveDashboardRoutePolicy('/subscription')
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { usePathname, useRouter } from 'next/navigation'
|
import { usePathname, useRouter } from 'next/navigation'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { apiFetch } from '@/lib/api'
|
import { apiFetch } from '@/lib/api'
|
||||||
import { toDashboardAppPath } from '@/lib/dashboardPaths'
|
import { toDashboardAppPath, toPublicDashboardPath } from '@/lib/dashboardPaths'
|
||||||
import {
|
import {
|
||||||
getDashboardFallbackRoute,
|
getDashboardFallbackRoute,
|
||||||
resolveDashboardRoutePolicy,
|
resolveDashboardRoutePolicy,
|
||||||
@@ -90,9 +90,9 @@ export function resolveAccessRedirect(currentPath: string, allowedRoutes: string
|
|||||||
return fallbackRoute === currentPath ? null : fallbackRoute
|
return fallbackRoute === currentPath ? null : fallbackRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSignInRedirect(currentPath: string) {
|
export function buildSignInRedirect(currentPath: string) {
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
params.set('redirect', currentPath)
|
params.set('redirect', toPublicDashboardPath(currentPath))
|
||||||
return `/sign-in?${params.toString()}`
|
return `/sign-in?${params.toString()}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,14 @@ describe('dashboard middleware', () => {
|
|||||||
expect(response).toEqual({ kind: 'redirect', url: 'https://rentaldrivego.example/dashboard/sign-in?redirect=%2Fdashboard%2Fteam' })
|
expect(response).toEqual({ kind: 'redirect', url: 'https://rentaldrivego.example/dashboard/sign-in?redirect=%2Fdashboard%2Fteam' })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('redirects unprefixed internal app paths with a public dashboard return path', async () => {
|
||||||
|
const { default: middleware } = await loadMiddleware('https://rentaldrivego.example')
|
||||||
|
|
||||||
|
const response = middleware(request('http://dashboard:3001/reservations') as never)
|
||||||
|
|
||||||
|
expect(response).toEqual({ kind: 'redirect', url: 'https://rentaldrivego.example/dashboard/sign-in?redirect=%2Fdashboard%2Freservations' })
|
||||||
|
})
|
||||||
|
|
||||||
it('uses trusted forwarded host/proto when building the dashboard sign-in redirect', async () => {
|
it('uses trusted forwarded host/proto when building the dashboard sign-in redirect', async () => {
|
||||||
const { default: middleware } = await loadMiddleware('https://market.example.com')
|
const { default: middleware } = await loadMiddleware('https://market.example.com')
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ function localJwtMiddleware(req: NextRequest): NextResponse {
|
|||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
const signInUrl = resolveProxyUrl(req, toPublicDashboardPath('/sign-in'))
|
const signInUrl = resolveProxyUrl(req, toPublicDashboardPath('/sign-in'))
|
||||||
signInUrl.searchParams.set('redirect', req.nextUrl.pathname)
|
signInUrl.searchParams.set('redirect', toPublicDashboardPath(req.nextUrl.pathname))
|
||||||
return NextResponse.redirect(signInUrl)
|
return NextResponse.redirect(signInUrl)
|
||||||
}
|
}
|
||||||
return NextResponse.next()
|
return NextResponse.next()
|
||||||
|
|||||||
Reference in New Issue
Block a user