signedRoute( 'signed.supplier-returns.show', $this->token($companyId, $supplier, $month), $companyId, now()->addDays(self::TTL_DAYS), ); } public function signedRoute( string $routeName, string $token, int $companyId, ?DateTimeInterface $expires = null, ): string { return URL::temporarySignedRoute($routeName, $expires ?? now()->addDays(self::TTL_DAYS), [ 'company_id' => $companyId, 'token' => $token, ]); } /** @return array{supplier:string,month:string}|null */ public function resolveToken(string $token, int $companyId): ?array { try { $padding = (4 - strlen($token) % 4) % 4; $encoded = strtr($token . str_repeat('=', $padding), '-_', '+/'); $encrypted = base64_decode($encoded, true); if ($encrypted === false) { return null; } $payload = json_decode(Crypt::decryptString($encrypted), true, flags: JSON_THROW_ON_ERROR); } catch (Throwable) { return null; } $supplier = is_array($payload) ? trim((string) ($payload['supplier'] ?? '')) : ''; $month = is_array($payload) ? trim((string) ($payload['month'] ?? '')) : ''; $payloadCompanyId = is_array($payload) ? (int) ($payload['company_id'] ?? 0) : 0; if ($supplier === '' || $payloadCompanyId !== $companyId || preg_match('/^\d{4}-\d{2}$/', $month) !== 1) { return null; } return ['supplier' => $supplier, 'month' => $month]; } private function token(int $companyId, string $supplier, string $month): string { $payload = json_encode([ 'company_id' => $companyId, 'supplier' => $supplier, 'month' => $month, ], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR); return rtrim(strtr(base64_encode(Crypt::encryptString($payload)), '+/', '-_'), '='); } }