CluPilotCloud/app/Livewire/Admin
nexxo 006ce3568b Manage hostnames and watch their certificates from the console
files.clupilot.com is why this exists. DNS pointed at the right machine, the
env var was set, the release was deployed — and there was still no certificate,
because /etc/caddy/Caddyfile is maintained by hand and nobody thought of it as a
second, separate step. Nothing in the console would have said so. Three settings
looked correct and the address did not answer.

So the page holds two things side by side. The WISH — which names should be
served — and the REALITY: whether the name has a certificate and for how much
longer. The second is measured by opening a TLS connection and reading the
expiry, not by reading configuration, because the configuration is exactly what
looked right while the address was dead. verify_peer stays on: a certificate
that fails validation is not a certificate for this question, and a display that
called it valid would be the fake R19 records.

Applying goes through the existing agent, not a new channel. The console writes
a request, the path unit wakes the agent within a second, and the agent calls one
fixed command line of the root-owned helper.

What that helper is allowed to do is the careful part. It fetches the list
ITSELF rather than being handed one, and the list is HOSTNAMES, never Caddy
blocks — `php artisan clupilot:proxy-hosts` prints `<name> <purpose>` and nothing
else. Each name is matched against a strict pattern before it is used, and the
template around it lives in the helper, which the service account cannot touch.
install-agent.sh already states the principle for the sudoers grant: a grant is
only worth anything if the holder cannot change what it grants. A service account
that could write proxy configuration would have everything the proxy can do —
redirects anywhere, files from any directory.

Purpose is a column rather than a habit. A console name gets the network lock,
a public one does not, and a console name published without it looks exactly
like a working page.

Removing takes the name out of the list and NOT out of the running proxy. Two
decisions in one click, and the second one takes a site off the air.

There is deliberately no "renew" button. Caddy renews on its own at two thirds
of the lifetime; what an operator actually needs is a second attempt after an
issuance has failed, and that is a reload — which is what Apply does. Thirty days
is treated as a problem rather than a warning: at ninety days' lifetime, a
renewal should long since have run, so anything under it is not a tight
certificate but a renewal that is not happening.

The ACME contact falls back to the owner's address, because a contact nobody
reads is the step before expired customer certificates.

CONTRACT and HOST_STEP_NEEDS both move to 2, which is what tells a server
carrying the older helper to run the installer again — caught by the guard test
that compares the two halves.

2035 tests pass, assets build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 22:55:55 +02:00
..
Capacity.php Take the order, park it, and say when it will be delivered 2026-07-29 18:50:46 +02:00
ConfirmDeleteDatacenter.php fix(admin): authorize datacenter modal mounts; stale threshold uses step maxDuration 2026-07-25 18:23:44 +02:00
ConfirmDeleteIncident.php Let an incident be deleted, and start measuring whether the hosts answer 2026-07-29 15:16:48 +02:00
ConfirmDeletePlanDraft.php feat(admin): a console for creating, pricing and scheduling plans 2026-07-26 12:41:51 +02:00
ConfirmDeleteVpnPeer.php feat(vpn): ownership, a Developer role, and password-gated config retrieval 2026-07-25 22:31:54 +02:00
ConfirmDisableTwoFactor.php Replace native confirm() dialogs with the app's own modal pattern 2026-07-28 19:34:27 +02:00
ConfirmEndOtherSessions.php Show where an account is signed in, and let it sign the other places out 2026-07-28 23:38:17 +02:00
ConfirmForgetSecret.php Replace native confirm() dialogs with the app's own modal pattern 2026-07-28 19:34:27 +02:00
ConfirmPublishDpa.php Deliver the processing agreement, and hold the proof it was accepted 2026-07-30 16:56:57 +02:00
ConfirmReissueVpnPeer.php Replace native confirm() dialogs with the app's own modal pattern 2026-07-28 19:34:27 +02:00
ConfirmRemoveHost.php feat(admin): staff RBAC (spatie) + admin settings page 2026-07-25 15:47:42 +02:00
ConfirmRestartInstance.php Restart a machine, enforce the quota that was sold, end a route that ended 2026-07-29 18:28:28 +02:00
ConfirmSaveEnv.php Add a raw .env editor to the Integrations page, with a net under it 2026-07-29 01:51:27 +02:00
ConfirmSaveSecret.php Replace native confirm() dialogs with the app's own modal pattern 2026-07-28 19:34:27 +02:00
ConfirmSwitchMode.php Put the switch where it governs, and say when it is thrown 2026-07-30 15:09:38 +02:00
CustomerDetail.php Put the open tab in the address bar, including the first one 2026-07-29 23:46:13 +02:00
Customers.php Ask whether they are a consumer, and let one change their mind 2026-07-29 21:06:06 +02:00
Datacenters.php Let a datacenter code be corrected while nothing depends on it, and say which building 2026-07-28 22:25:21 +02:00
EditCustomer.php Take the address by field, fix the customer type, ask why they leave 2026-07-30 16:41:32 +02:00
EditDatacenter.php Let a datacenter code be corrected while nothing depends on it, and say which building 2026-07-28 22:25:21 +02:00
EditExportTarget.php Let a destination say how it is laid out and how long anything stays 2026-07-29 03:08:27 +02:00
EditInvoiceSeries.php Give the console a Finance tab: company details, VAT rate, invoice series 2026-07-29 01:18:43 +02:00
EditMailTemplate.php Show the customer, and write the answers once 2026-07-29 22:37:30 +02:00
EditPlanFamily.php Move each plan's marketing copy from the controller into the console 2026-07-29 14:31:44 +02:00
Finance.php Quote what a person pays, and tab the settings page 2026-07-29 19:18:10 +02:00
GrantPlan.php Grant a package or module from the customer's row in the console 2026-07-29 12:42:21 +02:00
HostCreate.php Give the operator one line to copy and three steps around it 2026-07-30 20:40:19 +02:00
HostDetail.php feat(admin): staff RBAC (spatie) + admin settings page 2026-07-25 15:47:42 +02:00
Hosts.php Put the instructions where somebody reads them before they start 2026-07-30 20:51:47 +02:00
Inbox.php Read the mailbox password where it actually is, and let the console test it 2026-07-30 13:12:29 +02:00
Incidents.php Let an incident be deleted, and start measuring whether the hosts answer 2026-07-29 15:16:48 +02:00
InstanceAdminAccess.php Send an operator with an expired session to sign in, not a 500 2026-07-28 18:09:22 +02:00
Instances.php Deliver the storage a customer actually buys 2026-07-29 19:13:10 +02:00
Integrations.php Merge main into the operating-mode branch 2026-07-30 17:53:20 +02:00
Invoices.php Take the invoice year off the storage clock too 2026-07-29 02:28:34 +02:00
Mail.php Merge credentials and infrastructure into one Integrations page 2026-07-29 01:49:39 +02:00
MailLog.php Keep a register of what was sent, and answer the customer from here 2026-07-29 21:02:36 +02:00
MailPreview.php Accept terms instead of a start date, and fix the sender no server accepts 2026-07-30 15:22:35 +02:00
MailTemplates.php Say that a click landed, and make moving one actually move it 2026-07-29 23:06:30 +02:00
Maintenance.php Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
NewInvoice.php Write an invoice for work that came off no price list 2026-07-29 20:12:26 +02:00
Overview.php Merge main into the operating-mode branch 2026-07-30 17:53:20 +02:00
PlanVersions.php Sell the year as well as the month, and say what it saves 2026-07-30 15:44:35 +02:00
Plans.php Let the owner mark one plan as recommended, from the console 2026-07-29 14:22:22 +02:00
ProcessingAgreements.php Store the agreement where the web process can actually read it 2026-07-30 17:19:39 +02:00
Provisioning.php Fix nine defects in the provisioning pipelines 2026-07-30 01:34:55 +02:00
ProxyHosts.php Manage hostnames and watch their certificates from the console 2026-07-30 22:55:55 +02:00
Readiness.php Fix round: point at the real tab, hide the button nobody can press, prove the quiet page load 2026-07-30 16:26:10 +02:00
RecordWithdrawal.php Charge the price the website shows, and hand a withdrawal back in full 2026-07-29 22:42:02 +02:00
Revenue.php Skip the invoice for a full gift, keep it out of revenue, hide its price 2026-07-29 12:41:32 +02:00
Sessions.php Show where an account is signed in, and let it sign the other places out 2026-07-28 23:38:17 +02:00
Settings.php Put the open tab in the address bar, including the first one 2026-07-29 23:46:13 +02:00
TwoFactorSetup.php Quote what a person pays, and tab the settings page 2026-07-29 19:18:10 +02:00
Vpn.php Replace native confirm() dialogs with the app's own modal pattern 2026-07-28 19:34:27 +02:00
VpnConfigAccess.php Send an operator with an expired session to sign in, not a 500 2026-07-28 18:09:22 +02:00