share = $share->load('files'); // A share at its download limit stays open for the recipient who took its last download. if (! $share->isCompleted() || $share->isExpired() || ($share->hasReachedDownloadLimit() && $shareService->downloadWindowEndsAt($share, session()->driver()) === null)) { abort(404); } if (! $share->isPasswordProtected()) { $this->authenticated = true; } if ($share->isPasswordProtected() && session('share_key_'.$share->token)) { $this->authenticated = true; } } public function verifyPassword(ShareService $shareService): void { $rateLimitKey = 'share-password:'.$this->share->token.'|'.request()->ip(); if (RateLimiter::tooManyAttempts($rateLimitKey, 5)) { $seconds = RateLimiter::availableIn($rateLimitKey); $this->addError('password', __('Too many attempts. Please try again in :seconds seconds.', ['seconds' => $seconds])); return; } $this->validate(); if (! $shareService->verifyPassword($this->share, $this->password)) { RateLimiter::hit($rateLimitKey, 60); $this->addError('password', __('The password is incorrect.')); return; } RateLimiter::clear($rateLimitKey); $encryptionKey = $shareService->getDecryptionKey($this->share, $this->password); session(['share_key_'.$this->share->token => $encryptionKey]); $this->authenticated = true; } public function render(): mixed { $shareService = app(ShareService::class); return view('livewire.share-download', [ 'downloadWindowEndsAt' => $shareService->downloadWindowEndsAt($this->share, session()->driver()), 'remainingDownloads' => $this->share->max_downloads ? max($this->share->max_downloads - $this->share->download_count, 0) : null, 'downloadWindow' => CarbonInterval::minutes(ShareService::DOWNLOAD_WINDOW_MINUTES)->cascade()->forHumans(), ]); } }