Skip to content

Releases: phlare/elixir-api-core

v0.4.1

28 Apr 15:30
185ec37

Choose a tag to compare

Docs + dependabot-config slice. No functional or dependency changes since v0.4.0.

Docs

  • Self-contained .claude/instructions/ so the template is usable standalone outside the parent workspace. Adds repo-local ci_cd.md, points pre-existing commit_workflow and dependabot_workflow references intra-repo, flags shared Elixir/Phoenix conventions as workspace-only.
  • Guidance parity refresh between AGENTS.md and CLAUDE.md.

Infra

  • Dependabot schedule: weekly → daily, with grouped patch/minor bumps and individual majors. open-pull-requests-limit 5 → 10. Conventional-commit scope in titles.

v0.4.0 — Soft delete, GDPR purge, admin, and transactional email

17 Apr 06:57
23ba2a4

Choose a tag to compare

  • Users and sole-owned accounts are now soft-deletable via deleted_at

  • Two-step deletion: soft_delete_user (user-facing, reversible) then
    purge_user! (hard delete for GDPR right-to-erasure)

  • Admin controller at /api/v1/admin/users with list/show/delete/restore/purge

  • system_admin role + RequireSystemAdmin plug

  • Daily CleanupDeletedUsersWorker auto-purges users soft-deleted past TTL

  • soft_delete_user preserves earlier account deleted_at timestamps as
    provenance; restore_user only restores accounts co-deleted with the user
    (exact deleted_at match)

  • Provider-agnostic Swoosh plumbing: Local adapter in dev (mailbox viewer
    on :4001), Test adapter in tests, commented production adapter
    placeholder in runtime.exs. Downstream projects bring their own adapter

  • Oban :email queue with a template+args worker pattern so jobs stay
    JSON-serializable and the Swoosh.Email is rebuilt on perform

  • Email verification flow:

    • POST /api/v1/auth/verify_email (public, token in body)
    • POST /api/v1/auth/send_verification (authenticated, rate-limited)
    • Auth.register/1 auto-enqueues a verification email
    • email_verified_at is recorded but does not gate login (downstream
      projects decide what, if anything, to gate)
  • Password reset flow:

    • POST /api/v1/auth/request_password_reset (public, rate-limited,
      always 200 to prevent enumeration)
    • POST /api/v1/auth/reset_password (public)
    • Reset tokens embed a password-hash fingerprint so replays after a
      successful reset are rejected (one-shot without a nonce table)
  • Rate-limit buckets for reset normalize on trim+downcase so whitespace/
    case variants share a bucket

  • Requires APP_URL and FROM_EMAIL env vars in prod

  • verify_email is POST + JSON. Any client previously calling
    GET /api/v1/auth/verify_email must switch to POST with {token} in the
    body. The email link now targets APP_URL/verify-email?token=X (a
    frontend page that collects the token and POSTs it to the API),
    mirroring the reset-password pattern.

  • APP_URL and FROM_EMAIL are required at boot in prod.

  • 274 tests, 0 failures; Dialyzer clean

  • Includes: soft delete (#7e5f53f), email infra (#1550b5e), review fixes (#60bc026)

v0.3.2

12 Apr 22:47
c9d1d07

Choose a tag to compare

Dependencies

  • oban 2.20.3 → 2.21.1
  • bandit 1.10.3 → 1.10.4

Docs

  • Added self-contained .claude/instructions/ for commit workflow and dependabot workflow

v0.3.1 — CORS credentials + token TTL

18 Mar 19:02
472428a

Choose a tag to compare

Changes

  • CORS credentials supportcredentials: true in CORS config (dev + prod) so browsers include HttpOnly cookies in cross-origin requests. Pairs with web-app-core v0.5.0's cookie-based refresh token transport.
  • Reduce refresh token TTL — 30 days → 7 days, limiting blast radius of compromised tokens.
  • Remove CHANGELOG.md — in favor of GitHub releases.

Closes #22

v0.3.0 — Security Hardening

17 Mar 07:06
bfc8293

Choose a tag to compare

Security Hardening

All items from the 2026-03-16 security audit addressed:

  • Security headers plugX-Content-Type-Options: nosniff and Cache-Control: no-store on all auth endpoints
  • Request body size limit — 1MB cap on Plug.Parsers (down from default 8MB)
  • Password max length — 128-char limit to prevent bcrypt truncation and CPU exhaustion
  • OAuth state validation — signed cookie stores state during google_start, verified with secure_compare on callback
  • CORS explicit origins — configurable per environment (dev: localhost, test: all, prod: CORS_ALLOWED_ORIGINS env var)
  • Rate limiting wired up — login (5/60s) and refresh (10/60s) endpoints enforce IP-based rate limits, return 429 + Retry-After

Other fixes

  • Bandit read_timeout moved to runtime.exs so it isn't overridden
  • localhost:5173 (Vite) added to default CORS origins

Stats

  • 159 tests, 0 failures
  • 20 files changed, +354 / -27 lines

v0.2.2

15 Mar 00:36
9f31ba1

Choose a tag to compare

What's new

  • CORS supportcors_plug added to endpoint. Permissive in dev, configurable via CORS_ALLOWED_ORIGINS env var in prod (#10)
  • Dialyzer fix:ex_unit added to plt_add_apps to resolve false positives on ExUnit internals in Elixir 1.19 + OTP 28 (#12)
  • Bandit timeout config — Dev read_timeout increased to 5 min to prevent error-level log noise from idle browser connections (#11)

v0.2.1 — Bug Fix and Housekeeping

12 Mar 06:24
a697a97

Choose a tag to compare

Changes

  • Fix: logout no longer crashes when no refresh token is provided in request body or cookie
  • Add GitHub Sponsors funding configuration
  • Add web-app-core cross-links to README
  • Remove docs/PLATFORM_TEMPLATES.md (consolidated into tiny-inbox-product/docs/)

Full Changelog: v0.2...v0.2.1

v0.2

07 Mar 18:22
dace0b9

Choose a tag to compare

What's Changed

  • CI fix: oasdiff breaking-change check now extracts base spec to workspace for Docker compatibility
  • Dependabot: actions/checkout bumped from v4 to v6
  • Docs: Added Related Templates section to README linking elixir-api-core and node-edge-core

No code changes — CI, docs, and dependency maintenance only.

v0.1.0

07 Mar 04:40

Choose a tag to compare

v0.1.0 — Initial Release
Multi-tenant identity, authentication, and authorization template for Phoenix APIs.

Highlights
10 endpoints — register, login, refresh, logout, switch account, Google OAuth (start/callback), /me, health, readiness
JWT access tokens (HS256, 15 min) + opaque refresh tokens (SHA-256 HMAC, 30 day, rotated)
Refresh rotation with reuse detection — replaying a revoked token revokes all user tokens
Multi-tenancy — accounts, users, memberships with role enforcement (owner | admin | member)
Owner invariant — row-level locking guarantees every account always has at least one owner
Google OAuth — configurable provider behaviour with three linking rules (login, link, create)
ETS-backed rate limiting for login and refresh endpoints
Oban background jobs — example worker + expired token cleanup
Fail-fast config validation — blocks unsafe dev secrets in production
OpenAPI 3.1 spec for all endpoints
Stack
Elixir 1.19.5 | OTP 28 | Phoenix 1.8 | PostgreSQL

Stats
122 tests, 0 failures | 7 DB tables | 5 core schemas | MIT licensed