1
0
Fork 0
mirror of synced 2024-06-28 11:00:55 +12:00

Refactoring worker, converting all controllers/routes to Typescript and all imports of backend-core to new style.

This commit is contained in:
mike12345567 2022-11-23 18:25:20 +00:00
parent df80aa974a
commit bfaef13768
41 changed files with 453 additions and 433 deletions

View file

@ -4,7 +4,7 @@ const JwtStrategy = require("passport-jwt").Strategy
import { getGlobalDB } from "./tenancy"
const refresh = require("passport-oauth2-refresh")
import { Config } from "./constants"
import { getScopedConfig } from "./db/utils"
import { getScopedConfig } from "./db"
import {
jwt,
local,

View file

@ -1,14 +1,15 @@
const { objectStore } = require("@budibase/backend-core")
const fs = require("fs")
const { join } = require("path")
const { TEMP_DIR, MINIO_DIR } = require("./utils")
const { progressBar } = require("../utils")
const {
ObjectStoreBuckets,
ObjectStore,
retrieve,
uploadDirectory,
makeSureBucketExists,
} = require("@budibase/backend-core/objectStore")
const fs = require("fs")
const { join } = require("path")
const { TEMP_DIR, MINIO_DIR } = require("./utils")
const { progressBar } = require("../utils")
} = objectStore
const bucketList = Object.values(ObjectStoreBuckets)

View file

@ -4,7 +4,7 @@ const { getSkeleton, fleshOutSkeleton } = require("./skeleton")
const questions = require("../questions")
const fs = require("fs")
const { PLUGIN_TYPE_ARR } = require("@budibase/types")
const { validate } = require("@budibase/backend-core/plugins")
const { plugins } = require("@budibase/backend-core")
const { runPkgCommand } = require("../exec")
const { join } = require("path")
const { success, error, info, moveDirectory } = require("../utils")
@ -107,7 +107,7 @@ async function verify() {
}
name = pkgJson.name
version = pkgJson.version
validate(schemaJson)
plugins.validate(schemaJson)
return { name, version }
} catch (err) {
if (err && err.message && err.message.includes("not valid JSON")) {

View file

@ -62,7 +62,9 @@ export const isOIDCConfig = (config: Config): config is OIDCConfig =>
export enum ConfigType {
SETTINGS = "settings",
ACCOUNT = "account",
SMTP = "smtp",
GOOGLE = "google",
OIDC = "oidc",
OIDC_LOGOS = "logos_oidc",
}

View file

@ -4,3 +4,4 @@ export * from "./userGroup"
export * from "./plugin"
export * from "./quotas"
export * from "./schedule"
export * from "./templates"

View file

@ -0,0 +1,9 @@
import { Document } from "../document"
export interface Template extends Document {
ownerId?: string
name?: string
contents: string
purpose: string
type?: string
}

View file

@ -1,25 +1,25 @@
import core from "@budibase/backend-core"
import { utils, constants, auth, db as dbCore } from "@budibase/backend-core"
import {
events,
users as usersCore,
context,
tenancy,
} from "@budibase/backend-core"
import { Config, EmailTemplatePurpose } from "../../../constants"
import { EmailTemplatePurpose } from "../../../constants"
import { sendEmail, isEmailConfigured } from "../../../utilities/email"
import { checkResetPasswordCode } from "../../../utilities/redis"
import env from "../../../environment"
import sdk from "../../../sdk"
import { User } from "@budibase/types"
const { setCookie, getCookie, clearCookie, hash, platformLogout } = core.utils
const { Cookie, Header } = core.constants
const { passport, ssoCallbackUrl, google, oidc } = core.auth
import { User, Config, ConfigType } from "@budibase/types"
const { setCookie, getCookie, clearCookie, hash, platformLogout } = utils
const { Cookie, Header } = constants
const { passport, ssoCallbackUrl, google, oidc } = auth
export const googleCallbackUrl = async (config: any) => {
export async function googleCallbackUrl(config?: Config) {
return ssoCallbackUrl(tenancy.getGlobalDB(), config, "google")
}
export const oidcCallbackUrl = async (config: any) => {
export async function oidcCallbackUrl(config?: Config) {
return ssoCallbackUrl(tenancy.getGlobalDB(), config, "oidc")
}
@ -135,7 +135,7 @@ export const logout = async (ctx: any) => {
export const datasourcePreAuth = async (ctx: any, next: any) => {
const provider = ctx.params.provider
const middleware = require(`@budibase/backend-core/middleware`)
const { middleware } = require(`@budibase/backend-core`)
const handler = middleware.datasource[provider]
setCookie(
@ -154,7 +154,7 @@ export const datasourcePreAuth = async (ctx: any, next: any) => {
export const datasourceAuth = async (ctx: any, next: any) => {
const authStateCookie = getCookie(ctx, Cookie.DatasourceAuth)
const provider = authStateCookie.provider
const middleware = require(`@budibase/backend-core/middleware`)
const { middleware } = require(`@budibase/backend-core`)
const handler = middleware.datasource[provider]
return handler.postAuth(passport, ctx, next)
}
@ -166,11 +166,11 @@ export const datasourceAuth = async (ctx: any, next: any) => {
export const googlePreAuth = async (ctx: any, next: any) => {
const db = tenancy.getGlobalDB()
const config = await core.db.getScopedConfig(db, {
type: Config.GOOGLE,
const config = await dbCore.getScopedConfig(db, {
type: ConfigType.GOOGLE,
workspace: ctx.query.workspace,
})
let callbackUrl = await exports.googleCallbackUrl(config)
let callbackUrl = await googleCallbackUrl(config)
const strategy = await google.strategyFactory(
config,
callbackUrl,
@ -187,11 +187,11 @@ export const googlePreAuth = async (ctx: any, next: any) => {
export const googleAuth = async (ctx: any, next: any) => {
const db = tenancy.getGlobalDB()
const config = await core.db.getScopedConfig(db, {
type: Config.GOOGLE,
const config = await dbCore.getScopedConfig(db, {
type: ConfigType.GOOGLE,
workspace: ctx.query.workspace,
})
const callbackUrl = await exports.googleCallbackUrl(config)
const callbackUrl = await googleCallbackUrl(config)
const strategy = await google.strategyFactory(
config,
callbackUrl,
@ -213,13 +213,13 @@ export const googleAuth = async (ctx: any, next: any) => {
export const oidcStrategyFactory = async (ctx: any, configId: any) => {
const db = tenancy.getGlobalDB()
const config = await core.db.getScopedConfig(db, {
type: Config.OIDC,
const config = await dbCore.getScopedConfig(db, {
type: ConfigType.OIDC,
group: ctx.query.group,
})
const chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0]
let callbackUrl = await exports.oidcCallbackUrl(chosenConfig)
let callbackUrl = await oidcCallbackUrl(chosenConfig)
//Remote Config
const enrichedConfig = await oidc.fetchStrategyConfig(
@ -240,8 +240,8 @@ export const oidcPreAuth = async (ctx: any, next: any) => {
setCookie(ctx, configId, Cookie.OIDC_CONFIG)
const db = tenancy.getGlobalDB()
const config = await core.db.getScopedConfig(db, {
type: Config.OIDC,
const config = await dbCore.getScopedConfig(db, {
type: ConfigType.OIDC,
group: ctx.query.group,
})

View file

@ -1,28 +1,26 @@
const {
generateConfigID,
getConfigParams,
getScopedFullConfig,
getAllApps,
} = require("@budibase/backend-core/db")
const { Config } = require("../../../constants")
const email = require("../../../utilities/email")
const {
upload,
ObjectStoreBuckets,
} = require("@budibase/backend-core/objectStore")
const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy")
const env = require("../../../environment")
const { googleCallbackUrl, oidcCallbackUrl } = require("./auth")
const {
withCache,
CacheKeys,
bustCache,
import * as email from "../../../utilities/email"
import env from "../../../environment"
import { googleCallbackUrl, oidcCallbackUrl } from "./auth"
import {
events,
cache,
} = require("@budibase/backend-core/cache")
const { events } = require("@budibase/backend-core")
const { checkAnyUserExists } = require("../../../utilities/users")
objectStore,
tenancy,
db as dbCore,
} from "@budibase/backend-core"
import { checkAnyUserExists } from "../../../utilities/users"
import {
Database,
Config as ConfigDoc,
ConfigType,
SSOType,
GoogleConfig,
OIDCConfig,
SettingsConfig,
BBContext,
} from "@budibase/types"
const getEventFns = async (db, config) => {
const getEventFns = async (db: Database, config: ConfigDoc) => {
const fns = []
const type = config.type
@ -31,41 +29,45 @@ const getEventFns = async (db, config) => {
existing = await db.get(config._id)
}
const ssoType = type as SSOType
if (!existing) {
switch (config.type) {
case Config.SMTP: {
case ConfigType.SMTP: {
fns.push(events.email.SMTPCreated)
break
}
case Config.GOOGLE: {
fns.push(() => events.auth.SSOCreated(type))
if (config.config.activated) {
fns.push(() => events.auth.SSOActivated(type))
case ConfigType.GOOGLE: {
const googleCfg = config as GoogleConfig
fns.push(() => events.auth.SSOCreated(ssoType))
if (googleCfg.config.activated) {
fns.push(() => events.auth.SSOActivated(ssoType))
}
break
}
case Config.OIDC: {
fns.push(() => events.auth.SSOCreated(type))
if (config.config.configs[0].activated) {
fns.push(() => events.auth.SSOActivated(type))
case ConfigType.OIDC: {
const oidcCfg = config as OIDCConfig
fns.push(() => events.auth.SSOCreated(ssoType))
if (oidcCfg.config.configs[0].activated) {
fns.push(() => events.auth.SSOActivated(ssoType))
}
break
}
case Config.SETTINGS: {
case ConfigType.SETTINGS: {
// company
const company = config.config.company
const settingsCfg = config as SettingsConfig
const company = settingsCfg.config.company
if (company && company !== "Budibase") {
fns.push(events.org.nameUpdated)
}
// logo
const logoUrl = config.config.logoUrl
const logoUrl = settingsCfg.config.logoUrl
if (logoUrl) {
fns.push(events.org.logoUpdated)
}
// platform url
const platformUrl = config.config.platformUrl
const platformUrl = settingsCfg.config.platformUrl
if (
platformUrl &&
platformUrl !== "http://localhost:10000" &&
@ -78,52 +80,55 @@ const getEventFns = async (db, config) => {
}
} else {
switch (config.type) {
case Config.SMTP: {
case ConfigType.SMTP: {
fns.push(events.email.SMTPUpdated)
break
}
case Config.GOOGLE: {
fns.push(() => events.auth.SSOUpdated(type))
if (!existing.config.activated && config.config.activated) {
fns.push(() => events.auth.SSOActivated(type))
} else if (existing.config.activated && !config.config.activated) {
fns.push(() => events.auth.SSODeactivated(type))
case ConfigType.GOOGLE: {
const googleCfg = config as GoogleConfig
fns.push(() => events.auth.SSOUpdated(ssoType))
if (!existing.config.activated && googleCfg.config.activated) {
fns.push(() => events.auth.SSOActivated(ssoType))
} else if (existing.config.activated && !googleCfg.config.activated) {
fns.push(() => events.auth.SSODeactivated(ssoType))
}
break
}
case Config.OIDC: {
fns.push(() => events.auth.SSOUpdated(type))
case ConfigType.OIDC: {
const oidcCfg = config as OIDCConfig
fns.push(() => events.auth.SSOUpdated(ssoType))
if (
!existing.config.configs[0].activated &&
config.config.configs[0].activated
oidcCfg.config.configs[0].activated
) {
fns.push(() => events.auth.SSOActivated(type))
fns.push(() => events.auth.SSOActivated(ssoType))
} else if (
existing.config.configs[0].activated &&
!config.config.configs[0].activated
!oidcCfg.config.configs[0].activated
) {
fns.push(() => events.auth.SSODeactivated(type))
fns.push(() => events.auth.SSODeactivated(ssoType))
}
break
}
case Config.SETTINGS: {
case ConfigType.SETTINGS: {
// company
const settingsCfg = config as SettingsConfig
const existingCompany = existing.config.company
const company = config.config.company
const company = settingsCfg.config.company
if (company && company !== "Budibase" && existingCompany !== company) {
fns.push(events.org.nameUpdated)
}
// logo
const existingLogoUrl = existing.config.logoUrl
const logoUrl = config.config.logoUrl
const logoUrl = settingsCfg.config.logoUrl
if (logoUrl && existingLogoUrl !== logoUrl) {
fns.push(events.org.logoUpdated)
}
// platform url
const existingPlatformUrl = existing.config.platformUrl
const platformUrl = config.config.platformUrl
const platformUrl = settingsCfg.config.platformUrl
if (
platformUrl &&
platformUrl !== "http://localhost:10000" &&
@ -140,13 +145,13 @@ const getEventFns = async (db, config) => {
return fns
}
exports.save = async function (ctx) {
const db = getGlobalDB()
export async function save(ctx: BBContext) {
const db = tenancy.getGlobalDB()
const { type, workspace, user, config } = ctx.request.body
let eventFns = await getEventFns(db, ctx.request.body)
// Config does not exist yet
if (!ctx.request.body._id) {
ctx.request.body._id = generateConfigID({
ctx.request.body._id = dbCore.generateConfigID({
type,
workspace,
user,
@ -155,18 +160,18 @@ exports.save = async function (ctx) {
try {
// verify the configuration
switch (type) {
case Config.SMTP:
case ConfigType.SMTP:
await email.verifyConfig(config)
break
}
} catch (err) {
} catch (err: any) {
ctx.throw(400, err)
}
try {
const response = await db.put(ctx.request.body)
await bustCache(CacheKeys.CHECKLIST)
await bustCache(CacheKeys.ANALYTICS_ENABLED)
await cache.bustCache(cache.CacheKeys.CHECKLIST)
await cache.bustCache(cache.CacheKeys.ANALYTICS_ENABLED)
for (const fn of eventFns) {
await fn()
@ -177,15 +182,15 @@ exports.save = async function (ctx) {
_id: response.id,
_rev: response.rev,
}
} catch (err) {
} catch (err: any) {
ctx.throw(400, err)
}
}
exports.fetch = async function (ctx) {
const db = getGlobalDB()
export async function fetch(ctx: BBContext) {
const db = tenancy.getGlobalDB()
const response = await db.allDocs(
getConfigParams(
dbCore.getConfigParams(
{ type: ctx.params.type },
{
include_docs: true,
@ -199,23 +204,23 @@ exports.fetch = async function (ctx) {
* Gets the most granular config for a particular configuration type.
* The hierarchy is type -> workspace -> user.
*/
exports.find = async function (ctx) {
const db = getGlobalDB()
export async function find(ctx: BBContext) {
const db = tenancy.getGlobalDB()
const { userId, workspaceId } = ctx.query
if (workspaceId && userId) {
const workspace = await db.get(workspaceId)
const workspace = await db.get(workspaceId as string)
const userInWorkspace = workspace.users.some(
workspaceUser => workspaceUser === userId
(workspaceUser: any) => workspaceUser === userId
)
if (!ctx.user.admin && !userInWorkspace) {
if (!ctx.user!.admin && !userInWorkspace) {
ctx.throw(400, `User is not in specified workspace: ${workspace}.`)
}
}
try {
// Find the config with the most granular scope based on context
const scopedConfig = await getScopedFullConfig(db, {
const scopedConfig = await dbCore.getScopedFullConfig(db, {
type: ctx.params.type,
user: userId,
workspace: workspaceId,
@ -227,48 +232,48 @@ exports.find = async function (ctx) {
// don't throw an error, there simply is nothing to return
ctx.body = {}
}
} catch (err) {
ctx.throw(err.status, err)
} catch (err: any) {
ctx.throw(err?.status || 400, err)
}
}
exports.publicOidc = async function (ctx) {
const db = getGlobalDB()
export async function publicOidc(ctx: BBContext) {
const db = tenancy.getGlobalDB()
try {
// Find the config with the most granular scope based on context
const oidcConfig = await getScopedFullConfig(db, {
type: Config.OIDC,
const oidcConfig = await dbCore.getScopedFullConfig(db, {
type: ConfigType.OIDC,
})
if (!oidcConfig) {
ctx.body = {}
} else {
ctx.body = oidcConfig.config.configs.map(config => ({
ctx.body = oidcConfig.config.configs.map((config: any) => ({
logo: config.logo,
name: config.name,
uuid: config.uuid,
}))
}
} catch (err) {
} catch (err: any) {
ctx.throw(err.status, err)
}
}
exports.publicSettings = async function (ctx) {
const db = getGlobalDB()
export async function publicSettings(ctx: BBContext) {
const db = tenancy.getGlobalDB()
try {
// Find the config with the most granular scope based on context
const publicConfig = await getScopedFullConfig(db, {
type: Config.SETTINGS,
const publicConfig = await dbCore.getScopedFullConfig(db, {
type: ConfigType.SETTINGS,
})
const googleConfig = await getScopedFullConfig(db, {
type: Config.GOOGLE,
const googleConfig = await dbCore.getScopedFullConfig(db, {
type: ConfigType.GOOGLE,
})
const oidcConfig = await getScopedFullConfig(db, {
type: Config.OIDC,
const oidcConfig = await dbCore.getScopedFullConfig(db, {
type: ConfigType.OIDC,
})
let config
@ -301,12 +306,12 @@ exports.publicSettings = async function (ctx) {
}
ctx.body = config
} catch (err) {
} catch (err: any) {
ctx.throw(err.status, err)
}
}
exports.upload = async function (ctx) {
export async function upload(ctx: BBContext) {
if (ctx.request.files == null || ctx.request.files.file.length > 1) {
ctx.throw(400, "One file must be uploaded.")
}
@ -315,19 +320,19 @@ exports.upload = async function (ctx) {
let bucket
if (env.SELF_HOSTED) {
bucket = ObjectStoreBuckets.GLOBAL
bucket = objectStore.ObjectStoreBuckets.GLOBAL
} else {
bucket = ObjectStoreBuckets.GLOBAL_CLOUD
bucket = objectStore.ObjectStoreBuckets.GLOBAL_CLOUD
}
let key
if (env.MULTI_TENANCY) {
key = `${getTenantId()}/${type}/${name}`
key = `${tenancy.getTenantId()}/${type}/${name}`
} else {
key = `${type}/${name}`
}
await upload({
await objectStore.upload({
bucket,
filename: key,
path: file.path,
@ -336,11 +341,11 @@ exports.upload = async function (ctx) {
// add to configuration structure
// TODO: right now this only does a global level
const db = getGlobalDB()
let cfgStructure = await getScopedFullConfig(db, { type })
const db = tenancy.getGlobalDB()
let cfgStructure = await dbCore.getScopedFullConfig(db, { type })
if (!cfgStructure) {
cfgStructure = {
_id: generateConfigID({ type }),
_id: dbCore.generateConfigID({ type }),
config: {},
}
}
@ -361,49 +366,49 @@ exports.upload = async function (ctx) {
}
}
exports.destroy = async function (ctx) {
const db = getGlobalDB()
export async function destroy(ctx: BBContext) {
const db = tenancy.getGlobalDB()
const { id, rev } = ctx.params
try {
await db.remove(id, rev)
await cache.delete(CacheKeys.CHECKLIST)
await cache.delete(cache.CacheKeys.CHECKLIST)
ctx.body = { message: "Config deleted successfully" }
} catch (err) {
} catch (err: any) {
ctx.throw(err.status, err)
}
}
exports.configChecklist = async function (ctx) {
const db = getGlobalDB()
const tenantId = getTenantId()
export async function configChecklist(ctx: BBContext) {
const db = tenancy.getGlobalDB()
const tenantId = tenancy.getTenantId()
try {
ctx.body = await withCache(
CacheKeys.CHECKLIST,
ctx.body = await cache.withCache(
cache.CacheKeys.CHECKLIST,
env.CHECKLIST_CACHE_TTL,
async () => {
let apps = []
if (!env.MULTI_TENANCY || tenantId) {
// Apps exist
apps = await getAllApps({ idsOnly: true, efficient: true })
apps = await dbCore.getAllApps({ idsOnly: true, efficient: true })
}
// They have set up SMTP
const smtpConfig = await getScopedFullConfig(db, {
type: Config.SMTP,
const smtpConfig = await dbCore.getScopedFullConfig(db, {
type: ConfigType.SMTP,
})
// They have set up Google Auth
const googleConfig = await getScopedFullConfig(db, {
type: Config.GOOGLE,
const googleConfig = await dbCore.getScopedFullConfig(db, {
type: ConfigType.GOOGLE,
})
// They have set up OIDC
const oidcConfig = await getScopedFullConfig(db, {
type: Config.OIDC,
const oidcConfig = await dbCore.getScopedFullConfig(db, {
type: ConfigType.OIDC,
})
// They have set up an global user
// They have set up a global user
const userExists = await checkAnyUserExists()
return {
apps: {
@ -429,7 +434,7 @@ exports.configChecklist = async function (ctx) {
}
}
)
} catch (err) {
} catch (err: any) {
ctx.throw(err.status, err)
}
}

View file

@ -1,7 +1,8 @@
const { sendEmail } = require("../../../utilities/email")
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
import { sendEmail as sendEmailFn } from "../../../utilities/email"
import { tenancy } from "@budibase/backend-core"
import { BBContext } from "@budibase/types"
exports.sendEmail = async ctx => {
export async function sendEmail(ctx: BBContext) {
let {
workspaceId,
email,
@ -16,10 +17,10 @@ exports.sendEmail = async ctx => {
} = ctx.request.body
let user
if (userId) {
const db = getGlobalDB()
const db = tenancy.getGlobalDB()
user = await db.get(userId)
}
const response = await sendEmail(email, purpose, {
const response = await sendEmailFn(email, purpose, {
workspaceId,
user,
contents,

View file

@ -1,68 +0,0 @@
const { getAllRoles } = require("@budibase/backend-core/roles")
const {
getAllApps,
getProdAppID,
getDevAppID,
DocumentType,
} = require("@budibase/backend-core/db")
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
const { user: userCache } = require("@budibase/backend-core/cache")
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
const { allUsers } = require("../../../sdk/users")
exports.fetch = async ctx => {
const tenantId = ctx.user.tenantId
// always use the dev apps as they'll be most up to date (true)
const apps = await getAllApps({ tenantId, all: true })
const promises = []
for (let app of apps) {
// use dev app IDs
promises.push(getAllRoles(app.appId))
}
const roles = await Promise.all(promises)
const response = {}
for (let app of apps) {
const deployedAppId = getProdAppID(app.appId)
response[deployedAppId] = {
roles: roles.shift(),
name: app.name,
version: app.version,
url: app.url,
}
}
ctx.body = response
}
exports.find = async ctx => {
const appId = ctx.params.appId
await doInAppContext(getDevAppID(appId), async () => {
const db = getAppDB()
const app = await db.get(DocumentType.APP_METADATA)
ctx.body = {
roles: await getAllRoles(),
name: app.name,
version: app.version,
url: app.url,
}
})
}
exports.removeAppRole = async ctx => {
const { appId } = ctx.params
const db = getGlobalDB()
const users = await allUsers(ctx)
const bulk = []
const cacheInvalidations = []
for (let user of users) {
if (user.roles[appId]) {
cacheInvalidations.push(userCache.invalidateUser(user._id))
delete user.roles[appId]
bulk.push(user)
}
}
await db.bulkDocs(bulk)
await Promise.all(cacheInvalidations)
ctx.body = {
message: "App role removed from all users",
}
}

View file

@ -0,0 +1,66 @@
import {
db as dbCore,
roles,
context,
cache,
tenancy,
} from "@budibase/backend-core"
import { BBContext, App } from "@budibase/types"
import { allUsers } from "../../../sdk/users"
export async function fetch(ctx: BBContext) {
const tenantId = ctx.user!.tenantId
// always use the dev apps as they'll be most up to date (true)
const apps = (await dbCore.getAllApps({ tenantId, all: true })) as App[]
const promises = []
for (let app of apps) {
// use dev app IDs
promises.push(roles.getAllRoles(app.appId))
}
const roleList = await Promise.all(promises)
const response: any = {}
for (let app of apps) {
const deployedAppId = dbCore.getProdAppID(app.appId)
response[deployedAppId] = {
roles: roleList.shift(),
name: app.name,
version: app.version,
url: app.url,
}
}
ctx.body = response
}
export async function find(ctx: BBContext) {
const appId = ctx.params.appId
await context.doInAppContext(dbCore.getDevAppID(appId), async () => {
const db = context.getAppDB()
const app = await db.get(dbCore.DocumentType.APP_METADATA)
ctx.body = {
roles: await roles.getAllRoles(),
name: app.name,
version: app.version,
url: app.url,
}
})
}
export async function removeAppRole(ctx: BBContext) {
const { appId } = ctx.params
const db = tenancy.getGlobalDB()
const users = await allUsers()
const bulk = []
const cacheInvalidations = []
for (let user of users) {
if (user.roles[appId]) {
cacheInvalidations.push(cache.user.invalidateUser(user._id))
delete user.roles[appId]
bulk.push(user)
}
}
await db.bulkDocs(bulk)
await Promise.all(cacheInvalidations)
ctx.body = {
message: "App role removed from all users",
}
}

View file

@ -1,16 +1,13 @@
const {
getWorkspaceParams,
generateWorkspaceID,
} = require("@budibase/backend-core/db")
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
import { tenancy, db as dbCore } from "@budibase/backend-core"
import { BBContext } from "@budibase/types"
exports.save = async function (ctx) {
const db = getGlobalDB()
export async function save(ctx: BBContext) {
const db = tenancy.getGlobalDB()
const workspaceDoc = ctx.request.body
// workspace does not exist yet
if (!workspaceDoc._id) {
workspaceDoc._id = generateWorkspaceID()
workspaceDoc._id = dbCore.generateWorkspaceID()
}
try {
@ -19,38 +16,38 @@ exports.save = async function (ctx) {
_id: response.id,
_rev: response.rev,
}
} catch (err) {
} catch (err: any) {
ctx.throw(err.status, err)
}
}
exports.fetch = async function (ctx) {
const db = getGlobalDB()
export async function fetch(ctx: BBContext) {
const db = tenancy.getGlobalDB()
const response = await db.allDocs(
getWorkspaceParams(undefined, {
dbCore.getWorkspaceParams(undefined, {
include_docs: true,
})
)
ctx.body = response.rows.map(row => row.doc)
}
exports.find = async function (ctx) {
const db = getGlobalDB()
export async function find(ctx: BBContext) {
const db = tenancy.getGlobalDB()
try {
ctx.body = await db.get(ctx.params.id)
} catch (err) {
} catch (err: any) {
ctx.throw(err.status, err)
}
}
exports.destroy = async function (ctx) {
const db = getGlobalDB()
export async function destroy(ctx: BBContext) {
const db = tenancy.getGlobalDB()
const { id, rev } = ctx.params
try {
await db.remove(id, rev)
ctx.body = { message: "Workspace deleted successfully" }
} catch (err) {
} catch (err: any) {
ctx.throw(err.status, err)
}
}

View file

@ -104,7 +104,7 @@ const NO_TENANCY_ENDPOINTS = [
// add them all to be safe
const NO_CSRF_ENDPOINTS = [...PUBLIC_ENDPOINTS]
const router = new Router()
const router: Router = new Router()
router
.use(
compress({
@ -163,4 +163,4 @@ for (let route of routes) {
router.use(route.allowedMethods())
}
module.exports = router
export = router

View file

@ -1,13 +1,13 @@
const Router = require("@koa/router")
const authController = require("../../controllers/global/auth")
const { joiValidator } = require("@budibase/backend-core/auth")
const Joi = require("joi")
import Router from "@koa/router"
import * as authController from "../../controllers/global/auth"
import { auth } from "@budibase/backend-core"
import Joi from "joi"
const router = new Router()
const router: Router = new Router()
function buildAuthValidation() {
// prettier-ignore
return joiValidator.body(Joi.object({
return auth.joiValidator.body(Joi.object({
username: Joi.string().required(),
password: Joi.string().required(),
}).required().unknown(false))
@ -15,14 +15,14 @@ function buildAuthValidation() {
function buildResetValidation() {
// prettier-ignore
return joiValidator.body(Joi.object({
return auth.joiValidator.body(Joi.object({
email: Joi.string().required(),
}).required().unknown(false))
}
function buildResetUpdateValidation() {
// prettier-ignore
return joiValidator.body(Joi.object({
return auth.joiValidator.body(Joi.object({
resetCode: Joi.string().required(),
password: Joi.string().required(),
}).required().unknown(false))
@ -85,4 +85,4 @@ router
.get("/api/global/auth/oidc/callback", authController.oidcAuth)
.get("/api/admin/auth/oidc/callback", authController.oidcAuth)
module.exports = router
export = router

View file

@ -1,11 +1,10 @@
const Router = require("@koa/router")
const controller = require("../../controllers/global/configs")
const { joiValidator } = require("@budibase/backend-core/auth")
const { adminOnly } = require("@budibase/backend-core/auth")
const Joi = require("joi")
const { Config } = require("@budibase/backend-core/constants")
import Router from "@koa/router"
import * as controller from "../../controllers/global/configs"
import { auth } from "@budibase/backend-core"
import Joi from "joi"
import { ConfigType } from "@budibase/types"
const router = new Router()
const router: Router = new Router()
function smtpValidation() {
// prettier-ignore
@ -55,27 +54,27 @@ function oidcValidation() {
activated: Joi.boolean().required(),
scopes: Joi.array().optional()
})
).required(true)
).required()
}).unknown(true)
}
function buildConfigSaveValidation() {
// prettier-ignore
return joiValidator.body(Joi.object({
return auth.joiValidator.body(Joi.object({
_id: Joi.string().optional(),
_rev: Joi.string().optional(),
workspace: Joi.string().optional(),
type: Joi.string().valid(...Object.values(Config)).required(),
type: Joi.string().valid(...Object.values(ConfigType)).required(),
createdAt: Joi.string().optional(),
updatedAt: Joi.string().optional(),
config: Joi.alternatives()
.conditional("type", {
switch: [
{ is: Config.SMTP, then: smtpValidation() },
{ is: Config.SETTINGS, then: settingValidation() },
{ is: Config.ACCOUNT, then: Joi.object().unknown(true) },
{ is: Config.GOOGLE, then: googleValidation() },
{ is: Config.OIDC, then: oidcValidation() }
{ is: ConfigType.SMTP, then: smtpValidation() },
{ is: ConfigType.SETTINGS, then: settingValidation() },
{ is: ConfigType.ACCOUNT, then: Joi.object().unknown(true) },
{ is: ConfigType.GOOGLE, then: googleValidation() },
{ is: ConfigType.OIDC, then: oidcValidation() }
],
}),
}).required().unknown(true),
@ -84,27 +83,27 @@ function buildConfigSaveValidation() {
function buildUploadValidation() {
// prettier-ignore
return joiValidator.params(Joi.object({
type: Joi.string().valid(...Object.values(Config)).required(),
return auth.joiValidator.params(Joi.object({
type: Joi.string().valid(...Object.values(ConfigType)).required(),
name: Joi.string().required(),
}).required().unknown(true))
}
function buildConfigGetValidation() {
// prettier-ignore
return joiValidator.params(Joi.object({
type: Joi.string().valid(...Object.values(Config)).required()
return auth.joiValidator.params(Joi.object({
type: Joi.string().valid(...Object.values(ConfigType)).required()
}).required().unknown(true))
}
router
.post(
"/api/global/configs",
adminOnly,
auth.adminOnly,
buildConfigSaveValidation(),
controller.save
)
.delete("/api/global/configs/:id/:rev", adminOnly, controller.destroy)
.delete("/api/global/configs/:id/:rev", auth.adminOnly, controller.destroy)
.get("/api/global/configs", controller.fetch)
.get("/api/global/configs/checklist", controller.configChecklist)
.get(
@ -117,9 +116,9 @@ router
.get("/api/global/configs/:type", buildConfigGetValidation(), controller.find)
.post(
"/api/global/configs/upload/:type/:name",
adminOnly,
auth.adminOnly,
buildUploadValidation(),
controller.upload
)
module.exports = router
export = router

View file

@ -1,15 +1,14 @@
const Router = require("@koa/router")
const controller = require("../../controllers/global/email")
const { EmailTemplatePurpose } = require("../../../constants")
const { joiValidator } = require("@budibase/backend-core/auth")
const { adminOnly } = require("@budibase/backend-core/auth")
const Joi = require("joi")
import Router from "@koa/router"
import * as controller from "../../controllers/global/email"
import { EmailTemplatePurpose } from "../../../constants"
import { auth } from "@budibase/backend-core"
import Joi from "joi"
const router = new Router()
const router: Router = new Router()
function buildEmailSendValidation() {
// prettier-ignore
return joiValidator.body(Joi.object({
return auth.joiValidator.body(Joi.object({
email: Joi.string().email({
multiple: true,
}),
@ -30,8 +29,8 @@ function buildEmailSendValidation() {
router.post(
"/api/global/email/send",
buildEmailSendValidation(),
adminOnly,
auth.adminOnly,
controller.sendEmail
)
module.exports = router
export = router

View file

@ -1,7 +1,7 @@
import Router from "@koa/router"
import * as controller from "../../controllers/global/license"
const router = new Router()
const router: Router = new Router()
router
.post("/api/global/license/activate", controller.activate)

View file

@ -1,12 +0,0 @@
const Router = require("@koa/router")
const controller = require("../../controllers/global/roles")
const { builderOrAdmin } = require("@budibase/backend-core/auth")
const router = new Router()
router
.get("/api/global/roles", builderOrAdmin, controller.fetch)
.get("/api/global/roles/:appId", builderOrAdmin, controller.find)
.delete("/api/global/roles/:appId", builderOrAdmin, controller.removeAppRole)
module.exports = router

View file

@ -0,0 +1,16 @@
import Router from "@koa/router"
import * as controller from "../../controllers/global/roles"
import { auth } from "@budibase/backend-core"
const router: Router = new Router()
router
.get("/api/global/roles", auth.builderOrAdmin, controller.fetch)
.get("/api/global/roles/:appId", auth.builderOrAdmin, controller.find)
.delete(
"/api/global/roles/:appId",
auth.builderOrAdmin,
controller.removeAppRole
)
export = router

View file

@ -3,7 +3,7 @@ import * as controller from "../../controllers/global/self"
import { auth } from "@budibase/backend-core"
import { users } from "../validation"
const router = new Router()
const router: Router = new Router()
router
.post("/api/global/self/api_key", auth.builderOnly, controller.generateAPIKey)
@ -15,4 +15,4 @@ router
controller.updateSelf
)
export default router as any
export = router

View file

@ -5,7 +5,7 @@ import { auth as authCore } from "@budibase/backend-core"
import Joi from "joi"
const { adminOnly, joiValidator } = authCore
const router = new Router()
const router: Router = new Router()
function buildTemplateSaveValidation() {
// prettier-ignore
@ -34,4 +34,4 @@ router
.get("/api/global/template/:id", controller.find)
.delete("/api/global/template/:id/:rev", adminOnly, controller.destroy)
export default router
export = router

View file

@ -1,17 +1,15 @@
const Router = require("@koa/router")
const controller = require("../../controllers/global/users")
const { joiValidator } = require("@budibase/backend-core/auth")
const { adminOnly } = require("@budibase/backend-core/auth")
const Joi = require("joi")
const cloudRestricted = require("../../../middleware/cloudRestricted")
const { users } = require("../validation")
const selfController = require("../../controllers/global/self")
const { builderOrAdmin } = require("@budibase/backend-core/auth")
import Router from "@koa/router"
import * as controller from "../../controllers/global/users"
import { auth } from "@budibase/backend-core"
import Joi from "joi"
import cloudRestricted from "../../../middleware/cloudRestricted"
import { users } from "../validation"
import * as selfController from "../../controllers/global/self"
const router = new Router()
const router: Router = new Router()
function buildAdminInitValidation() {
return joiValidator.body(
return auth.joiValidator.body(
Joi.object({
email: Joi.string().required(),
password: Joi.string(),
@ -24,7 +22,7 @@ function buildAdminInitValidation() {
function buildInviteValidation() {
// prettier-ignore
return joiValidator.body(Joi.object({
return auth.joiValidator.body(Joi.object({
email: Joi.string().required(),
userInfo: Joi.object().optional(),
}).required())
@ -32,7 +30,7 @@ function buildInviteValidation() {
function buildInviteMultipleValidation() {
// prettier-ignore
return joiValidator.body(Joi.array().required().items(
return auth.joiValidator.body(Joi.array().required().items(
Joi.object({
email: Joi.string(),
userInfo: Joi.object().optional(),
@ -42,7 +40,7 @@ function buildInviteMultipleValidation() {
function buildInviteAcceptValidation() {
// prettier-ignore
return joiValidator.body(Joi.object({
return auth.joiValidator.body(Joi.object({
inviteCode: Joi.string().required(),
password: Joi.string().required(),
}).required().unknown(true))
@ -51,31 +49,35 @@ function buildInviteAcceptValidation() {
router
.post(
"/api/global/users",
adminOnly,
auth.adminOnly,
users.buildUserSaveValidation(),
controller.save
)
.post(
"/api/global/users/bulk",
adminOnly,
auth.adminOnly,
users.buildUserBulkUserValidation(),
controller.bulkUpdate
)
.get("/api/global/users", builderOrAdmin, controller.fetch)
.post("/api/global/users/search", builderOrAdmin, controller.search)
.delete("/api/global/users/:id", adminOnly, controller.destroy)
.get("/api/global/users/count/:appId", builderOrAdmin, controller.countByApp)
.get("/api/global/users", auth.builderOrAdmin, controller.fetch)
.post("/api/global/users/search", auth.builderOrAdmin, controller.search)
.delete("/api/global/users/:id", auth.adminOnly, controller.destroy)
.get(
"/api/global/users/count/:appId",
auth.builderOrAdmin,
controller.countByApp
)
.get("/api/global/roles/:appId")
.post(
"/api/global/users/invite",
adminOnly,
auth.adminOnly,
buildInviteValidation(),
controller.invite
)
.post(
"/api/global/users/multi/invite",
adminOnly,
auth.adminOnly,
buildInviteMultipleValidation(),
controller.inviteMultiple
)
@ -94,7 +96,7 @@ router
)
.get("/api/global/users/tenant/:id", controller.tenantUserLookup)
// global endpoint but needs to come at end (blocks other endpoints otherwise)
.get("/api/global/users/:id", builderOrAdmin, controller.find)
.get("/api/global/users/:id", auth.builderOrAdmin, controller.find)
// DEPRECATED - use new versions with self API
.get("/api/global/users/self", selfController.getSelf)
.post(
@ -103,4 +105,4 @@ router
selfController.updateSelf
)
module.exports = router
export = router

View file

@ -1,14 +1,13 @@
const Router = require("@koa/router")
const controller = require("../../controllers/global/workspaces")
const { joiValidator } = require("@budibase/backend-core/auth")
const { adminOnly } = require("@budibase/backend-core/auth")
const Joi = require("joi")
import Router from "@koa/router"
import * as controller from "../../controllers/global/workspaces"
import { auth } from "@budibase/backend-core"
import Joi from "joi"
const router = new Router()
const router: Router = new Router()
function buildWorkspaceSaveValidation() {
// prettier-ignore
return joiValidator.body(Joi.object({
return auth.joiValidator.body(Joi.object({
_id: Joi.string().optional(),
_rev: Joi.string().optional(),
name: Joi.string().required(),
@ -27,12 +26,12 @@ function buildWorkspaceSaveValidation() {
router
.post(
"/api/global/workspaces",
adminOnly,
auth.adminOnly,
buildWorkspaceSaveValidation(),
controller.save
)
.delete("/api/global/workspaces/:id", adminOnly, controller.destroy)
.delete("/api/global/workspaces/:id", auth.adminOnly, controller.destroy)
.get("/api/global/workspaces", controller.fetch)
.get("/api/global/workspaces/:id", controller.find)
module.exports = router
export = router

View file

@ -1,3 +1,4 @@
import Router from "@koa/router"
import { api } from "@budibase/pro"
import userRoutes from "./global/users"
import configRoutes from "./global/configs"
@ -16,7 +17,7 @@ import accountRoutes from "./system/accounts"
import restoreRoutes from "./system/restore"
let userGroupRoutes = api.groups
export const routes = [
export const routes: Router[] = [
configRoutes,
userRoutes,
workspaceRoutes,

View file

@ -2,7 +2,7 @@ import Router from "@koa/router"
import * as controller from "../../controllers/system/accounts"
import { middleware } from "@budibase/backend-core"
const router = new Router()
const router: Router = new Router()
router
.put(

View file

@ -1,8 +1,8 @@
import Router from "@koa/router"
import * as controller from "../../controllers/system/environment"
const router = new Router()
const router: Router = new Router()
router.get("/api/system/environment", controller.fetch)
export default router
export = router

View file

@ -2,7 +2,7 @@ import Router from "@koa/router"
import * as migrationsController from "../../controllers/system/migrations"
import { auth } from "@budibase/backend-core"
const router = new Router()
const router: Router = new Router()
router
.post(

View file

@ -1,7 +1,7 @@
import * as controller from "../../controllers/system/restore"
import Router from "@koa/router"
const router = new Router()
const router: Router = new Router()
router.post("/api/system/restored", controller.systemRestored)

View file

@ -1,8 +1,8 @@
import Router from "@koa/router"
import * as controller from "../../controllers/system/status"
const router = new Router()
const router: Router = new Router()
router.get("/api/system/status", controller.fetch)
export default router
export = router

View file

@ -2,7 +2,7 @@ import Router from "@koa/router"
import * as controller from "../../controllers/system/tenants"
import { middleware } from "@budibase/backend-core"
const router = new Router()
const router: Router = new Router()
router.delete(
"/api/system/tenants/:tenantId",
@ -10,4 +10,4 @@ router.delete(
controller.delete
)
export default router
export = router

View file

@ -1,4 +1,4 @@
const { joiValidator } = require("@budibase/backend-core/auth")
import { auth } from "@budibase/backend-core"
import Joi from "joi"
let schema: any = {
@ -25,7 +25,7 @@ export const buildUserSaveValidation = (isSelf = false) => {
_rev: Joi.string(),
}
}
return joiValidator.body(Joi.object(schema).required().unknown(true))
return auth.joiValidator.body(Joi.object(schema).required().unknown(true))
}
export const buildUserBulkUserValidation = (isSelf = false) => {
@ -46,5 +46,5 @@ export const buildUserBulkUserValidation = (isSelf = false) => {
}),
}
return joiValidator.body(Joi.object(bulkSchema).required().unknown(true))
return auth.joiValidator.body(Joi.object(bulkSchema).required().unknown(true))
}

View file

@ -1,15 +1,15 @@
const { readStaticFile } = require("../../utilities/fileSystem")
const {
import { readStaticFile } from "../../utilities/fileSystem"
import {
EmailTemplatePurpose,
TemplateType,
TemplatePurpose,
GLOBAL_OWNER,
} = require("../index")
const { join } = require("path")
const { getTemplateParams } = require("@budibase/backend-core/db")
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
} from "../index"
import { join } from "path"
import { db as dbCore, tenancy } from "@budibase/backend-core"
import { Template } from "@budibase/types"
exports.EmailTemplates = {
export const EmailTemplates = {
[EmailTemplatePurpose.PASSWORD_RECOVERY]: readStaticFile(
join(__dirname, "passwordRecovery.hbs")
),
@ -23,7 +23,7 @@ exports.EmailTemplates = {
[EmailTemplatePurpose.CUSTOM]: readStaticFile(join(__dirname, "custom.hbs")),
}
exports.addBaseTemplates = (templates, type = null) => {
export function addBaseTemplates(templates: Template[], type?: string) {
let purposeList
switch (type) {
case TemplateType.EMAIL:
@ -38,9 +38,9 @@ exports.addBaseTemplates = (templates, type = null) => {
if (templates.find(template => template.purpose === purpose)) {
continue
}
if (exports.EmailTemplates[purpose]) {
if (EmailTemplates[purpose]) {
templates.push({
contents: exports.EmailTemplates[purpose],
contents: EmailTemplates[purpose],
purpose,
type,
})
@ -49,10 +49,14 @@ exports.addBaseTemplates = (templates, type = null) => {
return templates
}
exports.getTemplates = async ({ ownerId, type, id } = {}) => {
const db = getGlobalDB()
export async function getTemplates({
ownerId,
type,
id,
}: { ownerId?: string; type?: string; id?: string } = {}) {
const db = tenancy.getGlobalDB()
const response = await db.allDocs(
getTemplateParams(ownerId || GLOBAL_OWNER, id, {
dbCore.getTemplateParams(ownerId || GLOBAL_OWNER, id, {
include_docs: true,
})
)
@ -64,10 +68,10 @@ exports.getTemplates = async ({ ownerId, type, id } = {}) => {
if (type) {
templates = templates.filter(template => template.type === type)
}
return exports.addBaseTemplates(templates, type)
return addBaseTemplates(templates, type)
}
exports.getTemplateByPurpose = async (type, purpose) => {
const templates = await exports.getTemplates({ type })
return templates.find(template => template.purpose === purpose)
export async function getTemplateByPurpose(type: string, purpose: string) {
const templates = await getTemplates({ type })
return templates.find((template: Template) => template.purpose === purpose)
}

View file

@ -1,5 +1,5 @@
// need to load environment first
const env = require("./environment")
import env from "./environment"
// enable APM if configured
if (process.env.ELASTIC_APM_ENABLED) {
@ -14,19 +14,17 @@ import { Event } from "@sentry/types/dist/event"
import Application from "koa"
import { bootstrap } from "global-agent"
import * as db from "./db"
import { auth, logging, events, pinoSettings } from "@budibase/backend-core"
db.init()
const Koa = require("koa")
const destroyable = require("server-destroy")
const koaBody = require("koa-body")
import Koa from "koa"
import koaBody from "koa-body"
import http from "http"
import * as api from "./api"
import * as redis from "./utilities/redis"
import Sentry from "@sentry/node"
const koaSession = require("koa-session")
const { passport } = require("@budibase/backend-core/auth")
const { logAlert } = require("@budibase/backend-core/logging")
const logger = require("koa-pino-logger")
const http = require("http")
const api = require("./api")
const redis = require("./utilities/redis")
const Sentry = require("@sentry/node")
import { events, pinoSettings } from "@budibase/backend-core"
const destroyable = require("server-destroy")
// this will setup http and https proxies form env variables
bootstrap()
@ -41,8 +39,8 @@ app.use(koaSession(app))
app.use(logger(pinoSettings()))
// authentication
app.use(passport.initialize())
app.use(passport.session())
app.use(auth.passport.initialize())
app.use(auth.passport.session())
// api routes
app.use(api.routes())
@ -81,17 +79,18 @@ server.on("close", async () => {
const shutdown = () => {
server.close()
// @ts-ignore
server.destroy()
}
export = server.listen(parseInt(env.PORT || 4002), async () => {
export = server.listen(parseInt(env.PORT || "4002"), async () => {
console.log(`Worker running on ${JSON.stringify(server.address())}`)
await redis.init()
})
process.on("uncaughtException", err => {
errCode = -1
logAlert("Uncaught exception.", err)
logging.logAlert("Uncaught exception.", err)
shutdown()
})

View file

@ -1,13 +1,14 @@
const env = require("../environment")
const { Header } = require("@budibase/backend-core/constants")
import env from "../environment"
import { constants } from "@budibase/backend-core"
import { BBContext } from "@budibase/types"
/**
* This is a restricted endpoint in the cloud.
* Ensure that the correct API key has been supplied.
*/
module.exports = async (ctx, next) => {
export = async (ctx: BBContext, next: any) => {
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
const apiKey = ctx.request.headers[Header.API_KEY]
const apiKey = ctx.request.headers[constants.Header.API_KEY]
if (apiKey !== env.INTERNAL_API_KEY) {
ctx.throw(403, "Unauthorized")
}

View file

@ -1,33 +0,0 @@
const fetch = require("node-fetch")
const { Header } = require("@budibase/backend-core/constants")
const { getTenantId, isTenantIdSet } = require("@budibase/backend-core/tenancy")
const { checkSlashesInUrl } = require("../utilities")
const env = require("../environment")
async function makeAppRequest(url, method, body) {
if (env.isTest()) {
return
}
const request = { headers: {} }
request.headers[Header.API_KEY] = env.INTERNAL_API_KEY
if (isTenantIdSet()) {
request.headers[Header.TENANT_ID] = getTenantId()
}
if (body) {
request.headers["Content-Type"] = "application/json"
request.body = JSON.stringify(body)
}
request.method = method
return fetch(checkSlashesInUrl(env.APPS_URL + url), request)
}
exports.syncUserInApps = async userId => {
const response = await makeAppRequest(
`/api/users/metadata/sync/${userId}`,
"POST",
{}
)
if (response && response.status !== 200) {
throw "Unable to sync user."
}
}

View file

@ -0,0 +1,32 @@
import fetch from "node-fetch"
import { constants, tenancy } from "@budibase/backend-core"
import { checkSlashesInUrl } from "../utilities"
import env from "../environment"
async function makeAppRequest(url: string, method: string, body: any) {
if (env.isTest()) {
return
}
const request: any = { headers: {} }
request.headers[constants.Header.API_KEY] = env.INTERNAL_API_KEY
if (tenancy.isTenantIdSet()) {
request.headers[constants.Header.TENANT_ID] = tenancy.getTenantId()
}
if (body) {
request.headers["Content-Type"] = "application/json"
request.body = JSON.stringify(body)
}
request.method = method
return fetch(checkSlashesInUrl(env.APPS_URL + url), request)
}
export async function syncUserInApps(userId: string) {
const response = await makeAppRequest(
`/api/users/metadata/sync/${userId}`,
"POST",
{}
)
if (response && response.status !== 200) {
throw "Unable to sync user."
}
}

View file

@ -1,5 +0,0 @@
const { readFileSync } = require("fs")
exports.readStaticFile = path => {
return readFileSync(path, "utf-8")
}

View file

@ -0,0 +1,5 @@
import { readFileSync } from "fs"
export function readStaticFile(path: string) {
return readFileSync(path, "utf-8")
}

View file

@ -4,6 +4,6 @@
* @param {string} url The URL to test and remove any extra double slashes.
* @return {string} The updated url.
*/
exports.checkSlashesInUrl = url => {
export function checkSlashesInUrl(url: string) {
return url.replace(/(https?:\/\/)|(\/)+/g, "$1$2")
}

View file

@ -1,17 +0,0 @@
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
const { getGlobalUserParams } = require("@budibase/backend-core/db")
exports.checkAnyUserExists = async () => {
try {
const db = getGlobalDB()
const users = await db.allDocs(
getGlobalUserParams(null, {
include_docs: true,
limit: 1,
})
)
return users && users.rows.length >= 1
} catch (err) {
throw new Error("Unable to retrieve user list")
}
}

View file

@ -0,0 +1,16 @@
import { tenancy, db as dbCore } from "@budibase/backend-core"
export async function checkAnyUserExists() {
try {
const db = tenancy.getGlobalDB()
const users = await db.allDocs(
dbCore.getGlobalUserParams(null, {
include_docs: true,
limit: 1,
})
)
return users && users.rows.length >= 1
} catch (err) {
throw new Error("Unable to retrieve user list")
}
}