Feature/#73 page route feat#74
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (19)
📝 WalkthroughWalkthroughRedirect root to /mockApply, move apply flow to /mockApply and /mockApply/actual (rename route params), rewire imports and navigation, add mockApply home UI and utilities, and introduce cookie-backed auth helpers plus Next.js middleware that redirects unauthenticated requests to /login. ChangesRoute Migration to mockApply Structure
MockApply Home UI & Utilities
Authentication and Middleware
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
jobdri/src/lib/auth.ts (1)
175-199:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd
Secure(and mirror attributes) for the auth access-token cookie; avoid unsafe token parsing assumptions.
saveAuthTokenssetsjobdri_accessTokenwithoutSecure(line 177); this allows the cookie to be sent over non-HTTPS, weakening transport security.clearAuthTokensdeletes the cookie without matching attributes likeSameSite(andSecureif added) (line 198); mirror the same attributes used when setting.getAuthHeadersextracts the cookie value with.split("=")[1](line 260), so an access token containing=would be truncated—don’t introduce encoding without also decoding/adjusting extraction.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@jobdri/src/lib/auth.ts` around lines 175 - 199, saveAuthTokens sets AUTH_COOKIE_KEYS.accessToken without the Secure flag and without encoding, clearAuthTokens removes it without mirroring attributes, and getAuthHeaders uses naive .split("=")[1] which breaks if the token contains "="; fix by (1) when setting in saveAuthTokens include Secure (and existing SameSite=Lax, path=/, max-age) and encode the token (e.g., encodeURIComponent) so cookie storage is safe, (2) in clearAuthTokens delete the cookie using the exact same attributes (SameSite, path, Secure) and max-age=0 to ensure the browser removes the same cookie, and (3) in getAuthHeaders stop using split("=")[1] and instead parse document.cookie to locate AUTH_COOKIE_KEYS.accessToken, then decodeURIComponent the value so tokens with "=" or other characters are handled correctly.
🧹 Nitpick comments (3)
jobdri/src/components/common/input/InputMain.tsx (1)
82-84: ⚡ Quick winFixed height conflicts with existing vertical padding contract.
h-12is being applied on top ofgetWrapperClass’s defaultpy-3, which leaves a very small inner content area. This can make the input feel cramped and risks clipping at larger text scaling.Proposed adjustment
- <div - className={clsx(getWrapperClass(focused, disabled, isError), "h-12")} - > + <div + className={clsx( + getWrapperClass(focused, disabled, isError, undefined, "px-4 py-0"), + "h-12", + )} + >🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@jobdri/src/components/common/input/InputMain.tsx` around lines 82 - 84, The div is forcing a fixed height via the "h-12" utility which conflicts with the wrapper's default vertical padding from getWrapperClass(focused, disabled, isError); remove the hard-coded "h-12" from the className and either use a fluid height (e.g., "h-auto") or a minimum height utility (e.g., "min-h-12" or a px-based min-height) so the wrapper's py-3 has room and text scaling won't clip; update the className string in InputMain.tsx where getWrapperClass(...) is combined with "h-12" to remove/replace that token.jobdri/src/middleware.ts (1)
7-7: ⚡ Quick winExtract token cookie key to a shared constant to avoid drift.
Line 7 hardcodes
"jobdri_accessToken"whilejobdri/src/lib/auth.tsdefinesAUTH_COOKIE_KEYS.accessToken. A shared constants module keeps client and middleware contracts aligned.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@jobdri/src/middleware.ts` at line 7, Replace the hardcoded cookie key in middleware.ts with the shared constant: instead of using the literal "jobdri_accessToken" when calling request.cookies.get (which sets the token variable), import and use AUTH_COOKIE_KEYS.accessToken from jobdri/src/lib/auth.ts so the middleware and auth library share the same key; update the import at the top and change the request.cookies.get call to use AUTH_COOKIE_KEYS.accessToken.jobdri/src/lib/auth.ts (1)
258-261: ⚡ Quick winMake cookie accessToken parsing robust (avoid
split("=")[1]) (jobdri/src/lib/auth.ts, lines 258-261)
getAuthHeaders()currently derives the cookie value with?.split("=")[1], which would truncate if an access token ever contains=. This is probably not an issue today ifaccessTokenis a standard JWT (the file decodes it viasplit(".")and base64url logic elsewhere), but it’s still fragile. Prefer extracting everything afterjobdri_accessToken=(e.g., viaslice(...)) rather than splitting on=. Also, the “264-264” part is just the localStorage fallback, not the parsing bug.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@jobdri/src/lib/auth.ts` around lines 258 - 261, The cookie parsing in getAuthHeaders (variable cookieToken) uses ?.split("=").[1] which breaks if the token contains '='; change it to locate the cookie key string `${AUTH_COOKIE_KEYS.accessToken}=` (e.g., with indexOf or a RegExp) and then slice the cookie string to extract everything after that '=' to the end of the cookie value (not splitting on '='), preserving the full token; update the logic that finds the cookie row (the .find callback and subsequent extraction) to return the sliced substring instead of using .split("=")[1].
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@jobdri/src/app/mockApply/actual/`[mockApplyId]/(jd)/jd-input/JdInputPageClient.tsx:
- Around line 69-71: The route param key is wrong: change useParams<{ id: string
}>() to useParams<{ mockApplyId: string }>() and replace usages of id with
mockApplyId (update the const from useParams and all places building
manualJdReviewPath, session/storage keys and any other paths such as the
occurrences around the current lines 162-166 and 182) so paths like
`/mockApply/actual/${id}/...` and storage keys use the correct mockApplyId
value; ensure useRouter usage remains unchanged and only the param name/type and
all references are updated consistently.
In
`@jobdri/src/app/mockApply/actual/`[mockApplyId]/questions/QuestionsPageClient.tsx:
- Line 24: The navigation call router.push(`/mockApply/actual/${id}/write`)
drops search params so WritePageClient loses the jobPostingId; change the push
to include the existing jobPostingId query (e.g., read jobPostingId from search
params or router.query in QuestionsPageClient and call router.push with an
object that preserves query: pathname `/mockApply/actual/${id}/write` and query:
{ jobPostingId: <existingJobPostingId>, ...otherParams } ) so WritePageClient
still receives jobPostingId.
In `@jobdri/src/app/mockApply/actual/`[mockApplyId]/write/WritePageClient.tsx:
- Line 75: The redirect URL currently uses
`/mockApply/actual/result/${jobPostingId}?sequence=${savedSequence}` but the new
result route contract requires both sequence and totalCount; update the URL in
WritePageClient.tsx (the place building the redirect in the WritePageClient
component/function) to include `&totalCount=${totalCount}` (or the existing
variable that holds the total applies, e.g.,
`savedTotalCount`/`selectedApplyCount`) and ensure that `totalCount` is in
scope/passed into this function so the query becomes
`?sequence=${savedSequence}&totalCount=${totalCount}` when navigating.
In `@jobdri/src/components/mockApply/MockApplicationHomePageClient.tsx`:
- Line 707: The CTA's router.push is pointing to the wrong/missing route; update
the onClick handler in MockApplicationHomePageClient (the router.push call
currently using "/mockApply/mockApply-type") to push the migrated path
"/mockApply/apply-type" so the button navigates to the correct page.
- Around line 221-229: The route normalization only matches "/mockApply/virtual"
so already-migrated paths like "/mockApply/actual/..." are rejected; update the
regex used when computing routeMatch to accept both "virtual" and "actual" (e.g.
use /^\/mockApply\/(?:virtual|actual)\/[^/]+\/([^/?#]+)([?#].*)?$/) so
routeSegment is captured for either form, then keep the existing logic that
checks RESUME_ROUTE_SEGMENTS and returns
`/mockApply/actual/${mockApplyId}/${routeSegment}${routeMatch[2] ?? ""}` using
the same routeMatch indices.
In `@jobdri/src/config/applySteps.ts`:
- Around line 14-19: The step definitions for "자소서 입력" and "결과 확인" use top-level
paths ("/mockApply/write", "/mockApply/result") which no longer match the
migrated pages under "/mockApply/actual/..." and can be mis-resolved by the
current startsWith matching; update those step objects so their path values
point to the migrated routes (e.g. "/mockApply/actual/write" and
"/mockApply/actual/result") or alternatively make the route-matching logic use
exact matching for the step list; locate and update the step array entries for
the labels "자소서 입력" and "결과 확인" in applySteps (the step objects with label and
path) accordingly.
In `@jobdri/src/middleware.ts`:
- Line 10: The public-route check in middleware uses pathname.startsWith(route)
(see isPublic and PUBLIC_ROUTES) which allows prefix bypasses; update the
isPublic logic to only treat a route as public when the pathname equals the
route or the route is a parent segment (i.e., pathname === route OR
pathname.startsWith(route + '/') ), or use a regex like ^route(/|$) to match
exact segment boundaries; ensure this logic handles the root route and preserves
existing PUBLIC_ROUTES values so paths like /login-anything no longer bypass
auth.
- Line 14: middleware.ts currently sets loginUrl.searchParams.set("redirect",
pathname) but the login UI (app/login/page.tsx and
components/login/EmailLoginScreen.tsx) never reads that param; either stop
setting it or wire the login flow to consume it. Option A: remove the
loginUrl.searchParams.set("redirect", ...) call in middleware.ts. Option B:
propagate the original next URL by adding request.nextUrl.search (or the
specific pathname) into the login URL in middleware.ts and update
app/login/page.tsx and components/login/EmailLoginScreen.tsx to read
searchParams.get("redirect") and use it after successful login to
navigate/redirect the user. Ensure consistency by choosing one approach and
updating all three symbols (middleware.ts loginUrl.searchParams.set,
app/login/page.tsx, components/login/EmailLoginScreen.tsx).
---
Outside diff comments:
In `@jobdri/src/lib/auth.ts`:
- Around line 175-199: saveAuthTokens sets AUTH_COOKIE_KEYS.accessToken without
the Secure flag and without encoding, clearAuthTokens removes it without
mirroring attributes, and getAuthHeaders uses naive .split("=")[1] which breaks
if the token contains "="; fix by (1) when setting in saveAuthTokens include
Secure (and existing SameSite=Lax, path=/, max-age) and encode the token (e.g.,
encodeURIComponent) so cookie storage is safe, (2) in clearAuthTokens delete the
cookie using the exact same attributes (SameSite, path, Secure) and max-age=0 to
ensure the browser removes the same cookie, and (3) in getAuthHeaders stop using
split("=")[1] and instead parse document.cookie to locate
AUTH_COOKIE_KEYS.accessToken, then decodeURIComponent the value so tokens with
"=" or other characters are handled correctly.
---
Nitpick comments:
In `@jobdri/src/components/common/input/InputMain.tsx`:
- Around line 82-84: The div is forcing a fixed height via the "h-12" utility
which conflicts with the wrapper's default vertical padding from
getWrapperClass(focused, disabled, isError); remove the hard-coded "h-12" from
the className and either use a fluid height (e.g., "h-auto") or a minimum height
utility (e.g., "min-h-12" or a px-based min-height) so the wrapper's py-3 has
room and text scaling won't clip; update the className string in InputMain.tsx
where getWrapperClass(...) is combined with "h-12" to remove/replace that token.
In `@jobdri/src/lib/auth.ts`:
- Around line 258-261: The cookie parsing in getAuthHeaders (variable
cookieToken) uses ?.split("=").[1] which breaks if the token contains '=';
change it to locate the cookie key string `${AUTH_COOKIE_KEYS.accessToken}=`
(e.g., with indexOf or a RegExp) and then slice the cookie string to extract
everything after that '=' to the end of the cookie value (not splitting on '='),
preserving the full token; update the logic that finds the cookie row (the .find
callback and subsequent extraction) to return the sliced substring instead of
using .split("=")[1].
In `@jobdri/src/middleware.ts`:
- Line 7: Replace the hardcoded cookie key in middleware.ts with the shared
constant: instead of using the literal "jobdri_accessToken" when calling
request.cookies.get (which sets the token variable), import and use
AUTH_COOKIE_KEYS.accessToken from jobdri/src/lib/auth.ts so the middleware and
auth library share the same key; update the import at the top and change the
request.cookies.get call to use AUTH_COOKIE_KEYS.accessToken.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 5f033590-8058-4f4c-bf4c-41c45ae5db08
📒 Files selected for processing (44)
jobdri/src/app/apply/page.tsxjobdri/src/app/mockApply/actual/[mockApplyId]/(jd)/jd-input/JdInputPageClient.tsxjobdri/src/app/mockApply/actual/[mockApplyId]/(jd)/jd-input/page.tsxjobdri/src/app/mockApply/actual/[mockApplyId]/(jd)/jd-review/JdReviewPageClient.tsxjobdri/src/app/mockApply/actual/[mockApplyId]/(jd)/jd-review/page.tsxjobdri/src/app/mockApply/actual/[mockApplyId]/(jd)/page.tsxjobdri/src/app/mockApply/actual/[mockApplyId]/questions/QuestionsPageClient.tsxjobdri/src/app/mockApply/actual/[mockApplyId]/questions/page.tsxjobdri/src/app/mockApply/actual/[mockApplyId]/write/WritePageClient.tsxjobdri/src/app/mockApply/actual/[mockApplyId]/write/page.tsxjobdri/src/app/mockApply/actual/result/[jobPostingId]/ResultPageClient.tsxjobdri/src/app/mockApply/actual/result/[jobPostingId]/page.tsxjobdri/src/app/mockApply/apply-type/ApplyTypePageClient.tsxjobdri/src/app/mockApply/apply-type/page.tsxjobdri/src/app/mockApply/page.tsxjobdri/src/app/page.tsxjobdri/src/components/common/header/Header.tsxjobdri/src/components/common/input/InputMain.tsxjobdri/src/components/common/lnb/Lnb.tsxjobdri/src/components/mockApply/AddQuestion.tsxjobdri/src/components/mockApply/InputSection.tsxjobdri/src/components/mockApply/MockApplicationHomePageClient.tsxjobdri/src/components/mockApply/PageLoading.tsxjobdri/src/components/mockApply/QuestionGenerationLoading.tsxjobdri/src/components/mockApply/ResumeAnalysisLoading.tsxjobdri/src/components/mockApply/SelectQuestion.tsxjobdri/src/components/mockApply/jd/JdReviewMain.tsxjobdri/src/components/mockApply/jd/jdReviewSections.tsjobdri/src/components/mockApply/result/Alret.tsxjobdri/src/components/mockApply/result/ApplyResult.tsxjobdri/src/components/mockApply/result/DetailAnotationPannel.tsxjobdri/src/components/mockApply/result/DetailSection.tsxjobdri/src/components/mockApply/result/OverviewSection.tsxjobdri/src/components/mockApply/result/ScoreCircle.tsxjobdri/src/components/mockApply/result/Sidebar.tsxjobdri/src/components/mockApply/result/SidebarItem.tsxjobdri/src/components/mockApply/result/SummaryCard.tsxjobdri/src/components/mockApply/result/Trybar.tsxjobdri/src/components/mockApply/result/highlightStyles.tsjobdri/src/config/applySteps.tsjobdri/src/constants/routes.tsjobdri/src/hooks/useReApply.tsjobdri/src/lib/auth.tsjobdri/src/middleware.ts
💤 Files with no reviewable changes (1)
- jobdri/src/app/apply/page.tsx
| shouldKeepLoading = true; | ||
| router.push( | ||
| `/apply/virtual/${jobPostingId}/result?sequence=${savedSequence}`, | ||
| `/mockApply/actual/result/${jobPostingId}?sequence=${savedSequence}`, |
There was a problem hiding this comment.
Include totalCount in result URL to match the new contract.
Line 75 only sends sequence, but the migrated result route contract expects ?sequence=N&totalCount=N.
Suggested fix
- router.push(
- `/mockApply/actual/result/${jobPostingId}?sequence=${savedSequence}`,
- );
+ router.push(
+ `/mockApply/actual/result/${jobPostingId}?sequence=${savedSequence}&totalCount=${savedSequence}`,
+ );📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| `/mockApply/actual/result/${jobPostingId}?sequence=${savedSequence}`, | |
| `/mockApply/actual/result/${jobPostingId}?sequence=${savedSequence}&totalCount=${savedSequence}`, |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@jobdri/src/app/mockApply/actual/`[mockApplyId]/write/WritePageClient.tsx at
line 75, The redirect URL currently uses
`/mockApply/actual/result/${jobPostingId}?sequence=${savedSequence}` but the new
result route contract requires both sequence and totalCount; update the URL in
WritePageClient.tsx (the place building the redirect in the WritePageClient
component/function) to include `&totalCount=${totalCount}` (or the existing
variable that holds the total applies, e.g.,
`savedTotalCount`/`selectedApplyCount`) and ensure that `totalCount` is in
scope/passed into this function so the query becomes
`?sequence=${savedSequence}&totalCount=${totalCount}` when navigating.
| /^\/mockApply\/virtual\/[^/]+\/([^/?#]+)([?#].*)?$/, | ||
| ); | ||
| const routeSegment = routeMatch?.[1]; | ||
|
|
||
| if (!routeSegment || !RESUME_ROUTE_SEGMENTS.has(routeSegment)) { | ||
| return ""; | ||
| } | ||
|
|
||
| return `/apply/virtual/${mockApplyId}/${routeSegment}${routeMatch[2] ?? ""}`; | ||
| return `/mockApply/actual/${mockApplyId}/${routeSegment}${routeMatch[2] ?? ""}`; |
There was a problem hiding this comment.
Resume-path normalization only matches /mockApply/virtual, not current /mockApply/actual.
Line 221 rejects already-migrated resumePath values like /mockApply/actual/{id}/jd-review, so resume can fall back to a wrong default route.
Suggested fix
- const routeMatch = path.match(
- /^\/mockApply\/virtual\/[^/]+\/([^/?#]+)([?#].*)?$/,
- );
+ const routeMatch = path.match(
+ /^\/(?:apply\/virtual|mockApply\/virtual|mockApply\/actual)\/[^/]+\/([^/?#]+)([?#].*)?$/,
+ );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@jobdri/src/components/mockApply/MockApplicationHomePageClient.tsx` around
lines 221 - 229, The route normalization only matches "/mockApply/virtual" so
already-migrated paths like "/mockApply/actual/..." are rejected; update the
regex used when computing routeMatch to accept both "virtual" and "actual" (e.g.
use /^\/mockApply\/(?:virtual|actual)\/[^/]+\/([^/?#]+)([?#].*)?$/) so
routeSegment is captured for either form, then keep the existing logic that
checks RESUME_ROUTE_SEGMENTS and returns
`/mockApply/actual/${mockApplyId}/${routeSegment}${routeMatch[2] ?? ""}` using
the same routeMatch indices.
| { label: "유형 선택", path: "/mockApply", exact: true }, | ||
| { label: "공고 생성", path: "/mockApply/job/create" }, | ||
| { label: "공고 확인", path: "/mockApply/job/confirm" }, | ||
| { label: "문항 선택", path: "/mockApply/actual" }, | ||
| { label: "자소서 입력", path: "/mockApply/write" }, | ||
| { label: "결과 확인", path: "/mockApply/result" }, |
There was a problem hiding this comment.
Step-path definitions no longer match migrated dynamic routes.
Line 18-19 still use top-level paths (/mockApply/write, /mockApply/result), but migrated pages are under /mockApply/actual/.... With current startsWith matching, write/result pages can resolve to the wrong step.
Proposed direction
export const APPLY_STEPS: ApplyStep[] = [
{ label: "유형 선택", path: "/mockApply", exact: true },
{ label: "공고 생성", path: "/mockApply/job/create" },
{ label: "공고 확인", path: "/mockApply/job/confirm" },
- { label: "문항 선택", path: "/mockApply/actual" },
- { label: "자소서 입력", path: "/mockApply/write" },
- { label: "결과 확인", path: "/mockApply/result" },
+ // Dynamic-route flow needs segment-aware matching, not only prefix constants.
+ // e.g. /mockApply/actual/:mockApplyId/questions, /write, /result/:jobPostingId
];🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@jobdri/src/config/applySteps.ts` around lines 14 - 19, The step definitions
for "자소서 입력" and "결과 확인" use top-level paths ("/mockApply/write",
"/mockApply/result") which no longer match the migrated pages under
"/mockApply/actual/..." and can be mis-resolved by the current startsWith
matching; update those step objects so their path values point to the migrated
routes (e.g. "/mockApply/actual/write" and "/mockApply/actual/result") or
alternatively make the route-matching logic use exact matching for the step
list; locate and update the step array entries for the labels "자소서 입력" and "결과
확인" in applySteps (the step objects with label and path) accordingly.
| const token = request.cookies.get("jobdri_accessToken")?.value; | ||
| const { pathname } = request.nextUrl; | ||
|
|
||
| const isPublic = PUBLIC_ROUTES.some((route) => pathname.startsWith(route)); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the file and show relevant sections with line numbers
echo "=== middleware.ts (context around line ~10) ==="
nl -ba jobdri/src/middleware.ts | sed -n '1,160p'
echo
echo "=== Find PUBLIC_ROUTES usage/definition ==="
rg -n "PUBLIC_ROUTES" -S jobdri/src || true
echo
echo "=== Find middleware auth/public logic ==="
rg -n "isPublic|startsWith\\(route\\)|pathname|PUBLIC_ROUTES\\.some" -S jobdri/src/middleware.ts || true
echo
echo "=== Inspect other middleware/auth files if referenced ==="
rg -n "middleware" -S jobdri/src | head -n 50Repository: JobDri-Developer/FrontEnd
Length of output: 178
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== middleware.ts (first 200 lines with numbers) ==="
cat -n jobdri/src/middleware.ts | sed -n '1,200p'
echo
echo "=== Find PUBLIC_ROUTES definitions/usages ==="
rg -n "PUBLIC_ROUTES" -S jobdri/src || true
echo
echo "=== Inspect auth/public logic ==="
rg -n "isPublic|startsWith\\(route\\)|pathname|PUBLIC_ROUTES\\.some" -S jobdri/src/middleware.ts || true
echo
echo "=== Find any other middleware usage ==="
rg -n "middleware" -S jobdri/src | head -n 50 || trueRepository: JobDri-Developer/FrontEnd
Length of output: 1624
Fix public-route matching in middleware to avoid prefix-based auth bypass
jobdri/src/middleware.ts uses pathname.startsWith(route), so any path beginning with /login or /oauth2 (e.g. /login-anything, /oauth2token) is treated as public and skips the auth redirect.
Suggested patch
- const isPublic = PUBLIC_ROUTES.some((route) => pathname.startsWith(route));
+ const isPublic = PUBLIC_ROUTES.some(
+ (route) => pathname === route || pathname.startsWith(`${route}/`),
+ );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@jobdri/src/middleware.ts` at line 10, The public-route check in middleware
uses pathname.startsWith(route) (see isPublic and PUBLIC_ROUTES) which allows
prefix bypasses; update the isPublic logic to only treat a route as public when
the pathname equals the route or the route is a parent segment (i.e., pathname
=== route OR pathname.startsWith(route + '/') ), or use a regex like ^route(/|$)
to match exact segment boundaries; ensure this logic handles the root route and
preserves existing PUBLIC_ROUTES values so paths like /login-anything no longer
bypass auth.
|
|
||
| if (!token && !isPublic) { | ||
| const loginUrl = new URL("/login", request.url); | ||
| loginUrl.searchParams.set("redirect", pathname); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Show the relevant middleware code around the reported line
echo "=== middleware.ts (lines near 14) ==="
nl -ba jobdri/src/middleware.ts | sed -n '1,80p'
# 2) Search for where "redirect" is used/read in the codebase
echo
echo "=== occurrences of 'redirect' in jobdri/src ==="
rg -n --hidden --no-ignore-vcs "redirect" jobdri/src || true
# 3) If the login screen exists, inspect it for redirect handling
echo
echo "=== Inspect EmailLoginScreen.tsx (if present) ==="
if [ -f jobdri/src/components/login/EmailLoginScreen.tsx ]; then
nl -ba jobdri/src/components/login/EmailLoginScreen.tsx | sed -n '1,220p'
else
echo "File not found: jobdri/src/components/login/EmailLoginScreen.tsx"
fi
# 4) Search for reading redirect from query params (common patterns)
echo
echo "=== occurrences of nextUrl/searchParams/get('redirect' patterns) ==="
rg -n --hidden --no-ignore-vcs "(searchParams|useSearchParams|query|get\\(\"redirect\"\\)|get\\('redirect'\\)|redirect\\s*[:=]|params\\.|param\\.)" jobdri/src/components/jobdri/src jobdri/src || trueRepository: JobDri-Developer/FrontEnd
Length of output: 168
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Print file with line numbers (without nl)
echo "=== middleware.ts (first 120 lines) ==="
awk '{printf "%6d\t%s\n", NR, $0}' jobdri/src/middleware.ts | sed -n '1,120p'
echo
echo "=== occurrences of 'redirect' in jobdri/src ==="
rg -n --hidden --no-ignore-vcs "redirect" jobdri/src || true
echo
echo "=== EmailLoginScreen.tsx (if present) ==="
if [ -f jobdri/src/components/login/EmailLoginScreen.tsx ]; then
awk '{printf "%6d\t%s\n", NR, $0}' jobdri/src/components/login/EmailLoginScreen.tsx | sed -n '1,260p'
else
echo "File not found: jobdri/src/components/login/EmailLoginScreen.tsx"
fi
echo
echo "=== occurrences of reading redirect from query/search params ==="
rg -n --hidden --no-ignore-vcs \
"searchParams\.get\\(\"redirect\"\\)|searchParams\.get\\('redirect'\\)|useSearchParams\\(|nextUrl\\.(search|toString)|get\\(\"redirect\"\\)|get\\('redirect'\\)" \
jobdri/src || trueRepository: JobDri-Developer/FrontEnd
Length of output: 11662
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Files under src/app related to login ==="
fd -t f "login" jobdri/src/app jobdri/src/components jobdri/src || true
echo
echo "=== occurrences of searchParams.get('redirect') / redirect param access ==="
rg -n --hidden --no-ignore-vcs "searchParams\.get\(\"redirect\"\)|searchParams\.get\('redirect'\)|useSearchParams\(\).*redirect|URLSearchParams\(.+redirect|new URL\\(.+redirect|\\bredirect\\b.*searchParams" jobdri/src || true
echo
echo "=== occurrences of 'redirect=' in strings/URLs ==="
rg -n --hidden --no-ignore-vcs "redirect=" jobdri/src || true
echo
echo "=== Inspect /login route entrypoint(s) ==="
# Try common locations; if they don't exist, the rg below will still help.
for f in \
jobdri/src/app/login/page.tsx \
jobdri/src/app/login/layout.tsx \
jobdri/src/app/login/page.jsx \
jobdri/src/app/login/page.ts \
jobdri/src/app/login/route.ts \
jobdri/src/app/(.*)/login/page.tsx \
; do
if [ -f "$f" ]; then
echo "--- $f ---"
awk '{printf "%6d\t%s\n", NR, $0}' "$f" | sed -n '1,220p'
fi
done
# Broader: show any route files whose path includes login
echo
echo "=== route files mentioning '/login' ==="
rg -n --hidden --no-ignore-vcs '"/login"|\'/login\'|PUBLIC_ROUTES|router\.push\(.*login|ROUTES\.LOGIN|app/login' jobdri/src/app jobdri/src/components jobdri/src/constants jobdri/src/lib || trueRepository: JobDri-Developer/FrontEnd
Length of output: 466
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Find login route files/dirs under src/app ==="
# List files whose path contains /login or login in name (case-insensitive)
fd -t f -i "login" jobdri/src/app || true
echo
find jobdri/src/app -maxdepth 6 -type f \( -iname "*login*" \) 2>/dev/null || true
echo
echo "=== List all page.tsx/route.tsx under app/login (if directory exists) ==="
if [ -d jobdri/src/app/login ]; then
fd -t f "page.tsx" jobdri/src/app/login || true
fd -t f "route.ts" jobdri/src/app/login || true
fd -t f -i "login" jobdri/src/app/login || true
else
echo "jobdri/src/app/login does not exist"
fi
echo
echo "=== Find where EmailLoginScreen is used ==="
rg -n --hidden --no-ignore-vcs "EmailLoginScreen" jobdri/src || true
echo
echo "=== Inspect constants/routes.ts (for login route constant) ==="
if [ -f jobdri/src/constants/routes.ts ]; then
awk '{printf "%6d\t%s\n", NR, $0}' jobdri/src/constants/routes.ts | sed -n '1,120p'
fi
echo
echo "=== Search for useSearchParams on login-related files ==="
# Look for searchParams usage in any file with "login" in path
rg -n --hidden --no-ignore-vcs "useSearchParams\\(|searchParams\\.get\\(" jobdri/src/components/login jobdri/src/app || true
echo
echo "=== Search for any code reading the 'redirect' query param in all files ==="
rg -n --hidden --no-ignore-vcs "(\"redirect\"|'redirect')\\s*[,)]" jobdri/src/app jobdri/src/components jobdri/src/lib || trueRepository: JobDri-Developer/FrontEnd
Length of output: 3130
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== app/login/page.tsx ==="
awk '{printf "%6d\t%s\n", NR, $0}' jobdri/src/app/login/page.tsx | sed -n '1,120p'
echo
echo "=== Search within EmailLoginScreen.tsx for redirect/search param handling ==="
rg -n --hidden --no-ignore-vcs "(redirect|searchParams|useSearchParams|query\\.|router\\.query)" jobdri/src/components/login/EmailLoginScreen.tsx || true
echo
echo "=== Search within login components for redirect ==="
rg -n --hidden --no-ignore-vcs "redirect" jobdri/src/components/login || true
echo
echo "=== Search within src for redirect= usage in routing to login ==="
rg -n --hidden --no-ignore-vcs "redirect.*ROUTES\\.LOGIN|ROUTES\\.LOGIN.*redirect|/login\\?redirect|\\?redirect=" jobdri/src || trueRepository: JobDri-Developer/FrontEnd
Length of output: 457
Avoid/adjust redirect query-string fix: /login?redirect=... is not consumed in this codebase.
middleware.ts sets loginUrl.searchParams.set("redirect", pathname), but app/login/page.tsx and components/login/EmailLoginScreen.tsx never read a redirect query param (no redirect/searchParams.get("redirect") usages found). Either wire the login flow to use redirect (and then include request.nextUrl.search) or remove/stop setting it.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@jobdri/src/middleware.ts` at line 14, middleware.ts currently sets
loginUrl.searchParams.set("redirect", pathname) but the login UI
(app/login/page.tsx and components/login/EmailLoginScreen.tsx) never reads that
param; either stop setting it or wire the login flow to consume it. Option A:
remove the loginUrl.searchParams.set("redirect", ...) call in middleware.ts.
Option B: propagate the original next URL by adding request.nextUrl.search (or
the specific pathname) into the login URL in middleware.ts and update
app/login/page.tsx and components/login/EmailLoginScreen.tsx to read
searchParams.get("redirect") and use it after successful login to
navigate/redirect the user. Ensure consistency by choosing one approach and
updating all three symbols (middleware.ts loginUrl.searchParams.set,
app/login/page.tsx, components/login/EmailLoginScreen.tsx).
minnngo
left a comment
There was a problem hiding this comment.
충돌 있는거만 해결하면 될듯?? 수고했어요~~👍👍
- JdInputPageClient useParams 키 mockApplyId로 수정 - QuestionsPageClient jobPostingId 폴백 로직 + 새 경로 적용 - MockApplicationHomePageClient develop 리팩토링 버전 반영 (home/ 서브 컴포넌트) - mock-application/home/ → mockApply/home/ 이동 및 경로 전체 업데이트 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🔗 관련 이슈
#73
📝 개요
⌨️ 작업 상세 내용
라우팅 구조 개편
/apply/virtual/[id]/...→/mockApply/actual/[mockApplyId]/...[id]→[jobPostingId]로 명확화/mockApply/actual/result/[jobPostingId]?sequence=N&totalCount=NmockApplyId기반에서jobPostingId + sequence기반으로 변경GET /api/job-postings/{jobPostingId}/analysis?sequence=NapplyId직접 조회 대신totalCountprop을 받아 렌더링하도록 변경폴더 구조 정리
src/components/apply/→src/components/mockApply/src/components/mock-application/→src/components/mockApply/src/app/apply/→src/app/mockApply/로그인 방어 로직
localStorage외cookie에도 저장middleware.ts추가 — 비인증 사용자 접근 시/login?redirect=로 리다이렉트버그 수정 / 소소한 개선
MockApplicationHomePageClienthydration 에러 수정InputMainheight 고정 (h-12)💡 코드 설명 및 참고사항
📸 스크린샷 (UI 변경 시)
🔍 리뷰 요구사항 (Reviewers)
테스트 체크리스트
/mockApply/actual/result/{jobPostingId})로 정상 이동하는지Summary by CodeRabbit
New Features
Bug Fixes
Refactor