AttestoPhoenix.Store.EctoCIBAStore (AttestoPhoenix v1.2.0)

Copy Markdown View Source

Ecto/Postgres implementation of Attesto.CIBAStore.

Every state transition is a single guarded atomic statement, so the CIBA authentication-request state machine is race-free across nodes:

  • approve/3 / deny/2UPDATE ... WHERE status = 'pending' AND expires_at > $now RETURNING, so the user's decision is taken exactly once and never lands on an expired request.
  • poll/2 — one conditional UPDATE ... SET last_polled_at = $now WHERE auth_req_id_hash = $1 AND (last_polled_at IS NULL OR last_polled_at <= $now - interval) RETURNING, enforcing the CIBA Core §7.3 minimum token-request interval (the ROW's interval column - the value the client was told at issue) and reading the row's state in the same statement. A zero-row result is disambiguated as slow_down vs unknown by one follow-up existence check (both are non-mint outcomes, so it is not a security race).
  • consume/2UPDATE ... SET status = 'consumed' WHERE status = 'approved' AND expires_at > $now RETURNING, so an approved request mints exactly one token family.

Backs the schema AttestoPhoenix.Schema.CIBARequest. Only the auth_req_id's hash is stored.