Skip to content

# OTP verification allows reuse and has unclear responses #138

Description

@Muneerali199

Summary

The OTP flow never enforces expiry or one-time use, and the verify endpoint always returns HTTP 200 with { message: "null" } even on failure. This lets a single OTP be reused indefinitely and makes it impossible for clients to distinguish success vs failure from the response.

Impact

  • Reusable OTPs weaken authentication and allow repeated logins with the same code.
  • Clients cannot reliably handle failures because the endpoint always returns 200, leading to inconsistent UX and potential security gaps.

Steps to Reproduce

  1. Call send-otp to generate an OTP.
  2. Call verify-otp with the correct OTP — response is 200.
  3. Call verify-otp again with the same OTP — response is still 200 and status is recorded as a string in the DB.
  4. Call verify-otp with a wrong OTP — response is also 200 with { message: "null" }.

Expected Behavior

  • OTPs expire after a short window (e.g., 5–10 minutes) and are single-use.
  • Verification returns success (200) only when valid; expired or incorrect OTPs return 400/401 with a clear error payload.
  • OTP documents are cleaned up or marked consumed after verification attempts.

Actual Behavior

  • No expiry or consumption; OTP can be reused indefinitely.
  • Endpoint always returns 200 with { message: "null" }, even on failure.

Proposed Fix

  1. Store expiresAt when generating the OTP and reject if expired.
  2. On verification, delete or mark the OTP document as consumed; reject subsequent attempts.
  3. Return distinct status codes/payloads:
    • 200 on success
    • 400/401 on invalid/expired
    • 500 on server errors
  4. (Optional) Store verification status as a boolean instead of a string for clearer semantics.

Acceptance Criteria

  • OTPs cannot be reused after one successful verification.
  • Expired or incorrect OTPs return 400/401 with an explanatory message; valid OTPs return 200 with a success message.
  • OTP records are removed or flagged as consumed after verification attempts, preventing reuse.
  • Tests or manual verification steps documented to confirm the behaviors above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions