From d2b448f462c80382b1ba8d0f0a41879ea2fb5b8b Mon Sep 17 00:00:00 2001 From: Jared Thirsk Date: Tue, 8 Oct 2019 15:42:17 -0600 Subject: [PATCH 1/8] formatting --- lib/local.js | 149 +++++++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 76 deletions(-) diff --git a/lib/local.js b/lib/local.js index 6eba334c..c7fca3df 100644 --- a/lib/local.js +++ b/lib/local.js @@ -1,104 +1,101 @@ -'use strict'; -var util = require('./util'); -var LocalStrategy = require('passport-local'); -var BearerStrategy = require('passport-http-bearer-sl').Strategy; - +'use strict' +var util = require('./util') +var LocalStrategy = require('passport-local') +var BearerStrategy = require('passport-http-bearer-sl').Strategy module.exports = function (config, passport, user) { - // API token strategy passport.use(new BearerStrategy( function (tokenPass, done) { - var parse = tokenPass.split(':'); - if(parse.length < 2) { - done(null, false, {message: 'invalid token'}); + var parse = tokenPass.split(':') + if (parse.length < 2) { + done(null, false, { message: 'invalid token' }) } - var token = parse[0]; - var password = parse[1]; + var token = parse[0] + var password = parse[1] user.confirmSession(token, password) .then(function (theuser) { - done(null, theuser); + done(null, theuser) }, function (err) { if (err instanceof Error) { - done(err, false); + done(err, false) } else { - done(null, false, {message: err}); + done(null, false, { message: err }) } - }); + }) } - )); + )) // Use local strategy passport.use(new LocalStrategy({ - usernameField: config.getItem('local.usernameField') || 'username', - passwordField: config.getItem('local.passwordField') || 'password', - session: false, - passReqToCallback: true - }, - function (req, username, password, done) { - user.get(username) - .then(function (theuser) { - if (theuser) { - // Check if the account is locked - if(theuser.local && theuser.local.lockedUntil && theuser.local.lockedUntil > Date.now()) { - return done(null, false, { - error: 'Unauthorized', - message: 'Your account is currently locked. Please wait a few minutes and try again.' - }); - } - if(!theuser.local || !theuser.local.derived_key) { - return done(null, false, { - error: 'Unauthorized', - message: 'Invalid username or password' - }); - } - util.verifyPassword(theuser.local, password) - .then(function () { - // Check if the email has been confirmed if it is required - if(config.getItem('local.requireEmailConfirm') && !theuser.email) { - return done(null, false, { - error: 'Unauthorized', - message: 'You must confirm your email address.' - }); - } - // Success!!! - return done(null, theuser); - }, function (err) { - if (!err) { - // Password didn't authenticate - return handleFailedLogin(theuser, req, done); - } else { - // Hashing function threw an error - return done(err); - } - }); - } else { - // user not found + usernameField: config.getItem('local.usernameField') || 'username', + passwordField: config.getItem('local.passwordField') || 'password', + session: false, + passReqToCallback: true + }, + function (req, username, password, done) { + user.get(username) + .then(function (theuser) { + if (theuser) { + // Check if the account is locked + if (theuser.local && theuser.local.lockedUntil && theuser.local.lockedUntil > Date.now()) { + return done(null, false, { + error: 'Unauthorized', + message: 'Your account is currently locked. Please wait a few minutes and try again.' + }) + } + if (!theuser.local || !theuser.local.derived_key) { return done(null, false, { error: 'Unauthorized', message: 'Invalid username or password' - }); + }) } - }, function (err) { - // Database threw an error - return done(err); - }); - } - )); + util.verifyPassword(theuser.local, password) + .then(function () { + // Check if the email has been confirmed if it is required + if (config.getItem('local.requireEmailConfirm') && !theuser.email) { + return done(null, false, { + error: 'Unauthorized', + message: 'You must confirm your email address.' + }) + } + // Success!!! + return done(null, theuser) + }, function (err) { + if (!err) { + // Password didn't authenticate + return handleFailedLogin(theuser, req, done) + } else { + // Hashing function threw an error + return done(err) + } + }) + } else { + // user not found + return done(null, false, { + error: 'Unauthorized', + message: 'Invalid username or password' + }) + } + }, function (err) { + // Database threw an error + return done(err) + }) + } + )) - function handleFailedLogin(userDoc, req, done) { + function handleFailedLogin (userDoc, req, done) { var invalid = { error: 'Unauthorized', message: 'Invalid username or password' - }; + } return user.handleFailedLogin(userDoc, req) - .then(function(locked) { - if(locked) { + .then(function (locked) { + if (locked) { invalid.message = 'Maximum failed login attempts exceeded. Your account has been locked for ' + - Math.round(config.getItem('security.lockoutTime') / 60) + ' minutes.'; + Math.round(config.getItem('security.lockoutTime') / 60) + ' minutes.' } - return done(null, false, invalid); - }); + return done(null, false, invalid) + }) } - -}; +} From 6448994a3e9bac22d824616b19a08798da55070a Mon Sep 17 00:00:00 2001 From: Jared Thirsk Date: Tue, 8 Oct 2019 15:43:40 -0600 Subject: [PATCH 2/8] fix: done called multiple times on invalid token --- lib/local.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/lib/local.js b/lib/local.js index c7fca3df..948ace8a 100644 --- a/lib/local.js +++ b/lib/local.js @@ -10,19 +10,20 @@ module.exports = function (config, passport, user) { var parse = tokenPass.split(':') if (parse.length < 2) { done(null, false, { message: 'invalid token' }) + } else { + var token = parse[0] + var password = parse[1] + user.confirmSession(token, password) + .then(function (theuser) { + done(null, theuser) + }, function (err) { + if (err instanceof Error) { + done(err, false) + } else { + done(null, false, { message: err }) + } + }) } - var token = parse[0] - var password = parse[1] - user.confirmSession(token, password) - .then(function (theuser) { - done(null, theuser) - }, function (err) { - if (err instanceof Error) { - done(err, false) - } else { - done(null, false, { message: err }) - } - }) } )) From 13ff699abd5f55ad89a289d146da43fef1c79256 Mon Sep 17 00:00:00 2001 From: Jared Thirsk Date: Tue, 8 Oct 2019 15:51:59 -0600 Subject: [PATCH 3/8] New: options to disable auth via userPassToken, userPass --- config/default.config.js | 8 ++- lib/local.js | 144 ++++++++++++++++++++------------------- 2 files changed, 80 insertions(+), 72 deletions(-) diff --git a/config/default.config.js b/config/default.config.js index 012a3862..f0f95064 100644 --- a/config/default.config.js +++ b/config/default.config.js @@ -1,4 +1,4 @@ -var path = require('path'); +var path = require('path') // These are the default settings that will be used if you don't override them in your config module.exports = { @@ -11,6 +11,10 @@ module.exports = { loginOnRegistration: false, loginOnPasswordReset: false }, + authStrategies: { + userPass: true, + userPassToken: true + }, local: { usernameField: 'username', passwordField: 'password' @@ -41,4 +45,4 @@ module.exports = { format: 'text' } } -}; +} diff --git a/lib/local.js b/lib/local.js index 948ace8a..622d9c03 100644 --- a/lib/local.js +++ b/lib/local.js @@ -5,85 +5,89 @@ var BearerStrategy = require('passport-http-bearer-sl').Strategy module.exports = function (config, passport, user) { // API token strategy - passport.use(new BearerStrategy( - function (tokenPass, done) { - var parse = tokenPass.split(':') - if (parse.length < 2) { - done(null, false, { message: 'invalid token' }) - } else { - var token = parse[0] - var password = parse[1] - user.confirmSession(token, password) - .then(function (theuser) { - done(null, theuser) - }, function (err) { - if (err instanceof Error) { - done(err, false) - } else { - done(null, false, { message: err }) - } - }) + if (config.authStrategies.userPassToken) { + passport.use(new BearerStrategy( + function (tokenPass, done) { + var parse = tokenPass.split(':') + if (parse.length < 2) { + done(null, false, { message: 'invalid token' }) + } else { + var token = parse[0] + var password = parse[1] + user.confirmSession(token, password) + .then(function (theuser) { + done(null, theuser) + }, function (err) { + if (err instanceof Error) { + done(err, false) + } else { + done(null, false, { message: err }) + } + }) + } } - } - )) + )) + } // Use local strategy - passport.use(new LocalStrategy({ - usernameField: config.getItem('local.usernameField') || 'username', - passwordField: config.getItem('local.passwordField') || 'password', - session: false, - passReqToCallback: true - }, - function (req, username, password, done) { - user.get(username) - .then(function (theuser) { - if (theuser) { - // Check if the account is locked - if (theuser.local && theuser.local.lockedUntil && theuser.local.lockedUntil > Date.now()) { - return done(null, false, { - error: 'Unauthorized', - message: 'Your account is currently locked. Please wait a few minutes and try again.' - }) - } - if (!theuser.local || !theuser.local.derived_key) { + if (config.authStrategies.userPass) { + passport.use(new LocalStrategy({ + usernameField: config.getItem('local.usernameField') || 'username', + passwordField: config.getItem('local.passwordField') || 'password', + session: false, + passReqToCallback: true + }, + function (req, username, password, done) { + user.get(username) + .then(function (theuser) { + if (theuser) { + // Check if the account is locked + if (theuser.local && theuser.local.lockedUntil && theuser.local.lockedUntil > Date.now()) { + return done(null, false, { + error: 'Unauthorized', + message: 'Your account is currently locked. Please wait a few minutes and try again.' + }) + } + if (!theuser.local || !theuser.local.derived_key) { + return done(null, false, { + error: 'Unauthorized', + message: 'Invalid username or password' + }) + } + util.verifyPassword(theuser.local, password) + .then(function () { + // Check if the email has been confirmed if it is required + if (config.getItem('local.requireEmailConfirm') && !theuser.email) { + return done(null, false, { + error: 'Unauthorized', + message: 'You must confirm your email address.' + }) + } + // Success!!! + return done(null, theuser) + }, function (err) { + if (!err) { + // Password didn't authenticate + return handleFailedLogin(theuser, req, done) + } else { + // Hashing function threw an error + return done(err) + } + }) + } else { + // user not found return done(null, false, { error: 'Unauthorized', message: 'Invalid username or password' }) } - util.verifyPassword(theuser.local, password) - .then(function () { - // Check if the email has been confirmed if it is required - if (config.getItem('local.requireEmailConfirm') && !theuser.email) { - return done(null, false, { - error: 'Unauthorized', - message: 'You must confirm your email address.' - }) - } - // Success!!! - return done(null, theuser) - }, function (err) { - if (!err) { - // Password didn't authenticate - return handleFailedLogin(theuser, req, done) - } else { - // Hashing function threw an error - return done(err) - } - }) - } else { - // user not found - return done(null, false, { - error: 'Unauthorized', - message: 'Invalid username or password' - }) - } - }, function (err) { - // Database threw an error - return done(err) - }) + }, function (err) { + // Database threw an error + return done(err) + }) + } + )) } - )) function handleFailedLogin (userDoc, req, done) { var invalid = { From 0f4e1ca394621cc280604191058f6b1ffd1a332b Mon Sep 17 00:00:00 2001 From: Jared Thirsk Date: Tue, 8 Oct 2019 15:59:24 -0600 Subject: [PATCH 4/8] rename option to apiToken --- config/default.config.js | 2 +- lib/local.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/default.config.js b/config/default.config.js index f0f95064..ee9dbad5 100644 --- a/config/default.config.js +++ b/config/default.config.js @@ -13,7 +13,7 @@ module.exports = { }, authStrategies: { userPass: true, - userPassToken: true + apiToken: true }, local: { usernameField: 'username', diff --git a/lib/local.js b/lib/local.js index 622d9c03..a7af0ba7 100644 --- a/lib/local.js +++ b/lib/local.js @@ -5,7 +5,7 @@ var BearerStrategy = require('passport-http-bearer-sl').Strategy module.exports = function (config, passport, user) { // API token strategy - if (config.authStrategies.userPassToken) { + if (config.authStrategies.apiToken) { passport.use(new BearerStrategy( function (tokenPass, done) { var parse = tokenPass.split(':') From f76315426885fdc48a3c0e635c8d56fc0d2cddb7 Mon Sep 17 00:00:00 2001 From: Jared Thirsk Date: Tue, 8 Oct 2019 15:59:35 -0600 Subject: [PATCH 5/8] add vscode workspace --- superlogin.code-workspace | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 superlogin.code-workspace diff --git a/superlogin.code-workspace b/superlogin.code-workspace new file mode 100644 index 00000000..876a1499 --- /dev/null +++ b/superlogin.code-workspace @@ -0,0 +1,8 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": {} +} \ No newline at end of file From 06835c196e735c613fd65bac76a70c7bfd334a76 Mon Sep 17 00:00:00 2001 From: Jared Thirsk Date: Tue, 8 Oct 2019 16:00:12 -0600 Subject: [PATCH 6/8] formatting --- lib/routes.js | 335 +++++++++++++++++++++++++------------------------- 1 file changed, 167 insertions(+), 168 deletions(-) diff --git a/lib/routes.js b/lib/routes.js index 8ccebe89..c4cf6634 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -1,267 +1,266 @@ -'use strict'; -var util = require('./util'); +'use strict' +var util = require('./util') -module.exports = function(config, router, passport, user) { +module.exports = function (config, router, passport, user) { + var env = process.env.NODE_ENV || 'development' - var env = process.env.NODE_ENV || 'development'; - - router.post('/login', function(req, res, next) { - passport.authenticate('local', function(err, user, info) { - if(err) { - return next(err); + router.post('/login', function (req, res, next) { + passport.authenticate('local', function (err, user, info) { + if (err) { + return next(err) } - if(!user) { - // Authentication failed - console.error('login 401', info) - return res.status(401).json(info); + if (!user) { + // Authentication failed + console.error('login 401', info) + return res.status(401).json(info) } // Success - req.logIn(user, {session: false}, function(err) { + req.logIn(user, { session: false }, function (err) { if (err) { - return next(err); + return next(err) } - }); - return next(); - })(req, res, next); - }, function (req, res, next) { - // Success handler - return user.createSession(req.user._id, 'local', req) - .then(function (mySession) { - res.status(200).json(mySession); - }, function (err) { - return next(err); - }); - }); + }) + return next() + })(req, res, next) + }, function (req, res, next) { + // Success handler + return user.createSession(req.user._id, 'local', req) + .then(function (mySession) { + res.status(200).json(mySession) + }, function (err) { + return next(err) + }) + }) router.post('/refresh', - passport.authenticate('bearer', {session: false}), + passport.authenticate('bearer', { session: false }), function (req, res, next) { return user.refreshSession(req.user.key) .then(function (mySession) { - res.status(200).json(mySession); + res.status(200).json(mySession) }, function (err) { - return next(err); - }); - }); + return next(err) + }) + }) router.post('/logout', function (req, res, next) { - var sessionToken = util.getSessionToken(req); - if(!sessionToken) { + var sessionToken = util.getSessionToken(req) + if (!sessionToken) { return next({ error: 'unauthorized', status: 401 - }); + }) } user.logoutSession(sessionToken) .then(function () { - res.status(200).json({ok: true, success: 'Logged out'}); + res.status(200).json({ ok: true, success: 'Logged out' }) }, function (err) { - console.error('Logout failed'); - return next(err); - }); - }); + console.error('Logout failed') + return next(err) + }) + }) router.post('/logout-others', - passport.authenticate('bearer', {session: false}), + passport.authenticate('bearer', { session: false }), function (req, res, next) { user.logoutOthers(req.user.key) .then(function () { - res.status(200).json({success: 'Other sessions logged out'}); + res.status(200).json({ success: 'Other sessions logged out' }) }, function (err) { - console.error('Logout failed'); - return next(err); - }); - }); + console.error('Logout failed') + return next(err) + }) + }) router.post('/logout-all', function (req, res, next) { - var sessionToken = util.getSessionToken(req); - if(!sessionToken) { + var sessionToken = util.getSessionToken(req) + if (!sessionToken) { return next({ error: 'unauthorized', status: 401 - }); + }) } user.logoutUser(null, sessionToken) .then(function () { - res.status(200).json({success: 'Logged out'}); + res.status(200).json({ success: 'Logged out' }) }, function (err) { - console.error('Logout-all failed'); - return next(err); - }); - }); + console.error('Logout-all failed') + return next(err) + }) + }) // Setting up the auth api router.post('/register', function (req, res, next) { - user.create(req.body, req) - .then(function (newUser) { - if(config.getItem('security.loginOnRegistration')) { - return user.createSession(newUser._id, 'local', req.ip) - .then(function (mySession) { - res.status(200).json(mySession); - }, function (err) { - return next(err); - }); - } else { - res.status(201).json({success: 'User created.'}); - } - }, function (err) { - res.status(err.status).json(err); - }); - }); + user.create(req.body, req) + .then(function (newUser) { + if (config.getItem('security.loginOnRegistration')) { + return user.createSession(newUser._id, 'local', req.ip) + .then(function (mySession) { + res.status(200).json(mySession) + }, function (err) { + return next(err) + }) + } else { + res.status(201).json({ success: 'User created.' }) + } + }, function (err) { + res.status(err.status).json(err) + }) + }) router.post('/forgot-password', function (req, res, next) { - user.forgotPassword(req.body.email, req).then(function () { - res.status(200).json({success: 'Password recovery email sent.'}); - }, function (err) { - return next(err); - }); - }); + user.forgotPassword(req.body.email, req).then(function () { + res.status(200).json({ success: 'Password recovery email sent.' }) + }, function (err) { + return next(err) + }) + }) router.post('/password-reset', function (req, res, next) { - user.resetPassword(req.body, req) - .then(function (currentUser) { - if(config.getItem('security.loginOnPasswordReset')) { - return user.createSession(currentUser._id, 'local', req.ip) - .then(function (mySession) { - res.status(200).json(mySession); - }, function (err) { - return next(err); - }); - } else { - res.status(200).json({success: 'Password successfully reset.'}); - } - }, function (err) { - return next(err); - }); - }); + user.resetPassword(req.body, req) + .then(function (currentUser) { + if (config.getItem('security.loginOnPasswordReset')) { + return user.createSession(currentUser._id, 'local', req.ip) + .then(function (mySession) { + res.status(200).json(mySession) + }, function (err) { + return next(err) + }) + } else { + res.status(200).json({ success: 'Password successfully reset.' }) + } + }, function (err) { + return next(err) + }) + }) router.post('/password-change', - passport.authenticate('bearer', {session: false}), + passport.authenticate('bearer', { session: false }), function (req, res, next) { user.changePasswordSecure(req.user._id, req.body, req) .then(function () { - res.status(200).json({success: 'password changed'}); + res.status(200).json({ success: 'password changed' }) }, function (err) { - return next(err); - }); - }); + return next(err) + }) + }) router.post('/unlink/:provider', - passport.authenticate('bearer', {session: false}), - function(req, res, next) { - var provider = req.params.provider; + passport.authenticate('bearer', { session: false }), + function (req, res, next) { + var provider = req.params.provider user.unlink(req.user._id, provider) - .then(function() { - res.status(200).json({success: util.capitalizeFirstLetter(provider) + ' unlinked'}); + .then(function () { + res.status(200).json({ success: util.capitalizeFirstLetter(provider) + ' unlinked' }) }, function (err) { - return next(err); - }); - }); + return next(err) + }) + }) router.get('/confirm-email/:token', function (req, res, next) { - var redirectURL = config.getItem('local.confirmEmailRedirectURL'); + var redirectURL = config.getItem('local.confirmEmailRedirectURL') if (!req.params.token) { - var err = {error: 'Email verification token required'}; - if(redirectURL) { - return res.status(201).redirect(redirectURL + '?error=' + encodeURIComponent(err.error)); + var err = { error: 'Email verification token required' } + if (redirectURL) { + return res.status(201).redirect(redirectURL + '?error=' + encodeURIComponent(err.error)) } - return res.status(400).send(err); + return res.status(400).send(err) } user.verifyEmail(req.params.token, req).then(function () { - if(redirectURL) { - return res.status(201).redirect(redirectURL + '?success=true'); + if (redirectURL) { + return res.status(201).redirect(redirectURL + '?success=true') } - res.status(200).send({ok: true, success: 'Email verified'}); + res.status(200).send({ ok: true, success: 'Email verified' }) }, function (err) { - if(redirectURL) { - var query = '?error=' + encodeURIComponent(err.error); - if(err.message) { - query += '&message=' + encodeURIComponent(err.message); + if (redirectURL) { + var query = '?error=' + encodeURIComponent(err.error) + if (err.message) { + query += '&message=' + encodeURIComponent(err.message) } - return res.status(201).redirect(redirectURL + query); + return res.status(201).redirect(redirectURL + query) } - return next(err); - }); - }); + return next(err) + }) + }) router.get('/validate-username/:username', - function(req, res, next) { - if(!req.params.username) { - return next({error: 'Username required', status: 400}); + function (req, res, next) { + if (!req.params.username) { + return next({ error: 'Username required', status: 400 }) } user.validateUsername(req.params.username) - .then(function(err) { - if(!err) { - res.status(200).json({ok: true}); + .then(function (err) { + if (!err) { + res.status(200).json({ ok: true }) } else { - res.status(409).json({error: 'Username already in use'}); + res.status(409).json({ error: 'Username already in use' }) } - }, function(err) { - return next(err); - }); + }, function (err) { + return next(err) + }) } - ); + ) router.get('/validate-email/:email', - function(req, res, next) { - var promise; - if(!req.params.email) { - return next({error: 'Email required', status: 400}); + function (req, res, next) { + var promise + if (!req.params.email) { + return next({ error: 'Email required', status: 400 }) } - if(config.getItem('local.emailUsername')) { - promise = user.validateEmailUsername(req.params.email); + if (config.getItem('local.emailUsername')) { + promise = user.validateEmailUsername(req.params.email) } else { - promise = user.validateEmail(req.params.email); + promise = user.validateEmail(req.params.email) } promise - .then(function(err) { - if(!err) { - res.status(200).json({ok: true}); + .then(function (err) { + if (!err) { + res.status(200).json({ ok: true }) } else { - res.status(409).json({error: 'Email already in use'}); + res.status(409).json({ error: 'Email already in use' }) } - }, function(err) { - return next(err); - }); + }, function (err) { + return next(err) + }) } - ); + ) router.post('/change-email', - passport.authenticate('bearer', {session: false}), + passport.authenticate('bearer', { session: false }), function (req, res, next) { user.changeEmail(req.user._id, req.body.newEmail, req) .then(function () { - res.status(200).json({ok: true, success: 'Email changed'}); + res.status(200).json({ ok: true, success: 'Email changed' }) }, function (err) { - return next(err); - }); - }); + return next(err) + }) + }) // route to test token authentication router.get('/session', - passport.authenticate('bearer', {session: false}), + passport.authenticate('bearer', { session: false }), function (req, res) { - var user = req.user; - user.user_id = user._id; - delete user._id; + var user = req.user + user.user_id = user._id + delete user._id // user.token = user.key; - delete user.key; - res.status(200).json(user); - }); + delete user.key + res.status(200).json(user) + }) // Error handling - router.use(function(err, req, res) { - console.error(err); - if(err.stack) { - console.error(err.stack); + router.use(function (err, req, res) { + console.error(err) + if (err.stack) { + console.error(err.stack) } - res.status(err.status || 500); - if(err.stack && env !== 'development') { - delete err.stack; + res.status(err.status || 500) + if (err.stack && env !== 'development') { + delete err.stack } - res.json(err); - }); + res.json(err) + }) }; From 188d2525b2bd2d7196c6284ab12ba0d355870bba Mon Sep 17 00:00:00 2001 From: Jared Thirsk Date: Fri, 11 Oct 2019 05:38:09 -0600 Subject: [PATCH 7/8] Add an overview of the fork --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5f32e166..41b2c84a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@ -# @sensu/superlogin [![Build Status](https://travis-ci.org/sen-su/superlogin.png?branch=master)](https://travis-ci.org/sen-su/superlogin) +# @jaredthirsk/superlogin -## An up-to-date version of superlogin that is actually published. +A fork of @sensu/superlogin, which seems to be a strong contender as a current / maintained version of the original @colinskow/superlogin, (which seems to be broken and out of date.) + +Features I add to @sensu's version: + - options to disable + - authenticating to superlogin via API token (`authStrategies.userPassToken = false`) + - authenticating to superlogin via username and password (`authStrategies.userPass = false`) + +# Superlogin SuperLogin is a full-featured NodeJS/Express user authentication solution for APIs and Single Page Apps (SPA) using CouchDB or Cloudant. From 9011ef17a47bb2d9de2553a3dec7715a7cfd7a9c Mon Sep 17 00:00:00 2001 From: Jared Thirsk Date: Sun, 20 Oct 2019 14:12:24 -0600 Subject: [PATCH 8/8] Change package name, Bump version --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b072738d..c46f9ead 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "@sensu/superlogin", - "version": "1.2.1", + "name": "@jaredthirsk/superlogin", + "version": "1.3.0", "description": "Powerful authentication for APIs and single page apps using the CouchDB ecosystem which supports a variety of providers.", "main": "./lib/index.js", "repository": { @@ -71,4 +71,4 @@ "sinon": "^3.3.0", "sinon-chai": "^2.14.0" } -} +} \ No newline at end of file