CluPilotCloud/app/Livewire/Admin
nexxo 52aacddc56 Store the agreement where the web process can actually read it
Every link on the agreement page answered 404 — the download visibly, the
two inline ones just as dead — and nothing anywhere said why. The files
were there, whole and correct.

An artisan run inside a container is root; PHP-FPM is www-data. Laravel's
local disk creates a PRIVATE directory, which is 0700, so `dpa/` came out
as root-only. The web process could not enter it, `Storage::exists()`
answered false, and the routes did exactly what they were told: abort 404.
No exception, no log line, a page full of links to nothing.

Both writers — the command and the console's upload form — now store with
"public" visibility, which is the file MODE and nothing to do with the web:
0755/0644 instead of 0700/0600. The disk's root is outside the document
root either way, and the two routes still check who is asking. The command
also warns if a file it just wrote is not readable, because the alternative
is finding out from a customer.

The download itself now looks like one: the `download` attribute on both
anchors, and in the console a bordered control rather than a third link in
a row of two.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 17:19:39 +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
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 feat(admin): staff RBAC (spatie) + admin settings page 2026-07-25 15:47:42 +02:00
HostDetail.php feat(admin): staff RBAC (spatie) + admin settings page 2026-07-25 15:47:42 +02:00
Hosts.php Read VPN host state from the synced peer table, not a live hub call 2026-07-29 00:18:21 +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 Read the mailbox password where it actually is, and let the console test it 2026-07-30 13:12:29 +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 Say when no mail is being delivered at all 2026-07-30 13:55:55 +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
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