Skip to content

Account And Downloads

Use this guide when adding customer account pages.

The ⓐ copied account Astro template files cover:

  • magic-link access;
  • account overview;
  • orders and protected invoice links;
  • subscriptions;
  • licenses;
  • downloads;
  • account export and delete request examples.

Account pages are host-owned Astro pages that call createMika(Astro). They should not project raw provider invoice URLs or raw storage paths to the browser. Use Mika-issued hrefs and token-bound routes.

Before exposing account pages in production, the host needs a session/customer policy, magic-link or stronger auth delivery, account rate limits, and storage for tokens, entitlements, licenses, downloads, export requests, and delete requests. Mika supplies the operation contracts and copied page examples; it does not decide who is allowed to see an account.

Treat AUTH_REQUIRED as “not signed in”, not as an error, and redirect first when the billing portal action returns a URL:

---
import { createMika } from "@bnomei/emdash-mika/astro";
import { actions } from "astro:actions";
export const prerender = false;
const Mika = createMika(Astro);
const portal = Astro.getActionResult(actions.mika.account.portal);
if (portal?.data?.redirectUrl) return Astro.redirect(portal.data.redirectUrl);
const result = await Mika.account.get();
const account = result.ok ? result.data : null;
const signInRequired = !result.ok && result.error.code === "AUTH_REQUIRED";
---

account.get() returns orders, subscriptions, entitlements, and downloads in one AccountDTO. Export and delete are forms posting account.export and account.delete — use bracket access for the reserved words: actions.mika.account["export"] and actions.mika.account["delete"].

Mika supplies passwordless magic-link request and verify actions. The host still owns session policy, link delivery, account gating, and any stronger authentication requirements. Request a link with magicLink.request (field email):

<form action={actions.mika.magicLink.request} method="post">
<input name="email" type="email" required />
<button type="submit">Email me a link</button>
</form>

The emailed link lands on a host page (e.g. /account/magic-link?token=...) that posts magicLink.verify (field token) and redirects to the account on success.

Downloads are tokenized. The package template provides a host-owned .astro interstitial page at templates/astro/pages/download/[token].astro that renders a GET confirmation page and consumes with download.confirm on POST. The seeded template repo uses the same .astro interstitial shape for its fixture download route.

A host can instead write a custom API route that resolves the token to a redirect. Never expose raw storage paths:

src/pages/download/[token].ts
import { createMika } from "@bnomei/emdash-mika/astro";
import type { APIRoute } from "astro";
export const prerender = false;
export const GET: APIRoute = async ({ params, request, url, redirect }) => {
const Mika = createMika({ request, url }); // a minimal { request, url } context, not full Astro
const result = await Mika.download.resolve(params.token!);
if (!result.ok) return new Response(result.error.message, { status: result.status });
if (result.data.redirectUrl) return redirect(result.data.redirectUrl);
return new Response("Download unavailable.", { status: 404 });
};

Account screens link download.href (tokenized) and order.invoiceHref (behind Mika’s protected order.invoice route) — never raw provider invoice URLs. Licenses show only a key suffix, never the full key.

Account export download uses a read-before-consume pattern. account.export returns an AccountExportDTO with a tokenized downloadHref when the export is ready. The protected route operation account.exportDownload (GET account/export/download) validates the export id and token without consuming the token, then returns requiresConfirmation: true and confirmMethod: "POST". The paired account.exportDownloadConsume operation (POST account/export/download) calls the same API with consumeToken: true and returns the artifact href only after confirmation.

This mirrors the regular download interstitial: GET can render a confirmation screen, while POST consumes a one-time token. Used or revoked export tokens return Mika token errors such as TOKEN_USED or DOWNLOAD_REVOKED.

The ⓣ seeded GitHub template repo documents /download/download_panel_pack_mira as a smoke-test path only. It is available when the sibling emdash-mika-template app is running with its fixture seed data.

That route is browser-reachable because src/pages/download/[token].astro is a seeded-repo host page. In the seeded repo fixture, download_panel_pack_mira is a literal seeded token for “Mira Panel Pack Download”; after POST confirmation it redirects to a local placeholder file under /template-downloads/.

Do not model production tokens after that readable fixture name. Production download resolution should use Mika-issued opaque tokens, expiry, token consumption, paid-order checks, and entitlement or license revocation checks before redirecting to a signed asset URL. The mira suffix is just the demo product/customer naming used by the seeded repo fixtures.

  • Account pages treat AUTH_REQUIRED as a sign-in state.
  • Download links use Mika tokenized hrefs, not raw storage paths.
  • Invoice links stay behind protected order/invoice resolution.
  • Production download tokens are opaque, expiring, and checked against paid-order or entitlement state.

Next: Backend And Provider covers the trusted API behind these account flows. Security And Idempotency covers the host policy boundary.

  • ../emdash-mika/src/templates/astro/pages/account.astro
  • ../emdash-mika/src/templates/astro/pages/account/orders.astro
  • ../emdash-mika/src/templates/astro/pages/account/magic-link.astro
  • ../emdash-mika/src/templates/astro/components/AccountSignInPanel.astro
  • ../emdash-mika/src/templates/astro/components/MagicLinkForm.astro
  • ../emdash-mika/src/templates/astro/pages/download/[token].astro
  • ../emdash-mika/src/api/operations.ts
  • ../emdash-mika/src/api/types.ts
  • ../emdash-mika/src/api/backend.ts
  • ../emdash-mika-template/src/pages/download/[token].astro
  • ../emdash-mika-template/src/lib/mika-fixture-storefront.ts
  • ../emdash-mika-template/seed/mika-actions.seed.json