@@ -52,6 +52,8 @@ import Data.Maybe
5252import Server.Auth.Token
5353import Server.Auth.Mail
5454import Data.Int
55+import Web.UAParser
56+import qualified Data.Text.Lazy as TL
5557
5658-- MARK: Documentation
5759
@@ -80,6 +82,7 @@ type RegisterDescription = Description "Register the user for a new account.\n\n
8082type AuthenticationHandler =
8183 "login" :> LoginDescription :>
8284 ReqBody '[JSON] AuthenticationCredits :>
85+ Header "User-Agent" String :>
8386 Post '[JSON] (Headers '[Header "Set-Cookie" String] UserLoginResponse) :<|>
8487 "logout" :> LogoutDescription
8588 :> Header "cookie" String
@@ -87,7 +90,9 @@ type AuthenticationHandler =
8790 "verify" :> VerifyDescription :>
8891 Header "cookie" String :> ReqBody '[JSON] Int32 :> PostNoContent '[JSON, PlainText, FormUrlEncoded] NoContent :<|>
8992 "register" :> RegisterDescription :>
90− ReqBody '[JSON] UserCreation :> PostNoContent '[JSON, PlainText, FormUrlEncoded] (Headers '[Header "Set-Cookie" String] NoContent)
93+ ReqBody '[JSON] UserCreation :>
94+ Header "User-Agent" String :>
95+ PostNoContent '[JSON, PlainText, FormUrlEncoded] (Headers '[Header "Set-Cookie" String] NoContent)
9196
9297data UserResponseStatus = UserIsRegistered | UserCanRegister | InvalidUser
9398 deriving (Show)
@@ -121,8 +126,8 @@ newtype AuthenticationCredits = AuthenticationCredits {authenticationEmail :: Us
121126authenticationAPI :: ServerT AuthenticationHandler App
122127authenticationAPI = logIn :<|> logOut :<|> verifyToken :<|> register
123128
124−logIn :: AuthenticationCredits -> App (Headers '[Header "Set-Cookie" String] UserLoginResponse)
125−logIn (AuthenticationCredits email') = do
129+logIn :: AuthenticationCredits -> Maybe String -> App (Headers '[Header "Set-Cookie" String] UserLoginResponse)
130+logIn (AuthenticationCredits email') ua' = do
126131 let email = T.toLower . T.strip $ email'
127132 if (not . validateEmail) email
128133 then return . noHeader $ UserLoginResponse InvalidUser
@@ -131,12 +136,13 @@ logIn (AuthenticationCredits email') = do
131136 case user of
132137 Nothing -> return . noHeader $ UserLoginResponse UserCanRegister
133138 Just User{..} -> do
134− token <- generateToken userId
139+ let ua = getUserAgent ua'
140+ token <- generateToken userId ua
135141 runQerror . createToken $ token
136142 let cookie = generateCookie token
137143 case tokenVerificationCode token of
138144 Just code -> do
139− sendTokenVerificationEmail code email
145+ sendTokenVerificationEmail code (TL.fromStrict ua) email
140146 return . addHeader cookie $ UserLoginResponse UserIsRegistered
141147 Nothing -> throwError err500
142148
@@ -182,25 +188,29 @@ checkToken conn (AuthenticationCookieData uId tokenData) = do
182188 token <- runQ' conn err500 $ getVerifiedToken uId tokenData
183189 case token of
184190 Nothing -> throwError invalidToken
185− Just (Token newUId _ _ _ _) -> return newUId
191+ Just (Token newUId _ _ _ _ _ _ _) -> return newUId
186192
187−register :: UserCreation -> App (Headers '[Header "Set-Cookie" String] NoContent)
188−register creation' = do
193+register :: UserCreation -> Maybe String -> App (Headers '[Header "Set-Cookie" String] NoContent)
194+register creation' ua' = do
189195 let creation = normalizaUser creation'
190196 unless (validateUser creation) $ throwError err400
191197 genToken <- generateTokenM
198+ let ua = getUserAgent ua'
192199 token <- runQ err409 . commitedTransactionallyUpdate $ do
193200 uId <- createUser creation
194− let token = genToken uId
201+ let token = genToken uId ua
195202 createToken token
196203 return token
197204 case tokenVerificationCode token of
198205 Just code -> do
199− sendTokenVerificationEmail code (userCreationUserEmail creation)
206+ sendTokenVerificationEmail code (TL.fromStrict ua) (userCreationUserEmail creation)
200207 let cookie = generateCookie token
201208 return $ addHeader cookie NoContent
202209 Nothing -> throwError err500
203210
211+getUserAgent :: Maybe String -> T.Text
212+getUserAgent = fromMaybe "Unknown" . fmap osrFamily . join . fmap parseOS . fmap C.pack
213+
204214normalizaUser :: UserCreation -> UserCreation
205215normalizaUser (UserCreation fName mName lName faculty email) =
206216 UserCreation