Files
BarangaySystem/app/Http/Controllers/Admin/ApiTokenController.php
2026-06-06 18:43:00 +08:00

132 lines
4.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Helpers\ResponseHelper;
use App\Models\PersonalAccessToken;
use App\Models\User;
use App\Support\TokenAbilities;
use Hypervel\Http\Request;
use Hypervel\Support\Facades\Auth;
class ApiTokenController
{
public function catalog()
{
return response()->json([
'success' => true,
'data' => [
'abilities' => TokenAbilities::catalog(),
'wildcard' => TokenAbilities::WILDCARD,
],
]);
}
public function index(Request $request)
{
$tokens = PersonalAccessToken::query()
->where('tokenable_type', User::class)
->orderByDesc('id')
->get()
->map(fn ($t) => $this->present($t));
return response()->json(['success' => true, 'data' => $tokens]);
}
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:120',
'description' => 'nullable|string|max:500',
'abilities' => 'required|array|min:1',
'abilities.*' => 'string',
'allowed_ips' => 'nullable|array',
'allowed_ips.*' => 'string',
'expires_at' => 'nullable|date',
'tokenable_user_id' => 'nullable|integer',
]);
foreach ($validated['abilities'] as $ability) {
if (! TokenAbilities::exists($ability)) {
return ResponseHelper::returnError("Unknown ability: {$ability}", 422);
}
}
$owner = Auth::user();
$tokenable = $owner;
if (! empty($validated['tokenable_user_id'])) {
$tokenable = User::query()->find($validated['tokenable_user_id']);
if (! $tokenable) {
return ResponseHelper::returnError('Target user not found.', 404);
}
}
$result = $tokenable->createToken(
name: $validated['name'],
abilities: $validated['abilities'],
allowedIps: $validated['allowed_ips'] ?? null,
expiresAt: !empty($validated['expires_at']) ? new \DateTimeImmutable($validated['expires_at']) : null,
description: $validated['description'] ?? null,
createdBy: $owner->id,
);
return response()->json([
'success' => true,
'data' => [
'token' => $this->present($result['token']),
'plain_text_token' => $result['plainTextToken'],
],
'message' => 'Token created. Copy it now — it will not be shown again.',
]);
}
public function revoke(Request $request, int $id)
{
$token = PersonalAccessToken::query()->find($id);
if (! $token) {
return ResponseHelper::returnError('Token not found.', 404);
}
if ($token->revoked_at !== null) {
return ResponseHelper::returnError('Token already revoked.', 422);
}
$token->forceFill([
'revoked_at' => now(),
'revoked_by' => Auth::id(),
])->save();
return response()->json(['success' => true, 'data' => $this->present($token)]);
}
public function destroy(Request $request, int $id)
{
$token = PersonalAccessToken::query()->find($id);
if (! $token) {
return ResponseHelper::returnError('Token not found.', 404);
}
$token->delete();
return response()->json(['success' => true]);
}
private function present(PersonalAccessToken $t): array
{
return [
'id' => $t->id,
'name' => $t->name,
'description' => $t->description,
'tokenable_id' => $t->tokenable_id,
'tokenable_type' => $t->tokenable_type,
'abilities' => $t->abilities ?? [],
'allowed_ips' => $t->allowed_ips ?? [],
'expires_at' => $t->expires_at,
'last_used_at' => $t->last_used_at,
'last_used_ip' => $t->last_used_ip,
'revoked_at' => $t->revoked_at,
'created_by' => $t->created_by,
'created_at' => $t->created_at,
'is_active' => $t->isActive(),
];
}
}