--
-- This file is part of Anastasis
-- Copyright (C) 2026 Anastasis SARL
--
-- ANASTASIS is free software; you can redistribute it and/or modify it under the
-- terms of the GNU General Public License as published by the Free Software
-- Foundation; either version 3, or (at your option) any later version.
--
-- ANASTASIS is distributed in the hope that it will be useful, but WITHOUT ANY
-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License along with
-- ANASTASIS; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
--

-- Everything in one big transaction
BEGIN;

-- Check patch versioning is in place.
SELECT _v.register_patch('stasis-0002', NULL, NULL);

SET search_path TO anastasis;

-- Garbage collection deletes WHERE expiration_date < $1 with no truth_uuid
-- predicate, so the index must lead with expiration_date; the existing
-- (truth_uuid, expiration_date) lookup index cannot serve that scan.
--
-- stasis-0001 already created an index of this name, as a straight duplicate
-- of anastasis_challengecode_uuid_index on (truth_uuid, expiration_date).  It
-- has to be dropped first: CREATE INDEX IF NOT EXISTS matches on the name
-- alone and does not compare definitions, so without this DROP every provider
-- that ran 0001 would silently keep the useless index, never get the one
-- garbage collection needs, and still have 0002 recorded as applied.
DROP INDEX IF EXISTS anastasis_challengecode_expiration_index;
CREATE INDEX anastasis_challengecode_expiration_index
  ON anastasis_challengecode
  (expiration_date);
COMMENT ON INDEX anastasis_challengecode_expiration_index
  IS 'for challenge garbage collection';

-- stasis-0001 commented anastasis_recdoc_payment twice: the second one, in
-- the anastasis_challenge_payment block, overwrote the recovery-document text
-- with the challenge text and left anastasis_challenge_payment itself
-- undocumented.  0001 is released and must stay byte-identical to what
-- providers already ran, so the correction lives here.
COMMENT ON TABLE anastasis_recdoc_payment
  IS 'Records a payment for a recovery document';
COMMENT ON TABLE anastasis_challenge_payment
  IS 'Records a payment for a challenge';

-- A TOTP code stays valid for a whole window of time steps, so without
-- remembering which step was already used an observed code can simply be
-- replayed while the window lasts.  RFC 6238 section 5.2 requires that a code
-- be accepted at most once; this column is what makes that decidable.  It
-- lives on the truth so that it is removed by the same garbage collection.
ALTER TABLE anastasis_truth
  ADD COLUMN IF NOT EXISTS last_totp_counter INT8 NOT NULL DEFAULT 0;
COMMENT ON COLUMN anastasis_truth.last_totp_counter
  IS 'Highest TOTP time step counter already accepted for this truth; a code for this or an earlier step is a replay and is refused. Zero means no code was accepted yet. Unused for other authentication methods.';

COMMIT;
