Files
BetiX/app/Http/Controllers/VaultPinController.php
Dolo 0280278978
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Initialer Laravel Commit für BetiX
2026-04-04 18:01:50 +02:00

87 lines
2.8 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class VaultPinController extends Controller
{
/**
* POST /api/wallet/vault/pin/set — local implementation
*/
public function set(Request $request)
{
$user = Auth::user();
abort_unless($user, 403);
$data = $request->validate([
'pin' => ['required','string','regex:/^\d{4,8}$/'],
'current_pin' => ['sometimes','nullable','string','regex:/^\d{4,8}$/'],
]);
// If PIN already set, require current_pin and verify
if (!empty($user->vault_pin_hash)) {
if (empty($data['current_pin']) || !Hash::check((string) $data['current_pin'], $user->vault_pin_hash)) {
return response()->json(['message' => 'Current PIN invalid'], 400);
}
}
$user->vault_pin_hash = Hash::make((string) $data['pin']);
$user->vault_pin_set_at = now();
$user->vault_pin_attempts = 0;
$user->vault_pin_locked_until = null;
$user->save();
return response()->json([
'success' => true,
'message' => 'Vault PIN saved.',
], 200);
}
/**
* POST /api/wallet/vault/pin/verify — local implementation
*/
public function verify(Request $request)
{
$user = Auth::user();
abort_unless($user, 403);
$data = $request->validate([
'pin' => ['required','string','regex:/^\d{4,8}$/'],
]);
// Locked?
if (!empty($user->vault_pin_locked_until) && now()->lessThan($user->vault_pin_locked_until)) {
return response()->json([
'success' => false,
'message' => 'Vault PIN locked. Try again later.',
'locked_until' => optional($user->vault_pin_locked_until)->toIso8601String(),
], 423);
}
if (empty($user->vault_pin_hash)) {
return response()->json(['success' => false, 'message' => 'Vault PIN not set'], 400);
}
if (!Hash::check((string) $data['pin'], $user->vault_pin_hash)) {
$attempts = (int) ($user->vault_pin_attempts ?? 0) + 1;
$user->vault_pin_attempts = $attempts;
if ($attempts >= 5) {
$user->vault_pin_locked_until = now()->addMinutes(15);
$user->vault_pin_attempts = 0;
}
$user->save();
return response()->json(['success' => false, 'message' => 'Invalid PIN'], 423);
}
// OK
if (!empty($user->vault_pin_attempts)) {
$user->vault_pin_attempts = 0;
$user->save();
}
return response()->json([
'success' => true,
'message' => 'Verified',
], 200);
}
}