Initial commit: Pireon Admin — headless admin panel and public API

Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer
collective, backed by the Pireon OAuth identity server. The public site is a
separate, server-rendered application consuming /api/public/v1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 17:55:27 +02:00
commit 3897113313
534 changed files with 64050 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace App\Console\Commands;
use App\Models\User;
use Illuminate\Console\Command;
use Spatie\Permission\Models\Role;
use function Laravel\Prompts\select;
/**
* Bootstraps administration.
*
* Local accounts only appear after their first OAuth login, so there is no
* super admin to promote anyone at install time. This command is the way in:
* sign in once through the panel, then run
*
* php artisan user:role you@example.com super_admin
*/
class AssignRole extends Command
{
protected $signature = 'user:role {email : Email of the user, as known to the identity server}
{role? : Role to grant; prompts when omitted}
{--revoke : Remove the role instead of granting it}
{--only : Replace all of the user\'s roles with this one}';
protected $description = 'Grant or revoke a local role for a user';
public function handle(): int
{
$user = User::query()->where('email', $this->argument('email'))->first();
if (! $user) {
$this->error("No local user with email [{$this->argument('email')}].");
$this->line('Local accounts are created on first login. Ask them to sign in once, then re-run this.');
return self::FAILURE;
}
$role = $this->argument('role') ?? select(
label: 'Which role?',
options: Role::query()->pluck('name', 'name')->all(),
);
if (! Role::query()->where('name', $role)->exists()) {
$this->error("No role named [{$role}]. Run `php artisan permissions:sync` first.");
return self::FAILURE;
}
match (true) {
(bool) $this->option('revoke') => $user->removeRole($role),
(bool) $this->option('only') => $user->syncRoles([$role]),
default => $user->assignRole($role),
};
$this->info(sprintf(
'%s now has roles: %s',
$user->email,
$user->fresh()->roles->pluck('name')->implode(', ') ?: '(none)',
));
return self::SUCCESS;
}
}