forked from tsai/budibase
14 changed files with 244 additions and 126 deletions
@ -0,0 +1,26 @@ |
|||||
|
const CouchDB = require("../../../db") |
||||
|
const { |
||||
|
hash, |
||||
|
generateUserID, |
||||
|
getUserParams, |
||||
|
StaticDatabases, |
||||
|
} = require("@budibase/auth") |
||||
|
const { UserStatus } = require("../../../constants") |
||||
|
|
||||
|
const USER_DB = StaticDatabases.USER.name |
||||
|
|
||||
|
exports.save = async function(ctx, next) { |
||||
|
const db = new CouchDB(USER_DB) |
||||
|
} |
||||
|
|
||||
|
exports.fetch = async function(ctx, next) { |
||||
|
const db = new CouchDB(USER_DB) |
||||
|
} |
||||
|
|
||||
|
exports.find = async function(ctx, next) { |
||||
|
const db = new CouchDB(USER_DB) |
||||
|
} |
||||
|
|
||||
|
exports.destroy = async function(ctx, next) { |
||||
|
const db = new CouchDB(USER_DB) |
||||
|
} |
||||
@ -1,90 +1,11 @@ |
|||||
const CouchDB = require("../../../db") |
const users = require("./users") |
||||
const { |
const groups = require("./groups") |
||||
hash, |
|
||||
generateUserID, |
|
||||
getUserParams, |
|
||||
StaticDatabases, |
|
||||
} = require("@budibase/auth") |
|
||||
const { UserStatus } = require("../../../constants") |
|
||||
|
|
||||
const USER_DB = StaticDatabases.USER.name |
exports.initialise = async function(ctx) { |
||||
|
// create the ALL users group
|
||||
exports.userSave = async ctx => { |
|
||||
const db = new CouchDB(USER_DB) |
|
||||
const { email, password, _id } = ctx.request.body |
|
||||
const hashedPassword = password ? await hash(password) : null |
|
||||
let user = { |
|
||||
...ctx.request.body, |
|
||||
_id: generateUserID(email), |
|
||||
password: hashedPassword, |
|
||||
} |
|
||||
let dbUser |
|
||||
// in-case user existed already
|
|
||||
if (_id) { |
|
||||
dbUser = await db.get(_id) |
|
||||
} |
|
||||
// add the active status to a user if its not provided
|
|
||||
if (user.status == null) { |
|
||||
user.status = UserStatus.ACTIVE |
|
||||
} |
|
||||
try { |
|
||||
const response = await db.post({ |
|
||||
password: hashedPassword || dbUser.password, |
|
||||
...user, |
|
||||
}) |
|
||||
ctx.body = { |
|
||||
_id: response.id, |
|
||||
_rev: response.rev, |
|
||||
email, |
|
||||
} |
|
||||
} catch (err) { |
|
||||
if (err.status === 409) { |
|
||||
ctx.throw(400, "User exists already") |
|
||||
} else { |
|
||||
ctx.throw(err.status, err) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
exports.userDelete = async ctx => { |
|
||||
const db = new CouchDB(USER_DB) |
|
||||
const dbUser = await db.get(generateUserID(ctx.params.email)) |
|
||||
await db.remove(dbUser._id, dbUser._rev) |
|
||||
ctx.body = { |
|
||||
message: `User ${ctx.params.email} deleted.`, |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// called internally by app server user fetch
|
|
||||
exports.userFetch = async ctx => { |
|
||||
const db = new CouchDB(USER_DB) |
|
||||
const response = await db.allDocs( |
|
||||
getUserParams(null, { |
|
||||
include_docs: true, |
|
||||
}) |
|
||||
) |
|
||||
const users = response.rows.map(row => row.doc) |
|
||||
// user hashed password shouldn't ever be returned
|
|
||||
for (let user of users) { |
|
||||
if (user) { |
|
||||
delete user.password |
|
||||
} |
|
||||
} |
|
||||
ctx.body = users |
|
||||
} |
} |
||||
|
|
||||
// called internally by app server user find
|
module.exports = { |
||||
exports.userFind = async ctx => { |
users, |
||||
const db = new CouchDB(USER_DB) |
groups, |
||||
let user |
|
||||
try { |
|
||||
user = await db.get(generateUserID(ctx.params.email)) |
|
||||
} catch (err) { |
|
||||
// no user found, just return nothing
|
|
||||
user = {} |
|
||||
} |
|
||||
if (user) { |
|
||||
delete user.password |
|
||||
} |
|
||||
ctx.body = user |
|
||||
} |
} |
||||
|
|||||
@ -0,0 +1,90 @@ |
|||||
|
const CouchDB = require("../../../db") |
||||
|
const { |
||||
|
hash, |
||||
|
generateUserID, |
||||
|
getUserParams, |
||||
|
StaticDatabases, |
||||
|
} = require("@budibase/auth") |
||||
|
const { UserStatus } = require("../../../constants") |
||||
|
|
||||
|
const USER_DB = StaticDatabases.USER.name |
||||
|
|
||||
|
exports.userSave = async ctx => { |
||||
|
const db = new CouchDB(USER_DB) |
||||
|
const { email, password, _id } = ctx.request.body |
||||
|
const hashedPassword = password ? await hash(password) : null |
||||
|
let user = { |
||||
|
...ctx.request.body, |
||||
|
_id: generateUserID(email), |
||||
|
password: hashedPassword, |
||||
|
} |
||||
|
let dbUser |
||||
|
// in-case user existed already
|
||||
|
if (_id) { |
||||
|
dbUser = await db.get(_id) |
||||
|
} |
||||
|
// add the active status to a user if its not provided
|
||||
|
if (user.status == null) { |
||||
|
user.status = UserStatus.ACTIVE |
||||
|
} |
||||
|
try { |
||||
|
const response = await db.post({ |
||||
|
password: hashedPassword || dbUser.password, |
||||
|
...user, |
||||
|
}) |
||||
|
ctx.body = { |
||||
|
_id: response.id, |
||||
|
_rev: response.rev, |
||||
|
email, |
||||
|
} |
||||
|
} catch (err) { |
||||
|
if (err.status === 409) { |
||||
|
ctx.throw(400, "User exists already") |
||||
|
} else { |
||||
|
ctx.throw(err.status, err) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
exports.userDelete = async ctx => { |
||||
|
const db = new CouchDB(USER_DB) |
||||
|
const dbUser = await db.get(generateUserID(ctx.params.email)) |
||||
|
await db.remove(dbUser._id, dbUser._rev) |
||||
|
ctx.body = { |
||||
|
message: `User ${ctx.params.email} deleted.`, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// called internally by app server user fetch
|
||||
|
exports.userFetch = async ctx => { |
||||
|
const db = new CouchDB(USER_DB) |
||||
|
const response = await db.allDocs( |
||||
|
getUserParams(null, { |
||||
|
include_docs: true, |
||||
|
}) |
||||
|
) |
||||
|
const users = response.rows.map(row => row.doc) |
||||
|
// user hashed password shouldn't ever be returned
|
||||
|
for (let user of users) { |
||||
|
if (user) { |
||||
|
delete user.password |
||||
|
} |
||||
|
} |
||||
|
ctx.body = users |
||||
|
} |
||||
|
|
||||
|
// called internally by app server user find
|
||||
|
exports.userFind = async ctx => { |
||||
|
const db = new CouchDB(USER_DB) |
||||
|
let user |
||||
|
try { |
||||
|
user = await db.get(generateUserID(ctx.params.email)) |
||||
|
} catch (err) { |
||||
|
// no user found, just return nothing
|
||||
|
user = {} |
||||
|
} |
||||
|
if (user) { |
||||
|
delete user.password |
||||
|
} |
||||
|
ctx.body = user |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
const Router = require("@koa/router") |
||||
|
const controller = require("../../controllers/admin/groups") |
||||
|
const joiValidator = require("../../../middleware/joi-validator") |
||||
|
const { authenticated } = require("@budibase/auth") |
||||
|
const Joi = require("joi") |
||||
|
|
||||
|
const router = Router() |
||||
|
|
||||
|
function buildGroupSaveValidation() { |
||||
|
// prettier-ignore
|
||||
|
return joiValidator.body(Joi.object({ |
||||
|
// _id: Joi.string(),
|
||||
|
// _rev: Joi.string(),
|
||||
|
// email: Joi.string(),
|
||||
|
// password: Joi.string().allow(null, ""),
|
||||
|
// builder: Joi.object({
|
||||
|
// global: Joi.boolean().optional(),
|
||||
|
// apps: Joi.array().optional(),
|
||||
|
// }).unknown(true).optional(),
|
||||
|
// // maps appId -> roleId for the user
|
||||
|
// roles: Joi.object()
|
||||
|
// .pattern(/.*/, Joi.string())
|
||||
|
// .required()
|
||||
|
// .unknown(true)
|
||||
|
}).required().unknown(true).optional()) |
||||
|
} |
||||
|
|
||||
|
router |
||||
|
.post( |
||||
|
"/api/admin/groups", |
||||
|
buildGroupSaveValidation(), |
||||
|
authenticated, |
||||
|
controller.save |
||||
|
) |
||||
|
.delete("/api/admin/groups/:id", authenticated, controller.destroy) |
||||
|
.get("/api/admin/groups", authenticated, controller.fetch) |
||||
|
.get("/api/admin/group/:id", authenticated, controller.find) |
||||
|
|
||||
|
module.exports = router |
||||
@ -0,0 +1,39 @@ |
|||||
|
const Router = require("@koa/router") |
||||
|
const controller = require("../../controllers/admin/users") |
||||
|
const joiValidator = require("../../../middleware/joi-validator") |
||||
|
const { authenticated } = require("@budibase/auth") |
||||
|
const Joi = require("joi") |
||||
|
|
||||
|
const router = Router() |
||||
|
|
||||
|
function buildUserSaveValidation() { |
||||
|
// prettier-ignore
|
||||
|
return joiValidator.body(Joi.object({ |
||||
|
_id: Joi.string(), |
||||
|
_rev: Joi.string(), |
||||
|
email: Joi.string(), |
||||
|
password: Joi.string().allow(null, ""), |
||||
|
builder: Joi.object({ |
||||
|
global: Joi.boolean().optional(), |
||||
|
apps: Joi.array().optional(), |
||||
|
}).unknown(true).optional(), |
||||
|
// maps appId -> roleId for the user
|
||||
|
roles: Joi.object() |
||||
|
.pattern(/.*/, Joi.string()) |
||||
|
.required() |
||||
|
.unknown(true) |
||||
|
}).required().unknown(true).optional()) |
||||
|
} |
||||
|
|
||||
|
router |
||||
|
.post( |
||||
|
"/api/admin/users", |
||||
|
buildUserSaveValidation(), |
||||
|
authenticated, |
||||
|
controller.userSave |
||||
|
) |
||||
|
.delete("/api/admin/users/:email", authenticated, controller.userDelete) |
||||
|
.get("/api/admin/users", authenticated, controller.userFetch) |
||||
|
.get("/api/admin/users/:email", authenticated, controller.userFind) |
||||
|
|
||||
|
module.exports = router |
||||
@ -1,5 +1,5 @@ |
|||||
const adminRoutes = require("./admin") |
const { userRoutes, groupRoutes } = require("./admin") |
||||
const authRoutes = require("./auth") |
const authRoutes = require("./auth") |
||||
const appRoutes = require("./app") |
const appRoutes = require("./app") |
||||
|
|
||||
exports.routes = [adminRoutes, authRoutes, appRoutes] |
exports.routes = [userRoutes, groupRoutes, authRoutes, appRoutes] |
||||
|
|||||
Loading…
Reference in new issue