Paystack blocks iframes, so checkout uses a popup beside the sheet/modal chrome. Opening about:blank on the user tap keeps that window from being blocked after the async initiate response.
Paystack checkout.paystack.com returns X-Frame-Options: SAMEORIGIN, so the shared sheet opened empty. Keep mobile sheet/desktop modal chrome, launch checkout in a named window with a Continue CTA fallback, and escape payment-return via window.opener or top.
Standardize customer-facing Ladill Pay checkout shells across products, open them on all viewports, and escape iframe callbacks back to the product flow.
act_runner v0.2.x does not expose gitea.run_attempt, so release archive and
workspace paths rendered with a trailing dash. Use gitea.run_id only, matching
the Meet/CRM deploy workflows.
Use bracketed paste, reliably bind paste capture, stop blocking mousedown focus, and give shells a short prompt with horizontal-scroll readline so long pasted commands do not wrap incorrectly.
Co-authored-by: Cursor <cursoragent@cursor.com>
Certbot was including www.data.example.com for managed DNS subdomains, which NXDOMAIN and failed the whole certificate.
Co-authored-by: Cursor <cursoragent@cursor.com>
Sales Centre left Active CustomerHostingOrder rows with pending-setup.local alongside real HostingAccounts, so customers saw two hostings.
Co-authored-by: Cursor <cursoragent@cursor.com>
Hosting had PDNS env vars but no config/pdns.php and was missing domain_dkim_keys, so linked domains never got authoritative zones.
Co-authored-by: Cursor <cursoragent@cursor.com>
Async-only zone jobs left Ladill NS returning REFUSED for new domains, which surfaces as Let's Encrypt SERVFAIL during SSL issuance.
Co-authored-by: Cursor <cursoragent@cursor.com>
Treat ns_auto domains as managed DNS, publish subdomain A records via PowerDNS without failing the UX when the local DNS registry is missing, and promote real linked domains over pending-setup.local placeholders.
Co-authored-by: Cursor <cursoragent@cursor.com>
Customers can create label-based subdomains under primary/addon sites with a separate max_domains×5 quota, nginx/docroot/SSL provisioning, and managed DNS A records when Ladill controls the parent zone.
Co-authored-by: Cursor <cursoragent@cursor.com>
The hosting panel referenced /images/app_logos/*.svg but the standalone app never shipped those assets.
Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the once-per-session sessionStorage guard (which suppressed the loading
screen after its first appearance) with entry-aware logic: show on app entry
and reloads, suppress on internal link navigations and back/forward.
Surface account counts, status breakdown, and available plans in heroes consistent with Ladill Servers.
Co-authored-by: Cursor <cursoragent@cursor.com>
Expose authenticated service endpoints for assigning, listing, renewing, and managing hosting accounts from the platform, with tests and deploy docs.
Co-authored-by: Cursor <cursoragent@cursor.com>
Sync mobile-header-btn partials, mobile x-btn.create, and update dashboard header actions for consistent mobile FABs.
Co-authored-by: Cursor <cursoragent@cursor.com>
Remove duplicate Billing header above Home; wallet card follows Billing
in menu order to match the desktop avatar dropdown.
Co-authored-by: Cursor <cursoragent@cursor.com>
Show wallet balance prominently in the mobile profile bottom sheet with refresh
on open; align session lifetime with the platform default.
Co-authored-by: Cursor <cursoragent@cursor.com>
Profile moves to the bottom nav sheet on small screens; optional search tab
support is synced from the Ladill platform template.
Co-authored-by: Cursor <cursoragent@cursor.com>
Profile moves to the bottom nav sheet on small screens; optional search tab
support is synced from the Ladill platform template.
Co-authored-by: Cursor <cursoragent@cursor.com>
The toolbar showed a static ~/public_html. The jailed shell now reports its cwd
via OSC 7 each prompt (jail rcfile keeps the user's prompt + emits it); xterm
captures it and the toolbar shows the full path (/home/<user>/...), updating as
the user cd's. Launcher/rcfile committed in deployment/ for reproducibility.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The jail's /etc/passwd listed every hosting username (no passwords — shadow isn't
in the jail — but it enumerated tenants). The launcher now binds a per-session
/etc/passwd|group (root + the current user only) inside each session's mount
namespace, and the shared jail passwd no longer carries hosting users.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Inside the jail, 'cd ..' from the home landed in a non-listable /home (Permission
denied). Mount a per-session tmpfs over the jail's /home containing only the
user's own directory, so 'ls /home' shows just their folder — no other tenants
leaked, confinement unchanged. (Live host launcher already updated.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Accounts whose node has an ssh_private_key take the remote branch, which still
launched an unjailed 'runuser' shell — leaving the breach open. Route it through
the same jailkit launcher (no sudo; provider connects as root). Now every
terminal session is chrooted to the customer's own home.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>