Skip to content

Improve bit Boilerplate identity (#12792) - #12793

Merged
yasmoradi merged 2 commits into
bitfoundation:developfrom
yasmoradi:12792
Jul 31, 2026
Merged

Improve bit Boilerplate identity (#12792)#12793
yasmoradi merged 2 commits into
bitfoundation:developfrom
yasmoradi:12792

Conversation

@yasmoradi

@yasmoradi yasmoradi commented Jul 31, 2026

Copy link
Copy Markdown
Member

closes #12792

Summary by CodeRabbit

  • Security & Reliability
    • Hardened authentication, confirmation, reset-password, and redirect flows against unsafe return URLs.
    • Improved handling of expired, reused, missing, or invalid confirmation tokens.
    • Prevented incomplete authentication state when two-factor verification is required.
    • Added validation for external sign-in ports and phone numbers with clearer localized errors.
  • Bug Fixes
    • Improved external provider setup and duplicate account-link handling.
  • Tests
    • Added coverage for return-url safety, token reuse, two-factor confirmation, phone validation, and sign-in behavior.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dc6282b5-cabe-4801-a40f-d8a8396a19ef

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The boilerplate identity flows now validate return URLs, handle missing or replayed tokens, support two-factor confirmation safely, localize phone parsing errors, adjust external authentication configuration, and add integration and UI tests.

Changes

Identity hardening

Layer / File(s) Summary
Safe return URL validation and propagation
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Infrastructure/Extensions/UriExtensions.cs, src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Identity/..., src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Features/Identity/IdentityController.*, src/Templates/Boilerplate/Bit.Boilerplate/src/Tests/Features/Identity/ReturnUrlHardeningTests.cs
Return URLs now accept only valid app-relative forms. Unsafe values use PageUrls.Home across sign-in, confirmation, authorization, and password-reset flows.
Confirmation, token, and phone error handling
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Identity/ConfirmPage.razor.cs, src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Features/Identity/..., src/Templates/Boilerplate/Bit.Boilerplate/src/Tests/Features/Identity/*
Two-factor confirmation avoids storing incomplete tokens. Missing token timestamps are expired. Phone parsing failures become localized bad requests. Tests cover these flows and asynchronous UI assertions.
External authentication configuration and association
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Features/Identity/IdentityController.ExternalSignIn.cs, src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Features/Identity/Services/RemoteAuthenticationOptionsConfigurator.cs
External sign-in validates local ports and reports failed login association. OpenID Connect and Apple use early configuration; OAuth providers remain post-configured.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ConfirmPage
  participant IdentityController
  participant IdentityStore
  ConfirmPage->>IdentityController: Confirm email or phone token
  IdentityController->>IdentityStore: Confirm contact
  IdentityStore-->>IdentityController: two-factor-required or success
  IdentityController-->>ConfirmPage: confirmation result
  ConfirmPage->>IdentityStore: store authentication tokens only on success
Loading

Poem

I’m a rabbit guarding every route,
No crooked path can hop out.
Tokens wait when two factors call,
Phone errors speak clearly to all.
Safe links lead home through the wall.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.24% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive The changes target identity improvements, but issue #12792 provides no specific coding requirements or acceptance criteria for complete validation. Add concrete acceptance criteria to issue #12792, then verify each identity-flow change against them.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main scope: identity improvements in the Bit Boilerplate, including safer authentication and confirmation flows.
Out of Scope Changes check ✅ Passed All production and test changes concern Bit Boilerplate identity flows, authentication configuration, token handling, phone validation, or related URL security.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Infrastructure/Services/PhoneService.cs (1)

25-41: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Solid fix: converts an unhandled 500 into a controlled 400 for anonymous callers.

Wrapping Parse/Format and returning a localized BadRequestException is correct given libphonenumber's stricter validation than the [Phone] attribute.

One optional note: the exception is not logged before conversion. Since the comment acknowledges that header-derived regions (XX, T1) can cause false failures for legitimate users, consider a low-level log entry to keep visibility into how often this path triggers.

🤖 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
`@src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Infrastructure/Services/PhoneService.cs`
around lines 25 - 41, Optionally add low-level logging in the
NumberParseException catch block before throwing BadRequestException, recording
the parse failure and caller-influenced region while preserving the existing
localized 400 conversion and exception data.
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/NotAuthorizedPage.razor.cs (1)

12-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate security-validation logic across three files.

GetSafeReturnUrl() is defined identically in NotAuthorizedPage.razor.cs, SignInPanel.razor.cs, and ConfirmPage.razor.cs. Extract this into a single shared helper, for example a static extension method next to Uri.IsAppRelativeUrl in UriExtensions.cs. A single implementation reduces the risk that a future change to the return-URL rule updates only some call sites.

♻️ Proposed extraction
// UriExtensions.cs
public static string GetSafeReturnUrl(this string? returnUrl) =>
    IsAppRelativeUrl(returnUrl, requireLeadingSlash: false) ? returnUrl! : PageUrls.Home;
-    private string GetSafeReturnUrl() => Uri.IsAppRelativeUrl(ReturnUrl, requireLeadingSlash: false) ? ReturnUrl : PageUrls.Home;
+    private string GetSafeReturnUrl() => ReturnUrl.GetSafeReturnUrl();
🤖 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
`@src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/NotAuthorizedPage.razor.cs`
at line 12, Extract the shared return-URL validation from GetSafeReturnUrl in
NotAuthorizedPage, SignInPanel, and ConfirmPage into one helper alongside
Uri.IsAppRelativeUrl in UriExtensions.cs. Update all three call sites to use the
shared helper and remove their duplicate local implementations, preserving the
existing fallback to PageUrls.Home.
🤖 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
`@src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Identity/SignIn/SignInPanel.razor.cs`:
- Around line 21-25: Update the return URL validation at the external sign-in
callback’s Uri.IsAppRelativeUrl call to pass requireLeadingSlash: false,
matching GetSafeReturnUrl and preserving valid rootless return URLs instead of
redirecting them home.

In
`@src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Features/Identity/IdentityController.ExternalSignIn.cs`:
- Around line 95-102: Update the external sign-in callback around user creation
and AddLoginAsync to track whether the callback created the user; when login
association fails, delete only that newly created user before throwing the
existing ResourceValidationException. Preserve existing users found by email or
phone, and retain the current successful-association flow.

---

Nitpick comments:
In
`@src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/NotAuthorizedPage.razor.cs`:
- Line 12: Extract the shared return-URL validation from GetSafeReturnUrl in
NotAuthorizedPage, SignInPanel, and ConfirmPage into one helper alongside
Uri.IsAppRelativeUrl in UriExtensions.cs. Update all three call sites to use the
shared helper and remove their duplicate local implementations, preserving the
existing fallback to PageUrls.Home.

In
`@src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Infrastructure/Services/PhoneService.cs`:
- Around line 25-41: Optionally add low-level logging in the
NumberParseException catch block before throwing BadRequestException, recording
the parse failure and caller-influenced region while preserving the existing
localized 400 conversion and exception data.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9a5e5ba3-bb8f-4358-aa18-42066888e8fc

📥 Commits

Reviewing files that changed from the base of the PR and between 9664deb and 99fd561.

📒 Files selected for processing (17)
  • src/Templates/Boilerplate/Bit.Boilerplate/.template.config/template.json
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Identity/ConfirmPage.razor.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Identity/SignIn/SignInPanel.razor
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Identity/SignIn/SignInPanel.razor.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/NotAuthorizedPage.razor.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Features/Identity/IdentityController.EmailConfirmation.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Features/Identity/IdentityController.ExternalSignIn.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Features/Identity/IdentityController.PhoneConfirmation.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Features/Identity/IdentityController.ResetPassword.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Features/Identity/Services/RemoteAuthenticationOptionsConfigurator.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Infrastructure/Services/PhoneService.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Infrastructure/Extensions/UriExtensions.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Tests/Features/Identity/BunitUITests.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Tests/Features/Identity/ConfirmPageTwoFactorTests.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Tests/Features/Identity/OneTimeTokenTests.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Tests/Features/Identity/PhoneNumberNormalizationUITests.cs
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Tests/Features/Identity/ReturnUrlHardeningTests.cs

@yasmoradi
yasmoradi merged commit bb32c96 into bitfoundation:develop Jul 31, 2026
3 checks passed
@yasmoradi
yasmoradi deleted the 12792 branch July 31, 2026 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bit Boilerplate identity needs improvements

1 participant