Better-auth v1.5.6 stores raw 32-char tokens in sessions.token, not SHA-256
hashes. The SHA-256 fix from PR #136 causes all authenticated API calls to
return 401 because the UAT sessions table contains raw tokens.
- Remove hashlib from dependencies.py; compare tokens directly
- Remove hashlib from conftest.py; store raw tokens in test DB
- Remove hashlib from test_expired_session_rejected; use raw tokens
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Better-Auth v1.2+ stores SHA-256(raw_token) in the sessions.token
column. The cookie/Bearer header carries the raw token, so the API was
doing a plain-text lookup that would never match a hashed value —
causing all authenticated endpoints to return 401.
- Add hashlib import and hash token in _validate_session_token()
- Update conftest._create_test_user_and_session() to store hashed tokens
- Update test_expired_session_rejected() to store hashed tokens
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Better-auth sets the session cookie with the __Secure- prefix on HTTPS
deployments. The API was only reading the plain cookie name, causing all
authenticated calls to return 401 in dev/UAT/prod environments.
Check __Secure-better-auth.session_token first, fall back to
better-auth.session_token for HTTP local dev compatibility.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Default varchar(32) alembic_version column truncates long revision IDs
like 003_make_users_hashed_password_nullable (39 chars) on fresh databases.
Set version_table_column_width=128 in both context.configure() calls.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Create migration 007 to raw-SQL CREATE TABLE IF NOT EXISTS the users table
as a safety net for fresh databases where Base.metadata.create_all() may
fail due to import errors before the table is created.
Wrap the create_all call in env.py with try/except so alembic never crashes
due to create_all failures — migrations already handle table creation.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
psycopg2 compiled against libpq-dev in the build stage now has
its runtime dependency (libpq5) available in the prod stage.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Better-Auth creates users via raw SQL INSERT (not through SQLAlchemy),
so it bypasses ORM defaults and causes HTTP 500 on sign-up/sign-in.
Adds PostgreSQL server_default so INSERT without email_inbound_token
auto-generates a URL-safe token matching Python secrets.token_urlsafe(16).
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The sha_tag output is a 40-char SHA, but docker/metadata-action
defaults to short (7-char) SHA tags. This caused UAT pods to fail
image pulls because kustomization tags didn't match GHCR tags.
Change type=sha,prefix=sha- to type=sha,prefix=sha-,format=long
in all four build jobs (cartsnitch, auth, receiptwitness, api).
Fixes CAR-482.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
PR #111 fixed the build context to ./api but forgot to also update
the file path. The job was using ./Dockerfile (the frontend Dockerfile
which references nginx.conf and package-lock.json from the repo root),
causing the API image build to fail with a cache checksum error.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Fix email format in AuthService.get_email_in_address to use
receipts+{token}@receipts.cartsnitch.com (was broken: @email.cartsnitch.com)
- Remove dead EmailInAddressResponse class and GET /auth/me/email-in-address
endpoint from auth/routes.py (endpoint moved to routes/user.py)
- Add instructions field to EmailInAddressResponse schema
- Update routes/user.py to include instructions in the response
- Update test URLs from /auth/me/email-in-address to /api/v1/me/email-in-address
Co-authored-by: CartSnitch Engineer Bot <cartnoreply@cartsnitch.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Mirrors deploy-dev job but targets apps/overlays/uat. Both deploy-dev
and deploy-uat run in parallel after all build jobs complete.
Co-authored-by: CartSnitch Engineer Bot <cartnoreply@cartsnitch.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>