Commit Graph

6 Commits

Author SHA1 Message Date
Sylvain Duchesne 223059c629 Run the pod provider from images with make start, and fix what a fresh stack exposed
- docker-compose-dev.yml: the redis host port is overridable (REDIS_PORT in the root
  .env, 6379 by default as in the sibling apps), and the pod provider, in host network
  mode, follows it for its queue and OIDC redis. All of ./data/fuseki is mounted at the
  image's SEMAPPS_FUSEKI_BASE, so account deletion removes the backups and, 24 h later,
  the secure dataset's files (it answered 500 without the mount).
- backend: GET /app served the app actor snapshot the mixin takes before it creates or
  replaces the access-need group, so a dataset's first boot lacked the link until a
  restart; the app service refreshes the snapshot from the store at the end of started().
- e2e smoke: the post-install poll sends Accept: application/ld+json; the pod answers 500
  to a container read in any other format.
- Docs: cookbook (Redis port, mounts, hot reload, dataset-named accounts, fresh-boot
  note), deployment note, env examples; claims about a parallel race are no longer stated
  as fact.
2026-11-02 21:46:37 +01:00
Sylvain Duchesne 908f7ea973 Keep sign-ups unlinkable on ActivityPods, and land the pending coherence-pass work
Participation privacy (decision_2026-10-29_participation-privacy-mechanism):
a sign-up is a private Join naming the meeting point, addressed to nobody,
handled by the backend on emission. Attendee lists hold member URNs hashed
from (WebID, event, a secret kept in the participant's profile), so counts
stay public and only contacts recognise anyone; the creator has no read
right and is notified anonymously. Each person's participations collection,
created by the backend at the first sign-up, is readable by their /contacts
WAC group only, never world-readable. The member URN is sticky per
(meeting point, participant) and every collection write is verified by
reading back, so a refused write leaves the act unrecorded and retryable.
The EventRef mechanism and its browser-side provisioning are gone.

The backend now runs with WebACL on, as the reference apps do, on its own
secure datasets festipod / settings-festipod instead of the pod provider's
settings dataset; pod-notifications needs it. The compose header and the
deployment leaf say how to reset a stack whose datasets predate this.

The rights matrix covers the new mechanism live (148 hard lines), including
a forged contact Accept between throwaway accounts: the stranger enters the
contacts list (platform defect, reported upstream) but is refused the profile
and the participations. Tests may attack as long as they never break the dev
environment (rule_tests-never-break-the-dev-environment).

Also lands the coherence-pass work that was still uncommitted: contacts as
the Pod's social graph and invite links, image upload to the Pod, the
meeting-point form, profile completion gate, and the doctrine for them.
Superseded briefs and decisions are deleted rather than annotated.
2026-10-30 17:06:38 +01:00
Sylvain Duchesne 738d59596a Serve the backend under a base path: one URL per environment, the backend under /api
The test deployment keeps one base URL per environment, as the sibling
ActivityPods apps do, so a pull-request preview lives on a single host: the
app at the root, the backend under /api on the same host, its /.well-known
routes at the origin root, the proxy passing paths through unchanged.

SemApps already works that way — it mounts every route it adds under the base
URL's path and keeps /.well-known at the root — but Festipod's own pieces were
written for a backend at the root of its own origin: its routes (/app,
/as/actor/app, /catalog) were mounted at fixed paths, the public-surface
allow-list matched fixed paths (so under /api every request would have been
refused), and the Solid-OIDC client_id joined the raw request path to the base
URL, which would have repeated the base path (/api/api/...).

base-path.js derives the base path from SEMAPPS_HOME_URL; the routes are
mounted under it; the allow-list matches paths relative to it, the two
/.well-known endpoints against the full path; the client_id is the requested
URI rebuilt from the base URL as written, equal byte for byte to the actor
URI and to what the front end derives. At the root every gate decision is
identical to before (compared over ~8M method/path cases). The rights matrix
probes /.well-known at the backend's origin root.

Verified: bun test (424 pass); the full gate at the root; and the built images
behind a local proxy routing /api and /.well-known unstripped with the Host
header kept — login flow, rights matrix 98/98, revocation.
2026-10-19 16:44:09 +02:00
Sylvain Duchesne a61c8704c9 Close the login loop end-to-end: client_id is the app actor uri, actor path serves the OIDC client document via a boot-safe service, startup heals the access-need-group link, stack aligned on pod provider v2.3.12 2026-10-12 13:12:38 +02:00
Sylvain Duchesne 3aa9131a01 Serve a Solid-OIDC Client ID Document at /app for the OIDC adapter fetch, keeping the app actor for SAI 2026-10-12 11:01:34 +02:00
Sylvain Duchesne e17398d86d T04.f: backend Festipod ActivityPods + dockerisation
- Ajoute la configuration et les services backend (app, actors, registration,
  attendees, contacts, catalog, core auth/nodeinfo/proxy/notification).
- Corrige le démarrage : désactive resourcesWithContainerPath pour éviter le
  conflit entre l'URI de l'acteur applicatif (/as/actor/app) et la route /app.
- Corrige l'URL du dépôt de shapes : https://shapes.activitypods.org/.
- Ajoute backend/Dockerfile et docker-compose.yml racine (frontend + backend).
- Met à jour .env.example racine avec les variables SEMAPPS_* et VITE_BACKEND_*.
- Gates verts : bunx tsc --noEmit (0 erreur) et bun test (50 pass).
2026-10-09 13:51:02 +02:00