fix: resolve broken custom domain routing in self-hosted status-page#2029
Open
johnib wants to merge 6 commits intoopenstatusHQ:mainfrom
Open
fix: resolve broken custom domain routing in self-hosted status-page#2029johnib wants to merge 6 commits intoopenstatusHQ:mainfrom
johnib wants to merge 6 commits intoopenstatusHQ:mainfrom
Conversation
Switch from CLAUDE_CODE_OAUTH_TOKEN to ANTHROPIC_API_KEY auth, remove author_association restrictions for fork usage, and add ANTHROPIC_BASE_URL env support.
The Regions table/chart on the monitor overview page was showing data for all possible regions (monitorRegions) instead of only the regions the monitor is actually configured to check. This caused unconfigured regions with zero-data rows from Tinybird to appear in the UI. Replaced monitorRegions with monitor.regions so mapRegionMetrics only processes regions the monitor is set up to use, plus any private locations. Removed the now-unnecessary isLoading conditional since mapRegionMetrics already handles the undefined-timeline case by returning placeholder entries for the given regions.
…deployments Hardcoded stpg.dev checks in the status-page middleware caused incorrect routing for self-hosted deployments where the SaaS subdomain infrastructure is unavailable. Introduces isSaasSubdomain() helper that returns false when SELF_HOST=true, and rewrites to internal paths instead of external stpg.dev URLs in self-hosted mode.
Split the custom-domain rewrite logic into separate SaaS and self-hosted code paths. In SaaS mode the slug is resolved via hostname routing on stpg.dev, so the rewrite URL must NOT include a slug prefix. In self-hosted mode the slug prefix is required and the rewrite targets req.nextUrl.origin instead of req.url. Also: - Add isSelfHosted() helper to consolidate SELF_HOST checks - Use isSelfHosted() in both domain.ts and proxy.ts - Remove unrelated dashboard client.tsx changes (monitor regions)
|
@johnib is attempting to deploy a commit to the OpenStatus Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
1 issue found across 5 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/workflows/claude.yml">
<violation number="1" location=".github/workflows/claude.yml:16">
P0: Removing the `author_association` checks allows **any** GitHub user to trigger the Claude Code action by commenting `@claude`. This exposes the repository to API credit abuse and lets untrusted users execute Claude with write permissions on pull requests and issues. Restore the authorization guards.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Comment on lines
+16
to
+19
| (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || | ||
| (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || | ||
| (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || | ||
| (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) |
There was a problem hiding this comment.
P0: Removing the author_association checks allows any GitHub user to trigger the Claude Code action by commenting @claude. This exposes the repository to API credit abuse and lets untrusted users execute Claude with write permissions on pull requests and issues. Restore the authorization guards.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/claude.yml, line 16:
<comment>Removing the `author_association` checks allows **any** GitHub user to trigger the Claude Code action by commenting `@claude`. This exposes the repository to API credit abuse and lets untrusted users execute Claude with write permissions on pull requests and issues. Restore the authorization guards.</comment>
<file context>
@@ -13,55 +13,29 @@ on:
- (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
- (github.event.issue.author_association == 'OWNER' || github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'COLLABORATOR')
- )
+ (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
+ (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
+ (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
</file context>
Suggested change
| (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || | |
| (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || | |
| (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || | |
| (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) | |
| ( | |
| github.event_name == 'issue_comment' && | |
| contains(github.event.comment.body, '@claude') && | |
| (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR') | |
| ) || | |
| ( | |
| github.event_name == 'pull_request_review_comment' && | |
| contains(github.event.comment.body, '@claude') && | |
| (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR') | |
| ) || | |
| ( | |
| github.event_name == 'pull_request_review' && | |
| contains(github.event.review.body, '@claude') && | |
| (github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'MEMBER' || github.event.review.author_association == 'COLLABORATOR') | |
| ) || | |
| ( | |
| github.event_name == 'issues' && | |
| (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && | |
| (github.event.issue.author_association == 'OWNER' || github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'COLLABORATOR') | |
| ) |
Biome's lint/performance/noDelete rule flags the delete operator. Use Reflect.deleteProperty to remove env vars in tests instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This fixes custom domain resolution for self-hosted OpenStatus deployments, as reported in #1968.
The problem
The status-page middleware has routing logic hardcoded around
stpg.dev(the SaaS platform domain). When you self-host via Docker and set up a custom domain likestatus.mycompany.com, the middleware can't resolve it — it tries to route throughstpg.devwhich doesn't exist in your environment, and you end up on a broken theme editor page.The fix
Rather than scattering
SELF_HOSTchecks everywhere, I introduced a smallisSaasSubdomain(host, slug)helper that answers "is this request hitting the SaaS subdomain?" WhenSELF_HOST=true, it always returnsfalse, so the middleware correctly takes the custom domain code path.The URL rewrite logic is now split into two paths:
{slug}.stpg.devwhere hostname routing resolves the pageI was careful to keep SaaS behavior identical — the new condition is logically equivalent to the old inline
host !== ${slug}.stpg.devcheck whenSELF_HOSTisn't set.Includes 8 new unit tests covering both modes.
Closes #1968