Removing the lookup of _id in usage quota when in dev/self host for performance reasons as part of usage quota, re-writing some bits of fetch self for cleaner implementation, fixing some issues with updating/saving users from within app.

This commit is contained in:
mike12345567 2021-04-13 17:11:55 +01:00
parent 56b4b1583c
commit a1227c5819
7 changed files with 39 additions and 27 deletions

View File

@ -79,20 +79,24 @@ exports.fetchSelf = async ctx => {
return
}
if (!appId) {
const db = new CouchDB(StaticDatabases.USER.name)
const user = await db.get(userId)
delete user.password
ctx.body = { user }
return
}
const db = new CouchDB(appId)
const user = await getFullUser({ ctx, userId: userId })
const userTable = await db.get(InternalTables.USER_METADATA)
if (user) {
delete user.password
if (appId) {
const db = new CouchDB(appId)
// remove the full roles structure
delete user.roles
try {
const userTable = await db.get(InternalTables.USER_METADATA)
const metadata = await db.get(userId)
// specifically needs to make sure is enriched
ctx.body = await outputProcessing(appId, userTable, {
...user,
...metadata,
})
} catch (err) {
ctx.body = user
}
} else {
ctx.body = user
}
// specifically needs to make sure is enriched
ctx.body = await outputProcessing(appId, userTable, user)
}

View File

@ -130,7 +130,7 @@ exports.save = async function(ctx) {
}
// if the row obj had an _id then it will have been retrieved
const existingRow = ctx.preExisting
const existingRow = await db.get(inputs._id)
if (existingRow) {
ctx.params.rowId = inputs._id
await exports.patch(ctx)

View File

@ -26,6 +26,9 @@ exports.fetchMetadata = async function(ctx) {
const users = []
for (let user of global) {
const info = metadata.find(meta => meta._id.includes(user.email))
// remove these props, not for the correct DB
delete user._id
delete user._rev
users.push({
...user,
...info,

View File

@ -76,8 +76,10 @@ describe("usageQuota middleware", () => {
})
it("passes through to next middleware if document already exists", async () => {
config.setProd(true)
config.setBody({
_id: "test"
_id: "test",
_rev: "test",
})
CouchDB.mockImplementationOnce(() => ({
@ -87,13 +89,14 @@ describe("usageQuota middleware", () => {
await config.executeMiddleware()
expect(config.next).toHaveBeenCalled()
expect(config.ctx.preExisting).toBe(true)
})
it("throws if request has _id, but the document no longer exists", async () => {
config.setBody({
_id: "123"
_id: "123",
_rev: "test",
})
config.setProd(true)
CouchDB.mockImplementationOnce(() => ({
get: async () => {

View File

@ -27,6 +27,11 @@ function getProperty(url) {
}
module.exports = async (ctx, next) => {
// if in development or a self hosted cloud usage quotas should not be executed
if (env.isDev() || env.SELF_HOSTED) {
return next()
}
const db = new CouchDB(ctx.appId)
let usage = METHOD_MAP[ctx.req.method]
const property = getProperty(ctx.req.url)
@ -34,20 +39,15 @@ module.exports = async (ctx, next) => {
return next()
}
// post request could be a save of a pre-existing entry
if (ctx.request.body && ctx.request.body._id) {
if (ctx.request.body && ctx.request.body._id && ctx.request.body._rev) {
try {
ctx.preExisting = await db.get(ctx.request.body._id)
await db.get(ctx.request.body._id)
return next()
} catch (err) {
ctx.throw(404, `${ctx.request.body._id} does not exist`)
return
}
}
// if in development or a self hosted cloud usage quotas should not be executed
if (env.isDev() || env.SELF_HOSTED) {
return next()
}
// update usage for uploads to be the total size
if (property === usageQuota.Properties.UPLOAD) {
const files =

View File

@ -96,7 +96,7 @@ exports.saveGlobalUser = async (ctx, appId, email, body) => {
body: {
...globalUser,
email,
password: body.password,
password: body.password || undefined,
status: body.status,
roles,
},
@ -114,5 +114,7 @@ exports.saveGlobalUser = async (ctx, appId, email, body) => {
delete body.password
delete body.roleId
delete body.status
delete body.roles
delete body.builder
return body
}

View File

@ -12,7 +12,7 @@ function buildUserSaveValidation() {
_id: Joi.string(),
_rev: Joi.string(),
email: Joi.string(),
password: Joi.string(),
password: Joi.string().allow(null, ""),
// maps appId -> roleId for the user
roles: Joi.object()
.pattern(/.*/, Joi.string())