--
-- This file is part of TALER
-- Copyright (C) 2025 Taler Systems SA
--
-- TALER 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.
--
-- TALER 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
-- TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
--

-- @file merchant-0023.sql
-- @brief Create table to store MFA related information
-- @author Christian Grothoff


BEGIN;

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

SET search_path TO merchant;


-- See enum TALER_MERCHANT_MFA_Channel
CREATE TYPE tan_enum
  AS ENUM ('sms', 'email', 'totp');

-- See enum TALER_MERCHANT_MFA_CriticalOperation
CREATE TYPE op_enum
  AS ENUM ('instance_provision', 'account_config', 'auth_config', 'instance_deletion', 'auth_token_creation');

CREATE TABLE tan_challenges
  (challenge_id INT8 GENERATED BY DEFAULT AS IDENTITY UNIQUE
  ,h_body BYTEA NOT NULL CHECK (LENGTH(h_body)=32)
  ,salt BYTEA NOT NULL CHECK (LENGTH(salt)=16)
  ,op op_enum NOT NULL
  ,code TEXT NOT NULL
  ,creation_date INT8 NOT NULL
  ,expiration_date INT8 NOT NULL
  ,retransmission_date INT8 NOT NULL DEFAULT 0
  ,confirmation_date INT8 DEFAULT NULL
  ,retry_counter INT4 NOT NULL
  ,tan_channel tan_enum NOT NULL
  ,required_address TEXT NOT NULL
);
COMMENT ON TABLE tan_challenges
  IS 'Stores multi-factor authorization (MFA) challenges';
COMMENT ON COLUMN tan_challenges.challenge_id
  IS 'Unique identifier for the challenge';
COMMENT ON COLUMN tan_challenges.h_body
  IS 'Salted hash of the body of the original request that triggered the challenge, to be replayed once the challenge is satisfied.';
COMMENT ON COLUMN tan_challenges.salt
  IS 'Salt used when hashing the original body.';
COMMENT ON COLUMN tan_challenges.op
  IS 'The protected operation to run after the challenge';
COMMENT ON COLUMN tan_challenges.code
  IS 'The pin code sent to the user and verified';
COMMENT ON COLUMN tan_challenges.creation_date
  IS 'Creation date of the code';
COMMENT ON COLUMN tan_challenges.retransmission_date
  IS 'When did we last transmit the challenge to the user';
COMMENT ON COLUMN tan_challenges.expiration_date
  IS 'When will the code expire';
COMMENT ON COLUMN tan_challenges.confirmation_date
  IS 'When was this challenge successfully verified, NULL if pending';
COMMENT ON COLUMN tan_challenges.retry_counter
  IS 'How many tries are left for this code; must be > 0';
COMMENT ON COLUMN tan_challenges.tan_channel
  IS 'TAN channel to use, if NULL use customer configured one';
COMMENT ON COLUMN tan_challenges.required_address
  IS 'Address to which the challenge will be sent';

CREATE INDEX tan_challenges_expiration_index
  ON tan_challenges (expiration_date);
COMMENT ON INDEX tan_challenges_expiration_index
  IS 'for garbage collection';

ALTER TABLE merchant_donau_instances
  ADD CONSTRAINT merchant_donau_charity_unique
    UNIQUE (donau_url, merchant_instance_serial, charity_id);

COMMIT;
