Auto approve functionality
Some checks failed
linter / quality (push) Successful in 3m5s
tests / ci (push) Failing after 7m46s

This commit is contained in:
Javier Feliz 2025-08-02 01:43:45 -04:00
parent 772103b55a
commit c976cf6e53
5 changed files with 64 additions and 9 deletions

View File

@ -20,22 +20,38 @@ class OIDCController extends Controller
{ {
public function authorize(Request $request) public function authorize(Request $request)
{ {
// $valid = $request->validate([
// 'client_id' => 'required',
// 'redirect_uri' => 'required|url',
// 'response_type' => 'required|in:code',
// ]);
$client = Application::where('client_id', $request->client_id)->firstOrFail(); $client = Application::where('client_id', $request->client_id)->firstOrFail();
if ($client->redirect_uri !== $request->redirect_uri) { if ($client->redirect_uri !== $request->redirect_uri) {
abort(403, 'Redirect URI mismatch'); abort(403, 'Redirect URI mismatch');
} }
$user = auth()->user();
// Check if user has auto-approval enabled and has previously authorized this app
$hasAuthorizedBefore = $user->tokens()->where('application_id', $client->id)->exists();
if ($user->auto_approve_apps && $hasAuthorizedBefore) {
// Auto-approve: generate code and redirect directly
$code = Str::random(40);
Log::info("Auto-approving and caching code: $code");
Cache::put("auth_code:$code", [
'user_id' => $user->id,
'client_id' => $client->id,
'scope' => $request->scope,
'code_challenge' => $request->code_challenge ?? null,
'code_challenge_method' => $request->code_challenge_method ?? null,
'nonce' => $request->input('nonce') ?? null,
], now()->addMinutes(5));
return redirect($request->redirect_uri . '?code=' . $code . '&state=' . $request->state);
}
// Standard flow: show confirmation screen
$code = Str::random(40); $code = Str::random(40);
Log::info("Caching code: $code"); Log::info("Caching code: $code");
Cache::put("auth_code:$code", [ Cache::put("auth_code:$code", [
'user_id' => auth()->id(), 'user_id' => $user->id,
'client_id' => $client->id, 'client_id' => $client->id,
'scope' => $request->scope, 'scope' => $request->scope,
'code_challenge' => $request->code_challenge ?? null, 'code_challenge' => $request->code_challenge ?? null,

View File

@ -4,9 +4,12 @@ namespace App\Livewire\Forms;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use App\Models\User; use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\Password as PasswordRule;
use Illuminate\Validation\ValidationException;
use Livewire\Attributes\Validate; use Livewire\Attributes\Validate;
use Livewire\Component; use Livewire\Component;
use Livewire\WithFileUploads; use Livewire\WithFileUploads;
@ -19,6 +22,7 @@ class UserProfile extends Component
public string $email = ''; public string $email = '';
public ?string $preferred_username = null; public ?string $preferred_username = null;
public ?string $avatar = null; public ?string $avatar = null;
public bool $auto_approve_apps = false;
#[Validate('image|max:10000')] #[Validate('image|max:10000')]
public $avatarUpload; public $avatarUpload;
// Password // Password
@ -32,6 +36,7 @@ class UserProfile extends Component
$this->email = Auth::user()->email; $this->email = Auth::user()->email;
$this->preferred_username = Auth::user()->preferred_username; $this->preferred_username = Auth::user()->preferred_username;
$this->avatar = Auth::user()->avatar; $this->avatar = Auth::user()->avatar;
$this->auto_approve_apps = Auth::user()->auto_approve_apps;
} }
/** /**
@ -51,7 +56,8 @@ class UserProfile extends Component
'max:255', 'max:255',
Rule::unique(User::class)->ignore($user->id), Rule::unique(User::class)->ignore($user->id),
], ],
'preferred_username' => 'string|max:255' 'preferred_username' => 'string|max:255',
'auto_approve_apps' => 'boolean'
]); ]);
$user->fill($validated); $user->fill($validated);

View File

@ -25,7 +25,8 @@ class User extends Authenticatable
'password', 'password',
'avatar', 'avatar',
'preferred_username', 'preferred_username',
'is_admin' 'is_admin',
'auto_approve_apps'
]; ];
/** /**
@ -49,6 +50,7 @@ class User extends Authenticatable
'email_verified_at' => 'datetime', 'email_verified_at' => 'datetime',
'password' => 'hashed', 'password' => 'hashed',
'is_admin' => 'boolean', 'is_admin' => 'boolean',
'auto_approve_apps' => 'boolean',
]; ];
} }

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->boolean('auto_approve_apps')->default(false);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('auto_approve_apps');
});
}
};

View File

@ -50,6 +50,9 @@
<flux:input wire:model="preferred_username" :label="__('Preferred Username')" type="text" required <flux:input wire:model="preferred_username" :label="__('Preferred Username')" type="text" required
autofocus autocomplete="username" /> autofocus autocomplete="username" />
<flux:input wire:model="email" :label="__('Email')" type="email" required autocomplete="email" /> <flux:input wire:model="email" :label="__('Email')" type="email" required autocomplete="email" />
<flux:checkbox wire:model="auto_approve_apps"
:label="__('Auto-approve applications I\'ve previously authorized')"
:description="__('Skip confirmation screen for apps you\'ve already approved')" />
</div> </div>
</div> </div>