Add all files
This commit is contained in:
123
extensions/Others/ComplianceTools/Services/SupportPinService.php
Normal file
123
extensions/Others/ComplianceTools/Services/SupportPinService.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace Paymenter\Extensions\Others\ComplianceTools\Services;
|
||||
|
||||
use App\Helpers\ExtensionHelper;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Paymenter\Extensions\Others\ComplianceTools\Models\SupportPin;
|
||||
|
||||
class SupportPinService
|
||||
{
|
||||
public function __construct(protected AuditLogService $auditLog)
|
||||
{
|
||||
}
|
||||
|
||||
public function generate(User $user): array
|
||||
{
|
||||
$extension = ExtensionHelper::getExtension('other', 'ComplianceTools');
|
||||
$length = (int) ($extension?->config('pin_length') ?? 6);
|
||||
$expiryMinutes = (int) ($extension?->config('pin_expiry_minutes') ?? 15);
|
||||
|
||||
$plainPin = $this->randomPin($length);
|
||||
$lookup = hash('sha256', $plainPin);
|
||||
|
||||
SupportPin::query()
|
||||
->where('user_id', $user->getKey())
|
||||
->whereNull('revoked_at')
|
||||
->update(['revoked_at' => now()]);
|
||||
|
||||
$pin = SupportPin::create([
|
||||
'user_id' => $user->getKey(),
|
||||
'pin_hash' => Hash::make($plainPin),
|
||||
'pin_lookup' => $lookup,
|
||||
'expires_at' => now()->addMinutes($expiryMinutes),
|
||||
'created_ip' => request()->ip(),
|
||||
'created_user_agent' => request()->header('User-Agent'),
|
||||
]);
|
||||
|
||||
$this->auditLog->record(
|
||||
category: 'support_pin',
|
||||
event: 'generated',
|
||||
context: [
|
||||
'support_pin_id' => $pin->getKey(),
|
||||
'expires_at' => $pin->expires_at?->toAtomString(),
|
||||
],
|
||||
subject: $user
|
||||
);
|
||||
|
||||
return [$pin, $plainPin];
|
||||
}
|
||||
|
||||
public function revoke(SupportPin $pin, ?User $actor = null): SupportPin
|
||||
{
|
||||
if ($pin->revoked_at) {
|
||||
return $pin;
|
||||
}
|
||||
|
||||
$pin->forceFill(['revoked_at' => now()])->save();
|
||||
|
||||
$this->auditLog->record(
|
||||
category: 'support_pin',
|
||||
event: 'revoked',
|
||||
context: ['support_pin_id' => $pin->getKey()],
|
||||
subject: $pin->user,
|
||||
actor: $actor
|
||||
);
|
||||
|
||||
return $pin;
|
||||
}
|
||||
|
||||
public function validate(string $plainPin): ?SupportPin
|
||||
{
|
||||
$plainPin = strtoupper(trim($plainPin));
|
||||
|
||||
if ($plainPin === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$lookup = hash('sha256', $plainPin);
|
||||
|
||||
$pin = SupportPin::query()
|
||||
->where('pin_lookup', $lookup)
|
||||
->first();
|
||||
|
||||
if (!$pin instanceof SupportPin) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!Hash::check($plainPin, $pin->pin_hash)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($pin->revoked_at || $pin->expires_at->isPast()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$pin->forceFill(['last_validated_at' => now()])->save();
|
||||
|
||||
$this->auditLog->record(
|
||||
category: 'support_pin',
|
||||
event: 'validated',
|
||||
context: [
|
||||
'support_pin_id' => $pin->getKey(),
|
||||
],
|
||||
subject: $pin->user
|
||||
);
|
||||
|
||||
return $pin;
|
||||
}
|
||||
|
||||
protected function randomPin(int $length): string
|
||||
{
|
||||
$alphabet = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
|
||||
$poolLength = strlen($alphabet) - 1;
|
||||
|
||||
$pin = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$pin .= $alphabet[random_int(0, $poolLength)];
|
||||
}
|
||||
|
||||
return $pin;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user