mirror of https://github.com/Budibase/budibase.git
48 changed files with 592 additions and 473 deletions
@ -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) |
||||
|
} |
||||
|
|||||
@ -0,0 +1,35 @@ |
|||||
|
const { DocumentTypes, ViewNames, StaticDatabases } = require("./utils") |
||||
|
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 () => { |
||||
|
const db = getDB(StaticDatabases.GLOBAL.name) |
||||
|
let designDoc |
||||
|
try { |
||||
|
designDoc = await db.get("_design/database") |
||||
|
} catch (err) { |
||||
|
// no design doc, make one
|
||||
|
designDoc = DesignDoc() |
||||
|
} |
||||
|
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) |
||||
|
} |
||||
@ -1,21 +1,25 @@ |
|||||
const { Cookies } = require("../constants") |
const { Cookies } = require("../constants") |
||||
const { getCookie } = require("../utils") |
const { getCookie } = require("../utils") |
||||
const { getEmailFromUserID } = require("../db/utils") |
|
||||
|
|
||||
module.exports = async (ctx, next) => { |
module.exports = (noAuthPatterns = []) => { |
||||
try { |
const regex = new RegExp(noAuthPatterns.join("|")) |
||||
// check the actual user is authenticated first
|
return async (ctx, next) => { |
||||
const authCookie = getCookie(ctx, Cookies.Auth) |
// the path is not authenticated
|
||||
|
if (regex.test(ctx.request.url)) { |
||||
if (authCookie) { |
return next() |
||||
ctx.isAuthenticated = true |
|
||||
ctx.user = authCookie |
|
||||
// make sure email is correct from ID
|
|
||||
ctx.user.email = getEmailFromUserID(authCookie.userId) |
|
||||
} |
} |
||||
|
try { |
||||
|
// check the actual user is authenticated first
|
||||
|
const authCookie = getCookie(ctx, Cookies.Auth) |
||||
|
|
||||
|
if (authCookie) { |
||||
|
ctx.isAuthenticated = true |
||||
|
ctx.user = authCookie |
||||
|
} |
||||
|
|
||||
await next() |
return next() |
||||
} catch (err) { |
} catch (err) { |
||||
ctx.throw(err.status || 403, err) |
ctx.throw(err.status || 403, err) |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -1,7 +0,0 @@ |
|||||
const users = require("./users") |
|
||||
const groups = require("./groups") |
|
||||
|
|
||||
module.exports = { |
|
||||
users, |
|
||||
groups, |
|
||||
} |
|
||||
@ -0,0 +1,75 @@ |
|||||
|
const { generateTemplateID, getTemplateParams, StaticDatabases } = require("@budibase/auth").db |
||||
|
const { CouchDB } = require("../../../db") |
||||
|
const { TemplatePurposePretty } = require("../../../constants") |
||||
|
|
||||
|
const GLOBAL_DB = StaticDatabases.GLOBAL.name |
||||
|
const GLOBAL_OWNER = "global" |
||||
|
|
||||
|
async function getTemplates({ ownerId, type, id } = {}) { |
||||
|
const db = new CouchDB(GLOBAL_DB) |
||||
|
const response = await db.allDocs( |
||||
|
getTemplateParams(ownerId, id, { |
||||
|
include_docs: true, |
||||
|
}) |
||||
|
) |
||||
|
let templates = response.rows.map(row => row.doc) |
||||
|
if (type) { |
||||
|
templates = templates.filter(template => template.type === type) |
||||
|
} |
||||
|
return templates |
||||
|
} |
||||
|
|
||||
|
exports.save = async ctx => { |
||||
|
const db = new CouchDB(GLOBAL_DB) |
||||
|
const type = ctx.params.type |
||||
|
let template = ctx.request.body |
||||
|
if (!template.ownerId) { |
||||
|
template.ownerId = GLOBAL_OWNER |
||||
|
} |
||||
|
if (!template._id) { |
||||
|
template._id = generateTemplateID(template.ownerId) |
||||
|
} |
||||
|
|
||||
|
const response = await db.put({ |
||||
|
...template, |
||||
|
type, |
||||
|
}) |
||||
|
ctx.body = { |
||||
|
...template, |
||||
|
_rev: response.rev, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
exports.definitions = async ctx => { |
||||
|
ctx.body = { |
||||
|
purpose: TemplatePurposePretty |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
exports.fetch = async ctx => { |
||||
|
ctx.body = await getTemplates() |
||||
|
} |
||||
|
|
||||
|
exports.fetchByType = async ctx => { |
||||
|
ctx.body = await getTemplates({ |
||||
|
type: ctx.params.type, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
exports.fetchByOwner = async ctx => { |
||||
|
ctx.body = await getTemplates({ |
||||
|
ownerId: ctx.params.ownerId, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
exports.find = async ctx => { |
||||
|
ctx.body = await getTemplates({ |
||||
|
id: ctx.params.id, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
exports.destroy = async ctx => { |
||||
|
// TODO
|
||||
|
const db = new CouchDB(GLOBAL_DB) |
||||
|
ctx.body = {} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
const Router = require("@koa/router") |
||||
|
const controller = require("../../controllers/admin/templates") |
||||
|
const joiValidator = require("../../../middleware/joi-validator") |
||||
|
const Joi = require("joi") |
||||
|
const { TemplatePurpose, TemplateTypes } = require("../../../constants") |
||||
|
|
||||
|
const router = Router() |
||||
|
|
||||
|
function buildTemplateSaveValidation() { |
||||
|
// prettier-ignore
|
||||
|
return joiValidator.body(Joi.object({ |
||||
|
_id: Joi.string().allow(null, ""), |
||||
|
_rev: Joi.string().allow(null, ""), |
||||
|
ownerId: Joi.string().allow(null, ""), |
||||
|
name: Joi.string().allow(null, ""), |
||||
|
contents: Joi.string().required(), |
||||
|
purpose: Joi.string().required().valid(...Object.values(TemplatePurpose)), |
||||
|
type: Joi.string().required().valid(...Object.values(TemplateTypes)), |
||||
|
}).required().unknown(true).optional()) |
||||
|
} |
||||
|
|
||||
|
router |
||||
|
.get("/api/admin/template/definitions", controller.definitions) |
||||
|
.post( |
||||
|
"/api/admin/template", |
||||
|
buildTemplateSaveValidation(), |
||||
|
controller.save |
||||
|
) |
||||
|
.get("/api/admin/template", controller.fetch) |
||||
|
.get("/api/admin/template/:type", controller.fetchByType) |
||||
|
.get("/api/admin/template/:ownerId", controller.fetchByOwner) |
||||
|
.delete("/api/admin/template/:id", controller.destroy) |
||||
|
.get("/api/admin/template/:id", controller.find) |
||||
@ -1,9 +1,8 @@ |
|||||
const Router = require("@koa/router") |
const Router = require("@koa/router") |
||||
const controller = require("../controllers/app") |
const controller = require("../controllers/app") |
||||
const { authenticated } = require("@budibase/auth") |
|
||||
|
|
||||
const router = Router() |
const router = Router() |
||||
|
|
||||
router.get("/api/apps", authenticated, controller.getApps) |
router.get("/api/apps", controller.getApps) |
||||
|
|
||||
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