authorize('instances.adminlogin'); $instance = Instance::query()->where('uuid', $uuid)->firstOrFail(); $this->uuid = $uuid; $this->subdomain = $instance->subdomain; } public function hydrate(): void { $this->authorize('instances.adminlogin'); } public function request(): void { $this->authorize('instances.adminlogin'); $this->resetErrorBag('password'); $key = 'instance-admin:'.auth()->id(); if (RateLimiter::tooManyAttempts($key, 5)) { $this->addError('password', __('instances.too_many_attempts', ['seconds' => RateLimiter::availableIn($key)])); return; } if (! Hash::check($this->password, auth()->user()->password)) { RateLimiter::hit($key, 300); $this->addError('password', __('instances.wrong_password')); return; } RateLimiter::clear($key); $this->reset('password'); // The reset runs on the provisioning worker — it owns the tunnel. The // token is where it will leave the result. $this->token = Str::random(40); $this->waiting = true; IssueInstanceAdminAccess::dispatch($this->uuid, $this->token, (int) auth()->id()); } public function render() { $payload = null; if ($this->token !== null) { $raw = ConfigHandoff::get($this->token); if ($raw !== null) { // Consumed on the first read: leaving it in the cache would make // "shown once" a figure of speech — any replayed component // request could fetch the password again for ten minutes. The // payload lives in a local variable, so it reaches the view and // nothing else. ConfigHandoff::forget($this->token); $this->token = null; $this->waiting = false; $payload = json_decode($raw, true); } } return view('livewire.admin.instance-admin-access', [ 'credentials' => isset($payload['password']) ? $payload : null, 'failed' => isset($payload['error']) ? $payload['error'] : null, ]); } }