Swapping over everything to use the new user ID and updating everything after some end to end testing.
This commit is contained in:
parent
1f8925ceb8
commit
b4c8bf81f7
|
@ -1,5 +1,9 @@
|
||||||
|
let Pouch
|
||||||
|
|
||||||
module.exports.setDB = pouch => {
|
module.exports.setDB = pouch => {
|
||||||
module.exports.CouchDB = pouch
|
Pouch = pouch
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.CouchDB = null
|
module.exports.getDB = dbName => {
|
||||||
|
return new Pouch(dbName)
|
||||||
|
}
|
||||||
|
|
|
@ -23,14 +23,6 @@ const SEPARATOR = "_"
|
||||||
|
|
||||||
exports.SEPARATOR = SEPARATOR
|
exports.SEPARATOR = SEPARATOR
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a new global user ID.
|
|
||||||
* @returns {string} The new user ID which the user doc can be stored under.
|
|
||||||
*/
|
|
||||||
exports.generateUserID = () => {
|
|
||||||
return `${DocumentTypes.USER}${SEPARATOR}${newid()}`
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a new group ID.
|
* Generates a new group ID.
|
||||||
* @returns {string} The new group ID which the group doc can be stored under.
|
* @returns {string} The new group ID which the group doc can be stored under.
|
||||||
|
@ -50,10 +42,18 @@ exports.getGroupParams = (id = "", otherProps = {}) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a new global user ID.
|
||||||
|
* @returns {string} The new user ID which the user doc can be stored under.
|
||||||
|
*/
|
||||||
|
exports.generateGlobalUserID = () => {
|
||||||
|
return `${DocumentTypes.USER}${SEPARATOR}${newid()}`
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets parameters for retrieving users.
|
* Gets parameters for retrieving users.
|
||||||
*/
|
*/
|
||||||
exports.getUserParams = (globalId = "", otherProps = {}) => {
|
exports.getGlobalUserParams = (globalId = "", otherProps = {}) => {
|
||||||
if (!globalId) {
|
if (!globalId) {
|
||||||
globalId = ""
|
globalId = ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
const { DocumentTypes, ViewNames, StaticDatabases } = require("./utils")
|
const { DocumentTypes, ViewNames, StaticDatabases } = require("./utils")
|
||||||
const { CouchDB } = require("./index")
|
const { getDB } = require("./index")
|
||||||
|
|
||||||
|
function DesignDoc() {
|
||||||
|
return {
|
||||||
|
_id: "_design/database",
|
||||||
|
// view collation information, read before writing any complex views:
|
||||||
|
// https://docs.couchdb.org/en/master/ddocs/views/collation.html#collation-specification
|
||||||
|
views: {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exports.createUserEmailView = async () => {
|
exports.createUserEmailView = async () => {
|
||||||
const db = new CouchDB(StaticDatabases.GLOBAL.name)
|
const db = getDB(StaticDatabases.GLOBAL.name)
|
||||||
const designDoc = await db.get("_design/database")
|
let designDoc
|
||||||
|
try {
|
||||||
|
designDoc = await db.get("_design/database")
|
||||||
|
} catch (err) {
|
||||||
|
// no design doc, make one
|
||||||
|
designDoc = DesignDoc()
|
||||||
|
}
|
||||||
const view = {
|
const view = {
|
||||||
// if using variables in a map function need to inject them before use
|
// if using variables in a map function need to inject them before use
|
||||||
map: `function(doc) {
|
map: `function(doc) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ const passport = require("koa-passport")
|
||||||
const LocalStrategy = require("passport-local").Strategy
|
const LocalStrategy = require("passport-local").Strategy
|
||||||
const JwtStrategy = require("passport-jwt").Strategy
|
const JwtStrategy = require("passport-jwt").Strategy
|
||||||
// const GoogleStrategy = require("passport-google-oauth").Strategy
|
// const GoogleStrategy = require("passport-google-oauth").Strategy
|
||||||
const database = require("./db")
|
const { setDB, getDB } = require("./db")
|
||||||
const { StaticDatabases } = require("./db/utils")
|
const { StaticDatabases } = require("./db/utils")
|
||||||
const { jwt, local, authenticated } = require("./middleware")
|
const { jwt, local, authenticated } = require("./middleware")
|
||||||
const { Cookies, UserStatus } = require("./constants")
|
const { Cookies, UserStatus } = require("./constants")
|
||||||
|
@ -13,14 +13,14 @@ const {
|
||||||
getCookie,
|
getCookie,
|
||||||
clearCookie,
|
clearCookie,
|
||||||
isClient,
|
isClient,
|
||||||
|
getGlobalUserByEmail,
|
||||||
} = require("./utils")
|
} = require("./utils")
|
||||||
const {
|
const {
|
||||||
generateUserID,
|
generateGlobalUserID,
|
||||||
getUserParams,
|
getGlobalUserParams,
|
||||||
generateGroupID,
|
generateGroupID,
|
||||||
getGroupParams,
|
getGroupParams,
|
||||||
} = require("./db/utils")
|
} = require("./db/utils")
|
||||||
const { getGlobalUserByEmail } = require("./utils")
|
|
||||||
|
|
||||||
// Strategies
|
// Strategies
|
||||||
passport.use(new LocalStrategy(local.options, local.authenticate))
|
passport.use(new LocalStrategy(local.options, local.authenticate))
|
||||||
|
@ -30,7 +30,7 @@ passport.use(new JwtStrategy(jwt.options, jwt.authenticate))
|
||||||
passport.serializeUser((user, done) => done(null, user))
|
passport.serializeUser((user, done) => done(null, user))
|
||||||
|
|
||||||
passport.deserializeUser(async (user, done) => {
|
passport.deserializeUser(async (user, done) => {
|
||||||
const db = new database.CouchDB(StaticDatabases.GLOBAL.name)
|
const db = getDB(StaticDatabases.GLOBAL.name)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const user = await db.get(user._id)
|
const user = await db.get(user._id)
|
||||||
|
@ -43,14 +43,14 @@ passport.deserializeUser(async (user, done) => {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init(pouch) {
|
init(pouch) {
|
||||||
database.setDB(pouch)
|
setDB(pouch)
|
||||||
},
|
},
|
||||||
passport,
|
passport,
|
||||||
Cookies,
|
Cookies,
|
||||||
UserStatus,
|
UserStatus,
|
||||||
StaticDatabases,
|
StaticDatabases,
|
||||||
generateUserID,
|
generateGlobalUserID,
|
||||||
getUserParams,
|
getGlobalUserParams,
|
||||||
generateGroupID,
|
generateGroupID,
|
||||||
getGroupParams,
|
getGroupParams,
|
||||||
hash,
|
hash,
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
const jwt = require("jsonwebtoken")
|
const jwt = require("jsonwebtoken")
|
||||||
const { UserStatus } = require("../../constants")
|
const { UserStatus } = require("../../constants")
|
||||||
const database = require("../../db")
|
|
||||||
const { StaticDatabases, generateUserID } = require("../../db/utils")
|
|
||||||
const { compare } = require("../../hashing")
|
const { compare } = require("../../hashing")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const { getGlobalUserByEmail } = require("../../utils")
|
const { getGlobalUserByEmail } = require("../../utils")
|
||||||
|
@ -21,11 +19,8 @@ exports.authenticate = async function(email, password, done) {
|
||||||
if (!email) return done(null, false, "Email Required.")
|
if (!email) return done(null, false, "Email Required.")
|
||||||
if (!password) return done(null, false, "Password Required.")
|
if (!password) return done(null, false, "Password Required.")
|
||||||
|
|
||||||
let dbUser
|
const dbUser = await getGlobalUserByEmail(email)
|
||||||
try {
|
if (dbUser == null) {
|
||||||
dbUser = await getGlobalUserByEmail(email)
|
|
||||||
} catch (err) {
|
|
||||||
console.error("User not found", err)
|
|
||||||
return done(null, false, { message: "User not found" })
|
return done(null, false, { message: "User not found" })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ const { DocumentTypes, SEPARATOR, ViewNames, StaticDatabases } = require("./db/u
|
||||||
const jwt = require("jsonwebtoken")
|
const jwt = require("jsonwebtoken")
|
||||||
const { options } = require("./middleware/passport/jwt")
|
const { options } = require("./middleware/passport/jwt")
|
||||||
const { createUserEmailView } = require("./db/views")
|
const { createUserEmailView } = require("./db/views")
|
||||||
const { CouchDB } = require("./db")
|
const { getDB } = require("./db")
|
||||||
|
|
||||||
const APP_PREFIX = DocumentTypes.APP + SEPARATOR
|
const APP_PREFIX = DocumentTypes.APP + SEPARATOR
|
||||||
|
|
||||||
|
@ -101,19 +101,23 @@ exports.isClient = ctx => {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getGlobalUserByEmail = async email => {
|
exports.getGlobalUserByEmail = async email => {
|
||||||
const db = new CouchDB(StaticDatabases.GLOBAL.name)
|
const db = getDB(StaticDatabases.GLOBAL.name)
|
||||||
try {
|
try {
|
||||||
let users = (await db.query(
|
let users = (await db.query(
|
||||||
`database/${ViewNames.USER_BY_EMAIL}`,
|
`database/${ViewNames.USER_BY_EMAIL}`,
|
||||||
{
|
{
|
||||||
key: email
|
key: email,
|
||||||
|
include_docs: true,
|
||||||
})
|
})
|
||||||
).rows
|
).rows
|
||||||
|
users = users.map(user => user.doc)
|
||||||
return users.length <= 1 ? users[0] : users
|
return users.length <= 1 ? users[0] : users
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err != null && err.name === "not_found") {
|
if (err != null && err.name === "not_found") {
|
||||||
await createUserEmailView()
|
await createUserEmailView()
|
||||||
return exports.getGlobalUserByEmail(email)
|
return exports.getGlobalUserByEmail(email)
|
||||||
|
} else {
|
||||||
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,7 @@
|
||||||
|
|
||||||
async function createTestUser() {
|
async function createTestUser() {
|
||||||
try {
|
try {
|
||||||
await auth.createUser({
|
await auth.firstUser()
|
||||||
email: "test@test.com",
|
|
||||||
password: "test",
|
|
||||||
roles: {},
|
|
||||||
builder: {
|
|
||||||
global: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
notifier.success("Test user created")
|
notifier.success("Test user created")
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
|
|
@ -151,8 +151,8 @@
|
||||||
const user = {
|
const user = {
|
||||||
roleId: $createAppStore.values.roleId,
|
roleId: $createAppStore.values.roleId,
|
||||||
}
|
}
|
||||||
const userResp = await api.post(`/api/users/metadata`, user)
|
const userResp = await api.post(`/api/users/metadata/self`, user)
|
||||||
const json = await userResp.json()
|
await userResp.json()
|
||||||
$goto(`./${appJson._id}`)
|
$goto(`./${appJson._id}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
|
@ -30,11 +30,24 @@ export function createAuthStore() {
|
||||||
},
|
},
|
||||||
logout: async () => {
|
logout: async () => {
|
||||||
const response = await api.post(`/api/admin/auth/logout`)
|
const response = await api.post(`/api/admin/auth/logout`)
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw "Unable to create logout"
|
||||||
|
}
|
||||||
await response.json()
|
await response.json()
|
||||||
set({ user: null })
|
set({ user: null })
|
||||||
},
|
},
|
||||||
createUser: async user => {
|
createUser: async user => {
|
||||||
const response = await api.post(`/api/admin/users`, user)
|
const response = await api.post(`/api/admin/users`, user)
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw "Unable to create user"
|
||||||
|
}
|
||||||
|
await response.json()
|
||||||
|
},
|
||||||
|
firstUser: async () => {
|
||||||
|
const response = await api.post(`/api/admin/users/first`)
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw "Unable to create test user"
|
||||||
|
}
|
||||||
await response.json()
|
await response.json()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,10 @@ exports.createMetadata = async function(ctx) {
|
||||||
const db = new CouchDB(appId)
|
const db = new CouchDB(appId)
|
||||||
const { roleId } = ctx.request.body
|
const { roleId } = ctx.request.body
|
||||||
|
|
||||||
|
if (ctx.request.body._id) {
|
||||||
|
return exports.updateMetadata(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// check role valid
|
// check role valid
|
||||||
const role = await getRole(appId, roleId)
|
const role = await getRole(appId, roleId)
|
||||||
if (!role) ctx.throw(400, "Invalid Role")
|
if (!role) ctx.throw(400, "Invalid Role")
|
||||||
|
@ -66,20 +70,26 @@ exports.createMetadata = async function(ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.updateSelfMetadata = async function(ctx) {
|
||||||
|
// overwrite the ID with current users
|
||||||
|
ctx.request.body._id = ctx.user.userId
|
||||||
|
// make sure no stale rev
|
||||||
|
delete ctx.request.body._rev
|
||||||
|
await exports.updateMetadata(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
exports.updateMetadata = async function(ctx) {
|
exports.updateMetadata = async function(ctx) {
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
const db = new CouchDB(appId)
|
const db = new CouchDB(appId)
|
||||||
const user = ctx.request.body
|
const user = ctx.request.body
|
||||||
const globalUser = await saveGlobalUser(
|
const globalUser = await saveGlobalUser(ctx, appId, {
|
||||||
ctx,
|
...user,
|
||||||
appId,
|
_id: getGlobalIDFromUserMetadataID(user._id),
|
||||||
getGlobalIDFromUserMetadataID(user._id),
|
})
|
||||||
ctx.request.body
|
|
||||||
)
|
|
||||||
const metadata = {
|
const metadata = {
|
||||||
...globalUser,
|
...globalUser,
|
||||||
_id: user._id || generateUserMetadataID(globalUser._id),
|
_id: user._id || generateUserMetadataID(globalUser._id),
|
||||||
_rev: ctx.request.body._rev,
|
_rev: user._rev,
|
||||||
}
|
}
|
||||||
ctx.body = await db.put(metadata)
|
ctx.body = await db.put(metadata)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,12 @@ router
|
||||||
usage,
|
usage,
|
||||||
controller.createMetadata
|
controller.createMetadata
|
||||||
)
|
)
|
||||||
|
.post(
|
||||||
|
"/api/users/metadata/self",
|
||||||
|
authorized(PermissionTypes.USER, PermissionLevels.WRITE),
|
||||||
|
usage,
|
||||||
|
controller.updateSelfMetadata
|
||||||
|
)
|
||||||
.delete(
|
.delete(
|
||||||
"/api/users/metadata/:id",
|
"/api/users/metadata/:id",
|
||||||
authorized(PermissionTypes.USER, PermissionLevels.WRITE),
|
authorized(PermissionTypes.USER, PermissionLevels.WRITE),
|
||||||
|
|
|
@ -2,6 +2,10 @@ const { getAppId, setCookie, getCookie, Cookies } = require("@budibase/auth")
|
||||||
const { getRole } = require("../utilities/security/roles")
|
const { getRole } = require("../utilities/security/roles")
|
||||||
const { getGlobalUsers } = require("../utilities/workerRequests")
|
const { getGlobalUsers } = require("../utilities/workerRequests")
|
||||||
const { BUILTIN_ROLE_IDS } = require("../utilities/security/roles")
|
const { BUILTIN_ROLE_IDS } = require("../utilities/security/roles")
|
||||||
|
const {
|
||||||
|
getGlobalIDFromUserMetadataID,
|
||||||
|
generateUserMetadataID,
|
||||||
|
} = require("../db/utils")
|
||||||
|
|
||||||
module.exports = async (ctx, next) => {
|
module.exports = async (ctx, next) => {
|
||||||
// try to get the appID from the request
|
// try to get the appID from the request
|
||||||
|
@ -26,7 +30,8 @@ module.exports = async (ctx, next) => {
|
||||||
appCookie.roleId === BUILTIN_ROLE_IDS.PUBLIC)
|
appCookie.roleId === BUILTIN_ROLE_IDS.PUBLIC)
|
||||||
) {
|
) {
|
||||||
// Different App ID means cookie needs reset, or if the same public user has logged in
|
// Different App ID means cookie needs reset, or if the same public user has logged in
|
||||||
const globalUser = await getGlobalUsers(ctx, requestAppId, ctx.user.email)
|
const globalId = getGlobalIDFromUserMetadataID(ctx.user.userId)
|
||||||
|
const globalUser = await getGlobalUsers(ctx, requestAppId, globalId)
|
||||||
updateCookie = true
|
updateCookie = true
|
||||||
appId = requestAppId
|
appId = requestAppId
|
||||||
if (globalUser.roles && globalUser.roles[requestAppId]) {
|
if (globalUser.roles && globalUser.roles[requestAppId]) {
|
||||||
|
@ -36,18 +41,24 @@ module.exports = async (ctx, next) => {
|
||||||
appId = appCookie.appId
|
appId = appCookie.appId
|
||||||
roleId = appCookie.roleId || BUILTIN_ROLE_IDS.PUBLIC
|
roleId = appCookie.roleId || BUILTIN_ROLE_IDS.PUBLIC
|
||||||
}
|
}
|
||||||
if (appId) {
|
// nothing more to do
|
||||||
ctx.appId = appId
|
if (!appId) {
|
||||||
if (roleId) {
|
return next()
|
||||||
ctx.roleId = roleId
|
}
|
||||||
ctx.user = {
|
|
||||||
...ctx.user,
|
ctx.appId = appId
|
||||||
_id: ctx.user ? ctx.user.userId : null,
|
if (roleId) {
|
||||||
role: await getRole(appId, roleId),
|
ctx.roleId = roleId
|
||||||
}
|
const userId = ctx.user ? generateUserMetadataID(ctx.user.userId) : null
|
||||||
|
ctx.user = {
|
||||||
|
...ctx.user,
|
||||||
|
// override userID with metadata one
|
||||||
|
_id: userId,
|
||||||
|
userId,
|
||||||
|
role: await getRole(appId, roleId),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (updateCookie && appId) {
|
if (updateCookie) {
|
||||||
setCookie(ctx, { appId, roleId }, Cookies.CurrentApp)
|
setCookie(ctx, { appId, roleId }, Cookies.CurrentApp)
|
||||||
}
|
}
|
||||||
return next()
|
return next()
|
||||||
|
|
|
@ -91,8 +91,10 @@ exports.getGlobalUsers = async (ctx, appId = null, globalId = null) => {
|
||||||
return users
|
return users
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.saveGlobalUser = async (ctx, appId, body, globalId = null) => {
|
exports.saveGlobalUser = async (ctx, appId, body) => {
|
||||||
const globalUser = await exports.getGlobalUsers(ctx, appId, globalId)
|
const globalUser = body._id
|
||||||
|
? await exports.getGlobalUsers(ctx, appId, body._id)
|
||||||
|
: {}
|
||||||
const roles = globalUser.roles || {}
|
const roles = globalUser.roles || {}
|
||||||
if (body.roleId) {
|
if (body.roleId) {
|
||||||
roles[appId] = body.roleId
|
roles[appId] = body.roleId
|
||||||
|
|
|
@ -31,15 +31,13 @@ exports.fetch = async function(ctx) {
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
const groups = response.rows.map(row => row.doc)
|
ctx.body = response.rows.map(row => row.doc)
|
||||||
ctx.body = groups
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.find = async function(ctx) {
|
exports.find = async function(ctx) {
|
||||||
const db = new CouchDB(GLOBAL_DB)
|
const db = new CouchDB(GLOBAL_DB)
|
||||||
try {
|
try {
|
||||||
const record = await db.get(ctx.params.id)
|
ctx.body = await db.get(ctx.params.id)
|
||||||
ctx.body = record
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ctx.throw(err.status, err)
|
ctx.throw(err.status, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,42 @@
|
||||||
const CouchDB = require("../../../db")
|
const CouchDB = require("../../../db")
|
||||||
const {
|
const {
|
||||||
hash,
|
hash,
|
||||||
generateUserID,
|
generateGlobalUserID,
|
||||||
getUserParams,
|
getGlobalUserParams,
|
||||||
StaticDatabases,
|
StaticDatabases,
|
||||||
|
getGlobalUserByEmail,
|
||||||
} = require("@budibase/auth")
|
} = require("@budibase/auth")
|
||||||
const { UserStatus } = require("../../../constants")
|
const { UserStatus } = require("../../../constants")
|
||||||
|
|
||||||
|
const FIRST_USER_EMAIL = "test@test.com"
|
||||||
|
const FIRST_USER_PASSWORD = "test"
|
||||||
const GLOBAL_DB = StaticDatabases.GLOBAL.name
|
const GLOBAL_DB = StaticDatabases.GLOBAL.name
|
||||||
|
|
||||||
exports.userSave = async ctx => {
|
exports.userSave = async ctx => {
|
||||||
const db = new CouchDB(GLOBAL_DB)
|
const db = new CouchDB(GLOBAL_DB)
|
||||||
const { email, password, _id } = ctx.request.body
|
const { email, password, _id } = ctx.request.body
|
||||||
const hashedPassword = password ? await hash(password) : null
|
|
||||||
let user = {
|
// make sure another user isn't using the same email
|
||||||
...ctx.request.body,
|
const dbUser = await getGlobalUserByEmail(email)
|
||||||
_id: generateUserID(email),
|
if (dbUser != null && (dbUser._id !== _id || Array.isArray(dbUser))) {
|
||||||
password: hashedPassword,
|
ctx.throw(400, "Email address already in use.")
|
||||||
}
|
}
|
||||||
let dbUser
|
|
||||||
// in-case user existed already
|
// get the password, make sure one is defined
|
||||||
if (_id) {
|
let hashedPassword
|
||||||
dbUser = await db.get(_id)
|
if (password) {
|
||||||
|
hashedPassword = await hash(password)
|
||||||
|
} else if (dbUser) {
|
||||||
|
hashedPassword = dbUser.password
|
||||||
|
} else {
|
||||||
|
ctx.throw(400, "Password must be specified.")
|
||||||
|
}
|
||||||
|
|
||||||
|
let user = {
|
||||||
|
...dbUser,
|
||||||
|
...ctx.request.body,
|
||||||
|
_id: _id || generateGlobalUserID(),
|
||||||
|
password: hashedPassword,
|
||||||
}
|
}
|
||||||
// add the active status to a user if its not provided
|
// add the active status to a user if its not provided
|
||||||
if (user.status == null) {
|
if (user.status == null) {
|
||||||
|
@ -29,7 +44,7 @@ exports.userSave = async ctx => {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const response = await db.post({
|
const response = await db.post({
|
||||||
password: hashedPassword || dbUser.password,
|
password: hashedPassword,
|
||||||
...user,
|
...user,
|
||||||
})
|
})
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
|
@ -46,12 +61,24 @@ exports.userSave = async ctx => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.firstUser = async ctx => {
|
||||||
|
ctx.request.body = {
|
||||||
|
email: FIRST_USER_EMAIL,
|
||||||
|
password: FIRST_USER_PASSWORD,
|
||||||
|
roles: {},
|
||||||
|
builder: {
|
||||||
|
global: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
await exports.userSave(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
exports.userDelete = async ctx => {
|
exports.userDelete = async ctx => {
|
||||||
const db = new CouchDB(GLOBAL_DB)
|
const db = new CouchDB(GLOBAL_DB)
|
||||||
const dbUser = await db.get(generateUserID(ctx.params.email))
|
const dbUser = await db.get(ctx.params.id)
|
||||||
await db.remove(dbUser._id, dbUser._rev)
|
await db.remove(dbUser._id, dbUser._rev)
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
message: `User ${ctx.params.email} deleted.`,
|
message: `User ${ctx.params.id} deleted.`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +86,7 @@ exports.userDelete = async ctx => {
|
||||||
exports.userFetch = async ctx => {
|
exports.userFetch = async ctx => {
|
||||||
const db = new CouchDB(GLOBAL_DB)
|
const db = new CouchDB(GLOBAL_DB)
|
||||||
const response = await db.allDocs(
|
const response = await db.allDocs(
|
||||||
getUserParams(null, {
|
getGlobalUserParams(null, {
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -78,7 +105,7 @@ exports.userFind = async ctx => {
|
||||||
const db = new CouchDB(GLOBAL_DB)
|
const db = new CouchDB(GLOBAL_DB)
|
||||||
let user
|
let user
|
||||||
try {
|
try {
|
||||||
user = await db.get(generateUserID(ctx.params.email))
|
user = await db.get(ctx.params.id)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// no user found, just return nothing
|
// no user found, just return nothing
|
||||||
user = {}
|
user = {}
|
||||||
|
|
|
@ -32,8 +32,9 @@ router
|
||||||
authenticated,
|
authenticated,
|
||||||
controller.userSave
|
controller.userSave
|
||||||
)
|
)
|
||||||
.delete("/api/admin/users/:email", authenticated, controller.userDelete)
|
.post("/api/admin/users/first", controller.firstUser)
|
||||||
|
.delete("/api/admin/users/:id", authenticated, controller.userDelete)
|
||||||
.get("/api/admin/users", authenticated, controller.userFetch)
|
.get("/api/admin/users", authenticated, controller.userFetch)
|
||||||
.get("/api/admin/users/:email", authenticated, controller.userFind)
|
.get("/api/admin/users/:id", authenticated, controller.userFind)
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
exports.StaticDatabases = {
|
|
||||||
USER: {
|
|
||||||
name: "user-db",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const DocumentTypes = {
|
|
||||||
USER: "us",
|
|
||||||
APP: "app",
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.DocumentTypes = DocumentTypes
|
|
||||||
|
|
||||||
const UNICODE_MAX = "\ufff0"
|
|
||||||
const 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.
|
|
||||||
* @returns {string} The new user ID which the user doc can be stored under.
|
|
||||||
*/
|
|
||||||
exports.generateUserID = email => {
|
|
||||||
return `${DocumentTypes.USER}${SEPARATOR}${email}`
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets parameters for retrieving users, this is a utility function for the getDocParams function.
|
|
||||||
*/
|
|
||||||
exports.getUserParams = (email = "", otherProps = {}) => {
|
|
||||||
return {
|
|
||||||
...otherProps,
|
|
||||||
startkey: `${DocumentTypes.USER}${SEPARATOR}${email}`,
|
|
||||||
endkey: `${DocumentTypes.USER}${SEPARATOR}${email}${UNICODE_MAX}`,
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue