AOSSIE-Org / AOSSIE-Org/Resonate-Backend

# OTP verification allows reuse and has unclear responses

Open
#138 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
43
Forks
120
PR merge metrics
No merged PRs in 30d

Description

## 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.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.