Updating middlewares to Typescript, as well as some fixes based on running tests.
This commit is contained in:
parent
535fab7997
commit
4328ed1b67
|
@ -109,10 +109,7 @@ export async function doInAppContext(appId: string, task: any): Promise<any> {
|
||||||
if (tenantId) {
|
if (tenantId) {
|
||||||
updates.tenantId = tenantId
|
updates.tenantId = tenantId
|
||||||
}
|
}
|
||||||
return newContext(
|
return newContext(updates, task)
|
||||||
updates,
|
|
||||||
task
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function doInIdentityContext(
|
export async function doInIdentityContext(
|
||||||
|
|
|
@ -45,9 +45,7 @@ const getSettingsDoc = async () => {
|
||||||
const db = tenancy.getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
let settings
|
let settings
|
||||||
try {
|
try {
|
||||||
settings = await db.get(
|
settings = await db.get(dbUtils.generateConfigID({ type: Config.SETTINGS }))
|
||||||
dbUtils.generateConfigID({ type: Config.SETTINGS })
|
|
||||||
)
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (e.status !== 404) {
|
if (e.status !== 404) {
|
||||||
throw e
|
throw e
|
||||||
|
|
|
@ -31,7 +31,7 @@ async function makeRequest(method, endpoint, body, appId = config.getAppId()) {
|
||||||
if (body) {
|
if (body) {
|
||||||
req.send(body)
|
req.send(body)
|
||||||
}
|
}
|
||||||
const res = await req.expect("Content-Type", /json/).expect(200)
|
const res = await req
|
||||||
expect(res.body).toBeDefined()
|
expect(res.body).toBeDefined()
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
const { isDevAppID, isProdAppID } = require("../db/utils")
|
import { isDevAppID, isProdAppID } from "../db/utils"
|
||||||
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
exports.AppType = {
|
export enum AppType {
|
||||||
DEV: "dev",
|
DEV = "dev",
|
||||||
PROD: "prod",
|
PROD = "prod",
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.middleware =
|
export function middleware({ appType }: { appType?: AppType } = {}) {
|
||||||
({ appType } = {}) =>
|
return (ctx: BBContext, next: any) => {
|
||||||
(ctx, next) => {
|
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
if (appType === exports.AppType.DEV && appId && !isDevAppID(appId)) {
|
if (appType === AppType.DEV && appId && !isDevAppID(appId)) {
|
||||||
ctx.throw(400, "Only apps in development support this endpoint")
|
ctx.throw(400, "Only apps in development support this endpoint")
|
||||||
}
|
}
|
||||||
if (appType === exports.AppType.PROD && appId && !isProdAppID(appId)) {
|
if (appType === AppType.PROD && appId && !isProdAppID(appId)) {
|
||||||
ctx.throw(400, "Only apps in production support this endpoint")
|
ctx.throw(400, "Only apps in production support this endpoint")
|
||||||
}
|
}
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
const { APP_DEV_PREFIX } = require("../db/utils")
|
import {
|
||||||
const {
|
APP_DEV_PREFIX,
|
||||||
|
DocumentType,
|
||||||
|
getGlobalIDFromUserMetadataID,
|
||||||
|
} from "../db/utils"
|
||||||
|
import {
|
||||||
doesUserHaveLock,
|
doesUserHaveLock,
|
||||||
updateLock,
|
updateLock,
|
||||||
checkDebounce,
|
checkDebounce,
|
||||||
setDebounce,
|
setDebounce,
|
||||||
} = require("../utilities/redis")
|
} from "../utilities/redis"
|
||||||
const { doWithDB } = require("@budibase/backend-core/db")
|
import { db as dbCore, cache, permissions } from "@budibase/backend-core"
|
||||||
const { DocumentType, getGlobalIDFromUserMetadataID } = require("../db/utils")
|
import { BBContext } from "@budibase/types"
|
||||||
const { PermissionTypes } = require("@budibase/backend-core/permissions")
|
import { PouchLike } from "@budibase/backend-core/src/db"
|
||||||
const { app: appCache } = require("@budibase/backend-core/cache")
|
|
||||||
|
|
||||||
const DEBOUNCE_TIME_SEC = 30
|
const DEBOUNCE_TIME_SEC = 30
|
||||||
|
|
||||||
|
@ -21,11 +24,11 @@ const DEBOUNCE_TIME_SEC = 30
|
||||||
* through the authorized middleware *
|
* through the authorized middleware *
|
||||||
****************************************************/
|
****************************************************/
|
||||||
|
|
||||||
async function checkDevAppLocks(ctx) {
|
async function checkDevAppLocks(ctx: BBContext) {
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
|
|
||||||
// if any public usage, don't proceed
|
// if any public usage, don't proceed
|
||||||
if (!ctx.user._id && !ctx.user.userId) {
|
if (!ctx.user?._id && !ctx.user?.userId) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,34 +44,34 @@ async function checkDevAppLocks(ctx) {
|
||||||
await updateLock(appId, ctx.user)
|
await updateLock(appId, ctx.user)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateAppUpdatedAt(ctx) {
|
async function updateAppUpdatedAt(ctx: BBContext) {
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
// if debouncing skip this update
|
// if debouncing skip this update
|
||||||
// get methods also aren't updating
|
// get methods also aren't updating
|
||||||
if (ctx.method === "GET" || (await checkDebounce(appId))) {
|
if (ctx.method === "GET" || (await checkDebounce(appId))) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await doWithDB(appId, async db => {
|
await dbCore.doWithDB(appId, async (db: PouchLike) => {
|
||||||
const metadata = await db.get(DocumentType.APP_METADATA)
|
const metadata = await db.get(DocumentType.APP_METADATA)
|
||||||
metadata.updatedAt = new Date().toISOString()
|
metadata.updatedAt = new Date().toISOString()
|
||||||
|
|
||||||
metadata.updatedBy = getGlobalIDFromUserMetadataID(ctx.user.userId)
|
metadata.updatedBy = getGlobalIDFromUserMetadataID(ctx.user?.userId!)
|
||||||
|
|
||||||
const response = await db.put(metadata)
|
const response = await db.put(metadata)
|
||||||
metadata._rev = response.rev
|
metadata._rev = response.rev
|
||||||
await appCache.invalidateAppMetadata(appId, metadata)
|
await cache.app.invalidateAppMetadata(appId, metadata)
|
||||||
// set a new debounce record with a short TTL
|
// set a new debounce record with a short TTL
|
||||||
await setDebounce(appId, DEBOUNCE_TIME_SEC)
|
await setDebounce(appId, DEBOUNCE_TIME_SEC)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = async (ctx, permType) => {
|
export = async function builder(ctx: BBContext, permType: string) {
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
// this only functions within an app context
|
// this only functions within an app context
|
||||||
if (!appId) {
|
if (!appId) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const isBuilderApi = permType === PermissionTypes.BUILDER
|
const isBuilderApi = permType === permissions.PermissionTypes.BUILDER
|
||||||
const referer = ctx.headers["referer"]
|
const referer = ctx.headers["referer"]
|
||||||
|
|
||||||
const overviewPath = "/builder/portal/overview/"
|
const overviewPath = "/builder/portal/overview/"
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
const Joi = require("joi")
|
import Joi from "joi"
|
||||||
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
function validate(schema, property) {
|
function validate(schema: Joi.Schema, property: string) {
|
||||||
// Return a Koa middleware function
|
// Return a Koa middleware function
|
||||||
return (ctx, next) => {
|
return (ctx: BBContext, next: any) => {
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
let params = null
|
let params = null
|
||||||
if (ctx[property] != null) {
|
if (ctx[property] != null) {
|
||||||
params = ctx[property]
|
params = ctx[property]
|
||||||
} else if (ctx.request[property] != null) {
|
} else if (ctx.request.get(property) != null) {
|
||||||
params = ctx.request[property]
|
params = ctx.request.get(property)
|
||||||
}
|
}
|
||||||
|
|
||||||
// not all schemas have the append property e.g. array schemas
|
// not all schemas have the append property e.g. array schemas
|
||||||
if (schema.append) {
|
if ("append" in schema && schema.append) {
|
||||||
schema = schema.append({
|
schema = schema.append({
|
||||||
createdAt: Joi.any().optional(),
|
createdAt: Joi.any().optional(),
|
||||||
updatedAt: Joi.any().optional(),
|
updatedAt: Joi.any().optional(),
|
||||||
|
@ -30,10 +31,10 @@ function validate(schema, property) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.body = schema => {
|
export function body(schema: Joi.Schema) {
|
||||||
return validate(schema, "body")
|
return validate(schema, "body")
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.params = schema => {
|
export function params(schema: Joi.Schema) {
|
||||||
return validate(schema, "params")
|
return validate(schema, "params")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
const { Header } = require("@budibase/backend-core/constants")
|
import { constants, utils } from "@budibase/backend-core"
|
||||||
const { getAppIdFromCtx } = require("@budibase/backend-core/utils")
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
module.exports = function ({ requiresAppId } = {}) {
|
export = function ({ requiresAppId }: { requiresAppId?: boolean } = {}) {
|
||||||
return async (ctx, next) => {
|
return async (ctx: BBContext, next: any) => {
|
||||||
const appId = await getAppIdFromCtx(ctx)
|
const appId = await utils.getAppIdFromCtx(ctx)
|
||||||
if (requiresAppId && !appId) {
|
if (requiresAppId && !appId) {
|
||||||
ctx.throw(
|
ctx.throw(
|
||||||
400,
|
400,
|
||||||
`Invalid app ID provided, please check the ${Header.APP_ID} header.`
|
`Invalid app ID provided, please check the ${constants.Header.APP_ID} header.`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (!ctx.headers[Header.API_KEY]) {
|
if (!ctx.headers[constants.Header.API_KEY]) {
|
||||||
ctx.throw(
|
ctx.throw(
|
||||||
400,
|
400,
|
||||||
`Invalid API key provided, please check the ${Header.API_KEY} header.`
|
`Invalid API key provided, please check the ${constants.Header.API_KEY} header.`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return next()
|
return next()
|
||||||
|
|
|
@ -1,17 +1,23 @@
|
||||||
class ResourceIdGetter {
|
import { BBContext } from "@budibase/types"
|
||||||
constructor(ctxProperty) {
|
|
||||||
|
export class ResourceIdGetter {
|
||||||
|
parameter: string
|
||||||
|
main: string | null
|
||||||
|
sub: string | null
|
||||||
|
|
||||||
|
constructor(ctxProperty: string) {
|
||||||
this.parameter = ctxProperty
|
this.parameter = ctxProperty
|
||||||
this.main = null
|
this.main = null
|
||||||
this.sub = null
|
this.sub = null
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
mainResource(field) {
|
mainResource(field: string) {
|
||||||
this.main = field
|
this.main = field
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
subResource(field) {
|
subResource(field: string) {
|
||||||
this.sub = field
|
this.sub = field
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -20,7 +26,8 @@ class ResourceIdGetter {
|
||||||
const parameter = this.parameter,
|
const parameter = this.parameter,
|
||||||
main = this.main,
|
main = this.main,
|
||||||
sub = this.sub
|
sub = this.sub
|
||||||
return (ctx, next) => {
|
return (ctx: BBContext, next: any) => {
|
||||||
|
// @ts-ignore
|
||||||
const request = ctx.request[parameter] || ctx[parameter]
|
const request = ctx.request[parameter] || ctx[parameter]
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
return next()
|
return next()
|
||||||
|
@ -36,24 +43,22 @@ class ResourceIdGetter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.ResourceIdGetter = ResourceIdGetter
|
export function paramResource(main: string) {
|
||||||
|
|
||||||
module.exports.paramResource = main => {
|
|
||||||
return new ResourceIdGetter("params").mainResource(main).build()
|
return new ResourceIdGetter("params").mainResource(main).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.paramSubResource = (main, sub) => {
|
export function paramSubResource(main: string, sub: string) {
|
||||||
return new ResourceIdGetter("params")
|
return new ResourceIdGetter("params")
|
||||||
.mainResource(main)
|
.mainResource(main)
|
||||||
.subResource(sub)
|
.subResource(sub)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.bodyResource = main => {
|
export function bodyResource(main: string) {
|
||||||
return new ResourceIdGetter("body").mainResource(main).build()
|
return new ResourceIdGetter("body").mainResource(main).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.bodySubResource = (main, sub) => {
|
export function bodySubResource(main: string, sub: string) {
|
||||||
return new ResourceIdGetter("body")
|
return new ResourceIdGetter("body")
|
||||||
.mainResource(main)
|
.mainResource(main)
|
||||||
.subResource(sub)
|
.subResource(sub)
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
const env = require("../environment")
|
import env from "../environment"
|
||||||
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
// if added as a middleware will stop requests unless builder is in self host mode
|
// if added as a middleware will stop requests unless builder is in self host mode
|
||||||
// or cloud is in self host
|
// or cloud is in self host
|
||||||
module.exports = async (ctx, next) => {
|
module.exports = async (ctx: BBContext, next: any) => {
|
||||||
if (env.SELF_HOSTED) {
|
if (env.SELF_HOSTED) {
|
||||||
await next()
|
await next()
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
const WEBHOOK_ENDPOINTS = new RegExp(
|
const WEBHOOK_ENDPOINTS = new RegExp(
|
||||||
["webhooks/trigger", "webhooks/schema"].join("|")
|
["webhooks/trigger", "webhooks/schema"].join("|")
|
||||||
)
|
)
|
||||||
|
|
||||||
exports.isWebhookEndpoint = ctx => {
|
export function isWebhookEndpoint(ctx: BBContext) {
|
||||||
return WEBHOOK_ENDPOINTS.test(ctx.request.url)
|
return WEBHOOK_ENDPOINTS.test(ctx.request.url)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ const {
|
||||||
const controllers = require("./controllers")
|
const controllers = require("./controllers")
|
||||||
const supertest = require("supertest")
|
const supertest = require("supertest")
|
||||||
const { cleanup } = require("../../utilities/fileSystem")
|
const { cleanup } = require("../../utilities/fileSystem")
|
||||||
const { Cookie, Headers } = require("@budibase/backend-core/constants")
|
const { Cookie, Header } = require("@budibase/backend-core/constants")
|
||||||
const { jwt } = require("@budibase/backend-core/auth")
|
const { jwt } = require("@budibase/backend-core/auth")
|
||||||
const { doInTenant, doWithGlobalDB } = require("@budibase/backend-core/tenancy")
|
const { doInTenant, doWithGlobalDB } = require("@budibase/backend-core/tenancy")
|
||||||
const { createASession } = require("@budibase/backend-core/sessions")
|
const { createASession } = require("@budibase/backend-core/sessions")
|
||||||
|
|
|
@ -3,7 +3,7 @@ const env = require("../environment")
|
||||||
const { checkSlashesInUrl } = require("./index")
|
const { checkSlashesInUrl } = require("./index")
|
||||||
const { getProdAppID } = require("@budibase/backend-core/db")
|
const { getProdAppID } = require("@budibase/backend-core/db")
|
||||||
const { updateAppRole } = require("./global")
|
const { updateAppRole } = require("./global")
|
||||||
const { Headers } = require("@budibase/backend-core/constants")
|
const { Header } = require("@budibase/backend-core/constants")
|
||||||
const { getTenantId, isTenantIdSet } = require("@budibase/backend-core/tenancy")
|
const { getTenantId, isTenantIdSet } = require("@budibase/backend-core/tenancy")
|
||||||
|
|
||||||
function request(ctx, request) {
|
function request(ctx, request) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ const core = require("@budibase/backend-core")
|
||||||
const { Config, EmailTemplatePurpose } = require("../../../constants")
|
const { Config, EmailTemplatePurpose } = require("../../../constants")
|
||||||
const { sendEmail, isEmailConfigured } = require("../../../utilities/email")
|
const { sendEmail, isEmailConfigured } = require("../../../utilities/email")
|
||||||
const { setCookie, getCookie, clearCookie, hash, platformLogout } = core.utils
|
const { setCookie, getCookie, clearCookie, hash, platformLogout } = core.utils
|
||||||
const { Cookie, Headers } = core.constants
|
const { Cookie, Header } = core.constants
|
||||||
const { passport, ssoCallbackUrl, google, oidc } = core.auth
|
const { passport, ssoCallbackUrl, google, oidc } = core.auth
|
||||||
const { checkResetPasswordCode } = require("../../../utilities/redis")
|
const { checkResetPasswordCode } = require("../../../utilities/redis")
|
||||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
const { Headers } = require("@budibase/backend-core/constants")
|
const { Header } = require("@budibase/backend-core/constants")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a restricted endpoint in the cloud.
|
* This is a restricted endpoint in the cloud.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const fetch = require("node-fetch")
|
const fetch = require("node-fetch")
|
||||||
const { Headers } = require("@budibase/backend-core/constants")
|
const { Header } = require("@budibase/backend-core/constants")
|
||||||
const { getTenantId, isTenantIdSet } = require("@budibase/backend-core/tenancy")
|
const { getTenantId, isTenantIdSet } = require("@budibase/backend-core/tenancy")
|
||||||
const { checkSlashesInUrl } = require("../utilities")
|
const { checkSlashesInUrl } = require("../utilities")
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
|
|
Loading…
Reference in New Issue