All files / app/api/auth/password/update route.ts

86.66% Statements 65/75
87.5% Branches 21/24
100% Functions 1/1
86.66% Lines 65/75

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 1011x       8x 8x 8x   8x 8x 8x 8x   8x 1x 1x   6x 6x     8x 1x 1x 1x 1x 1x     8x 8x 1x 1x 1x 1x 1x     4x 4x 4x 4x 4x 4x 4x 4x 8x 8x           8x 3x 1x 1x     2x 2x 2x 2x   3x 1x 1x 3x     2x 2x 2x   8x                 2x 2x 2x 8x         2x 2x 8x 8x 8x 1x 1x 1x 8x  
import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';
import { createAdminClient } from '@/lib/supabase/admin';
 
export async function POST(request: NextRequest) {
  try {
    const supabase = await createClient();
 
    const {
      data: { user },
      error: authError,
    } = await supabase.auth.getUser();
 
    if (authError || !user) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }
 
    const body = await request.json();
    const { currentPassword, newPassword } = body;
 
    // Validate new password
    if (!newPassword || newPassword.length < 8) {
      return NextResponse.json(
        { error: 'Password must be at least 8 characters' },
        { status: 400 }
      );
    }
 
    // Check if user has a real email
    const isPlaceholderEmail = user.email?.endsWith('@proofid.internal');
    if (!user.email || isPlaceholderEmail) {
      return NextResponse.json(
        { error: 'You need to verify your email before setting a password' },
        { status: 400 }
      );
    }
 
    // Check if user has a password set by checking our database flag
    let hasPassword = false;
    try {
      const supabaseAdmin = createAdminClient();
      const { data: userData } = await supabaseAdmin
        .from('users')
        .select('has_password')
        .eq('id', user.id)
        .single();
      hasPassword = userData?.has_password === true;
    } catch {
      // If we can't check, assume no password (safer - allows setting one)
      hasPassword = false;
    }
 
    // If user already has a password, verify the current password
    if (hasPassword) {
      if (!currentPassword) {
        return NextResponse.json({ error: 'Current password is required' }, { status: 400 });
      }
 
      // Verify current password by attempting to sign in
      const { error: signInError } = await supabase.auth.signInWithPassword({
        email: user.email,
        password: currentPassword,
      });
 
      if (signInError) {
        return NextResponse.json({ error: 'Current password is incorrect' }, { status: 400 });
      }
    }
 
    // Update the password
    const { error: updateError } = await supabase.auth.updateUser({
      password: newPassword,
    });
 
    if (updateError) {
      console.error('Password update error:', updateError);
      return NextResponse.json(
        { error: updateError.message || 'Failed to update password' },
        { status: 400 }
      );
    }
 
    // Set the has_password flag in our users table
    try {
      const supabaseAdmin = createAdminClient();
      await supabaseAdmin.from('users').update({ has_password: true }).eq('id', user.id);
    } catch (flagError) {
      // Log but don't fail - password was still updated successfully
      console.error('Failed to update has_password flag:', flagError);
    }
 
    return NextResponse.json({
      success: true,
      message: hasPassword ? 'Password changed successfully' : 'Password set successfully',
    });
  } catch (error) {
    console.error('Password update error:', error);
    return NextResponse.json({ error: 'Failed to update password' }, { status: 500 });
  }
}