Updating auth package to remove use of email address (bar logging in).
This commit is contained in:
parent
eaa89c824e
commit
c3a1841f01
|
@ -12,6 +12,7 @@
|
|||
"passport-google-auth": "^1.0.2",
|
||||
"passport-google-oauth": "^2.0.0",
|
||||
"passport-jwt": "^4.0.0",
|
||||
"passport-local": "^1.0.0"
|
||||
"passport-local": "^1.0.0",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
const uuid = require("uuid/v4")
|
||||
|
||||
exports.ViewNames = {
|
||||
USER_BY_EMAIL: "by_email",
|
||||
}
|
||||
|
||||
exports.StaticDatabases = {
|
||||
GLOBAL: {
|
||||
name: "global-db",
|
||||
|
@ -17,28 +23,23 @@ const SEPARATOR = "_"
|
|||
exports.SEPARATOR = SEPARATOR
|
||||
|
||||
/**
|
||||
* Generates a new user ID based on the passed in email.
|
||||
* @param {string} email The email which the ID is going to be built up of.
|
||||
* Generates a new global user ID.
|
||||
* @returns {string} The new user ID which the user doc can be stored under.
|
||||
*/
|
||||
exports.generateUserID = email => {
|
||||
return `${DocumentTypes.USER}${SEPARATOR}${email}`
|
||||
}
|
||||
|
||||
exports.getEmailFromUserID = userId => {
|
||||
return userId.split(`${DocumentTypes.USER}${SEPARATOR}`)[1]
|
||||
exports.generateUserID = () => {
|
||||
return `${DocumentTypes.USER}${SEPARATOR}${uuid()}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets parameters for retrieving users, this is a utility function for the getDocParams function.
|
||||
*/
|
||||
exports.getUserParams = (email = "", otherProps = {}) => {
|
||||
if (!email) {
|
||||
email = ""
|
||||
exports.getUserParams = (globalId = "", otherProps = {}) => {
|
||||
if (!globalId) {
|
||||
globalId = ""
|
||||
}
|
||||
return {
|
||||
...otherProps,
|
||||
startkey: `${DocumentTypes.USER}${SEPARATOR}${email}`,
|
||||
endkey: `${DocumentTypes.USER}${SEPARATOR}${email}${UNICODE_MAX}`,
|
||||
startkey: `${DocumentTypes.USER}${SEPARATOR}${globalId}`,
|
||||
endkey: `${DocumentTypes.USER}${SEPARATOR}${globalId}${UNICODE_MAX}`,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
const { DocumentTypes, ViewNames, StaticDatabases } = require("./utils")
|
||||
const { CouchDB } = require("./index")
|
||||
|
||||
exports.createUserEmailView = async () => {
|
||||
const db = new CouchDB(StaticDatabases.GLOBAL.name)
|
||||
const designDoc = await db.get("_design/database")
|
||||
const view = {
|
||||
// if using variables in a map function need to inject them before use
|
||||
map: `function(doc) {
|
||||
if (doc._id.startsWith("${DocumentTypes.USER}")) {
|
||||
emit(doc.email, doc._id)
|
||||
}
|
||||
}`,
|
||||
}
|
||||
designDoc.views = {
|
||||
...designDoc.views,
|
||||
[ViewNames.USER_BY_EMAIL]: view,
|
||||
}
|
||||
await db.put(designDoc)
|
||||
}
|
|
@ -17,8 +17,8 @@ const {
|
|||
const {
|
||||
generateUserID,
|
||||
getUserParams,
|
||||
getEmailFromUserID,
|
||||
} = require("./db/utils")
|
||||
const { getGlobalUserByEmail } = require("./utils")
|
||||
|
||||
// Strategies
|
||||
passport.use(new LocalStrategy(local.options, local.authenticate))
|
||||
|
@ -49,7 +49,6 @@ module.exports = {
|
|||
StaticDatabases,
|
||||
generateUserID,
|
||||
getUserParams,
|
||||
getEmailFromUserID,
|
||||
hash,
|
||||
compare,
|
||||
getAppId,
|
||||
|
@ -58,4 +57,5 @@ module.exports = {
|
|||
clearCookie,
|
||||
authenticated,
|
||||
isClient,
|
||||
getGlobalUserByEmail,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const { Cookies } = require("../constants")
|
||||
const { getCookie } = require("../utils")
|
||||
const { getEmailFromUserID } = require("../db/utils")
|
||||
|
||||
module.exports = async (ctx, next) => {
|
||||
try {
|
||||
|
@ -10,8 +9,6 @@ module.exports = async (ctx, next) => {
|
|||
if (authCookie) {
|
||||
ctx.isAuthenticated = true
|
||||
ctx.user = authCookie
|
||||
// make sure email is correct from ID
|
||||
ctx.user.email = getEmailFromUserID(authCookie.userId)
|
||||
}
|
||||
|
||||
await next()
|
||||
|
|
|
@ -4,6 +4,7 @@ const database = require("../../db")
|
|||
const { StaticDatabases, generateUserID } = require("../../db/utils")
|
||||
const { compare } = require("../../hashing")
|
||||
const env = require("../../environment")
|
||||
const { getGlobalUserByEmail } = require("../../utils")
|
||||
|
||||
const INVALID_ERR = "Invalid Credentials"
|
||||
|
||||
|
@ -11,21 +12,18 @@ exports.options = {}
|
|||
|
||||
/**
|
||||
* Passport Local Authentication Middleware.
|
||||
* @param {*} username - username to login with
|
||||
* @param {*} email - username to login with
|
||||
* @param {*} password - plain text password to log in with
|
||||
* @param {*} done - callback from passport to return user information and errors
|
||||
* @returns The authenticated user, or errors if they occur
|
||||
*/
|
||||
exports.authenticate = async function(username, password, done) {
|
||||
if (!username) return done(null, false, "Email Required.")
|
||||
exports.authenticate = async function(email, password, done) {
|
||||
if (!email) return done(null, false, "Email Required.")
|
||||
if (!password) return done(null, false, "Password Required.")
|
||||
|
||||
// Check the user exists in the instance DB by email
|
||||
const db = new database.CouchDB(StaticDatabases.GLOBAL.name)
|
||||
|
||||
let dbUser
|
||||
try {
|
||||
dbUser = await db.get(generateUserID(username))
|
||||
dbUser = await getGlobalUserByEmail(email)
|
||||
} catch (err) {
|
||||
console.error("User not found", err)
|
||||
return done(null, false, { message: "User not found" })
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
const { DocumentTypes, SEPARATOR } = require("./db/utils")
|
||||
const { DocumentTypes, SEPARATOR, ViewNames, StaticDatabases } = require("./db/utils")
|
||||
const jwt = require("jsonwebtoken")
|
||||
const { options } = require("./middleware/passport/jwt")
|
||||
const { createUserEmailView } = require("./db/views")
|
||||
const { CouchDB } = require("./db")
|
||||
|
||||
const APP_PREFIX = DocumentTypes.APP + SEPARATOR
|
||||
|
||||
|
@ -97,3 +99,21 @@ exports.clearCookie = (ctx, name) => {
|
|||
exports.isClient = ctx => {
|
||||
return ctx.headers["x-budibase-type"] === "client"
|
||||
}
|
||||
|
||||
exports.getGlobalUserByEmail = async email => {
|
||||
const db = new CouchDB(StaticDatabases.GLOBAL.name)
|
||||
try {
|
||||
let users = (await db.query(
|
||||
`database/${ViewNames.USER_BY_EMAIL}`,
|
||||
{
|
||||
key: email
|
||||
})
|
||||
).rows
|
||||
return users.length <= 1 ? users[0] : users
|
||||
} catch (err) {
|
||||
if (err != null && err.name === "not_found") {
|
||||
await createUserEmailView()
|
||||
return exports.getGlobalUserByEmail(email)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -584,6 +584,11 @@ uuid@^3.3.2:
|
|||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
|
||||
uuid@^8.3.2:
|
||||
version "8.3.2"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
||||
verror@1.10.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
|
||||
|
|
Loading…
Reference in New Issue