fix(github): derive app API URLs from HTML hosts

Normalize GitHub organization values and derive API URLs for GitHub.com,
GHE.com, and enterprise hosts when creating or updating GitHub Apps.
This commit is contained in:
Andras Bacsai committed 2026-06-09 18:31:06 +02:00
1 parent a9d9bfdbe3
commit 281184c040
11 files changed
+496 -26

No files matched your search

+18 -5
View File
@@ -86,7 +86,7 @@ class Change extends Component
{
return [
'name' => 'required|string',
'organization' => 'nullable|string',
'organization' => ['nullable', 'string', 'regex:/\A[^\s\/?#]+\z/'],
'apiUrl' => ['required', 'string', 'url', new SafeExternalUrl],
'htmlUrl' => ['required', 'string', 'url', new SafeExternalUrl],
'customUser' => 'required|string',
@@ -107,6 +107,11 @@ class Change extends Component
];
}
public function updatedHtmlUrl(): void
{
$this->apiUrl = githubApiUrlFromHtmlUrl($this->htmlUrl);
}
public function boot()
{
if ($this->github_app) {
@@ -123,6 +128,9 @@ class Change extends Component
{
if ($toModel) {
// Sync TO model (before save)
$this->organization = normalizeGithubOrganization($this->organization);
$this->apiUrl = githubApiUrlFromHtmlUrl($this->htmlUrl);
$this->github_app->name = $this->name;
$this->github_app->organization = $this->organization;
$this->github_app->api_url = $this->apiUrl;
@@ -296,11 +304,14 @@ class Change extends Component
public function getGithubAppNameUpdatePath()
{
if (str($this->github_app->organization)->isNotEmpty()) {
return "{$this->github_app->html_url}/organizations/{$this->github_app->organization}/settings/apps/{$this->github_app->name}";
$name = encodeGithubPathSegment($this->github_app->name);
$organization = normalizeGithubOrganization($this->github_app->organization);
if (filled($organization)) {
return rtrim($this->github_app->html_url, '/').'/organizations/'.encodeGithubPathSegment($organization)."/settings/apps/{$name}";
}
return "{$this->github_app->html_url}/settings/apps/{$this->github_app->name}";
return rtrim($this->github_app->html_url, '/')."/settings/apps/{$name}";
}
private function generateGithubJwt($private_key, $app_id): string
@@ -315,7 +326,7 @@ class Change extends Component
return $configuration->builder()
->issuedBy((string) $app_id)
->permittedFor('https://api.github.com')
->permittedFor($this->github_app->api_url)
->identifiedBy((string) $now)
->issuedAt(new \DateTimeImmutable("@{$now}"))
->expiresAt(new \DateTimeImmutable('@'.($now + 600)))
@@ -373,6 +384,8 @@ class Change extends Component
$this->authorize('update', $this->github_app);
$this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret');
$this->organization = normalizeGithubOrganization($this->organization);
$this->apiUrl = githubApiUrlFromHtmlUrl($this->htmlUrl);
$this->validate();
$this->syncData(true);