Re-building the context module to use a single object, meaning we can create new context frames and copy over whatever exists, then update.
This commit is contained in:
parent
9e01a9d1be
commit
45e7ef61ef
|
@ -1,4 +1,8 @@
|
||||||
export enum ContextKey {
|
export enum ContextKey {
|
||||||
|
MAIN = "main",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ContextElement {
|
||||||
TENANT_ID = "tenantId",
|
TENANT_ID = "tenantId",
|
||||||
APP_ID = "appId",
|
APP_ID = "appId",
|
||||||
IDENTITY = "identity",
|
IDENTITY = "identity",
|
||||||
|
|
|
@ -4,34 +4,36 @@ import cls from "./FunctionContext"
|
||||||
import { baseGlobalDBName } from "../db/tenancy"
|
import { baseGlobalDBName } from "../db/tenancy"
|
||||||
import { IdentityContext } from "@budibase/types"
|
import { IdentityContext } from "@budibase/types"
|
||||||
import { DEFAULT_TENANT_ID as _DEFAULT_TENANT_ID } from "../constants"
|
import { DEFAULT_TENANT_ID as _DEFAULT_TENANT_ID } from "../constants"
|
||||||
import { ContextKey } from "./constants"
|
import { ContextElement, ContextKey } from "./constants"
|
||||||
import { PouchLike } from "../couch"
|
import { PouchLike } from "../couch"
|
||||||
import { getDevelopmentAppID, getProdAppID } from "../db/conversions"
|
import { getDevelopmentAppID, getProdAppID } from "../db/conversions"
|
||||||
|
|
||||||
|
type ContextMap = { [key in ContextElement]?: any }
|
||||||
|
|
||||||
export const DEFAULT_TENANT_ID = _DEFAULT_TENANT_ID
|
export const DEFAULT_TENANT_ID = _DEFAULT_TENANT_ID
|
||||||
|
|
||||||
// some test cases call functions directly, need to
|
// some test cases call functions directly, need to
|
||||||
// store an app ID to pretend there is a context
|
// store an app ID to pretend there is a context
|
||||||
let TEST_APP_ID: string | null = null
|
let TEST_APP_ID: string | null = null
|
||||||
|
|
||||||
export const isMultiTenant = () => {
|
export function isMultiTenant() {
|
||||||
return env.MULTI_TENANCY
|
return env.MULTI_TENANCY
|
||||||
}
|
}
|
||||||
|
|
||||||
const setAppTenantId = (appId: string) => {
|
export function isTenantIdSet() {
|
||||||
const appTenantId = getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID
|
const context = cls.getFromContext(ContextKey.MAIN) as ContextMap
|
||||||
updateTenantId(appTenantId)
|
return !!context?.[ContextElement.TENANT_ID]
|
||||||
}
|
}
|
||||||
|
|
||||||
const setIdentity = (identity: IdentityContext | null) => {
|
export function isTenancyEnabled() {
|
||||||
cls.setOnContext(ContextKey.IDENTITY, identity)
|
return env.MULTI_TENANCY
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an app ID this will attempt to retrieve the tenant ID from it.
|
* Given an app ID this will attempt to retrieve the tenant ID from it.
|
||||||
* @return {null|string} The tenant ID found within the app ID.
|
* @return {null|string} The tenant ID found within the app ID.
|
||||||
*/
|
*/
|
||||||
export const getTenantIDFromAppID = (appId: string) => {
|
export function getTenantIDFromAppID(appId: string) {
|
||||||
if (!appId) {
|
if (!appId) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -50,84 +52,134 @@ export const getTenantIDFromAppID = (appId: string) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const doInContext = async (appId: string, task: any) => {
|
function updateContext(updates: ContextMap) {
|
||||||
// gets the tenant ID from the app ID
|
let context: ContextMap
|
||||||
const tenantId = getTenantIDFromAppID(appId)
|
try {
|
||||||
return doInTenant(tenantId, async () => {
|
context = cls.getFromContext(ContextKey.MAIN)
|
||||||
return doInAppContext(appId, async () => {
|
} catch (err) {
|
||||||
return task()
|
// no context, start empty
|
||||||
})
|
context = {}
|
||||||
|
}
|
||||||
|
context = {
|
||||||
|
...context,
|
||||||
|
...updates,
|
||||||
|
}
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
async function newContext(updates: ContextMap, task: any) {
|
||||||
|
// see if there already is a context setup
|
||||||
|
let context: ContextMap = updateContext(updates)
|
||||||
|
return cls.run(async () => {
|
||||||
|
cls.setOnContext(ContextKey.MAIN, context)
|
||||||
|
return await task()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const doInTenant = (tenantId: string | null, task: any): any => {
|
export async function doInContext(appId: string, task: any): Promise<any> {
|
||||||
|
const tenantId = getTenantIDFromAppID(appId)
|
||||||
|
return newContext(
|
||||||
|
{
|
||||||
|
[ContextElement.TENANT_ID]: tenantId,
|
||||||
|
[ContextElement.APP_ID]: appId,
|
||||||
|
},
|
||||||
|
task
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function doInTenant(
|
||||||
|
tenantId: string | null,
|
||||||
|
task: any
|
||||||
|
): Promise<any> {
|
||||||
// make sure default always selected in single tenancy
|
// make sure default always selected in single tenancy
|
||||||
if (!env.MULTI_TENANCY) {
|
if (!env.MULTI_TENANCY) {
|
||||||
tenantId = tenantId || DEFAULT_TENANT_ID
|
tenantId = tenantId || DEFAULT_TENANT_ID
|
||||||
}
|
}
|
||||||
|
|
||||||
return cls.run(async () => {
|
return newContext(
|
||||||
updateTenantId(tenantId)
|
{
|
||||||
return await task()
|
[ContextElement.TENANT_ID]: tenantId,
|
||||||
})
|
},
|
||||||
|
task
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const doInAppContext = (appId: string, task: any): any => {
|
export async function doInAppContext(appId: string, task: any): Promise<any> {
|
||||||
if (!appId) {
|
if (!appId) {
|
||||||
throw new Error("appId is required")
|
throw new Error("appId is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
const identity = getIdentity()
|
const tenantId = getTenantIDFromAppID(appId)
|
||||||
|
return newContext(
|
||||||
return cls.run(async () => {
|
{
|
||||||
// set the app tenant id
|
[ContextElement.TENANT_ID]: tenantId,
|
||||||
setAppTenantId(appId)
|
[ContextElement.APP_ID]: appId,
|
||||||
// set the app ID
|
},
|
||||||
cls.setOnContext(ContextKey.APP_ID, appId)
|
task
|
||||||
|
)
|
||||||
// preserve the identity
|
|
||||||
if (identity) {
|
|
||||||
setIdentity(identity)
|
|
||||||
}
|
|
||||||
// invoke the task
|
|
||||||
return await task()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const doInIdentityContext = (
|
export async function doInIdentityContext(
|
||||||
identity: IdentityContext,
|
identity: IdentityContext,
|
||||||
task: any
|
task: any
|
||||||
): any => {
|
): Promise<any> {
|
||||||
if (!identity) {
|
if (!identity) {
|
||||||
throw new Error("identity is required")
|
throw new Error("identity is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
return cls.run(async () => {
|
const context: ContextMap = {
|
||||||
cls.setOnContext(ContextKey.IDENTITY, identity)
|
[ContextElement.IDENTITY]: identity,
|
||||||
// set the tenant so that doInTenant will preserve identity
|
}
|
||||||
if (identity.tenantId) {
|
if (identity.tenantId) {
|
||||||
updateTenantId(identity.tenantId)
|
context[ContextElement.TENANT_ID] = identity.tenantId
|
||||||
}
|
}
|
||||||
// invoke the task
|
return newContext(context, task)
|
||||||
return await task()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getIdentity = (): IdentityContext | undefined => {
|
export function getIdentity(): IdentityContext | undefined {
|
||||||
try {
|
try {
|
||||||
return cls.getFromContext(ContextKey.IDENTITY)
|
const context = cls.getFromContext(ContextKey.MAIN) as ContextMap
|
||||||
|
return context?.[ContextElement.IDENTITY]
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// do nothing - identity is not in context
|
// do nothing - identity is not in context
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateTenantId = (tenantId: string | null) => {
|
export function getTenantId(): string {
|
||||||
cls.setOnContext(ContextKey.TENANT_ID, tenantId)
|
if (!isMultiTenant()) {
|
||||||
|
return DEFAULT_TENANT_ID
|
||||||
|
}
|
||||||
|
const context = cls.getFromContext(ContextKey.MAIN) as ContextMap
|
||||||
|
const tenantId = context?.[ContextElement.TENANT_ID]
|
||||||
|
if (!tenantId) {
|
||||||
|
throw new Error("Tenant id not found")
|
||||||
|
}
|
||||||
|
return tenantId
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateAppId = async (appId: string) => {
|
export function getAppId(): string | undefined {
|
||||||
|
const context = cls.getFromContext(ContextKey.MAIN) as ContextMap
|
||||||
|
const foundId = context?.[ContextElement.APP_ID]
|
||||||
|
if (!foundId && env.isTest() && TEST_APP_ID) {
|
||||||
|
return TEST_APP_ID
|
||||||
|
} else {
|
||||||
|
return foundId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateTenantId(tenantId: string | null) {
|
||||||
|
let context: ContextMap = updateContext({
|
||||||
|
[ContextElement.TENANT_ID]: tenantId,
|
||||||
|
})
|
||||||
|
cls.setOnContext(ContextKey.MAIN, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateAppId(appId: string) {
|
||||||
|
let context: ContextMap = updateContext({
|
||||||
|
[ContextElement.APP_ID]: appId,
|
||||||
|
})
|
||||||
try {
|
try {
|
||||||
cls.setOnContext(ContextKey.APP_ID, appId)
|
cls.setOnContext(ContextKey.MAIN, context)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (env.isTest()) {
|
if (env.isTest()) {
|
||||||
TEST_APP_ID = appId
|
TEST_APP_ID = appId
|
||||||
|
@ -137,63 +189,34 @@ export const updateAppId = async (appId: string) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getGlobalDB = (): PouchLike => {
|
export function getGlobalDB(): PouchLike {
|
||||||
const tenantId = cls.getFromContext(ContextKey.TENANT_ID)
|
const context = cls.getFromContext(ContextKey.MAIN) as ContextMap
|
||||||
return new PouchLike(baseGlobalDBName(tenantId))
|
return new PouchLike(baseGlobalDBName(context?.[ContextElement.TENANT_ID]))
|
||||||
}
|
|
||||||
|
|
||||||
export const isTenantIdSet = () => {
|
|
||||||
const tenantId = cls.getFromContext(ContextKey.TENANT_ID)
|
|
||||||
return !!tenantId
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getTenantId = () => {
|
|
||||||
if (!isMultiTenant()) {
|
|
||||||
return DEFAULT_TENANT_ID
|
|
||||||
}
|
|
||||||
const tenantId = cls.getFromContext(ContextKey.TENANT_ID)
|
|
||||||
if (!tenantId) {
|
|
||||||
throw new Error("Tenant id not found")
|
|
||||||
}
|
|
||||||
return tenantId
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getAppId = () => {
|
|
||||||
const foundId = cls.getFromContext(ContextKey.APP_ID)
|
|
||||||
if (!foundId && env.isTest() && TEST_APP_ID) {
|
|
||||||
return TEST_APP_ID
|
|
||||||
} else {
|
|
||||||
return foundId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isTenancyEnabled = () => {
|
|
||||||
return env.MULTI_TENANCY
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the app database based on whatever the request
|
* Gets the app database based on whatever the request
|
||||||
* contained, dev or prod.
|
* contained, dev or prod.
|
||||||
*/
|
*/
|
||||||
export const getAppDB = (opts?: any): PouchLike => {
|
export function getAppDB(opts?: any): PouchLike {
|
||||||
const appId = getAppId()
|
const appId = getAppId()
|
||||||
return new PouchLike(appId, opts)
|
return new PouchLike(appId, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This specifically gets the prod app ID, if the request
|
* This specifically gets the prod app ID, if the request
|
||||||
* contained a development app ID, this will open the prod one.
|
* contained a development app ID, this will get the prod one.
|
||||||
*/
|
*/
|
||||||
export const getProdAppDB = (opts?: any): PouchLike => {
|
export function getProdAppDB(opts?: any): PouchLike {
|
||||||
const appId = getAppId()
|
const appId = getAppId()
|
||||||
return new PouchLike(getProdAppID(appId), opts)
|
return new PouchLike(getProdAppID(appId), opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This specifically gets the dev app ID, if the request
|
* This specifically gets the dev app ID, if the request
|
||||||
* contained a prod app ID, this will open the dev one.
|
* contained a prod app ID, this will get the dev one.
|
||||||
*/
|
*/
|
||||||
export const getDevAppDB = (opts?: any): PouchLike => {
|
export function getDevAppDB(opts?: any): PouchLike {
|
||||||
const appId = getAppId()
|
const appId = getAppId()
|
||||||
return new PouchLike(getDevelopmentAppID(appId), opts)
|
return new PouchLike(getDevelopmentAppID(appId), opts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,10 @@ export class PouchLike {
|
||||||
private static nano: Nano.ServerScope
|
private static nano: Nano.ServerScope
|
||||||
private readonly pouchOpts: PouchLikeOpts
|
private readonly pouchOpts: PouchLikeOpts
|
||||||
|
|
||||||
constructor(dbName: string, opts?: PouchLikeOpts) {
|
constructor(dbName?: string, opts?: PouchLikeOpts) {
|
||||||
|
if (dbName == null) {
|
||||||
|
throw new Error("Database name cannot be undefined.")
|
||||||
|
}
|
||||||
this.name = dbName
|
this.name = dbName
|
||||||
this.pouchOpts = opts || {}
|
this.pouchOpts = opts || {}
|
||||||
if (!PouchLike.nano) {
|
if (!PouchLike.nano) {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import { getAppMetadata } from "../cache/appMetadata"
|
||||||
import { isDevApp, isDevAppID, getProdAppID } from "./conversions"
|
import { isDevApp, isDevAppID, getProdAppID } from "./conversions"
|
||||||
import { APP_PREFIX } from "./constants"
|
import { APP_PREFIX } from "./constants"
|
||||||
import * as events from "../events"
|
import * as events from "../events"
|
||||||
|
import { PouchLike } from "../couch"
|
||||||
|
|
||||||
export * from "./constants"
|
export * from "./constants"
|
||||||
export * from "./conversions"
|
export * from "./conversions"
|
||||||
|
@ -254,7 +255,7 @@ export function getRoleParams(roleId = null, otherProps = {}) {
|
||||||
return getDocParams(DocumentType.ROLE, roleId, otherProps)
|
return getDocParams(DocumentType.ROLE, roleId, otherProps)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getStartEndKeyURL(baseKey: any, tenantId = null) {
|
export function getStartEndKeyURL(baseKey: any, tenantId?: string) {
|
||||||
const tenancy = tenantId ? `${SEPARATOR}${tenantId}` : ""
|
const tenancy = tenantId ? `${SEPARATOR}${tenantId}` : ""
|
||||||
return `startkey="${baseKey}${tenancy}"&endkey="${baseKey}${tenancy}${UNICODE_MAX}"`
|
return `startkey="${baseKey}${tenancy}"&endkey="${baseKey}${tenancy}${UNICODE_MAX}"`
|
||||||
}
|
}
|
||||||
|
@ -388,20 +389,10 @@ export async function getDevAppIDs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function dbExists(dbName: any) {
|
export async function dbExists(dbName: any) {
|
||||||
let exists = false
|
|
||||||
return doWithDB(
|
return doWithDB(
|
||||||
dbName,
|
dbName,
|
||||||
async (db: any) => {
|
async (db: PouchLike) => {
|
||||||
try {
|
return await db.exists()
|
||||||
// check if database exists
|
|
||||||
const info = await db.info()
|
|
||||||
if (info && !info.error) {
|
|
||||||
exists = true
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
exists = false
|
|
||||||
}
|
|
||||||
return exists
|
|
||||||
},
|
},
|
||||||
{ skip_setup: true }
|
{ skip_setup: true }
|
||||||
)
|
)
|
||||||
|
|
|
@ -41,7 +41,7 @@ export const runMigration = async (
|
||||||
options: MigrationOptions = {}
|
options: MigrationOptions = {}
|
||||||
) => {
|
) => {
|
||||||
const migrationType = migration.type
|
const migrationType = migration.type
|
||||||
let tenantId: string
|
let tenantId: string | undefined
|
||||||
if (migrationType !== MigrationType.INSTALLATION) {
|
if (migrationType !== MigrationType.INSTALLATION) {
|
||||||
tenantId = getTenantId()
|
tenantId = getTenantId()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,23 @@
|
||||||
const fetch = require("node-fetch")
|
import fetch from "node-fetch"
|
||||||
const env = require("../../environment")
|
import env from "../../environment"
|
||||||
const { checkSlashesInUrl } = require("../../utilities")
|
import { checkSlashesInUrl } from "../../utilities"
|
||||||
const { request } = require("../../utilities/workerRequests")
|
import { request } from "../../utilities/workerRequests"
|
||||||
const { clearLock } = require("../../utilities/redis")
|
import { clearLock as redisClearLock } from "../../utilities/redis"
|
||||||
const { Replication, getProdAppID } = require("@budibase/backend-core/db")
|
import { DocumentType } from "../../db/utils"
|
||||||
const { DocumentType } = require("../../db/utils")
|
import { context } from "@budibase/backend-core"
|
||||||
const { app: appCache } = require("@budibase/backend-core/cache")
|
import { events, db as dbCore, cache } from "@budibase/backend-core"
|
||||||
const { getProdAppDB, getAppDB } = require("@budibase/backend-core/context")
|
|
||||||
const { events } = require("@budibase/backend-core")
|
|
||||||
|
|
||||||
async function redirect(ctx, method, path = "global") {
|
async function redirect(ctx: any, method: string, path: string = "global") {
|
||||||
const { devPath } = ctx.params
|
const { devPath } = ctx.params
|
||||||
const queryString = ctx.originalUrl.split("?")[1] || ""
|
const queryString = ctx.originalUrl.split("?")[1] || ""
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
checkSlashesInUrl(
|
checkSlashesInUrl(
|
||||||
`${env.WORKER_URL}/api/${path}/${devPath}?${queryString}`
|
`${env.WORKER_URL}/api/${path}/${devPath}?${queryString}`
|
||||||
),
|
),
|
||||||
request(
|
request(ctx, {
|
||||||
ctx,
|
method,
|
||||||
{
|
body: ctx.request.body,
|
||||||
method,
|
})
|
||||||
body: ctx.request.body,
|
|
||||||
},
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
const err = await response.text()
|
const err = await response.text()
|
||||||
|
@ -46,28 +40,28 @@ async function redirect(ctx, method, path = "global") {
|
||||||
ctx.cookies
|
ctx.cookies
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.buildRedirectGet = path => {
|
export function buildRedirectGet(path: string) {
|
||||||
return async ctx => {
|
return async (ctx: any) => {
|
||||||
await redirect(ctx, "GET", path)
|
await redirect(ctx, "GET", path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.buildRedirectPost = path => {
|
export function buildRedirectPost(path: string) {
|
||||||
return async ctx => {
|
return async (ctx: any) => {
|
||||||
await redirect(ctx, "POST", path)
|
await redirect(ctx, "POST", path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.buildRedirectDelete = path => {
|
export function buildRedirectDelete(path: string) {
|
||||||
return async ctx => {
|
return async (ctx: any) => {
|
||||||
await redirect(ctx, "DELETE", path)
|
await redirect(ctx, "DELETE", path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.clearLock = async ctx => {
|
export async function clearLock(ctx: any) {
|
||||||
const { appId } = ctx.params
|
const { appId } = ctx.params
|
||||||
try {
|
try {
|
||||||
await clearLock(appId, ctx.user)
|
await redisClearLock(appId, ctx.user)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ctx.throw(400, `Unable to remove lock. ${err}`)
|
ctx.throw(400, `Unable to remove lock. ${err}`)
|
||||||
}
|
}
|
||||||
|
@ -76,16 +70,16 @@ exports.clearLock = async ctx => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.revert = async ctx => {
|
export async function revert(ctx: any) {
|
||||||
const { appId } = ctx.params
|
const { appId } = ctx.params
|
||||||
const productionAppId = getProdAppID(appId)
|
const productionAppId = dbCore.getProdAppID(appId)
|
||||||
|
|
||||||
// App must have been deployed first
|
// App must have been deployed first
|
||||||
try {
|
try {
|
||||||
const db = getProdAppDB({ skip_setup: true })
|
const db = context.getProdAppDB({ skip_setup: true })
|
||||||
const info = await db.info()
|
const exists = await db.exists()
|
||||||
if (info.error) {
|
if (!exists) {
|
||||||
throw info.error
|
throw new Error("App must be deployed to be reverted.")
|
||||||
}
|
}
|
||||||
const deploymentDoc = await db.get(DocumentType.DEPLOYMENTS)
|
const deploymentDoc = await db.get(DocumentType.DEPLOYMENTS)
|
||||||
if (
|
if (
|
||||||
|
@ -98,7 +92,7 @@ exports.revert = async ctx => {
|
||||||
return ctx.throw(400, "App has not yet been deployed")
|
return ctx.throw(400, "App has not yet been deployed")
|
||||||
}
|
}
|
||||||
|
|
||||||
const replication = new Replication({
|
const replication = new dbCore.Replication({
|
||||||
source: productionAppId,
|
source: productionAppId,
|
||||||
target: appId,
|
target: appId,
|
||||||
})
|
})
|
||||||
|
@ -109,12 +103,12 @@ exports.revert = async ctx => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// update appID in reverted app to be dev version again
|
// update appID in reverted app to be dev version again
|
||||||
const db = getAppDB()
|
const db = context.getAppDB()
|
||||||
const appDoc = await db.get(DocumentType.APP_METADATA)
|
const appDoc = await db.get(DocumentType.APP_METADATA)
|
||||||
appDoc.appId = appId
|
appDoc.appId = appId
|
||||||
appDoc.instance._id = appId
|
appDoc.instance._id = appId
|
||||||
await db.put(appDoc)
|
await db.put(appDoc)
|
||||||
await appCache.invalidateAppMetadata(appId)
|
await cache.app.invalidateAppMetadata(appId)
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
message: "Reverted changes successfully.",
|
message: "Reverted changes successfully.",
|
||||||
}
|
}
|
||||||
|
@ -126,7 +120,7 @@ exports.revert = async ctx => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getBudibaseVersion = async ctx => {
|
export async function getBudibaseVersion(ctx: any) {
|
||||||
const version = require("../../../package.json").version
|
const version = require("../../../package.json").version
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
version,
|
version,
|
|
@ -95,8 +95,7 @@ module.exports = async (ctx, next) => {
|
||||||
// need to judge this only based on the request app ID,
|
// need to judge this only based on the request app ID,
|
||||||
if (
|
if (
|
||||||
env.MULTI_TENANCY &&
|
env.MULTI_TENANCY &&
|
||||||
ctx.user &&
|
ctx.user & requestAppId &&
|
||||||
requestAppId &&
|
|
||||||
!isUserInAppTenant(requestAppId, ctx.user)
|
!isUserInAppTenant(requestAppId, ctx.user)
|
||||||
) {
|
) {
|
||||||
// don't error, simply remove the users rights (they are a public user)
|
// don't error, simply remove the users rights (they are a public user)
|
||||||
|
|
Loading…
Reference in New Issue