stasis-0002.sql (3112B)
1 -- 2 -- This file is part of Anastasis 3 -- Copyright (C) 2026 Anastasis SARL 4 -- 5 -- ANASTASIS is free software; you can redistribute it and/or modify it under the 6 -- terms of the GNU General Public License as published by the Free Software 7 -- Foundation; either version 3, or (at your option) any later version. 8 -- 9 -- ANASTASIS is distributed in the hope that it will be useful, but WITHOUT ANY 10 -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 -- A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 -- 13 -- You should have received a copy of the GNU General Public License along with 14 -- ANASTASIS; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 -- 16 17 -- Everything in one big transaction 18 BEGIN; 19 20 -- Check patch versioning is in place. 21 SELECT _v.register_patch('stasis-0002', NULL, NULL); 22 23 SET search_path TO anastasis; 24 25 -- Garbage collection deletes WHERE expiration_date < $1 with no truth_uuid 26 -- predicate, so the index must lead with expiration_date; the existing 27 -- (truth_uuid, expiration_date) lookup index cannot serve that scan. 28 -- 29 -- stasis-0001 already created an index of this name, as a straight duplicate 30 -- of anastasis_challengecode_uuid_index on (truth_uuid, expiration_date). It 31 -- has to be dropped first: CREATE INDEX IF NOT EXISTS matches on the name 32 -- alone and does not compare definitions, so without this DROP every provider 33 -- that ran 0001 would silently keep the useless index, never get the one 34 -- garbage collection needs, and still have 0002 recorded as applied. 35 DROP INDEX IF EXISTS anastasis_challengecode_expiration_index; 36 CREATE INDEX anastasis_challengecode_expiration_index 37 ON anastasis_challengecode 38 (expiration_date); 39 COMMENT ON INDEX anastasis_challengecode_expiration_index 40 IS 'for challenge garbage collection'; 41 42 -- stasis-0001 commented anastasis_recdoc_payment twice: the second one, in 43 -- the anastasis_challenge_payment block, overwrote the recovery-document text 44 -- with the challenge text and left anastasis_challenge_payment itself 45 -- undocumented. 0001 is released and must stay byte-identical to what 46 -- providers already ran, so the correction lives here. 47 COMMENT ON TABLE anastasis_recdoc_payment 48 IS 'Records a payment for a recovery document'; 49 COMMENT ON TABLE anastasis_challenge_payment 50 IS 'Records a payment for a challenge'; 51 52 -- A TOTP code stays valid for a whole window of time steps, so without 53 -- remembering which step was already used an observed code can simply be 54 -- replayed while the window lasts. RFC 6238 section 5.2 requires that a code 55 -- be accepted at most once; this column is what makes that decidable. It 56 -- lives on the truth so that it is removed by the same garbage collection. 57 ALTER TABLE anastasis_truth 58 ADD COLUMN IF NOT EXISTS last_totp_counter INT8 NOT NULL DEFAULT 0; 59 COMMENT ON COLUMN anastasis_truth.last_totp_counter 60 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.'; 61 62 COMMIT;