Update email invitation workflow.
[?]
Jan 9, 2021, 6:13 AM
UD5T5B7ACLIM7CPSRYGXSQ3EFNS6DTPABPXJE4HQCBI7JYLE5K3QCDependencies
- [2]
MU6WOCCJUpdate auctions to permit zcash as a funding currency. - [3]
HMDM3B55Implement core of payments/billing infrastructure. - [4]
M3KUPGZKAdd invitation email template. - [5]
NLZ3JXLOFix formatting with stylish-haskell. - [6]
U256ZALIAdd captcha check to register route. - [7]
5IDB3IWSIntegrate zcashd-based zaddr validation. - [8]
NEDDHXUKReformat via stylish-haskell - [9]
2XQD6KKKAdd invitation logic and clean up DBProg error handling. - [10]
ENNZIQJGUse live signup API for client. - [11]
EFSXYZPOAutoformat everything with brittany. - [12]
MB5SHULBAdd route for accepting an invitation with an existing account - [13]
X3ES7NUAFine. I'll use ormolu. At least it doesn't break the code. - [14]
O2BZOX7MAdd signup form, captcha check. - [15]
SQ7UMLN5Get z-addr checks working. - [16]
BROSTG5KBeginning of modularization of server. - [17]
BXGLKYRXAdded primitive user registration handler. - [18]
QMRKFEPGRefactor QDB to use a free monad algebra instead. - [19]
Z7KS5XHHVery WIP. Wow. - [20]
M4PWY5RUPreliminary work to add support for Zcash payments. - [21]
F4ONFXF4Fix signup database issues. - [*]
64C6AWH6Rename Ananke -> Quixotic, project reboot. - [*]
JUFBTX45Add project auction queries.
Change contents
- edit in lib/Aftok/Database.hs at line 104
data InvitationError= InvitationExpired| InvitationAlreadyAccepted| InvitationNotFoundderiving (Eq, Show) - replacement in lib/Aftok/Database.hs at line 114
| InvitationExpired| InvitationAlreadyAccepted| InvitationError InvitationError - replacement in lib/Aftok/Database.hs at line 222
findInvitation :: (MonadDB m) => InvitationCode -> m (Maybe Invitation)findInvitation ic = liftdb $ FindInvitation icfindCurrentInvitation :: (MonadDB m) => C.UTCTime -> InvitationCode -> m (Either InvitationError Invitation)findCurrentInvitation t ic =maybe (Left InvitationNotFound) checkInvitation <$> liftdb (FindInvitation ic)wherecheckInvitation i| t .-. (i ^. invitationTime) > fromSeconds (60 * 60 * 72 :: Int) = Left InvitationExpired| isJust (i ^. acceptanceTime) = Left InvitationAlreadyAccepted| otherwise = Right i - replacement in lib/Aftok/Database.hs at line 233
inv <- findInvitation icinv <- findCurrentInvitation t ic - replacement in lib/Aftok/Database.hs at line 236[3.6088]→[3.28852:28892](∅→∅),[3.28892]→[3.29309:29556](∅→∅),[3.29556]→[3.28893:28968](∅→∅),[3.8393]→[3.28893:28968](∅→∅)
Nothing -> raiseSubjectNotFound actJust i| t .-. (i ^. invitationTime) > fromSeconds (60 * 60 * 72 :: Int) ->raiseOpForbidden uid InvitationExpired actJust i| isJust (i ^. acceptanceTime) ->raiseOpForbidden uid InvitationAlreadyAccepted actJust i -> withProjectAuth (i ^. P.projectId) (i ^. P.invitingUser) actLeft InvitationNotFound -> raiseSubjectNotFound actLeft InvitationExpired -> raiseOpForbidden uid (InvitationError InvitationExpired) actLeft InvitationAlreadyAccepted -> raiseOpForbidden uid (InvitationError InvitationAlreadyAccepted) actRight i -> withProjectAuth (i ^. P.projectId) (i ^. P.invitingUser) act - edit in migrations/2021-01-03_16-15-52_auction-descriptions.txt at line 8[2.6903]
ALTER TABLE bids ADD COLUMN currency currency_t NOT NULL; - replacement in server/Aftok/Snaplet/Users.hs at line 18
import Aftok.Database (acceptInvitation, createUser)import Aftok.Database (acceptInvitation, createUser, findCurrentInvitation) - replacement in server/Aftok/Snaplet/Users.hs at line 39
import Data.Text as Timport Data.Text.Encoding as Timport qualified Data.Text as Timport qualified Data.Text.Encoding as T - replacement in server/Aftok/Snaplet/Users.hs at line 76
_captchaToken :: Text,_captchaToken :: Maybe Text, - replacement in server/Aftok/Snaplet/Users.hs at line 94
<*> (v .: "captchaToken")<*> (parseInvitationCodes . maybeToList =<< v .:? "invitation_codes")<*> (v .:? "captchaToken")<*> (parseInvitationCodes . join . maybeToList =<< v .:? "invitation_codes") - replacement in server/Aftok/Snaplet/Users.hs at line 141
captchaResult <- liftIO $ checkCaptcha cfg (userData ^. captchaToken)case captchaResult ofLeft err ->let cmsg = "Captcha check failed, please try again."in snapErrorJS 400 cmsg (RegCaptchaError err)Right _ -> pure ()now <- liftIO C.getCurrentTime(_, invs) <- partitionEithers <$> snapEval (traverse (findCurrentInvitation now) (userData ^. invitationCodes))if null invsthen checkCaptcha' (userData ^. captchaToken)else pure () -- skip the captcha check with a valid invitation code - edit in server/Aftok/Snaplet/Users.hs at line 158
now <- liftIO C.getCurrentTime - edit in server/Aftok/Snaplet/Users.hs at line 166
wherecheckCaptcha' = \caseJust ct -> docaptchaResult <- liftIO $ checkCaptcha cfg ctcase captchaResult ofLeft err ->let cmsg = "Captcha check failed, please try again."in snapErrorJS 400 cmsg (RegCaptchaError err)Right _ -> pure ()Nothing ->let cmsg = "Captcha token or invitation code required."in snapErrorJS 400 cmsg () - replacement in server/templates/invitation_email.st at line 29
curl -k -v -H 'Content-Type: application/json' -d '{"username":"USER", "password":"PASS", "email":"$to_email$", "btcAddr":"BTC_ADDR", "invitation_codes":["$inv_code$"]}' 'https://aftok.com/register'curl --header 'Content-Type: application/json' \\--data '{"username":"USER", "password":"PASS", "recoveryType": "email", "recoveryEmail":"$to_email$", "invitation_codes":["$inv_code$"]}' \\'https://aftok.com/api/register'