validated(); $user = User::where('phone', $data['phone'])->first(); if (! $user) { return $this->fail('Invalid code', ['code' => ['not_found']], 422); } $result = $otp->verify($data['phone'], OtpCode::PURPOSE_PASSWORD_RESET, $data['code']); if (! $result->isOk()) { return $this->fail( $this->messageFor($result->status), ['code' => [$result->status]], 422, ); } $user->forceFill(['password' => Hash::make($data['password'])])->save(); PersonalAccessToken::query() ->where('tokenable_type', $user->getMorphClass()) ->where('tokenable_id', $user->id) ->delete(); return $this->ok(null, 'Password reset successful. Please log in.'); } private function messageFor(string $status): string { return match ($status) { OtpVerifyResult::STATUS_INVALID => 'Invalid code', OtpVerifyResult::STATUS_EXPIRED => 'Code expired', OtpVerifyResult::STATUS_EXHAUSTED => 'Too many attempts. Request a new code.', OtpVerifyResult::STATUS_NOT_FOUND => 'No active code for this destination', default => 'Reset failed', }; } }