Use live signup API for client.

[?]
Oct 5, 2020, 7:50 PM
ENNZIQJG4XJ62QCNRMLNAXN7ICTPCHQFZTURX6QSUYYWNADFJHXQC

Dependencies

  • [2] 5IDB3IWS Integrate zcashd-based zaddr validation.
  • [3] SAESJLLY Initial experiments in hash routing.
  • [4] 4FDQGIXN Make payment request retrieval key an opaque 32-bit hash.
  • [5] AL37SVTC Implement payments service endpoints.
  • [6] DFOBMSAO Initial work on payments API
  • [7] JFOEOFGA stylish-haskell formatting.
  • [8] Q5X5RYQL stylish-haskell reformatting
  • [9] EFSXYZPO Autoformat everything with brittany.
  • [10] BROSTG5K Beginning of modularization of server.
  • [11] BFZN4SUA Make timeline component work.
  • [12] TKGBRIQT Login component now raises LoginComplete message.
  • [13] UWMGUJOW Autoformat sources.
  • [14] 4R7XIYK3 Switch from ClassyPrelude to Relude
  • [15] O2BZOX7M Add signup form, captcha check.
  • [16] U256ZALI Add captcha check to register route.
  • [17] 4U7F3CPI THE GREAT RENAMING OF THINGS!
  • [18] WRPIYG3E Use project listing functionality to check for whether we have a cookie.
  • [19] HMDM3B55 Implement core of payments/billing infrastructure.
  • [20] B6HWAPDP Modularize & update to recent haskoin.
  • [21] MB5SHULB Add route for accepting an invitation with an existing account
  • [22] 73NDXDEZ Begin implementation of billing event persistence.
  • [23] IPG33FAW Add billing daemon
  • [24] I2KHGVD4 Require project permissions for access to most data.
  • [25] 64C6AWH6 Rename Ananke -> Quixotic, project reboot.
  • [26] LTSVBVA2 Update to a recent haskoin-core. Fix Stack build.
  • [27] W35DDBFY Factor common JSON conversions up into client lib module.
  • [28] IZEVQF62 Work in progress replacing sqlite with postgres.
  • [29] SEWTRB6S Implement payment request creation functions.
  • [30] NJNMO72S Add zcash.com submodule and update client to modern halogen.
  • [31] QU5FW67R Add project selection to time tracker.
  • [32] 5R2Z7FSX Initial rendering for signup controls.
  • [33] NEDDHXUK Reformat via stylish-haskell
  • [*] RB2ETNIF Add skeletal PureScript client project.
  • [*] Y3LIJ5US Add handler for CreatePaymentRequest
  • [*] EMVTF2IW WIP moving back to snap.
  • [*] 2XQD6KKK Add invitation logic and clean up DBProg error handling.
  • [*] ADMKQQGC Initial empty Snap project.

Change contents

  • replacement in aftok.cabal at line 1
    [3.1][3.1:20]()
    cabal-version: 2.4
    [3.1]
    [3.37]
    cabal-version: 3.0
  • edit in aftok.cabal at line 19
    [3.129]
    [3.44]
    , MultiParamTypeClasses
  • edit in aftok.cabal at line 21
    [3.84]
    [3.122]
    , RankNTypes
  • replacement in client/src/Aftok/Api/Account.purs at line 5
    [3.198][3.198:239]()
    import Control.Monad.Trans.Class (lift)
    [3.198]
    [3.239]
    import Data.Argonaut.Core (stringify)
  • edit in client/src/Aftok/Api/Account.purs at line 16
    [3.548][3.548:857]()
    import Halogen as H
    import Halogen.HTML.Core (ClassName(..))
    import Halogen.HTML as HH
    import Halogen.HTML.CSS as CSS
    import Halogen.HTML.Events as E
    import Web.Event.Event as WE
    import Halogen.HTML.Properties as P
    import CSS (backgroundImage, url)
    import Landkit.Card as Card
    import Aftok.Types (System)
  • edit in client/src/Aftok/Api/Account.purs at line 73
    [3.2595]
    [3.2595]
    | ServiceError (Maybe StatusCode) String
  • edit in client/src/Aftok/Api/Account.purs at line 75
    [3.2596]
    [3.2596]
    instance srShow :: Show SignupResponse where
    show r = case r of
    SignupOK -> "SignupOK"
    CaptchaInvalid -> "CaptchaInvalid"
    ZAddrInvalid -> "ZAddrInvalid"
    UsernameTaken -> "UsernameTaken"
    ServiceError _ _ -> "ServiceError"
  • replacement in client/src/Aftok/Api/Account.purs at line 88
    [3.2691][3.2691:2708]()
    = ZAddrCheckOK
    [3.2691]
    [3.2708]
    = ZAddrCheckValid
  • replacement in client/src/Aftok/Api/Account.purs at line 97
    [3.2902][3.2902:2922]()
    pure ZAddrCheckOK
    [3.2902]
    [3.2922]
    result <- get RF.ignore ("/api/validate_zaddr?zaddr=" <> zaddr)
    case result of
    Left err -> do
    log ("ZAddr validation failed: " <> printError err)
    pure ZAddrCheckInvalid
    Right r | r.status == StatusCode 200 -> do
    pure ZAddrCheckValid
    Right r -> do
    log ("ZAddr was determined to be invalid: " <> r.statusText)
    pure ZAddrCheckInvalid
  • replacement in client/src/Aftok/Api/Account.purs at line 114
    [3.568][3.568:974]()
    RecoverByEmail _ => "email"
    RecoverByZAddr _ => "zaddr"
    , email: case req.recoverBy of
    RecoverByEmail email -> Just email
    RecoverByZAddr _ -> Nothing
    , zaddr: case req.recoverBy of
    RecoverByEmail _ -> Nothing
    RecoverByZAddr zaddr -> Just zaddr
    [3.568]
    [2.155]
    RecoverByEmail _ -> "email"
    RecoverByZAddr _ -> "zaddr"
    , recoveryEmail: case req.recoverBy of
    RecoverByEmail email -> Just email
    RecoverByZAddr _ -> Nothing
    , recoveryZAddr: case req.recoverBy of
    RecoverByEmail _ -> Nothing
    RecoverByZAddr zaddr -> Just zaddr
  • replacement in client/src/Aftok/Api/Account.purs at line 124
    [3.984][2.197:272]()
    result <- post RF.ignore "/api/register" (Just <<< RB.Json $ signupJson)
    [3.984]
    [2.272]
    log ("Sending JSON request: " <> stringify signupJSON)
    result <- post RF.ignore "/api/register" (Just <<< RB.Json $ signupJSON)
  • replacement in client/src/Aftok/Api/Account.purs at line 127
    [2.289][2.289:422]()
    Left err -> log ("Registration failed: " <> printError err)
    Right r -> log ("Registration status: " <> show r.status)
    [2.289]
    [2.422]
    Left err -> do
    log ("Registration failed: " <> printError err)
    pure (ServiceError Nothing $ printError err)
    Right r | r.status == StatusCode 200 -> do
    log "Registration succeeded!"
    pure SignupOK
    Right r | r.status == StatusCode 403 -> do
    log ("Registration failed: Capcha Invalid")
    pure CaptchaInvalid
    Right r | r.status == StatusCode 400 -> do
    log ("Registration failed: Z-Address Invalid")
    pure ZAddrInvalid
    Right r -> do
    log ("Registration failed: " <> r.statusText)
    pure $ ServiceError (Just r.status) r.statusText
  • edit in client/src/Aftok/Signup.purs at line 222
    [3.6997]
    [3.6997]
    lift $ system.log "Switching to signin..."
  • replacement in client/src/Aftok/Signup.purs at line 226
    [3.7114][3.7114:7154]()
    Acc.ZAddrCheckOK -> pure unit
    [3.7114]
    [3.7154]
    Acc.ZAddrCheckValid -> pure unit
  • edit in client/src/Aftok/Signup.purs at line 230
    [3.7261]
    [3.7261]
    lift $ system.log "Switching to signin..."
  • edit in client/src/Aftok/Signup.purs at line 247
    [3.8103]
    [3.8103]
    lift $ system.log "Sending signup request..."
  • replacement in client/src/Aftok/Signup.purs at line 255
    [3.8503][3.8503:8529]()
    Left errors ->
    [3.8503]
    [3.8529]
    Left errors -> do
    lift $ system.log "Got signup HTTP error."
  • edit in client/src/Aftok/Signup.purs at line 260
    [3.8654]
    [3.8654]
    lift <<< system.log $ "Got signup response " <> show response
  • replacement in client/src/Aftok/Signup.purs at line 262
    [3.8683][3.8683:9003]()
    Acc.SignupOK -> H.raise (SignupComplete $ req.username)
    Acc.CaptchaInvalid -> H.modify_ (_ { signupErrors = [CaptchaError] })
    Acc.ZAddrInvalid -> H.modify_ (_ { signupErrors = [ZAddrInvalid] })
    Acc.UsernameTaken -> H.modify_ (_ { signupErrors = [UsernameTaken] })
    [3.8683]
    [3.6157]
    Acc.SignupOK -> H.raise (SignupComplete $ req.username)
    Acc.CaptchaInvalid -> H.modify_ (_ { signupErrors = [CaptchaError] })
    Acc.ZAddrInvalid -> H.modify_ (_ { signupErrors = [ZAddrInvalid] })
    Acc.UsernameTaken -> H.modify_ (_ { signupErrors = [UsernameTaken] })
    Acc.ServiceError c m -> H.modify_ (_ { signupErrors = [APIError { status: c, message: m }]})
  • edit in client/src/Aftok/Signup.purs at line 337
    [3.8397]
    [3.8397]
    apiCapability :: Capability Aff
    apiCapability =
    { checkUsername: \_ -> pure Acc.UsernameCheckOK
    , checkZAddr: Acc.checkZAddr
    , signup: Acc.signup
    , getRecaptchaResponse: liftEffect <<< getRecaptchaResponse
    }
  • replacement in client/src/Aftok/Signup.purs at line 349
    [3.9088][3.9088:9132]()
    , checkZAddr: \_ -> pure Acc.ZAddrCheckOK
    [3.9088]
    [3.9132]
    , checkZAddr: \_ -> pure Acc.ZAddrCheckValid
  • replacement in client/src/Main.purs at line 34
    [3.1617][3.1572:1609]()
    signup = Signup.mockCapability
    [3.1617]
    [3.7682]
    signup = Signup.apiCapability
  • edit in daemon/AftokD/AftokM.hs at line 35
    [3.1781][3.131:191]()
    import Haskoin.Address ( Address )
  • edit in daemon/AftokD/AftokM.hs at line 48
    [3.2506][3.2506:2566]()
    , userEmail
  • edit in daemon/AftokD/AftokM.hs at line 49
    [3.2623][3.2623:2791]()
    )
    import Aftok.Currency.Bitcoin ( NetworkId
    , satoshi
  • edit in daemon/AftokD/AftokM.hs at line 50
    [3.2841]
    [3.2841]
    import Aftok.Currency.Bitcoin ( satoshi )
  • edit in daemon/AftokD/AftokM.hs at line 55
    [3.3077]
    [3.3077]
    , ContactChannel(..)
    , contactChannel
  • replacement in daemon/AftokD/AftokM.hs at line 160
    [3.5418][3.5418:5558]()
    -> P.PaymentRequest'
    ( Subscription'
    (User (NetworkId, Address))
    (Billable' Project UserId Satoshi)
    )
    [3.5418]
    [3.5558]
    -> P.PaymentRequest' (Subscription' User (Billable' Project UserId Satoshi))
  • replacement in daemon/AftokD/AftokM.hs at line 173
    [3.5817][3.1349:1370](),[3.6526][3.1349:1370]()
    Just template ->
    [3.5817]
    [3.6548]
    Just template -> do
    toEmail <- case req ^. (subscription . contactChannel) of
    EmailChannel email -> pure email
    -- TODO: other channels
  • edit in daemon/AftokD/AftokM.hs at line 178
    [3.6596][3.5818:5885]()
    toEmail = req ^. (subscription . customer . userEmail)
  • replacement in daemon/AftokD/AftokM.hs at line 191
    [3.1603][3.7345:7417](),[3.57711][3.7345:7417](),[3.7345][3.7345:7417]()
    in pure $ SMTP.simpleMail fromAddr [toAddr] [] [] subject [body]
    [3.57711]
    [3.7417]
    pure $ SMTP.simpleMail fromAddr [toAddr] [] [] subject [body]
  • replacement in lib/Aftok/Billables.hs at line 16
    [3.915][3.3389:3443](),[3.3443][3.57798:57837]()
    import Aftok.Types (UserId, ProjectId)
    import Bippy.Types (Satoshi)
    [3.915]
    [3.981]
    import Aftok.Types (UserId, ProjectId, Email)
    import Bippy.Types (Satoshi)
  • edit in lib/Aftok/Billables.hs at line 77
    [36.62]
    [3.1423]
    data ContactChannel
    = EmailChannel Email
  • replacement in lib/Aftok/Billables.hs at line 82
    [3.149][3.149:189](),[3.189][3.1480:1508](),[3.659][3.1480:1508](),[3.1480][3.1480:1508](),[3.1508][3.660:694]()
    { _customer :: u
    , _billable :: b
    , _startTime :: C.UTCTime
    , _endTime :: Maybe C.UTCTime
    [3.149]
    [3.3491]
    { _customer :: u
    , _billable :: b
    , _contactChannel :: ContactChannel
    , _startTime :: C.UTCTime
    , _endTime :: Maybe C.UTCTime
  • edit in lib/Aftok/Database/PostgreSQL.hs at line 246
    [3.18233]
    [3.18233]
    <*> (B.EmailChannel . Email <$> field)
  • replacement in lib/Aftok/Database/PostgreSQL.hs at line 678
    [3.24347][3.24347:24400]()
    [sql| SELECT id, billable_id, start_date, end_date
    [3.24347]
    [3.16985]
    [sql| SELECT id, billable_id, contact_email, start_date, end_date
  • replacement in lib/Aftok/Database/PostgreSQL.hs at line 685
    [3.24543][3.24543:24607]()
    [sql| SELECT s.id, user_id, billable_id, start_date, end_date
    [3.24543]
    [3.17151]
    [sql| SELECT s.id, user_id, billable_id, contact_email, start_date, end_date
  • replacement in lib/Aftok/Database/PostgreSQL.hs at line 742
    [3.18176][3.18176:18247]()
    s.user_id, s.billable_id, s.start_date, s.end_date,
    [3.18176]
    [3.18247]
    s.user_id, s.billable_id, s.contact_email, s.start_date, s.end_date,
  • edit in lib/Aftok/Database.hs at line 8
    [37.427]
    [3.1442]
    -- brittany --disable-next-binding
  • replacement in lib/Aftok/Users.hs at line 14
    [2.4308][2.4308:4365]()
    { parseZAddr :: Text -> m (Either RegisterError ZAddr)
    [2.4308]
    [2.4365]
    { parseZAddr :: Text -> m (Either ZAddrError ZAddr)
  • replacement in server/Aftok/Snaplet/Users.hs at line 6
    [3.2560][3.3137:3157](),[3.8604][3.3137:3157](),[3.3137][3.3137:3157](),[3.3157][3.449:477]()
    ( registerHandler
    , acceptInvitationHandler
    [3.8604]
    [3.9796]
    ( acceptInvitationHandler
    , checkZAddrHandler
    , registerHandler
  • edit in server/Aftok/Snaplet/Users.hs at line 41
    [38.10432]
    [2.4786]
    import Aftok.Currency.Zcash ( ZAddr )
  • replacement in server/Aftok/Snaplet/Users.hs at line 76
    [3.5684][3.5684:5741](),[3.5741][2.5513:5570]()
    "email" -> RecoverByEmail . Email <$> v .: "email"
    "zaddr" -> RecoverByZAddr <$> v .: "zaddr"
    [3.5684]
    [3.5798]
    "email" -> RecoverByEmail . Email <$> v .: "recoveryEmail"
    "zaddr" -> RecoverByZAddr <$> v .: "recoveryZAddr"
  • edit in server/Aftok/Snaplet/Users.hs at line 94
    [3.4425]
    [2.5802]
    checkZAddrHandler :: RegisterOps IO -> S.Handler App App ZAddr
    checkZAddrHandler ops = do
    params <- S.getParams
    zaddrBytes <- maybe (snapError 400 "zaddr parameter is required")
    pure
    (listToMaybe =<< M.lookup "zaddr" params)
    zaddrEither <- liftIO $ parseZAddr ops (T.decodeUtf8 zaddrBytes)
    case zaddrEither of
    Left _ ->
    snapError 400 "The Z-Address provided for account recovery was invalid."
    Right zaddr ->
    pure zaddr
  • edit in server/Aftok/Snaplet/Users.hs at line 113
    [3.6412]
    [3.6412]
  • replacement in server/Aftok/Snaplet/Users.hs at line 125
    [2.6330][2.6330:6465]()
    Left _ -> snapError 400 "The Z-Address provided for account recovery was invalid."
    Right r -> pure $ RecoverByZAddr r
    [2.6330]
    [2.6465]
    Left _ ->
    snapError 400 "The Z-Address provided for account recovery was invalid."
    Right r ->
    pure $ RecoverByZAddr r
  • edit in server/Aftok/Snaplet/Users.hs at line 142
    [2.6677][2.6677:6678]()
  • edit in server/Main.hs at line 22
    [3.11390][2.6847:6917]()
    import Aftok.Users ( RegisterError(..) )
  • replacement in server/Main.hs at line 51
    [2.7004][2.7004:7109]()
    { parseZAddr =
    (pure . first ZAddrParseError)
    <=< rpcValidateZAddr mgr (_zcashdConfig cfg)
    [2.7004]
    [2.7109]
    { parseZAddr = rpcValidateZAddr mgr (_zcashdConfig cfg)
  • edit in server/Main.hs at line 77
    [38.12971]
    [2.7246]
    checkZAddrRoute = void $ method GET (checkZAddrHandler rops)
  • edit in server/Main.hs at line 133
    [3.16973]
    [3.16973]
    , ("validate_zaddr", checkZAddrRoute)