Skip to content

Comments

refactor: simplify session casting and improve type safety in MyMento…#3505

Merged
arkid15r merged 4 commits intoOWASP:mainfrom
ThetaLogN:refactor/mentorship-session-fix
Jan 24, 2026
Merged

refactor: simplify session casting and improve type safety in MyMento…#3505
arkid15r merged 4 commits intoOWASP:mainfrom
ThetaLogN:refactor/mentorship-session-fix

Conversation

@ThetaLogN
Copy link
Contributor

Resolves #3501

This is the resolution:
https://sonarcloud.io/project/issues?open=AZihbH8RrMCFFhRwcFZN&id=OWASP_Nest

Checklist

  • Required: I followed the contributing workflow
  • Required: I verified that my code works as intended and resolves the issue as described
  • Required: I ran make check-test locally: all warnings addressed, tests passed
  • I used AI for code, documentation, tests, or communication related to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 23, 2026

Summary by CodeRabbit

  • Refactor
    • Improved session handling on the mentorship page for safer, clearer access to user properties (including name, email, and avatar).
    • Streamlined loading checks to rely on the derived user identifier, reducing intermittent loading noise.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Replaces direct session type assertions in MyMentorshipPage with a typed extendedSession variable and optional chaining for user.login and user.isLeader; relocates email and image fields within ExtendedSession.user type declarations.

Changes

Cohort / File(s) Summary
Session type assertion refactor
frontend/src/app/my/mentorship/page.tsx
Introduces extendedSession typed wrapper; replaces (session as ExtendedSession)?... casts with extendedSession?.user?...; extracts userName variable and updates loading gate to check !userName.
Session type shape update
frontend/src/types/auth.ts
Moves email?: string and image?: string into ExtendedSession.user earlier in the type, removing duplicate declarations and adjusting field order.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • kasya
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: refactoring session casting and improving type safety in the MyMentorship page component.
Description check ✅ Passed The description appropriately references the linked issue (#3501), provides the SonarCloud reference, and documents the completion of required checks.
Linked Issues check ✅ Passed The code changes directly address issue #3501 by removing redundant session type assertions through the introduction of extendedSession wrapper and eliminating type casting.
Out of Scope Changes check ✅ Passed All changes are scoped to addressing the type assertion refactoring in MyMentorshipPage and the related ExtendedSession type definition, with no unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 23, 2026
@arkid15r arkid15r enabled auto-merge January 24, 2026 00:58
@codecov
Copy link

codecov bot commented Jan 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.57%. Comparing base (11a1f63) to head (5777a8b).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #3505   +/-   ##
=======================================
  Coverage   85.56%   85.57%           
=======================================
  Files         461      461           
  Lines       14227    14228    +1     
  Branches     1895     1895           
=======================================
+ Hits        12174    12175    +1     
  Misses       1680     1680           
  Partials      373      373           
Flag Coverage Δ
backend 84.47% <ø> (ø)
frontend 88.62% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
frontend/src/app/my/mentorship/page.tsx 81.03% <100.00%> (+0.33%) ⬆️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 11a1f63...5777a8b. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@frontend/src/app/my/mentorship/page.tsx`:
- Around line 86-88: The current loading gate uses only userName which conflates
a true loading state with unauthenticated users; update the component to
destructure status from useSession() (const { data: session, status } =
useSession()), stop using the single check if (!userName) to show
<LoadingSpinner />, and instead explicitly handle status === 'loading' (show
LoadingSpinner), status === 'unauthenticated' (perform a redirect to login or
render a clear unauthenticated message), and status === 'authenticated' (render
the normal UI using session/userName); adjust references to userName and
LoadingSpinner accordingly so unauthenticated users don’t see an indefinite
spinner.

Comment on lines +86 to 88
if (!userName) {
return <LoadingSpinner />
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for middleware files in the frontend app
echo "=== Looking for middleware files ==="
find frontend -name 'middleware.ts' -o -name 'middleware.js' 2>/dev/null

echo ""
echo "=== Checking root-level middleware ==="
find . -maxdepth 2 -name 'middleware.ts' -o -name 'middleware.js' 2>/dev/null | head -20

echo ""
echo "=== Directory structure of /my/ routes ==="
fd -t d 'my' frontend/src/app/ 2>/dev/null

echo ""
echo "=== Files in /my/ directory ==="
fd -t f frontend/src/app/my/ 2>/dev/null | head -20

Repository: OWASP/Nest

Length of output: 228


🏁 Script executed:

#!/bin/bash
# Check the actual page file to see the full implementation
echo "=== Content of frontend/src/app/my/mentorship/page.tsx ==="
cat -n frontend/src/app/my/mentorship/page.tsx | head -100

echo ""
echo "=== Checking for useSession and status usage in the file ==="
rg -n "useSession|status|redirect|authenticated" frontend/src/app/my/mentorship/page.tsx

Repository: OWASP/Nest

Length of output: 4325


🏁 Script executed:

#!/bin/bash
# Check how other /my/ pages handle authentication
echo "=== Looking for other pages in /my/ directory ==="
fd -t f '.tsx$' frontend/src/app/my/ --exec basename {} \; | sort -u

echo ""
echo "=== Checking auth patterns in other /my/ pages ==="
fd -t f '.tsx$' frontend/src/app/my/ -exec sh -c 'echo "=== {} ===" && grep -n "useSession\|status\|redirect\|LoadingSpinner" {} | head -15' \;

Repository: OWASP/Nest

Length of output: 397


🏁 Script executed:

#!/bin/bash
# Check if there's a layout file that might handle auth at the route level
echo "=== Checking for layout files in /my/ routes ==="
fd -t f 'layout.tsx' frontend/src/app/my/

echo ""
echo "=== Examining /my/ layout if it exists ==="
if [ -f "frontend/src/app/my/layout.tsx" ]; then
  cat -n frontend/src/app/my/layout.tsx
fi

if [ -f "frontend/src/app/my/mentorship/layout.tsx" ]; then
  echo "=== Examining /my/mentorship/ layout if it exists ==="
  cat -n frontend/src/app/my/mentorship/layout.tsx
fi

Repository: OWASP/Nest

Length of output: 146


Fix unauthenticated user handling with proper session status check.

Currently, the loading gate !userName cannot distinguish between the loading state (session data still loading) and the unauthenticated state (user not logged in). Since there's no middleware or layout-level route protection for /my/* routes, an unauthenticated user will see the spinner indefinitely.

Verify the session loading state by including status from useSession():

const { data: session, status } = useSession()

Then handle all three states explicitly: loading, unauthenticated, and authenticated. For the unauthenticated case, redirect to login or show an appropriate message instead of displaying the spinner.

🤖 Prompt for AI Agents
In `@frontend/src/app/my/mentorship/page.tsx` around lines 86 - 88, The current
loading gate uses only userName which conflates a true loading state with
unauthenticated users; update the component to destructure status from
useSession() (const { data: session, status } = useSession()), stop using the
single check if (!userName) to show <LoadingSpinner />, and instead explicitly
handle status === 'loading' (show LoadingSpinner), status === 'unauthenticated'
(perform a redirect to login or render a clear unauthenticated message), and
status === 'authenticated' (render the normal UI using session/userName); adjust
references to userName and LoadingSpinner accordingly so unauthenticated users
don’t see an indefinite spinner.

@sonarqubecloud
Copy link

coderabbitai[bot]
coderabbitai bot previously requested changes Jan 24, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@frontend/src/types/auth.ts`:
- Around line 10-14: The intersection on the user type is narrowing next-auth's
nullability for email and image; update the inline overrides in the user?:
Session['user'] & { ... } declaration so that email and image preserve
next-auth's possible null (e.g., use email?: string | null and image?: string |
null) or remove those re-declarations entirely and only add non-conflicting
fields like isLeader?: boolean, ensuring you keep the type name Session['user']
to locate the declaration.

Comment on lines 10 to 14
user?: Session['user'] & {
email?: string
expires?: string
image?: string
isLeader?: boolean
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n frontend/src/types/auth.ts

Repository: OWASP/Nest

Length of output: 576


🌐 Web query:

next-auth v4.24.13 Session user email image type definitions TypeScript

💡 Result:

In next-auth v4.24.x (including v4.24.13), the default TypeScript types already define the session’s user as having (optional) name, email, and image:

  • User includes: name?: string | null, email?: string | null, image?: string | null (and id: string). [1]
  • To keep those defaults when you extend Session.user, intersect with DefaultSession["user"]. [2]

Create a declaration file (e.g. types/next-auth.d.ts) and add:

import NextAuth, { DefaultSession } from "next-auth"

declare module "next-auth" {
  interface Session {
    user: {
      // your custom fields here, e.g. id: string
    } & DefaultSession["user"] // keeps name/email/image types
  }
}

This ensures session.user.email and session.user.image are typed as string | null | undefined (unless you further narrow them in your own app). [2]

Sources:
[1] next-auth v4.24.x docs “Types” (User/email/image)
[2] NextAuth.js TypeScript docs (module augmentation + DefaultSession["user"])


🏁 Script executed:

rg "session\.user\.email|session\.user\.image" --type ts --type tsx -A 2 -B 2

Repository: OWASP/Nest

Length of output: 81


🏁 Script executed:

rg "ExtendedSession" --type ts --type tsx -A 3 | head -100

Repository: OWASP/Nest

Length of output: 81


🏁 Script executed:

rg "session\.user\.email|session\.user\.image" -A 2 -B 2

Repository: OWASP/Nest

Length of output: 36


🏁 Script executed:

rg "ExtendedSession" -A 3 | head -150

Repository: OWASP/Nest

Length of output: 10757


🏁 Script executed:

fd "\.(ts|tsx)$" frontend/src --type f | head -20

Repository: OWASP/Nest

Length of output: 933


🏁 Script executed:

rg "email" frontend/src --type-add 'ts:*.{ts,tsx}' -t ts | grep -i "session\|user\|email" | head -40

Repository: OWASP/Nest

Length of output: 20371


🏁 Script executed:

rg "\.image" frontend/src --type-add 'ts:*.{ts,tsx}' -t ts | head -40

Repository: OWASP/Nest

Length of output: 320


🏁 Script executed:

cat frontend/src/components/UserMenu.tsx | head -80

Repository: OWASP/Nest

Length of output: 2804


🏁 Script executed:

rg "session\.user\." frontend/src/components/UserMenu.tsx -B 2 -A 2

Repository: OWASP/Nest

Length of output: 36


Avoid narrowing email/image nullability from next-auth.

In next-auth v4.24.13, Session['user'] defines email and image as string | null. Redeclaring them as optional strings in the intersection intersects and narrows the type, removing null from the union. This masks the actual nullability from next-auth and can lead to unsafe assumptions about these fields.

🛠️ Proposed fix
   user?: Session['user'] & {
-    email?: string
+    email?: Session['user']['email']
     expires?: string
-    image?: string
+    image?: Session['user']['image']
     isLeader?: boolean
📝 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.

Suggested change
user?: Session['user'] & {
email?: string
expires?: string
image?: string
isLeader?: boolean
user?: Session['user'] & {
email?: Session['user']['email']
expires?: string
image?: Session['user']['image']
isLeader?: boolean
🤖 Prompt for AI Agents
In `@frontend/src/types/auth.ts` around lines 10 - 14, The intersection on the
user type is narrowing next-auth's nullability for email and image; update the
inline overrides in the user?: Session['user'] & { ... } declaration so that
email and image preserve next-auth's possible null (e.g., use email?: string |
null and image?: string | null) or remove those re-declarations entirely and
only add non-conflicting fields like isLeader?: boolean, ensuring you keep the
type name Session['user'] to locate the declaration.

@arkid15r arkid15r dismissed coderabbitai[bot]’s stale review January 24, 2026 01:49

will revisit it later

@arkid15r arkid15r added this pull request to the merge queue Jan 24, 2026
Merged via the queue into OWASP:main with commit 181b704 Jan 24, 2026
36 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor: remove redundant session type assertions in MyMentorshipPage

2 participants