Feat/345 add support for custom domains#369
Conversation
This commit implements organization-level custom domains with SSL certificates via Cloudflare for SaaS, including: Backend: - Custom domain model and repository - Cloudflare for SaaS API integration - Custom domain CRUD API endpoints - KV dual-write for hostname:short_code mappings - Redirect handler updates for custom domain resolution - Scheduled polling for domain status updates - Admin API for manual domain polling and listing - Database migration for custom_domains table Frontend: - Custom domain management UI - Admin domains page with manual polling button - Admin API client updates - Domains API client - Admin sidebar navigation updates Infrastructure: - Added CF_SAAS_API_TOKEN secret to staging and production workflows - Added domain polling cron to production Tier limits enforced at organization level.
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
Add the support for a custom fallback domain so that we're not limited to using the existing one, and allow the use of a sub-domain such as `redirect.my-domain.com` if preferred.
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
Cloudflare for SaaS is an Enterprise-only feature. When quota is not allocated, fall back to dev/test mode instead of failing with 500 error. - Add quota error detection (error 1404 or 'quota' in message) - Return stub DNS instructions when CF for SaaS unavailable - Update documentation to clarify Enterprise plan requirement
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
…tion Cloudflare for SaaS now returns ACME validation records in ssl.validation_records instead of ownership_verification. This fixes the TXT record mismatch where the dashboard showed _cf-custom-hostname but Cloudflare expected _acme-challenge. - Add validation_records field to CfSslResult - Update domain creation to check both validation_records and ownership_verification - Prioritize ACME validation records if available
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
… domains Cloudflare for SaaS requires TWO different TXT verification methods: 1. Domain ownership verification (_cf-custom-hostname.*) - validates hostname ownership 2. SSL certificate validation (_acme-challenge.*) - validates for certificate issuance Both are required for production traffic. The previous implementation only showed one TXT record, causing verification failures when Cloudflare expected the other type. This ensures users see all required TXT records with clear labels indicating which is for domain ownership vs SSL certificate validation.
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
SSL validation records (_acme-challenge.*) are only returned when the certificate is in pending_validation state. The initial CREATE response may not include them - they appear after Cloudflare starts the certificate issuance process. Added a follow-up GET call after creating the custom hostname to fetch the full hostname details, which includes the validation_records when the SSL status becomes pending_validation.
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
The SSL validation records (_acme-challenge.*) from Cloudflare are returned by the GET endpoint, not just on creation. For non-wildcard hostnames, CF uses HTTP validation automatically once the CNAME is set, but falls back to TXT if that fails (showing "Pending Validation (TXT)").
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
The refresh endpoint was only returning dns_instructions when the hostname status was not active. But the hostname can be "active" while the SSL certificate is still "Pending Validation (TXT)" - this is the common case after CNAME validation succeeds but before SSL completes. Now when a user clicks Refresh: - If SSL certificate is still pending (even if hostname is active) - The response includes both _cf-custom-hostname and _acme-challenge records - The frontend displays all required TXT records
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
Changes: - Added ssl_status field to CustomDomain model with SSL_STATUS_* constants - Added database migration 0031_ssl_status.sql for ssl_status column - Updated CustomDomainRepository to include ssl_status in all queries - Added update_ssl_status() method to persist SSL status from Cloudflare - Updated refresh endpoint to persist ssl_status from Cloudflare API - Updated frontend CustomDomain type to include ssl_status - Updated frontend to auto-fetch DNS instructions on page load if SSL is pending - Show Refresh button for active domains (not just pending) Now when a user reloads the page: - If any domain has ssl_status === "pending", the DNS instructions panel automatically shows with the SSL validation TXT records - Users can click Refresh on active domains to re-check SSL status
|
🚀 Ephemeral Environment Deployed (Unified Worker) Application: https://rushomon-pr-369.piffio.workers.dev This unified Worker deployment serves both frontend and backend from the same domain for better security (httpOnly cookies work correctly). This environment will be automatically cleaned up when the PR is closed. Worker: 💡 Tip: To skip preview deployment, add the |
This PR implements organization-level custom domains with SSL
certificates via Cloudflare for SaaS, including:
Backend:
Frontend:
Infrastructure:
Tier limits are enforced at the organisation level.
Closes #345