postUploadR :: Handler ()
postUploadR = do
    -- Allows cross-domain AJAX requests.
    -- See <https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS>.
    addHeader "Access-Control-Allow-Origin" "*"

    ((res, _), _) <- runFormPostNoToken uploadForm
    withFormSuccess res $ \ (~(file:_), Options public mEmail) -> do
        -- Allocates an new admin key if the client doesn't have one.
        mAdminKey <- getAdminKey
        adminKeyId <- case mAdminKey of
            Just (AdminKeyUser (Entity i _) _ _) -> return i
            Just (AdminKeyAnon (Entity i _))     -> return i
            Nothing                              -> do
                adminKeyId <- runDB newAdminKey
                setAdminKey adminKeyId
                return adminKeyId

        -- Process the file.
        eUpload <- processFile adminKeyId file public
        case eUpload of
            Right upload -> do
                let hmac  = uploadHmac upload
                    route = ViewR $ toPathPiece hmac
                whenJust mEmail (sendEmailLink upload route)
                sendObjectCreated hmac route
            Left err -> do
                let status = case err of
                        DailyIPLimitReached -> tooManyRequests429
                        FileTooLarge -> requestEntityTooLarge413
                sendErrorResponse status [err]

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

-- | Creates a form for the upload and its options.
postUploadR :: Handler ()
postUploadR = do
    -- Allows cross-domain AJAX requests.
    -- See <https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS>.
    addHeader "Access-Control-Allow-Origin" "*"

    ((res, _), _) <- runFormPostNoToken uploadForm
    withFormSuccess res $ \ (~(file:_), Options public mEmail) -> do
        -- Allocates an new admin key if the client doesn't have one.
        mAdminKey <- getAdminKey
        adminKeyId <- case mAdminKey of
            Just (AdminKeyUser (Entity i _) _ _) -> return i
            Just (AdminKeyAnon (Entity i _))     -> return i
            Nothing                              -> do
                adminKeyId <- runDB newAdminKey
                setAdminKey adminKeyId
                return adminKeyId

        -- Process the file.
        eUpload <- processFile adminKeyId file public
        case eUpload of
            Right upload -> do
                let hmac  = uploadHmac upload
                    route = ViewR $ toPathPiece hmac
                whenJust mEmail (sendEmailLink upload route)
                sendObjectCreated hmac route
            Left err -> do
                let status = case err of
                        DailyIPLimitReached -> tooManyRequests429
                        FileTooLarge -> requestEntityTooLarge413
                sendErrorResponse status [err]

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

-- | Creates a form for the upload and its options.
postUploadR = do
    -- Allows cross-domain AJAX requests.
    -- See <https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS>.
    addHeader "Access-Control-Allow-Origin" "*"

    ((res, _), _) <- runFormPostNoToken uploadForm
    withFormSuccess res $ \ (~(file:_), Options public mEmail) -> do
        -- Allocates an new admin key if the client doesn't have one.
        mAdminKey <- getAdminKey
        adminKeyId <- case mAdminKey of
            Just (AdminKeyUser (Entity i _) _ _) -> return i
            Just (AdminKeyAnon (Entity i _))     -> return i
            Nothing                              -> do
                adminKeyId <- runDB newAdminKey
                setAdminKey adminKeyId
                return adminKeyId

        -- Process the file.
        eUpload <- processFile adminKeyId file public
        case eUpload of
            Right upload -> do
                let hmac  = uploadHmac upload
                    route = ViewR $ toPathPiece hmac
                whenJust mEmail (sendEmailLink upload route)
                sendObjectCreated hmac route
            Left err -> do
                let status = case err of
                        DailyIPLimitReached -> tooManyRequests429
                        FileTooLarge -> requestEntityTooLarge413
                sendErrorResponse status [err]

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

-- | Creates a form for the upload and its options.