Skip to content

security: process account recovery requests asynchronously#74

Draft
enlorik wants to merge 2 commits into
mainfrom
security/async-account-recovery
Draft

security: process account recovery requests asynchronously#74
enlorik wants to merge 2 commits into
mainfrom
security/async-account-recovery

Conversation

@enlorik

@enlorik enlorik commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Noticed the forgot-password endpoint answers almost instantly for unknown accounts but only after a token insert plus an email-provider round trip for real ones, so response timing leaks account existence even though the message is generic. Moved all the account-dependent work into a new AccountRecoveryService running on a bounded async executor (AbortPolicy on purpose — CallerRunsPolicy would put the work back on the request thread), so the controller now returns the generic message immediately either way; a rejected submission is logged and still gets the same reply. One caveat: the bounded in-memory executor reduces the timing side channel but is not a durable message queue, so queued work can be lost during application shutdown or restart. Reworked the controller tests and added service, masking and executor wiring tests — mvn test went from 185 to 193 tests, all passing (0 failures, 0 errors).

@enlorik

enlorik commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c3d7ce1f3d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

log.info("Password reset email sent - username: {}, email: {}",
username,
LoggingUtil.maskEmail(email));
} catch (Exception e) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear MDC after async reset failures

When createTokenAndSendResetEmail throws after PasswordResetService.createPasswordResetTokenForEmail has set actionType/userId but before it clears them (for example a token repository save failure), this catch logs and then leaves the MDC on the reused account-recovery-* executor thread. Previously the request interceptor cleared MDC at the end of the HTTP request, but this work now runs outside that lifecycle, so later recovery tasks on the same thread can be logged with the wrong user context unless the async task clears MDC in a finally block.

Useful? React with 👍 / 👎.

@enlorik

enlorik commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 40713a8972

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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