packages feed

snaplet-sqlite-simple-jwt-auth 0.1.0.0 → 0.1.1.0

raw patch · 3 files changed

+89/−4 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Snap.Snaplet.SqliteSimple.JwtAuth.Db: DbUser :: Int -> Text -> ByteString -> DbUser
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: [dbuserHashedPass] :: DbUser -> ByteString
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: [dbuserId] :: DbUser -> Int
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: [dbuserLogin] :: DbUser -> Text
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: createInitialSchema :: Connection -> IO ()
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: createTableIfMissing :: MVar Connection -> IO ()
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: data DbUser
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: executeSingle :: (ToRow q) => Query -> q -> H b ()
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: fromDbUser :: DbUser -> User
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: insertUser :: Text -> ByteString -> Handler b SqliteJwt ()
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: instance Database.SQLite.Simple.FromRow.FromRow Snap.Snaplet.SqliteSimple.JwtAuth.Db.DbUser
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: instance GHC.Classes.Eq Snap.Snaplet.SqliteSimple.JwtAuth.Db.DbUser
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: instance GHC.Show.Show Snap.Snaplet.SqliteSimple.JwtAuth.Db.DbUser
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: jwtAuthTable :: Text
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: qconcat :: [Text] -> Query
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: querySingle :: (ToRow q, FromRow a) => Query -> q -> H b (Maybe a)
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: queryUser :: Text -> Handler b SqliteJwt (Maybe DbUser)
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: schemaVersion :: Connection -> IO Int
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: setSchemaVersion :: Connection -> Int -> IO ()
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: tableExists :: Connection -> Text -> IO Bool
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: upgradeSchema :: Connection -> Int -> IO ()
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: userTable :: Text
- Snap.Snaplet.SqliteSimple.JwtAuth.Db: versionTable :: Text
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: DuplicateLogin :: AuthFailure
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: SqliteJwt :: Secret -> MVar Connection -> SqliteJwt
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: UnknownUser :: AuthFailure
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: User :: Int -> Text -> User
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: WrongPassword :: AuthFailure
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: [siteSecret] :: SqliteJwt -> Secret
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: [sqliteJwtConn] :: SqliteJwt -> MVar Connection
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: [userId] :: User -> Int
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: [userLogin] :: User -> Text
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: createUser :: Text -> Text -> Handler b SqliteJwt (Either AuthFailure User)
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: data AuthFailure
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: data SqliteJwt
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: data User
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: jsonResponse :: MonadSnap m => m ()
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: login :: Text -> Text -> Handler b SqliteJwt (Either AuthFailure User)
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: loginUser :: Handler b SqliteJwt ()
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: registerUser :: Handler b SqliteJwt ()
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: reqJSON :: (MonadSnap m, FromJSON b) => m b
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: requireAuth :: (User -> Handler b SqliteJwt a) -> Handler b SqliteJwt a
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: sqliteJwtInit :: String -> Snaplet Sqlite -> SnapletInit b SqliteJwt
- Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth: writeJSON :: (MonadSnap m, ToJSON a) => a -> m ()
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: DuplicateLogin :: AuthFailure
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: HttpError :: Int -> String -> HttpError
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: LoginParams :: Text -> Text -> LoginParams
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: SqliteJwt :: Secret -> MVar Connection -> SqliteJwt
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: UnknownUser :: AuthFailure
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: User :: Int -> Text -> User
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: WrongPassword :: AuthFailure
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: [lpLogin] :: LoginParams -> Text
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: [lpPass] :: LoginParams -> Text
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: [siteSecret] :: SqliteJwt -> Secret
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: [sqliteJwtConn] :: SqliteJwt -> MVar Connection
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: [userId] :: User -> Int
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: [userLogin] :: User -> Text
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: data AuthFailure
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: data HttpError
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: data LoginParams
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: data SqliteJwt
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: data User
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: instance Data.Aeson.Types.FromJSON.FromJSON Snap.Snaplet.SqliteSimple.JwtAuth.Types.LoginParams
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: instance Data.Aeson.Types.FromJSON.FromJSON Snap.Snaplet.SqliteSimple.JwtAuth.Types.User
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: instance Data.Aeson.Types.ToJSON.ToJSON Snap.Snaplet.SqliteSimple.JwtAuth.Types.User
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: instance GHC.Classes.Eq Snap.Snaplet.SqliteSimple.JwtAuth.Types.AuthFailure
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: instance GHC.Classes.Eq Snap.Snaplet.SqliteSimple.JwtAuth.Types.User
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: instance GHC.Show.Show Snap.Snaplet.SqliteSimple.JwtAuth.Types.AuthFailure
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: instance GHC.Show.Show Snap.Snaplet.SqliteSimple.JwtAuth.Types.User
- Snap.Snaplet.SqliteSimple.JwtAuth.Types: type H a b = Handler a SqliteJwt b
- Snap.Snaplet.SqliteSimple.JwtAuth.Util: finishEarly :: MonadSnap m => Int -> ByteString -> m b
- Snap.Snaplet.SqliteSimple.JwtAuth.Util: getBoundedJSON :: (MonadSnap m, FromJSON a) => Int64 -> m (Either String a)
- Snap.Snaplet.SqliteSimple.JwtAuth.Util: getKey :: FilePath -> IO ByteString
- Snap.Snaplet.SqliteSimple.JwtAuth.Util: jsonResponse :: MonadSnap m => m ()
- Snap.Snaplet.SqliteSimple.JwtAuth.Util: reqBoundedJSON :: (MonadSnap m, FromJSON a) => Int64 -> m a
- Snap.Snaplet.SqliteSimple.JwtAuth.Util: reqJSON :: (MonadSnap m, FromJSON b) => m b
- Snap.Snaplet.SqliteSimple.JwtAuth.Util: writeJSON :: (MonadSnap m, ToJSON a) => a -> m ()

Files

snaplet-sqlite-simple-jwt-auth.cabal view
@@ -1,5 +1,5 @@ name:                snaplet-sqlite-simple-jwt-auth-version:             0.1.0.0+version:             0.1.1.0 synopsis:            Snaplet for JWT authentication with snaplet-sqlite-simple description:     JWT authentication snaplet for snaplet-sqlite-simple.@@ -22,7 +22,7 @@ library   hs-source-dirs:      src   exposed-modules:     Snap.Snaplet.SqliteSimple.JwtAuth-                       Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth+  other-modules:       Snap.Snaplet.SqliteSimple.JwtAuth.JwtAuth                        Snap.Snaplet.SqliteSimple.JwtAuth.Db                        Snap.Snaplet.SqliteSimple.JwtAuth.Util                        Snap.Snaplet.SqliteSimple.JwtAuth.Types
src/Snap/Snaplet/SqliteSimple/JwtAuth.hs view
@@ -17,10 +17,23 @@   -- | Use these handlers to implement user registration, login and protecting   -- routes with authentication.   --+  -- The 'registerUser' and 'loginUser' handlers follow a fixed convention for+  -- request parameters and response.  To sign up a user or login an existing+  -- user, make a POST request to a route handled by 'registerUser' or+  -- 'loginUser'.  Both require input parameters to be passed in as JSON.  A+  -- successful user creation or a login will return HTTP 400 code and reply+  -- with a JSON object containing the JWT.  Failed login attempts will reply+  -- with an HTTP 401 error and will reply with a JSON object containing the+  -- error message.+  --+  -- Use the 'requireAuth' wrapper for implementing routes that require+  -- authentication.  The client side is responsible for passing in a valid+  -- JWT in the Authentication header.+  --   -- If you need to customize error handling or need a different JSON schema   -- for communicating between the server and client, you may wish the re--  -- implement these using the low-level handlers documented later in the-  -- API ref.+  -- implement 'registerUser' and 'loginUser' using the low-level handlers+  -- documented later in the API ref.   , registerUser   , loginUser   , requireAuth@@ -47,6 +60,8 @@ -- accounts persisted in a SQLite3 database.  It's intended use is to protect -- server API routes used in single-page web applications (SPA) and mobile -- applications.+--+-- Passwords are hashed and salted using the BCrypt library. -- -- See the https://github.com/nurpax/snap-reactjs-todo project for a full -- application using this library.  It implements a todo application as an SPA
src/Snap/Snaplet/SqliteSimple/JwtAuth/JwtAuth.hs view
@@ -133,6 +133,15 @@ -- Verify authentication from the JWT token passed in the Authorization -- header, and run the user provided 'action' with the logged in user. --+-- Use the following syntax for constructing the Authorization header:+--+-- @+-- Bearer \<JWT\>+-- @+--+-- where \<JWT\> is obtained from the "token" field of a successful call to+-- 'registerUser' or 'loginUser'.+-- -- On errors such as missing or malformed JWT or failure to verify the JWT, -- error out early and issue an HTTP 401 error. requireAuth :: (User -> Handler b SqliteJwt a) -> Handler b SqliteJwt a@@ -173,6 +182,36 @@   jwt <- jwtFromUser user   writeJSON $ object [ "token" .= jwt ] +-- | Create a new user.+--+-- Use a POST request for this handler with password and login encoded as JSON+-- in the body of the request:+--+-- @+-- {+--    "login": \<login name\>,+--    "pass": \<password\>+-- }+-- @+--+-- A successful login will reply with an HTTP 400 code and the following JSON:+--+-- @+-- {+--    "token": \<JWT\>+-- }+-- @+--+-- The returned token can be used to make authenticated requests.+--+-- Login and user registration errors will be reported with an HTTP error code+-- 401 and the error message will be sent as a JSON object:+--+-- @+-- {+--   "error": \<message\>+-- }+-- @ registerUser :: Handler b SqliteJwt () registerUser = method POST newUser   where@@ -181,8 +220,39 @@       userOrErr <- createUser (lpLogin params) (lpPass params)       either handleLoginError loginOK userOrErr +-- | Login an existing user.+--+-- Use a POST request for this handler with password and login encoded as JSON+-- in the body of the request:+--+-- @+-- {+--   "login": \<login name\>,+--   "pass": \<password\>+-- }+-- @+--+-- A successful login will reply with an HTTP 400 code and the following JSON:+--+-- @+-- {+--   "token": \<JWT\>+-- }+-- @+--+-- The returned token can be used to make authenticated requests.+--+-- Login and user registration errors will be reported with an HTTP error code+-- 401 and the error message will be sent as a JSON object:+--+-- @+-- {+--   "error": \<message\>+-- }+-- @ loginUser :: Handler b SqliteJwt () loginUser = method POST $ do   params    <- reqJSON   userOrErr <- login (lpLogin params) (lpPass params)   either handleLoginError loginOK userOrErr+