Skip to content

Comments

Added OTP Verification for Phone Number Updates#52

Merged
fortune710 merged 15 commits intostagingfrom
dev
Feb 8, 2026
Merged

Added OTP Verification for Phone Number Updates#52
fortune710 merged 15 commits intostagingfrom
dev

Conversation

@fortune710
Copy link
Owner

@fortune710 fortune710 commented Feb 8, 2026

Note

High Risk
Introduces new OTP/SMS verification endpoints and credentialed Twilio integration plus a client flow that updates user phone numbers via RPC; authentication, PII, and external API failure modes make this change security- and reliability-sensitive.

Overview
Adds a phone-number verification flow: backend exposes new /user/phone/otp/start and /user/phone/otp/resend endpoints (Twilio SMS) and configures Twilio env vars; the legacy /user/phone/otp/verify endpoint remains but is marked deprecated in favor of a Supabase RPC-based atomic verify+update.

Updates the mobile app to prompt users to add/verify a phone number when entering /capture, including a new PhoneNumberBottomSheet, local device-based prompt suppression (skip/don’t ask again), and a hook to read pending phone_number_updates records; OTP verification is performed via supabase.rpc('rpc_verify_and_update_phone', ...).

Improves date handling across calendar/vault views by routing date grouping/filtering through useTimezone().getLocalDateString and adjusting vault date parsing to avoid UTC drift. Also refactors backend ingestion to lazily initialize Pinecone (async, lock-protected) and tweaks a Supabase query in notification lookup to use supabase.table(...) directly.

Written by Cursor Bugbot for commit ab6fe2a. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • New Features

    • Added phone number verification via OTP (one-time password) workflow.
    • Added phone number input component with country code selection and validation.
    • Added phone verification prompt interface for users during capture.
  • Documentation

    • Added comprehensive React Native performance and best-practices guide covering 35+ rules across 13 categories.
    • Added frontend development guidelines for custom hooks and database access patterns.
    • Added ESLint configuration for the frontend project.

cursoragent and others added 15 commits February 5, 2026 02:40
Co-authored-by: Fortune Oluwasemilore Alebiosu <fortunealebiosu710@gmail.com>
Co-authored-by: Fortune Oluwasemilore Alebiosu <fortunealebiosu710@gmail.com>
Co-authored-by: Fortune Oluwasemilore Alebiosu <fortunealebiosu710@gmail.com>
Co-authored-by: Fortune Oluwasemilore Alebiosu <fortunealebiosu710@gmail.com>
Co-authored-by: Fortune Oluwasemilore Alebiosu <fortunealebiosu710@gmail.com>
Co-authored-by: Fortune Oluwasemilore Alebiosu <fortunealebiosu710@gmail.com>
…tom-sheet-eca6

Phone number bottom sheet
@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@vercel
Copy link

vercel bot commented Feb 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
keepsafe Ready Ready Preview, Comment Feb 8, 2026 6:37am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 8, 2026

Caution

Review failed

The pull request is closed.

Walkthrough

This PR adds comprehensive React Native development guidelines for AI agents across 35+ documentation rules, implements end-to-end phone-based OTP verification with backend FastAPI endpoints and frontend UI components, introduces timezone-aware date handling utilities, creates supporting database schema with RLS policies, and updates configuration and type definitions.

Changes

Cohort / File(s) Summary
AI Agent Documentation
.agents/skills/vercel-react-native-skills/{AGENTS.md, SKILL.md}, .agents/skills/vercel-react-native-skills/rules/*
Comprehensive 35+ rule guide across 13 categories covering rendering, list performance, animations, navigation, state management, React Compiler, UI patterns, design systems, monorepo practices, third-party dependencies, and JavaScript/font optimization. Includes incorrect vs. correct code examples and observable behavior guidance. Rules are homogeneous and documentation-only.
Frontend ESLint Configuration
frontend/.eslintrc.cjs, frontend/AGENTS.md
Adds ESLint configuration extending expo preset and development guidelines for Supabase table references and custom hook design patterns.
Backend Phone OTP Router
backend/routers/phone_number.py
New FastAPI router implementing phone-based OTP verification with three endpoints: /otp/start (initiate OTP), /otp/resend (regenerate OTP with cooldown), and /otp/verify (validate and update phone). Includes OTP generation, SHA-256 hashing, Twilio SMS integration, and 10-minute expiration logic.
Backend Configuration & Services
backend/config.py, backend/main.py, backend/services/ingestion_service.py, backend/services/notification_service.ts
Adds Twilio credentials to Settings config, mounts phone_number router, introduces lazy async Pinecone index initialization with lock-based synchronization, and simplifies Supabase query construction in notification service.
Frontend Phone Number UI Components
frontend/components/phone-number-bottom-sheet.tsx, frontend/components/profile/phone-number-input.tsx, frontend/components/ui/otp-input.tsx, frontend/components/profile/phone-update-form.tsx
Implements bottom sheet flow for phone verification with two-step UI (phone entry + OTP confirmation), country-code-aware phone input with validation, single-value OTP input with digit auto-focusing and paste handling, and refactored form using new components.
Frontend Timezone & Phone Hooks
frontend/hooks/use-timezone.ts, frontend/hooks/use-phone-number-update-record.ts, frontend/hooks/use-otp-hash.ts, frontend/hooks/use-profile-operations.ts
Adds timezone utilities for UTC/local date conversion, phone update record fetching from Supabase, SHA-256-based OTP hashing for client-side verification, and updates profile operations to use phone_number field.
Frontend Utilities & Services
frontend/lib/utils.ts, frontend/services/phone-number-prompt-service.ts, frontend/constants/supabase.ts
Extends groupBy and getEntriesForDate with optional timezone-aware grouping, adds device storage-based phone prompt state management (skip tracking, "don't ask again" flag, 7-day cooldown), and adds PHONE_NUMBER_UPDATES table constant.
Frontend Route Updates
frontend/app/calendar/day.tsx, frontend/app/calendar/index.tsx, frontend/app/capture/index.tsx, frontend/app/vault.tsx, frontend/hooks/use-user-entries.ts, frontend/package.json
Integrates timezone hook for local date rendering across calendar and vault screens, adds phone prompt sheet triggering logic to capture screen based on OTP pending state, and adds ESLint/Expo tooling dependencies.
Database Schema & Migrations
frontend/supabase/migrations/20260205120000_phone_number_updates.sql, frontend/supabase/migrations/20260206000000_rpc_verify_and_update_phone.sql, frontend/types/database.ts
Creates phone_number_updates table (id, user_id, phone_number, otp_hash, created_at) with unique constraint per user and RLS policies for authenticated access; adds RPC function rpc_verify_and_update_phone for atomic OTP verification and profile update with 10-minute expiration; updates TypeScript database types.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Frontend Client
    participant Backend as FastAPI Server
    participant Twilio as Twilio SMS API
    participant DB as Supabase Database

    rect rgba(100, 150, 200, 0.5)
    Note over Client,DB: Phase 1: Start OTP
    Client->>Backend: POST /user/phone/otp/start<br/>(phone_number)
    Backend->>DB: Upsert phone_number_updates<br/>(user_id, phone_number, otp_hash)
    DB-->>Backend: Confirmation
    Backend->>Twilio: Send SMS with OTP
    Twilio-->>Backend: Success/Error
    Backend-->>Client: Response
    end

    rect rgba(150, 100, 200, 0.5)
    Note over Client,DB: Phase 2: Resend OTP
    Client->>Backend: POST /user/phone/otp/resend<br/>(optional phone_number)
    Backend->>DB: Fetch existing pending record
    DB-->>Backend: phone_number_updates record
    Backend->>DB: Update otp_hash & created_at
    DB-->>Backend: Confirmation
    Backend->>Twilio: Send SMS with new OTP
    Twilio-->>Backend: Success/Error
    Backend-->>Client: Response (with cooldown)
    end

    rect rgba(200, 150, 100, 0.5)
    Note over Client,DB: Phase 3: Verify OTP
    Client->>Backend: POST /user/phone/otp/verify<br/>(phone_number, otp)
    Backend->>DB: Fetch phone_number_updates
    DB-->>Backend: otp_hash, created_at
    Backend->>Backend: Hash provided OTP<br/>Check expiration (10 min)<br/>Compare hashes
    alt OTP Valid
        Backend->>DB: RPC rpc_verify_and_update_phone<br/>(user_id, phone_number, otp)
        DB->>DB: Update profiles.phone_number<br/>Delete phone_number_updates
        DB-->>Backend: Success JSON
        Backend-->>Client: Confirmation
        Client->>Client: Refresh auth state<br/>Clear prompt
    else OTP Invalid/Expired
        Backend-->>Client: Error response
        Client->>Client: Show error toast
    end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

The PR spans multiple distinct domains (frontend components, backend routing, database schema, cryptography, timezone utilities) with varying logic density. While the 35+ documentation rules are repetitive and homogeneous, the functional changes involve careful review of: OTP hashing/verification, Twilio integration error handling, RLS policy correctness, async synchronization locks, client-side phone validation, and timezone conversion logic across multiple files. The heterogeneous nature of changes across different subsystems and the need to verify security-sensitive operations (OTP, hashing, RLS) elevate the effort.

Possibly related PRs

  • Phone number bottom sheet #48: Directly related — implements identical phone-number OTP verification feature set at code level with matching backend router, frontend components, database migrations, and hook implementations.
  • improvement #3: Modifies phone-number input UI component with country-code picker enhancements and keyboard handling in the same frontend component files.
  • Added Improvements for Version 0.9.7 #45: Refactors backend/services/notification_service.py Supabase query structure in the same _get_user_info_from_tokens method.

Poem

🐰 A rabbit's hoppy ode to phone verification:

Through timezones hopped and OTPs sent,
Six digits hashed with SHA intent,
The Twilio bell rings clear and bright,
While RLS guards each user's right,
From capture screen to vault so deep,
Your phone is verified—now sleep! 🔐

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

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 and usage tips.

@fortune710 fortune710 merged commit d22c432 into staging Feb 8, 2026
4 of 5 checks passed
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

if not res.data:
raise HTTPException(status_code=404, detail="No pending phone verification record found")

phone_number = res.data[0].get("phone_number")
Copy link

Choose a reason for hiding this comment

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

Missing phone number validation after database fetch

Medium Severity

In resend_phone_otp, after fetching the phone number from the database with res.data[0].get("phone_number"), there's no validation that the returned value is actually a valid phone number. If the database record exists but the phone_number column is null, the code proceeds to call _send_sms_otp with None, which will fail with a misleading "Failed to send OTP SMS" error from Twilio rather than a clear validation error.

Fix in Cursor Fix in Web

)
except ValueError as e:
logger.exception("Failed to parse created_at timestamp")
raise HTTPException(status_code=500, detail="Invalid timestamp in verification record") from e
Copy link

Choose a reason for hiding this comment

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

Unhandled AttributeError when created_at is null

Low Severity

In verify_phone_otp, created_at_str is retrieved via record.get("created_at") which returns None if the column is null. Line 232 then calls created_at_str.replace("Z", "+00:00"), which would raise an AttributeError on None. The try-except block only catches ValueError, so this AttributeError would propagate as an unhandled 500 error with no meaningful message.

Fix in Cursor Fix in Web

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.

2 participants