normalizeManualWebhookRepositoryPath($fullName); } /** * @return Collection */ protected function manualWebhookApplications(Builder $query, string $fullName): Collection { return $query->get() ->filter(fn (Application $application): bool => $this->manualWebhookRepositoryMatches($application->git_repository, $fullName)) ->values(); } protected function manualWebhookRepositoryMatches(?string $gitRepository, string $fullName): bool { $repositoryPath = $this->canonicalManualWebhookRepository($gitRepository); return $repositoryPath !== null && hash_equals($fullName, $repositoryPath); } /** * @return array{status: string, message: string} */ protected function unauthenticatedManualWebhookFailurePayload(): array { return [ 'status' => 'failed', 'message' => 'Invalid signature.', ]; } protected function canonicalManualWebhookRepository(?string $gitRepository): ?string { if (! is_string($gitRepository)) { return null; } $gitRepository = trim($gitRepository); if ($gitRepository === '') { return null; } $path = null; $parts = parse_url($gitRepository); if (is_array($parts) && isset($parts['scheme'])) { $path = data_get($parts, 'path'); } elseif (Str::startsWith($gitRepository, 'git@') && str_contains($gitRepository, ':')) { $path = Str::after($gitRepository, ':'); } else { $path = $gitRepository; } if (! is_string($path) || $path === '') { return null; } return $this->normalizeManualWebhookRepositoryPath($path); } protected function normalizeManualWebhookRepositoryPath(string $path): string { $path = trim($path); $path = strtok($path, '?#') ?: $path; $path = trim($path, '/'); $path = preg_replace('/\.git\z/i', '', $path) ?? $path; return $path; } }