
module Zero.Registration.Client
  (
    initCredentialsHkdf
  , bindRegistration
  ) where

import           Control.Monad.IO.Class (liftIO)
import qualified Data.Text as T
import           Data.Text (Text)
import           Data.ByteString.Char8 (ByteString)
import           Reflex.Dom.Core
import           Zero.Sjcl.BitArray (BitArray, bitSlice)
import qualified Zero.Sjcl.Hex as Hex
import qualified Zero.Sjcl.Utf8 as Utf8
import           Zero.Sjcl.Hkdf (hkdf)
import           Zero.SRP.Client (calcV)
import           Zero.Crypto (hexBS)
import           Zero.Crypto.Client (generateBytes)
import           Zero.Account.Client (Credentials(..))
import           Zero.Registration.Internal (Registration(..))

------------------------------------------------------------------------------

initCredentialsHkdf :: MonadWidget t m => Event t (Text, Text) -> m (Event t Credentials)
initCredentialsHkdf e =
  performEvent $ ffor e $ \(email, stretchedPass) -> liftIO $ do
    srpSalt <- generateBytes 32
    stretched <- hkdf (Hex.toBits stretchedPass) (64 * 8) (Hex.toBits srpSalt) email
    let p = bitSlice stretched 0 (32 * 8)
    let w = bitSlice stretched (32 * 8) (64 * 8)
    return $ Credentials email srpSalt (Hex.fromBits p) (Hex.fromBits w)

bindRegistration :: Credentials -> Registration
bindRegistration Credentials{..} =
  let
    v = T.pack $ calcV (T.unpack c_email) (T.unpack c_salt) (T.unpack c_pass)
  in
    Registration c_email v c_salt
