2020-10-06 20:13:41 +02:00
|
|
|
const CouchDB = require("../db")
|
2020-10-07 18:56:47 +02:00
|
|
|
const usageQuota = require("../utilities/usageQuota")
|
2020-10-28 21:35:06 +01:00
|
|
|
const env = require("../environment")
|
2020-10-06 20:13:41 +02:00
|
|
|
|
|
|
|
// currently only counting new writes and deletes
|
|
|
|
const METHOD_MAP = {
|
|
|
|
POST: 1,
|
|
|
|
DELETE: -1,
|
|
|
|
}
|
|
|
|
|
|
|
|
const DOMAIN_MAP = {
|
2020-10-09 20:10:28 +02:00
|
|
|
rows: usageQuota.Properties.ROW,
|
2020-10-07 18:56:47 +02:00
|
|
|
upload: usageQuota.Properties.UPLOAD,
|
|
|
|
views: usageQuota.Properties.VIEW,
|
|
|
|
users: usageQuota.Properties.USER,
|
|
|
|
// this will not be updated by endpoint calls
|
|
|
|
// instead it will be updated by triggers
|
|
|
|
automationRuns: usageQuota.Properties.AUTOMATION,
|
2020-10-06 20:13:41 +02:00
|
|
|
}
|
|
|
|
|
2020-10-07 18:56:47 +02:00
|
|
|
function getProperty(url) {
|
|
|
|
for (let domain of Object.keys(DOMAIN_MAP)) {
|
|
|
|
if (url.indexOf(domain) !== -1) {
|
|
|
|
return DOMAIN_MAP[domain]
|
|
|
|
}
|
2020-10-06 20:13:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = async (ctx, next) => {
|
2021-04-13 18:11:55 +02:00
|
|
|
// if in development or a self hosted cloud usage quotas should not be executed
|
|
|
|
if (env.isDev() || env.SELF_HOSTED) {
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
|
2021-03-29 18:32:05 +02:00
|
|
|
const db = new CouchDB(ctx.appId)
|
2020-10-07 18:56:47 +02:00
|
|
|
let usage = METHOD_MAP[ctx.req.method]
|
|
|
|
const property = getProperty(ctx.req.url)
|
2020-10-06 20:13:41 +02:00
|
|
|
if (usage == null || property == null) {
|
|
|
|
return next()
|
|
|
|
}
|
|
|
|
// post request could be a save of a pre-existing entry
|
2021-04-13 18:11:55 +02:00
|
|
|
if (ctx.request.body && ctx.request.body._id && ctx.request.body._rev) {
|
2020-10-06 20:13:41 +02:00
|
|
|
try {
|
2021-04-13 18:11:55 +02:00
|
|
|
await db.get(ctx.request.body._id)
|
2020-10-06 20:13:41 +02:00
|
|
|
return next()
|
|
|
|
} catch (err) {
|
|
|
|
ctx.throw(404, `${ctx.request.body._id} does not exist`)
|
|
|
|
}
|
|
|
|
}
|
2021-03-09 16:13:14 +01:00
|
|
|
|
2020-10-07 18:56:47 +02:00
|
|
|
// update usage for uploads to be the total size
|
|
|
|
if (property === usageQuota.Properties.UPLOAD) {
|
|
|
|
const files =
|
|
|
|
ctx.request.files.file.length > 1
|
|
|
|
? Array.from(ctx.request.files.file)
|
|
|
|
: [ctx.request.files.file]
|
|
|
|
usage = files.map(file => file.size).reduce((total, size) => total + size)
|
2020-10-06 20:13:41 +02:00
|
|
|
}
|
|
|
|
try {
|
2020-10-12 14:32:52 +02:00
|
|
|
await usageQuota.update(ctx.auth.apiKey, property, usage)
|
2020-10-08 18:34:41 +02:00
|
|
|
return next()
|
2020-10-06 20:13:41 +02:00
|
|
|
} catch (err) {
|
2020-10-07 18:56:47 +02:00
|
|
|
ctx.throw(403, err)
|
2020-10-06 20:13:41 +02:00
|
|
|
}
|
2020-10-07 18:56:47 +02:00
|
|
|
}
|