Files
id/Dockerfile
zooqueen 8f3f605bea fix(id): rebuild SPA so login POSTs /v1/iam/login + serve via hanzoai/spa
The deployed hanzo.id SPA (id:0.1.7, 26d old) POSTed login to /api/login
with the implicit-flow body type:"token". That path hit the SPA static
catch-all -> index.html (HTML 200) -> JSON.parse threw -> "Unable to sign
in", and even reaching IAM, type:"token" is rejected (implicit flow
disabled). Current source already POSTs /v1/iam/login with
responseType=code; a fresh build of HEAD fixes it.

- Dockerfile: final stage ghcr.io/hanzoai/static:0.4.1 -> hanzoai/spa:1.2.0.
  static's default CSP is `default-src 'none'` (no script-src/connect-src)
  which blanks the SPA and blocks fetch() to IAM; spa serves /public on
  :3000 with index.html fallback and an SPA-safe CSP (frame-ancestors
  'none'). Matches the live deploy contract (containerPort 3000, /health
  probe) exactly.
- LoginForm identifier input stays type="text" (accepts `z` and
  `[email protected]`); forgot/signup keep type="email" (semantically correct).
- Adds social-provider + email/SMS-code login UI (best-effort appLogin),
  and a signupEnabled tenant flag for invite-only tenants.
- Tenant clientId hanzo-id (verified: POST /v1/iam/login app=hanzo-id
  org=hanzo user=z -> {"status":"ok","data":"hanzo/z"}).
- Pin @hanzo/iam to ^0.9.4 (published patch line).
- apps/web 0.1.1 -> 0.1.8.
2026-06-19 10:32:01 -07:00

26 lines
1.1 KiB
Docker

# syntax=docker/dockerfile:1.7
# Hanzo ID — Vite SPA built once, served by hanzoai/spa.
FROM node:24-alpine AS build
WORKDIR /build
ENV PNPM_HOME=/pnpm PATH=$PNPM_HOME:$PATH
RUN corepack enable && corepack prepare [email protected] --activate
# Copy the full workspace first, then install. pnpm links each package's
# node_modules as symlinks into the root .pnpm store; a later `COPY apps apps`
# over an already-installed tree drops those symlinks (.dockerignore excludes
# node_modules), so install must run AFTER all source is present.
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json tsconfig.base.json ./
COPY apps apps
COPY pkgs pkgs
RUN pnpm install --frozen-lockfile=false
RUN pnpm --filter @hanzo/id-web build
# SPA server stage — hanzoai/spa serves /public on :3000 with index.html
# fallback for client-side routing and an SPA-safe CSP (frame-ancestors
# 'none' only). Must NOT be hanzoai/static: its default CSP is
# `default-src 'none'` (no script-src/connect-src), which blanks the SPA
# and blocks fetch() to IAM.
FROM ghcr.io/hanzoai/spa:1.2.0
COPY --from=build /build/apps/web/dist /public
EXPOSE 3000