Users with valid invitation codes don't have to provide captcha validation.
UD5T5B7ACLIM7CPSRYGXSQ3EFNS6DTPABPXJE4HQCBI7JYLE5K3QC
MU6WOCCJQWG4A5NLD3GBFATCE3SRE3QQCYXYH6WIKSGLHQOOBVRAC
QMRKFEPGFBCEWAIXPEIG5ILKAJ2JH5L3TOITHR4HNJXK5FN3KXBQC
X3ES7NUA42D2BF7CQDDKXM5CLMVCYA3H5YU5KXLPTGDBFPE2LNVAC
64C6AWH66FDKU6UE6Z6JPX2J2GBM2JOPTH2GL6LHKAIUBGNGDZ5AC
2XQD6KKKD6QVHFHAEMVE3XXY7X2T7BLTLL7XIILZAXNJJH2YONUQC
HMDM3B557TO5RYP2IGFFC2C2VN6HYZTDQ47CJY2O37BW55DSMFZAC
MB5SHULBN3WP7TGUWZDP6BRGP423FTYKF67T5IF5YHHLNXKQ5REAC
EFSXYZPOGA5M4DN65IEIDO7JK6U34DMQELAPHOIL2UAT6HRC66BAC
Z7KS5XHHC6PAMTVBHXY7KUSS3BWAOU6FSYIITUCFOOJZU4OUJHBAC
JUFBTX45TKSZMB2D4CGNB73UYM5FXAV2QMKIHBSMHEQDAECYP7HQC
M4PWY5RUV72AEDCNC4O7UKBPHBIACR4354YTSC3SUZGWFV5UBJBQC
BROSTG5KP3NUNLSYPVQID254TE47E5RKQAKLPIY7PGWETE6JNMTAC
5IDB3IWSB6LFW4U772Y7BH5Y3FQOQ7IFWLVXDZE5XS6SKJITFV4QC
F4ONFXF4MSA3QM64T7ATRVO3NQR2MC3RVZGVNGSQXCKXXQX2UG7QC
U256ZALIPTVWLNACYPIMWLNEYDQWP7CHF4Y4CGMILQTONJHMGQVQC
ENNZIQJG4XJ62QCNRMLNAXN7ICTPCHQFZTURX6QSUYYWNADFJHXQC
SQ7UMLN5WCPHIF66RO4UQVX6RSNRRZBOVZP7HEMSKP7VO6YNQPRAC
NEDDHXUK3GNFMOFO3KLU7NRIHCTYNWBT3D6HTKZAOXFDE6HMDZ6AC
M3KUPGZK2UTW4FG3Q632K7P7MI4FVWD5TTIP45UTI3E72UKOWJBAC
findInvitation :: (MonadDB m) => InvitationCode -> m (Maybe Invitation)
findInvitation ic = liftdb $ FindInvitation ic
findCurrentInvitation :: (MonadDB m) => C.UTCTime -> InvitationCode -> m (Either InvitationError Invitation)
findCurrentInvitation t ic =
maybe (Left InvitationNotFound) checkInvitation <$> liftdb (FindInvitation ic)
where
checkInvitation i
| t .-. (i ^. invitationTime) > fromSeconds (60 * 60 * 72 :: Int) = Left InvitationExpired
| isJust (i ^. acceptanceTime) = Left InvitationAlreadyAccepted
| otherwise = Right i
Nothing -> raiseSubjectNotFound act
Just i
| t .-. (i ^. invitationTime) > fromSeconds (60 * 60 * 72 :: Int) ->
raiseOpForbidden uid InvitationExpired act
Just i
| isJust (i ^. acceptanceTime) ->
raiseOpForbidden uid InvitationAlreadyAccepted act
Just i -> withProjectAuth (i ^. P.projectId) (i ^. P.invitingUser) act
Left InvitationNotFound -> raiseSubjectNotFound act
Left InvitationExpired -> raiseOpForbidden uid (InvitationError InvitationExpired) act
Left InvitationAlreadyAccepted -> raiseOpForbidden uid (InvitationError InvitationAlreadyAccepted) act
Right i -> withProjectAuth (i ^. P.projectId) (i ^. P.invitingUser) act
ALTER TABLE bids ADD COLUMN currency currency_t NOT NULL;
captchaResult <- liftIO $ checkCaptcha cfg (userData ^. captchaToken)
case captchaResult of
Left 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 invs
then checkCaptcha' (userData ^. captchaToken)
else pure () -- skip the captcha check with a valid invitation code
where
checkCaptcha' = \case
Just ct -> do
captchaResult <- liftIO $ checkCaptcha cfg ct
case captchaResult of
Left 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 ()
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'