Skip to content

Verify email ownership for Microsoft authentication - #2687

Draft
niemyjski wants to merge 1 commit into
issue/external-account-statefrom
issue/microsoft-email-ownership
Draft

niemyjski wants to merge 1 commit into
issue/external-account-statefrom
issue/microsoft-email-ownership

Conversation

@niemyjski

@niemyjski niemyjski commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Stacked on #2630. This draft contains only the proposed Microsoft email-ownership policy and its regression tests. The provider migration is already merged in #2403; review this behavior change separately from external-account state handling.

Why

The OAuth2 Microsoft client maps Graph mail, falling back to userPrincipalName, without a mailbox-verification assertion. Microsoft documents that a privileged tenant user can assign an unverified Mail value to an account without a mailbox. Matching that reported address alone can attach an unrecognized Microsoft identity to an existing Exceptionless account.

Proposed behavior

Flow Result
New Microsoft identity with an unused email Signup remains available under the existing account-creation rules. Return an authentication token and start the existing email-verification flow.
Sign-in through an already linked Microsoft provider ID Sign in normally and preserve the local email-verification state, even if the provider profile email has changed.
Signed-in user explicitly links Microsoft Linking remains available, including when profile and local emails differ.
Unlinked Microsoft identity reports an existing account's email Return 403 with an instruction to sign in to that account and explicitly link Microsoft.
Local email change supported only by a Microsoft profile Require the existing mailbox-verification flow.

The generic OpenAPI 403 description remains unchanged. The Created result is internal: it identifies initial account creation so verification mail is attempted once, after invitation processing; the endpoint still returns the normal authentication-token response.

Dependencies

Limitations for review

  • WindowsLive-only users with no active session or other usable login must recover access through password reset before explicitly linking Microsoft. Email matching no longer migrates those users automatically.
  • The policy applies equally to personal and organizational Microsoft accounts; the current client supplies no mailbox-verification assertion that supports different treatment.
  • A valid invitation for the same address can still establish verification through the existing invitation flow.
  • Existing links, issued tokens, and email-verification states are not retroactively invalidated. Other providers retain their existing email policy.
  • Password recovery retains existing external-account links, including links established before mailbox verification; reviewing or revalidating ownership of those links during recovery remains outside this draft.
  • Live Microsoft consent and Graph callbacks have not been exercised.

Validation

  • Backend test-project build passed with zero warnings or errors.
  • All 17 authentication handler unit tests passed, including the Microsoft email-collision rejection and the Validate external account state and identity #2630 concurrency-admission regressions.
  • HTTP regressions cover signup and repeat-login tokens, verified/unverified stable-ID login, authenticated linking, legacy-email collisions, invitation-before-mail ordering, and local email changes.
  • Full CI passed for 2e63c4e2: all four backend shards (including service-backed HTTP regressions), frontend checks/tests, all six browser shards, and image builds. Live Microsoft consent/Graph calls are not part of these automated tests.

Base automatically changed from issue/microsoft-authentication to main October 22, 2026 17:25
@niemyjski
niemyjski force-pushed the issue/microsoft-email-ownership branch from d58fd2f to 2e63c4e Compare October 22, 2026 19:32
@niemyjski
niemyjski changed the base branch from main to issue/external-account-state October 22, 2026 19:32
@github-actions

Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Complexity Health
Exceptionless.AppHost 70% 65% 128 ➖
Exceptionless.Core 78% 70% 10998 ✔
Exceptionless.Insulation 51% 43% 370 ➖
Exceptionless.Web 86% 72% 9491 ✔
Summary 81% (28939 / 35668) 70% (14468 / 20580) 20987 ✔

This branch has not been deployed

No deployments
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.

1 participant