module Foundation.Yesod.ErrorHandler ( errorHandler ) where import Import.NoFoundation hiding (errorHandler) import Foundation.Type import Foundation.I18n import Foundation.Authorization import Foundation.SiteLayout import Foundation.Routes import Foundation.DB import qualified Data.Aeson as JSON import qualified Data.Text as Text import qualified Network.Wai as W errorHandler :: ( MonadSecretBox (HandlerFor UniWorX) , MonadSecretBox (WidgetFor UniWorX) , MonadSecretBox (ExceptT EncodedSecretBoxException (HandlerFor UniWorX)) , MonadAuth (HandlerFor UniWorX) , BearerAuthSite UniWorX , YesodPersistBackend UniWorX ~ SqlBackend ) => ErrorResponse -> HandlerFor UniWorX TypedContent errorHandler err = do let shouldEncrypt' = getsYesod $ view _appEncryptErrors canDecrypt' = runDBRead $ hasWriteAccessTo AdminErrMsgR decrypted' <- runMaybeT $ do internalErrorContent <- hoistMaybe $ err ^? _InternalError exceptTMaybe $ encodedSecretBoxOpen @Text internalErrorContent let isEncrypted = is _Just decrypted' shouldEncrypt <- andM [ shouldEncrypt' , return $ not isEncrypted , not <$> canDecrypt' ] let decrypted = guardOnM (not shouldEncrypt) decrypted' sessErr <- bool return (traverseOf _InternalError $ encodedSecretBox SecretBoxShort) shouldEncrypt err void . runMaybeT $ do reqHost <- MaybeT $ W.requestHeaderHost <$> waiRequest approotHost <- MaybeT . getsYesod $ approotScopeHost ApprootDefault when (approotHost /= reqHost) $ do authErr <- lift $ encodedAuth sessErr redirect (ErrorR, [(toPathPiece GetError, authErr)]) when (is _NotAuthenticated err) $ do authed <- is _Just <$> maybeAuthId unless authed $ do mCurrent <- getCurrentRoute gets' <- reqGetParams <$> getRequest wai <- waiRequest maybe clearUltDest setUltDest $ do current <- mCurrent case current of _ | W.requestMethod wai /= "GET" -> Nothing ErrorR -> Nothing current' -> Just (current', gets') $logInfoS "errorHandler" "Redirect to LoginR" redirect $ AuthR LoginR setSessionJson SessionError sessErr selectRep $ do provideRep $ do mr <- getMessageRender let encrypted :: Text -> WidgetFor UniWorX () -> WidgetFor UniWorX () encrypted plaintextJson plaintext = do let displayEncrypted ciphertext = [whamlet| $newline never

_{MsgErrorResponseEncrypted}

                    #{ciphertext}
                |]
          if
            | isEncrypted && shouldEncrypt -> displayEncrypted plaintextJson
            | shouldEncrypt -> displayEncrypted =<< encodedSecretBox SecretBoxPretty plaintextJson
            | otherwise -> plaintext

        errPage = case err of
          NotFound -> [whamlet|

_{MsgErrorResponseNotFound}|] InternalError err' -> encrypted err' [whamlet|

#{fromMaybe err' decrypted}|] InvalidArgs errs -> [whamlet|