Refactoring worker, converting all controllers/routes to Typescript and all imports of backend-core to new style.
This commit is contained in:
parent
df80aa974a
commit
bfaef13768
|
@ -4,7 +4,7 @@ const JwtStrategy = require("passport-jwt").Strategy
|
||||||
import { getGlobalDB } from "./tenancy"
|
import { getGlobalDB } from "./tenancy"
|
||||||
const refresh = require("passport-oauth2-refresh")
|
const refresh = require("passport-oauth2-refresh")
|
||||||
import { Config } from "./constants"
|
import { Config } from "./constants"
|
||||||
import { getScopedConfig } from "./db/utils"
|
import { getScopedConfig } from "./db"
|
||||||
import {
|
import {
|
||||||
jwt,
|
jwt,
|
||||||
local,
|
local,
|
||||||
|
|
|
@ -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 {
|
const {
|
||||||
ObjectStoreBuckets,
|
ObjectStoreBuckets,
|
||||||
ObjectStore,
|
ObjectStore,
|
||||||
retrieve,
|
retrieve,
|
||||||
uploadDirectory,
|
uploadDirectory,
|
||||||
makeSureBucketExists,
|
makeSureBucketExists,
|
||||||
} = require("@budibase/backend-core/objectStore")
|
} = objectStore
|
||||||
const fs = require("fs")
|
|
||||||
const { join } = require("path")
|
|
||||||
const { TEMP_DIR, MINIO_DIR } = require("./utils")
|
|
||||||
const { progressBar } = require("../utils")
|
|
||||||
|
|
||||||
const bucketList = Object.values(ObjectStoreBuckets)
|
const bucketList = Object.values(ObjectStoreBuckets)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ const { getSkeleton, fleshOutSkeleton } = require("./skeleton")
|
||||||
const questions = require("../questions")
|
const questions = require("../questions")
|
||||||
const fs = require("fs")
|
const fs = require("fs")
|
||||||
const { PLUGIN_TYPE_ARR } = require("@budibase/types")
|
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 { runPkgCommand } = require("../exec")
|
||||||
const { join } = require("path")
|
const { join } = require("path")
|
||||||
const { success, error, info, moveDirectory } = require("../utils")
|
const { success, error, info, moveDirectory } = require("../utils")
|
||||||
|
@ -107,7 +107,7 @@ async function verify() {
|
||||||
}
|
}
|
||||||
name = pkgJson.name
|
name = pkgJson.name
|
||||||
version = pkgJson.version
|
version = pkgJson.version
|
||||||
validate(schemaJson)
|
plugins.validate(schemaJson)
|
||||||
return { name, version }
|
return { name, version }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err && err.message && err.message.includes("not valid JSON")) {
|
if (err && err.message && err.message.includes("not valid JSON")) {
|
||||||
|
|
|
@ -62,7 +62,9 @@ export const isOIDCConfig = (config: Config): config is OIDCConfig =>
|
||||||
|
|
||||||
export enum ConfigType {
|
export enum ConfigType {
|
||||||
SETTINGS = "settings",
|
SETTINGS = "settings",
|
||||||
|
ACCOUNT = "account",
|
||||||
SMTP = "smtp",
|
SMTP = "smtp",
|
||||||
GOOGLE = "google",
|
GOOGLE = "google",
|
||||||
OIDC = "oidc",
|
OIDC = "oidc",
|
||||||
|
OIDC_LOGOS = "logos_oidc",
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,3 +4,4 @@ export * from "./userGroup"
|
||||||
export * from "./plugin"
|
export * from "./plugin"
|
||||||
export * from "./quotas"
|
export * from "./quotas"
|
||||||
export * from "./schedule"
|
export * from "./schedule"
|
||||||
|
export * from "./templates"
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Document } from "../document"
|
||||||
|
|
||||||
|
export interface Template extends Document {
|
||||||
|
ownerId?: string
|
||||||
|
name?: string
|
||||||
|
contents: string
|
||||||
|
purpose: string
|
||||||
|
type?: string
|
||||||
|
}
|
|
@ -1,25 +1,25 @@
|
||||||
import core from "@budibase/backend-core"
|
import { utils, constants, auth, db as dbCore } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
events,
|
events,
|
||||||
users as usersCore,
|
users as usersCore,
|
||||||
context,
|
context,
|
||||||
tenancy,
|
tenancy,
|
||||||
} from "@budibase/backend-core"
|
} from "@budibase/backend-core"
|
||||||
import { Config, EmailTemplatePurpose } from "../../../constants"
|
import { EmailTemplatePurpose } from "../../../constants"
|
||||||
import { sendEmail, isEmailConfigured } from "../../../utilities/email"
|
import { sendEmail, isEmailConfigured } from "../../../utilities/email"
|
||||||
import { checkResetPasswordCode } from "../../../utilities/redis"
|
import { checkResetPasswordCode } from "../../../utilities/redis"
|
||||||
import env from "../../../environment"
|
import env from "../../../environment"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import { User } from "@budibase/types"
|
import { User, Config, ConfigType } from "@budibase/types"
|
||||||
const { setCookie, getCookie, clearCookie, hash, platformLogout } = core.utils
|
const { setCookie, getCookie, clearCookie, hash, platformLogout } = utils
|
||||||
const { Cookie, Header } = core.constants
|
const { Cookie, Header } = constants
|
||||||
const { passport, ssoCallbackUrl, google, oidc } = core.auth
|
const { passport, ssoCallbackUrl, google, oidc } = auth
|
||||||
|
|
||||||
export const googleCallbackUrl = async (config: any) => {
|
export async function googleCallbackUrl(config?: Config) {
|
||||||
return ssoCallbackUrl(tenancy.getGlobalDB(), config, "google")
|
return ssoCallbackUrl(tenancy.getGlobalDB(), config, "google")
|
||||||
}
|
}
|
||||||
|
|
||||||
export const oidcCallbackUrl = async (config: any) => {
|
export async function oidcCallbackUrl(config?: Config) {
|
||||||
return ssoCallbackUrl(tenancy.getGlobalDB(), config, "oidc")
|
return ssoCallbackUrl(tenancy.getGlobalDB(), config, "oidc")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ export const logout = async (ctx: any) => {
|
||||||
|
|
||||||
export const datasourcePreAuth = async (ctx: any, next: any) => {
|
export const datasourcePreAuth = async (ctx: any, next: any) => {
|
||||||
const provider = ctx.params.provider
|
const provider = ctx.params.provider
|
||||||
const middleware = require(`@budibase/backend-core/middleware`)
|
const { middleware } = require(`@budibase/backend-core`)
|
||||||
const handler = middleware.datasource[provider]
|
const handler = middleware.datasource[provider]
|
||||||
|
|
||||||
setCookie(
|
setCookie(
|
||||||
|
@ -154,7 +154,7 @@ export const datasourcePreAuth = async (ctx: any, next: any) => {
|
||||||
export const datasourceAuth = async (ctx: any, next: any) => {
|
export const datasourceAuth = async (ctx: any, next: any) => {
|
||||||
const authStateCookie = getCookie(ctx, Cookie.DatasourceAuth)
|
const authStateCookie = getCookie(ctx, Cookie.DatasourceAuth)
|
||||||
const provider = authStateCookie.provider
|
const provider = authStateCookie.provider
|
||||||
const middleware = require(`@budibase/backend-core/middleware`)
|
const { middleware } = require(`@budibase/backend-core`)
|
||||||
const handler = middleware.datasource[provider]
|
const handler = middleware.datasource[provider]
|
||||||
return handler.postAuth(passport, ctx, next)
|
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) => {
|
export const googlePreAuth = async (ctx: any, next: any) => {
|
||||||
const db = tenancy.getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
|
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await dbCore.getScopedConfig(db, {
|
||||||
type: Config.GOOGLE,
|
type: ConfigType.GOOGLE,
|
||||||
workspace: ctx.query.workspace,
|
workspace: ctx.query.workspace,
|
||||||
})
|
})
|
||||||
let callbackUrl = await exports.googleCallbackUrl(config)
|
let callbackUrl = await googleCallbackUrl(config)
|
||||||
const strategy = await google.strategyFactory(
|
const strategy = await google.strategyFactory(
|
||||||
config,
|
config,
|
||||||
callbackUrl,
|
callbackUrl,
|
||||||
|
@ -187,11 +187,11 @@ export const googlePreAuth = async (ctx: any, next: any) => {
|
||||||
export const googleAuth = async (ctx: any, next: any) => {
|
export const googleAuth = async (ctx: any, next: any) => {
|
||||||
const db = tenancy.getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
|
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await dbCore.getScopedConfig(db, {
|
||||||
type: Config.GOOGLE,
|
type: ConfigType.GOOGLE,
|
||||||
workspace: ctx.query.workspace,
|
workspace: ctx.query.workspace,
|
||||||
})
|
})
|
||||||
const callbackUrl = await exports.googleCallbackUrl(config)
|
const callbackUrl = await googleCallbackUrl(config)
|
||||||
const strategy = await google.strategyFactory(
|
const strategy = await google.strategyFactory(
|
||||||
config,
|
config,
|
||||||
callbackUrl,
|
callbackUrl,
|
||||||
|
@ -213,13 +213,13 @@ export const googleAuth = async (ctx: any, next: any) => {
|
||||||
|
|
||||||
export const oidcStrategyFactory = async (ctx: any, configId: any) => {
|
export const oidcStrategyFactory = async (ctx: any, configId: any) => {
|
||||||
const db = tenancy.getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await dbCore.getScopedConfig(db, {
|
||||||
type: Config.OIDC,
|
type: ConfigType.OIDC,
|
||||||
group: ctx.query.group,
|
group: ctx.query.group,
|
||||||
})
|
})
|
||||||
|
|
||||||
const chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0]
|
const chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0]
|
||||||
let callbackUrl = await exports.oidcCallbackUrl(chosenConfig)
|
let callbackUrl = await oidcCallbackUrl(chosenConfig)
|
||||||
|
|
||||||
//Remote Config
|
//Remote Config
|
||||||
const enrichedConfig = await oidc.fetchStrategyConfig(
|
const enrichedConfig = await oidc.fetchStrategyConfig(
|
||||||
|
@ -240,8 +240,8 @@ export const oidcPreAuth = async (ctx: any, next: any) => {
|
||||||
setCookie(ctx, configId, Cookie.OIDC_CONFIG)
|
setCookie(ctx, configId, Cookie.OIDC_CONFIG)
|
||||||
|
|
||||||
const db = tenancy.getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await dbCore.getScopedConfig(db, {
|
||||||
type: Config.OIDC,
|
type: ConfigType.OIDC,
|
||||||
group: ctx.query.group,
|
group: ctx.query.group,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,26 @@
|
||||||
const {
|
import * as email from "../../../utilities/email"
|
||||||
generateConfigID,
|
import env from "../../../environment"
|
||||||
getConfigParams,
|
import { googleCallbackUrl, oidcCallbackUrl } from "./auth"
|
||||||
getScopedFullConfig,
|
import {
|
||||||
getAllApps,
|
events,
|
||||||
} = 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,
|
|
||||||
cache,
|
cache,
|
||||||
} = require("@budibase/backend-core/cache")
|
objectStore,
|
||||||
const { events } = require("@budibase/backend-core")
|
tenancy,
|
||||||
const { checkAnyUserExists } = require("../../../utilities/users")
|
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 fns = []
|
||||||
const type = config.type
|
const type = config.type
|
||||||
|
|
||||||
|
@ -31,41 +29,45 @@ const getEventFns = async (db, config) => {
|
||||||
existing = await db.get(config._id)
|
existing = await db.get(config._id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ssoType = type as SSOType
|
||||||
if (!existing) {
|
if (!existing) {
|
||||||
switch (config.type) {
|
switch (config.type) {
|
||||||
case Config.SMTP: {
|
case ConfigType.SMTP: {
|
||||||
fns.push(events.email.SMTPCreated)
|
fns.push(events.email.SMTPCreated)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Config.GOOGLE: {
|
case ConfigType.GOOGLE: {
|
||||||
fns.push(() => events.auth.SSOCreated(type))
|
const googleCfg = config as GoogleConfig
|
||||||
if (config.config.activated) {
|
fns.push(() => events.auth.SSOCreated(ssoType))
|
||||||
fns.push(() => events.auth.SSOActivated(type))
|
if (googleCfg.config.activated) {
|
||||||
|
fns.push(() => events.auth.SSOActivated(ssoType))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Config.OIDC: {
|
case ConfigType.OIDC: {
|
||||||
fns.push(() => events.auth.SSOCreated(type))
|
const oidcCfg = config as OIDCConfig
|
||||||
if (config.config.configs[0].activated) {
|
fns.push(() => events.auth.SSOCreated(ssoType))
|
||||||
fns.push(() => events.auth.SSOActivated(type))
|
if (oidcCfg.config.configs[0].activated) {
|
||||||
|
fns.push(() => events.auth.SSOActivated(ssoType))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Config.SETTINGS: {
|
case ConfigType.SETTINGS: {
|
||||||
// company
|
// company
|
||||||
const company = config.config.company
|
const settingsCfg = config as SettingsConfig
|
||||||
|
const company = settingsCfg.config.company
|
||||||
if (company && company !== "Budibase") {
|
if (company && company !== "Budibase") {
|
||||||
fns.push(events.org.nameUpdated)
|
fns.push(events.org.nameUpdated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// logo
|
// logo
|
||||||
const logoUrl = config.config.logoUrl
|
const logoUrl = settingsCfg.config.logoUrl
|
||||||
if (logoUrl) {
|
if (logoUrl) {
|
||||||
fns.push(events.org.logoUpdated)
|
fns.push(events.org.logoUpdated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// platform url
|
// platform url
|
||||||
const platformUrl = config.config.platformUrl
|
const platformUrl = settingsCfg.config.platformUrl
|
||||||
if (
|
if (
|
||||||
platformUrl &&
|
platformUrl &&
|
||||||
platformUrl !== "http://localhost:10000" &&
|
platformUrl !== "http://localhost:10000" &&
|
||||||
|
@ -78,52 +80,55 @@ const getEventFns = async (db, config) => {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (config.type) {
|
switch (config.type) {
|
||||||
case Config.SMTP: {
|
case ConfigType.SMTP: {
|
||||||
fns.push(events.email.SMTPUpdated)
|
fns.push(events.email.SMTPUpdated)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Config.GOOGLE: {
|
case ConfigType.GOOGLE: {
|
||||||
fns.push(() => events.auth.SSOUpdated(type))
|
const googleCfg = config as GoogleConfig
|
||||||
if (!existing.config.activated && config.config.activated) {
|
fns.push(() => events.auth.SSOUpdated(ssoType))
|
||||||
fns.push(() => events.auth.SSOActivated(type))
|
if (!existing.config.activated && googleCfg.config.activated) {
|
||||||
} else if (existing.config.activated && !config.config.activated) {
|
fns.push(() => events.auth.SSOActivated(ssoType))
|
||||||
fns.push(() => events.auth.SSODeactivated(type))
|
} else if (existing.config.activated && !googleCfg.config.activated) {
|
||||||
|
fns.push(() => events.auth.SSODeactivated(ssoType))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Config.OIDC: {
|
case ConfigType.OIDC: {
|
||||||
fns.push(() => events.auth.SSOUpdated(type))
|
const oidcCfg = config as OIDCConfig
|
||||||
|
fns.push(() => events.auth.SSOUpdated(ssoType))
|
||||||
if (
|
if (
|
||||||
!existing.config.configs[0].activated &&
|
!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 (
|
} else if (
|
||||||
existing.config.configs[0].activated &&
|
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
|
break
|
||||||
}
|
}
|
||||||
case Config.SETTINGS: {
|
case ConfigType.SETTINGS: {
|
||||||
// company
|
// company
|
||||||
|
const settingsCfg = config as SettingsConfig
|
||||||
const existingCompany = existing.config.company
|
const existingCompany = existing.config.company
|
||||||
const company = config.config.company
|
const company = settingsCfg.config.company
|
||||||
if (company && company !== "Budibase" && existingCompany !== company) {
|
if (company && company !== "Budibase" && existingCompany !== company) {
|
||||||
fns.push(events.org.nameUpdated)
|
fns.push(events.org.nameUpdated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// logo
|
// logo
|
||||||
const existingLogoUrl = existing.config.logoUrl
|
const existingLogoUrl = existing.config.logoUrl
|
||||||
const logoUrl = config.config.logoUrl
|
const logoUrl = settingsCfg.config.logoUrl
|
||||||
if (logoUrl && existingLogoUrl !== logoUrl) {
|
if (logoUrl && existingLogoUrl !== logoUrl) {
|
||||||
fns.push(events.org.logoUpdated)
|
fns.push(events.org.logoUpdated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// platform url
|
// platform url
|
||||||
const existingPlatformUrl = existing.config.platformUrl
|
const existingPlatformUrl = existing.config.platformUrl
|
||||||
const platformUrl = config.config.platformUrl
|
const platformUrl = settingsCfg.config.platformUrl
|
||||||
if (
|
if (
|
||||||
platformUrl &&
|
platformUrl &&
|
||||||
platformUrl !== "http://localhost:10000" &&
|
platformUrl !== "http://localhost:10000" &&
|
||||||
|
@ -140,13 +145,13 @@ const getEventFns = async (db, config) => {
|
||||||
return fns
|
return fns
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.save = async function (ctx) {
|
export async function save(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const { type, workspace, user, config } = ctx.request.body
|
const { type, workspace, user, config } = ctx.request.body
|
||||||
let eventFns = await getEventFns(db, ctx.request.body)
|
let eventFns = await getEventFns(db, ctx.request.body)
|
||||||
// Config does not exist yet
|
// Config does not exist yet
|
||||||
if (!ctx.request.body._id) {
|
if (!ctx.request.body._id) {
|
||||||
ctx.request.body._id = generateConfigID({
|
ctx.request.body._id = dbCore.generateConfigID({
|
||||||
type,
|
type,
|
||||||
workspace,
|
workspace,
|
||||||
user,
|
user,
|
||||||
|
@ -155,18 +160,18 @@ exports.save = async function (ctx) {
|
||||||
try {
|
try {
|
||||||
// verify the configuration
|
// verify the configuration
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Config.SMTP:
|
case ConfigType.SMTP:
|
||||||
await email.verifyConfig(config)
|
await email.verifyConfig(config)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
ctx.throw(400, err)
|
ctx.throw(400, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await db.put(ctx.request.body)
|
const response = await db.put(ctx.request.body)
|
||||||
await bustCache(CacheKeys.CHECKLIST)
|
await cache.bustCache(cache.CacheKeys.CHECKLIST)
|
||||||
await bustCache(CacheKeys.ANALYTICS_ENABLED)
|
await cache.bustCache(cache.CacheKeys.ANALYTICS_ENABLED)
|
||||||
|
|
||||||
for (const fn of eventFns) {
|
for (const fn of eventFns) {
|
||||||
await fn()
|
await fn()
|
||||||
|
@ -177,15 +182,15 @@ exports.save = async function (ctx) {
|
||||||
_id: response.id,
|
_id: response.id,
|
||||||
_rev: response.rev,
|
_rev: response.rev,
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
ctx.throw(400, err)
|
ctx.throw(400, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.fetch = async function (ctx) {
|
export async function fetch(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const response = await db.allDocs(
|
const response = await db.allDocs(
|
||||||
getConfigParams(
|
dbCore.getConfigParams(
|
||||||
{ type: ctx.params.type },
|
{ type: ctx.params.type },
|
||||||
{
|
{
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
|
@ -199,23 +204,23 @@ exports.fetch = async function (ctx) {
|
||||||
* Gets the most granular config for a particular configuration type.
|
* Gets the most granular config for a particular configuration type.
|
||||||
* The hierarchy is type -> workspace -> user.
|
* The hierarchy is type -> workspace -> user.
|
||||||
*/
|
*/
|
||||||
exports.find = async function (ctx) {
|
export async function find(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
|
|
||||||
const { userId, workspaceId } = ctx.query
|
const { userId, workspaceId } = ctx.query
|
||||||
if (workspaceId && userId) {
|
if (workspaceId && userId) {
|
||||||
const workspace = await db.get(workspaceId)
|
const workspace = await db.get(workspaceId as string)
|
||||||
const userInWorkspace = workspace.users.some(
|
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}.`)
|
ctx.throw(400, `User is not in specified workspace: ${workspace}.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Find the config with the most granular scope based on context
|
// 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,
|
type: ctx.params.type,
|
||||||
user: userId,
|
user: userId,
|
||||||
workspace: workspaceId,
|
workspace: workspaceId,
|
||||||
|
@ -227,48 +232,48 @@ exports.find = async function (ctx) {
|
||||||
// don't throw an error, there simply is nothing to return
|
// don't throw an error, there simply is nothing to return
|
||||||
ctx.body = {}
|
ctx.body = {}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
ctx.throw(err.status, err)
|
ctx.throw(err?.status || 400, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.publicOidc = async function (ctx) {
|
export async function publicOidc(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
try {
|
try {
|
||||||
// Find the config with the most granular scope based on context
|
// Find the config with the most granular scope based on context
|
||||||
const oidcConfig = await getScopedFullConfig(db, {
|
const oidcConfig = await dbCore.getScopedFullConfig(db, {
|
||||||
type: Config.OIDC,
|
type: ConfigType.OIDC,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!oidcConfig) {
|
if (!oidcConfig) {
|
||||||
ctx.body = {}
|
ctx.body = {}
|
||||||
} else {
|
} else {
|
||||||
ctx.body = oidcConfig.config.configs.map(config => ({
|
ctx.body = oidcConfig.config.configs.map((config: any) => ({
|
||||||
logo: config.logo,
|
logo: config.logo,
|
||||||
name: config.name,
|
name: config.name,
|
||||||
uuid: config.uuid,
|
uuid: config.uuid,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
ctx.throw(err.status, err)
|
ctx.throw(err.status, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.publicSettings = async function (ctx) {
|
export async function publicSettings(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Find the config with the most granular scope based on context
|
// Find the config with the most granular scope based on context
|
||||||
const publicConfig = await getScopedFullConfig(db, {
|
const publicConfig = await dbCore.getScopedFullConfig(db, {
|
||||||
type: Config.SETTINGS,
|
type: ConfigType.SETTINGS,
|
||||||
})
|
})
|
||||||
|
|
||||||
const googleConfig = await getScopedFullConfig(db, {
|
const googleConfig = await dbCore.getScopedFullConfig(db, {
|
||||||
type: Config.GOOGLE,
|
type: ConfigType.GOOGLE,
|
||||||
})
|
})
|
||||||
|
|
||||||
const oidcConfig = await getScopedFullConfig(db, {
|
const oidcConfig = await dbCore.getScopedFullConfig(db, {
|
||||||
type: Config.OIDC,
|
type: ConfigType.OIDC,
|
||||||
})
|
})
|
||||||
|
|
||||||
let config
|
let config
|
||||||
|
@ -301,12 +306,12 @@ exports.publicSettings = async function (ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.body = config
|
ctx.body = config
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
ctx.throw(err.status, err)
|
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) {
|
if (ctx.request.files == null || ctx.request.files.file.length > 1) {
|
||||||
ctx.throw(400, "One file must be uploaded.")
|
ctx.throw(400, "One file must be uploaded.")
|
||||||
}
|
}
|
||||||
|
@ -315,19 +320,19 @@ exports.upload = async function (ctx) {
|
||||||
|
|
||||||
let bucket
|
let bucket
|
||||||
if (env.SELF_HOSTED) {
|
if (env.SELF_HOSTED) {
|
||||||
bucket = ObjectStoreBuckets.GLOBAL
|
bucket = objectStore.ObjectStoreBuckets.GLOBAL
|
||||||
} else {
|
} else {
|
||||||
bucket = ObjectStoreBuckets.GLOBAL_CLOUD
|
bucket = objectStore.ObjectStoreBuckets.GLOBAL_CLOUD
|
||||||
}
|
}
|
||||||
|
|
||||||
let key
|
let key
|
||||||
if (env.MULTI_TENANCY) {
|
if (env.MULTI_TENANCY) {
|
||||||
key = `${getTenantId()}/${type}/${name}`
|
key = `${tenancy.getTenantId()}/${type}/${name}`
|
||||||
} else {
|
} else {
|
||||||
key = `${type}/${name}`
|
key = `${type}/${name}`
|
||||||
}
|
}
|
||||||
|
|
||||||
await upload({
|
await objectStore.upload({
|
||||||
bucket,
|
bucket,
|
||||||
filename: key,
|
filename: key,
|
||||||
path: file.path,
|
path: file.path,
|
||||||
|
@ -336,11 +341,11 @@ exports.upload = async function (ctx) {
|
||||||
|
|
||||||
// add to configuration structure
|
// add to configuration structure
|
||||||
// TODO: right now this only does a global level
|
// TODO: right now this only does a global level
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
let cfgStructure = await getScopedFullConfig(db, { type })
|
let cfgStructure = await dbCore.getScopedFullConfig(db, { type })
|
||||||
if (!cfgStructure) {
|
if (!cfgStructure) {
|
||||||
cfgStructure = {
|
cfgStructure = {
|
||||||
_id: generateConfigID({ type }),
|
_id: dbCore.generateConfigID({ type }),
|
||||||
config: {},
|
config: {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,49 +366,49 @@ exports.upload = async function (ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.destroy = async function (ctx) {
|
export async function destroy(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const { id, rev } = ctx.params
|
const { id, rev } = ctx.params
|
||||||
try {
|
try {
|
||||||
await db.remove(id, rev)
|
await db.remove(id, rev)
|
||||||
await cache.delete(CacheKeys.CHECKLIST)
|
await cache.delete(cache.CacheKeys.CHECKLIST)
|
||||||
ctx.body = { message: "Config deleted successfully" }
|
ctx.body = { message: "Config deleted successfully" }
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
ctx.throw(err.status, err)
|
ctx.throw(err.status, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.configChecklist = async function (ctx) {
|
export async function configChecklist(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const tenantId = getTenantId()
|
const tenantId = tenancy.getTenantId()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ctx.body = await withCache(
|
ctx.body = await cache.withCache(
|
||||||
CacheKeys.CHECKLIST,
|
cache.CacheKeys.CHECKLIST,
|
||||||
env.CHECKLIST_CACHE_TTL,
|
env.CHECKLIST_CACHE_TTL,
|
||||||
async () => {
|
async () => {
|
||||||
let apps = []
|
let apps = []
|
||||||
if (!env.MULTI_TENANCY || tenantId) {
|
if (!env.MULTI_TENANCY || tenantId) {
|
||||||
// Apps exist
|
// Apps exist
|
||||||
apps = await getAllApps({ idsOnly: true, efficient: true })
|
apps = await dbCore.getAllApps({ idsOnly: true, efficient: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
// They have set up SMTP
|
// They have set up SMTP
|
||||||
const smtpConfig = await getScopedFullConfig(db, {
|
const smtpConfig = await dbCore.getScopedFullConfig(db, {
|
||||||
type: Config.SMTP,
|
type: ConfigType.SMTP,
|
||||||
})
|
})
|
||||||
|
|
||||||
// They have set up Google Auth
|
// They have set up Google Auth
|
||||||
const googleConfig = await getScopedFullConfig(db, {
|
const googleConfig = await dbCore.getScopedFullConfig(db, {
|
||||||
type: Config.GOOGLE,
|
type: ConfigType.GOOGLE,
|
||||||
})
|
})
|
||||||
|
|
||||||
// They have set up OIDC
|
// They have set up OIDC
|
||||||
const oidcConfig = await getScopedFullConfig(db, {
|
const oidcConfig = await dbCore.getScopedFullConfig(db, {
|
||||||
type: Config.OIDC,
|
type: ConfigType.OIDC,
|
||||||
})
|
})
|
||||||
|
|
||||||
// They have set up an global user
|
// They have set up a global user
|
||||||
const userExists = await checkAnyUserExists()
|
const userExists = await checkAnyUserExists()
|
||||||
return {
|
return {
|
||||||
apps: {
|
apps: {
|
||||||
|
@ -429,7 +434,7 @@ exports.configChecklist = async function (ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
ctx.throw(err.status, err)
|
ctx.throw(err.status, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
const { sendEmail } = require("../../../utilities/email")
|
import { sendEmail as sendEmailFn } from "../../../utilities/email"
|
||||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
import { tenancy } from "@budibase/backend-core"
|
||||||
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
exports.sendEmail = async ctx => {
|
export async function sendEmail(ctx: BBContext) {
|
||||||
let {
|
let {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
email,
|
email,
|
||||||
|
@ -16,10 +17,10 @@ exports.sendEmail = async ctx => {
|
||||||
} = ctx.request.body
|
} = ctx.request.body
|
||||||
let user
|
let user
|
||||||
if (userId) {
|
if (userId) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
user = await db.get(userId)
|
user = await db.get(userId)
|
||||||
}
|
}
|
||||||
const response = await sendEmail(email, purpose, {
|
const response = await sendEmailFn(email, purpose, {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
user,
|
user,
|
||||||
contents,
|
contents,
|
|
@ -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",
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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",
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,13 @@
|
||||||
const {
|
import { tenancy, db as dbCore } from "@budibase/backend-core"
|
||||||
getWorkspaceParams,
|
import { BBContext } from "@budibase/types"
|
||||||
generateWorkspaceID,
|
|
||||||
} = require("@budibase/backend-core/db")
|
|
||||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
|
||||||
|
|
||||||
exports.save = async function (ctx) {
|
export async function save(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const workspaceDoc = ctx.request.body
|
const workspaceDoc = ctx.request.body
|
||||||
|
|
||||||
// workspace does not exist yet
|
// workspace does not exist yet
|
||||||
if (!workspaceDoc._id) {
|
if (!workspaceDoc._id) {
|
||||||
workspaceDoc._id = generateWorkspaceID()
|
workspaceDoc._id = dbCore.generateWorkspaceID()
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -19,38 +16,38 @@ exports.save = async function (ctx) {
|
||||||
_id: response.id,
|
_id: response.id,
|
||||||
_rev: response.rev,
|
_rev: response.rev,
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
ctx.throw(err.status, err)
|
ctx.throw(err.status, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.fetch = async function (ctx) {
|
export async function fetch(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const response = await db.allDocs(
|
const response = await db.allDocs(
|
||||||
getWorkspaceParams(undefined, {
|
dbCore.getWorkspaceParams(undefined, {
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
ctx.body = response.rows.map(row => row.doc)
|
ctx.body = response.rows.map(row => row.doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.find = async function (ctx) {
|
export async function find(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
try {
|
try {
|
||||||
ctx.body = await db.get(ctx.params.id)
|
ctx.body = await db.get(ctx.params.id)
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
ctx.throw(err.status, err)
|
ctx.throw(err.status, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.destroy = async function (ctx) {
|
export async function destroy(ctx: BBContext) {
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const { id, rev } = ctx.params
|
const { id, rev } = ctx.params
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await db.remove(id, rev)
|
await db.remove(id, rev)
|
||||||
ctx.body = { message: "Workspace deleted successfully" }
|
ctx.body = { message: "Workspace deleted successfully" }
|
||||||
} catch (err) {
|
} catch (err: any) {
|
||||||
ctx.throw(err.status, err)
|
ctx.throw(err.status, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -104,7 +104,7 @@ const NO_TENANCY_ENDPOINTS = [
|
||||||
// add them all to be safe
|
// add them all to be safe
|
||||||
const NO_CSRF_ENDPOINTS = [...PUBLIC_ENDPOINTS]
|
const NO_CSRF_ENDPOINTS = [...PUBLIC_ENDPOINTS]
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
router
|
router
|
||||||
.use(
|
.use(
|
||||||
compress({
|
compress({
|
||||||
|
@ -163,4 +163,4 @@ for (let route of routes) {
|
||||||
router.use(route.allowedMethods())
|
router.use(route.allowedMethods())
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = router
|
export = router
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
const Router = require("@koa/router")
|
import Router from "@koa/router"
|
||||||
const authController = require("../../controllers/global/auth")
|
import * as authController from "../../controllers/global/auth"
|
||||||
const { joiValidator } = require("@budibase/backend-core/auth")
|
import { auth } from "@budibase/backend-core"
|
||||||
const Joi = require("joi")
|
import Joi from "joi"
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
function buildAuthValidation() {
|
function buildAuthValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.body(Joi.object({
|
return auth.joiValidator.body(Joi.object({
|
||||||
username: Joi.string().required(),
|
username: Joi.string().required(),
|
||||||
password: Joi.string().required(),
|
password: Joi.string().required(),
|
||||||
}).required().unknown(false))
|
}).required().unknown(false))
|
||||||
|
@ -15,14 +15,14 @@ function buildAuthValidation() {
|
||||||
|
|
||||||
function buildResetValidation() {
|
function buildResetValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.body(Joi.object({
|
return auth.joiValidator.body(Joi.object({
|
||||||
email: Joi.string().required(),
|
email: Joi.string().required(),
|
||||||
}).required().unknown(false))
|
}).required().unknown(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildResetUpdateValidation() {
|
function buildResetUpdateValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.body(Joi.object({
|
return auth.joiValidator.body(Joi.object({
|
||||||
resetCode: Joi.string().required(),
|
resetCode: Joi.string().required(),
|
||||||
password: Joi.string().required(),
|
password: Joi.string().required(),
|
||||||
}).required().unknown(false))
|
}).required().unknown(false))
|
||||||
|
@ -85,4 +85,4 @@ router
|
||||||
.get("/api/global/auth/oidc/callback", authController.oidcAuth)
|
.get("/api/global/auth/oidc/callback", authController.oidcAuth)
|
||||||
.get("/api/admin/auth/oidc/callback", authController.oidcAuth)
|
.get("/api/admin/auth/oidc/callback", authController.oidcAuth)
|
||||||
|
|
||||||
module.exports = router
|
export = router
|
|
@ -1,11 +1,10 @@
|
||||||
const Router = require("@koa/router")
|
import Router from "@koa/router"
|
||||||
const controller = require("../../controllers/global/configs")
|
import * as controller from "../../controllers/global/configs"
|
||||||
const { joiValidator } = require("@budibase/backend-core/auth")
|
import { auth } from "@budibase/backend-core"
|
||||||
const { adminOnly } = require("@budibase/backend-core/auth")
|
import Joi from "joi"
|
||||||
const Joi = require("joi")
|
import { ConfigType } from "@budibase/types"
|
||||||
const { Config } = require("@budibase/backend-core/constants")
|
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
function smtpValidation() {
|
function smtpValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
@ -55,27 +54,27 @@ function oidcValidation() {
|
||||||
activated: Joi.boolean().required(),
|
activated: Joi.boolean().required(),
|
||||||
scopes: Joi.array().optional()
|
scopes: Joi.array().optional()
|
||||||
})
|
})
|
||||||
).required(true)
|
).required()
|
||||||
}).unknown(true)
|
}).unknown(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildConfigSaveValidation() {
|
function buildConfigSaveValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.body(Joi.object({
|
return auth.joiValidator.body(Joi.object({
|
||||||
_id: Joi.string().optional(),
|
_id: Joi.string().optional(),
|
||||||
_rev: Joi.string().optional(),
|
_rev: Joi.string().optional(),
|
||||||
workspace: 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(),
|
createdAt: Joi.string().optional(),
|
||||||
updatedAt: Joi.string().optional(),
|
updatedAt: Joi.string().optional(),
|
||||||
config: Joi.alternatives()
|
config: Joi.alternatives()
|
||||||
.conditional("type", {
|
.conditional("type", {
|
||||||
switch: [
|
switch: [
|
||||||
{ is: Config.SMTP, then: smtpValidation() },
|
{ is: ConfigType.SMTP, then: smtpValidation() },
|
||||||
{ is: Config.SETTINGS, then: settingValidation() },
|
{ is: ConfigType.SETTINGS, then: settingValidation() },
|
||||||
{ is: Config.ACCOUNT, then: Joi.object().unknown(true) },
|
{ is: ConfigType.ACCOUNT, then: Joi.object().unknown(true) },
|
||||||
{ is: Config.GOOGLE, then: googleValidation() },
|
{ is: ConfigType.GOOGLE, then: googleValidation() },
|
||||||
{ is: Config.OIDC, then: oidcValidation() }
|
{ is: ConfigType.OIDC, then: oidcValidation() }
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
}).required().unknown(true),
|
}).required().unknown(true),
|
||||||
|
@ -84,27 +83,27 @@ function buildConfigSaveValidation() {
|
||||||
|
|
||||||
function buildUploadValidation() {
|
function buildUploadValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.params(Joi.object({
|
return auth.joiValidator.params(Joi.object({
|
||||||
type: Joi.string().valid(...Object.values(Config)).required(),
|
type: Joi.string().valid(...Object.values(ConfigType)).required(),
|
||||||
name: Joi.string().required(),
|
name: Joi.string().required(),
|
||||||
}).required().unknown(true))
|
}).required().unknown(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildConfigGetValidation() {
|
function buildConfigGetValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.params(Joi.object({
|
return auth.joiValidator.params(Joi.object({
|
||||||
type: Joi.string().valid(...Object.values(Config)).required()
|
type: Joi.string().valid(...Object.values(ConfigType)).required()
|
||||||
}).required().unknown(true))
|
}).required().unknown(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
router
|
router
|
||||||
.post(
|
.post(
|
||||||
"/api/global/configs",
|
"/api/global/configs",
|
||||||
adminOnly,
|
auth.adminOnly,
|
||||||
buildConfigSaveValidation(),
|
buildConfigSaveValidation(),
|
||||||
controller.save
|
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", controller.fetch)
|
||||||
.get("/api/global/configs/checklist", controller.configChecklist)
|
.get("/api/global/configs/checklist", controller.configChecklist)
|
||||||
.get(
|
.get(
|
||||||
|
@ -117,9 +116,9 @@ router
|
||||||
.get("/api/global/configs/:type", buildConfigGetValidation(), controller.find)
|
.get("/api/global/configs/:type", buildConfigGetValidation(), controller.find)
|
||||||
.post(
|
.post(
|
||||||
"/api/global/configs/upload/:type/:name",
|
"/api/global/configs/upload/:type/:name",
|
||||||
adminOnly,
|
auth.adminOnly,
|
||||||
buildUploadValidation(),
|
buildUploadValidation(),
|
||||||
controller.upload
|
controller.upload
|
||||||
)
|
)
|
||||||
|
|
||||||
module.exports = router
|
export = router
|
|
@ -1,15 +1,14 @@
|
||||||
const Router = require("@koa/router")
|
import Router from "@koa/router"
|
||||||
const controller = require("../../controllers/global/email")
|
import * as controller from "../../controllers/global/email"
|
||||||
const { EmailTemplatePurpose } = require("../../../constants")
|
import { EmailTemplatePurpose } from "../../../constants"
|
||||||
const { joiValidator } = require("@budibase/backend-core/auth")
|
import { auth } from "@budibase/backend-core"
|
||||||
const { adminOnly } = require("@budibase/backend-core/auth")
|
import Joi from "joi"
|
||||||
const Joi = require("joi")
|
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
function buildEmailSendValidation() {
|
function buildEmailSendValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.body(Joi.object({
|
return auth.joiValidator.body(Joi.object({
|
||||||
email: Joi.string().email({
|
email: Joi.string().email({
|
||||||
multiple: true,
|
multiple: true,
|
||||||
}),
|
}),
|
||||||
|
@ -30,8 +29,8 @@ function buildEmailSendValidation() {
|
||||||
router.post(
|
router.post(
|
||||||
"/api/global/email/send",
|
"/api/global/email/send",
|
||||||
buildEmailSendValidation(),
|
buildEmailSendValidation(),
|
||||||
adminOnly,
|
auth.adminOnly,
|
||||||
controller.sendEmail
|
controller.sendEmail
|
||||||
)
|
)
|
||||||
|
|
||||||
module.exports = router
|
export = router
|
|
@ -1,7 +1,7 @@
|
||||||
import Router from "@koa/router"
|
import Router from "@koa/router"
|
||||||
import * as controller from "../../controllers/global/license"
|
import * as controller from "../../controllers/global/license"
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
router
|
router
|
||||||
.post("/api/global/license/activate", controller.activate)
|
.post("/api/global/license/activate", controller.activate)
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
@ -3,7 +3,7 @@ import * as controller from "../../controllers/global/self"
|
||||||
import { auth } from "@budibase/backend-core"
|
import { auth } from "@budibase/backend-core"
|
||||||
import { users } from "../validation"
|
import { users } from "../validation"
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
router
|
router
|
||||||
.post("/api/global/self/api_key", auth.builderOnly, controller.generateAPIKey)
|
.post("/api/global/self/api_key", auth.builderOnly, controller.generateAPIKey)
|
||||||
|
@ -15,4 +15,4 @@ router
|
||||||
controller.updateSelf
|
controller.updateSelf
|
||||||
)
|
)
|
||||||
|
|
||||||
export default router as any
|
export = router
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { auth as authCore } from "@budibase/backend-core"
|
||||||
import Joi from "joi"
|
import Joi from "joi"
|
||||||
const { adminOnly, joiValidator } = authCore
|
const { adminOnly, joiValidator } = authCore
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
function buildTemplateSaveValidation() {
|
function buildTemplateSaveValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
@ -34,4 +34,4 @@ router
|
||||||
.get("/api/global/template/:id", controller.find)
|
.get("/api/global/template/:id", controller.find)
|
||||||
.delete("/api/global/template/:id/:rev", adminOnly, controller.destroy)
|
.delete("/api/global/template/:id/:rev", adminOnly, controller.destroy)
|
||||||
|
|
||||||
export default router
|
export = router
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
const Router = require("@koa/router")
|
import Router from "@koa/router"
|
||||||
const controller = require("../../controllers/global/users")
|
import * as controller from "../../controllers/global/users"
|
||||||
const { joiValidator } = require("@budibase/backend-core/auth")
|
import { auth } from "@budibase/backend-core"
|
||||||
const { adminOnly } = require("@budibase/backend-core/auth")
|
import Joi from "joi"
|
||||||
const Joi = require("joi")
|
import cloudRestricted from "../../../middleware/cloudRestricted"
|
||||||
const cloudRestricted = require("../../../middleware/cloudRestricted")
|
import { users } from "../validation"
|
||||||
const { users } = require("../validation")
|
import * as selfController from "../../controllers/global/self"
|
||||||
const selfController = require("../../controllers/global/self")
|
|
||||||
const { builderOrAdmin } = require("@budibase/backend-core/auth")
|
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
function buildAdminInitValidation() {
|
function buildAdminInitValidation() {
|
||||||
return joiValidator.body(
|
return auth.joiValidator.body(
|
||||||
Joi.object({
|
Joi.object({
|
||||||
email: Joi.string().required(),
|
email: Joi.string().required(),
|
||||||
password: Joi.string(),
|
password: Joi.string(),
|
||||||
|
@ -24,7 +22,7 @@ function buildAdminInitValidation() {
|
||||||
|
|
||||||
function buildInviteValidation() {
|
function buildInviteValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.body(Joi.object({
|
return auth.joiValidator.body(Joi.object({
|
||||||
email: Joi.string().required(),
|
email: Joi.string().required(),
|
||||||
userInfo: Joi.object().optional(),
|
userInfo: Joi.object().optional(),
|
||||||
}).required())
|
}).required())
|
||||||
|
@ -32,7 +30,7 @@ function buildInviteValidation() {
|
||||||
|
|
||||||
function buildInviteMultipleValidation() {
|
function buildInviteMultipleValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.body(Joi.array().required().items(
|
return auth.joiValidator.body(Joi.array().required().items(
|
||||||
Joi.object({
|
Joi.object({
|
||||||
email: Joi.string(),
|
email: Joi.string(),
|
||||||
userInfo: Joi.object().optional(),
|
userInfo: Joi.object().optional(),
|
||||||
|
@ -42,7 +40,7 @@ function buildInviteMultipleValidation() {
|
||||||
|
|
||||||
function buildInviteAcceptValidation() {
|
function buildInviteAcceptValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.body(Joi.object({
|
return auth.joiValidator.body(Joi.object({
|
||||||
inviteCode: Joi.string().required(),
|
inviteCode: Joi.string().required(),
|
||||||
password: Joi.string().required(),
|
password: Joi.string().required(),
|
||||||
}).required().unknown(true))
|
}).required().unknown(true))
|
||||||
|
@ -51,31 +49,35 @@ function buildInviteAcceptValidation() {
|
||||||
router
|
router
|
||||||
.post(
|
.post(
|
||||||
"/api/global/users",
|
"/api/global/users",
|
||||||
adminOnly,
|
auth.adminOnly,
|
||||||
users.buildUserSaveValidation(),
|
users.buildUserSaveValidation(),
|
||||||
controller.save
|
controller.save
|
||||||
)
|
)
|
||||||
.post(
|
.post(
|
||||||
"/api/global/users/bulk",
|
"/api/global/users/bulk",
|
||||||
adminOnly,
|
auth.adminOnly,
|
||||||
users.buildUserBulkUserValidation(),
|
users.buildUserBulkUserValidation(),
|
||||||
controller.bulkUpdate
|
controller.bulkUpdate
|
||||||
)
|
)
|
||||||
|
|
||||||
.get("/api/global/users", builderOrAdmin, controller.fetch)
|
.get("/api/global/users", auth.builderOrAdmin, controller.fetch)
|
||||||
.post("/api/global/users/search", builderOrAdmin, controller.search)
|
.post("/api/global/users/search", auth.builderOrAdmin, controller.search)
|
||||||
.delete("/api/global/users/:id", adminOnly, controller.destroy)
|
.delete("/api/global/users/:id", auth.adminOnly, controller.destroy)
|
||||||
.get("/api/global/users/count/:appId", builderOrAdmin, controller.countByApp)
|
.get(
|
||||||
|
"/api/global/users/count/:appId",
|
||||||
|
auth.builderOrAdmin,
|
||||||
|
controller.countByApp
|
||||||
|
)
|
||||||
.get("/api/global/roles/:appId")
|
.get("/api/global/roles/:appId")
|
||||||
.post(
|
.post(
|
||||||
"/api/global/users/invite",
|
"/api/global/users/invite",
|
||||||
adminOnly,
|
auth.adminOnly,
|
||||||
buildInviteValidation(),
|
buildInviteValidation(),
|
||||||
controller.invite
|
controller.invite
|
||||||
)
|
)
|
||||||
.post(
|
.post(
|
||||||
"/api/global/users/multi/invite",
|
"/api/global/users/multi/invite",
|
||||||
adminOnly,
|
auth.adminOnly,
|
||||||
buildInviteMultipleValidation(),
|
buildInviteMultipleValidation(),
|
||||||
controller.inviteMultiple
|
controller.inviteMultiple
|
||||||
)
|
)
|
||||||
|
@ -94,7 +96,7 @@ router
|
||||||
)
|
)
|
||||||
.get("/api/global/users/tenant/:id", controller.tenantUserLookup)
|
.get("/api/global/users/tenant/:id", controller.tenantUserLookup)
|
||||||
// global endpoint but needs to come at end (blocks other endpoints otherwise)
|
// 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
|
// DEPRECATED - use new versions with self API
|
||||||
.get("/api/global/users/self", selfController.getSelf)
|
.get("/api/global/users/self", selfController.getSelf)
|
||||||
.post(
|
.post(
|
||||||
|
@ -103,4 +105,4 @@ router
|
||||||
selfController.updateSelf
|
selfController.updateSelf
|
||||||
)
|
)
|
||||||
|
|
||||||
module.exports = router
|
export = router
|
|
@ -1,14 +1,13 @@
|
||||||
const Router = require("@koa/router")
|
import Router from "@koa/router"
|
||||||
const controller = require("../../controllers/global/workspaces")
|
import * as controller from "../../controllers/global/workspaces"
|
||||||
const { joiValidator } = require("@budibase/backend-core/auth")
|
import { auth } from "@budibase/backend-core"
|
||||||
const { adminOnly } = require("@budibase/backend-core/auth")
|
import Joi from "joi"
|
||||||
const Joi = require("joi")
|
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
function buildWorkspaceSaveValidation() {
|
function buildWorkspaceSaveValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.body(Joi.object({
|
return auth.joiValidator.body(Joi.object({
|
||||||
_id: Joi.string().optional(),
|
_id: Joi.string().optional(),
|
||||||
_rev: Joi.string().optional(),
|
_rev: Joi.string().optional(),
|
||||||
name: Joi.string().required(),
|
name: Joi.string().required(),
|
||||||
|
@ -27,12 +26,12 @@ function buildWorkspaceSaveValidation() {
|
||||||
router
|
router
|
||||||
.post(
|
.post(
|
||||||
"/api/global/workspaces",
|
"/api/global/workspaces",
|
||||||
adminOnly,
|
auth.adminOnly,
|
||||||
buildWorkspaceSaveValidation(),
|
buildWorkspaceSaveValidation(),
|
||||||
controller.save
|
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", controller.fetch)
|
||||||
.get("/api/global/workspaces/:id", controller.find)
|
.get("/api/global/workspaces/:id", controller.find)
|
||||||
|
|
||||||
module.exports = router
|
export = router
|
|
@ -1,3 +1,4 @@
|
||||||
|
import Router from "@koa/router"
|
||||||
import { api } from "@budibase/pro"
|
import { api } from "@budibase/pro"
|
||||||
import userRoutes from "./global/users"
|
import userRoutes from "./global/users"
|
||||||
import configRoutes from "./global/configs"
|
import configRoutes from "./global/configs"
|
||||||
|
@ -16,7 +17,7 @@ import accountRoutes from "./system/accounts"
|
||||||
import restoreRoutes from "./system/restore"
|
import restoreRoutes from "./system/restore"
|
||||||
|
|
||||||
let userGroupRoutes = api.groups
|
let userGroupRoutes = api.groups
|
||||||
export const routes = [
|
export const routes: Router[] = [
|
||||||
configRoutes,
|
configRoutes,
|
||||||
userRoutes,
|
userRoutes,
|
||||||
workspaceRoutes,
|
workspaceRoutes,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Router from "@koa/router"
|
||||||
import * as controller from "../../controllers/system/accounts"
|
import * as controller from "../../controllers/system/accounts"
|
||||||
import { middleware } from "@budibase/backend-core"
|
import { middleware } from "@budibase/backend-core"
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
router
|
router
|
||||||
.put(
|
.put(
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import Router from "@koa/router"
|
import Router from "@koa/router"
|
||||||
import * as controller from "../../controllers/system/environment"
|
import * as controller from "../../controllers/system/environment"
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
router.get("/api/system/environment", controller.fetch)
|
router.get("/api/system/environment", controller.fetch)
|
||||||
|
|
||||||
export default router
|
export = router
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Router from "@koa/router"
|
||||||
import * as migrationsController from "../../controllers/system/migrations"
|
import * as migrationsController from "../../controllers/system/migrations"
|
||||||
import { auth } from "@budibase/backend-core"
|
import { auth } from "@budibase/backend-core"
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
router
|
router
|
||||||
.post(
|
.post(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as controller from "../../controllers/system/restore"
|
import * as controller from "../../controllers/system/restore"
|
||||||
import Router from "@koa/router"
|
import Router from "@koa/router"
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
router.post("/api/system/restored", controller.systemRestored)
|
router.post("/api/system/restored", controller.systemRestored)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import Router from "@koa/router"
|
import Router from "@koa/router"
|
||||||
import * as controller from "../../controllers/system/status"
|
import * as controller from "../../controllers/system/status"
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
router.get("/api/system/status", controller.fetch)
|
router.get("/api/system/status", controller.fetch)
|
||||||
|
|
||||||
export default router
|
export = router
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Router from "@koa/router"
|
||||||
import * as controller from "../../controllers/system/tenants"
|
import * as controller from "../../controllers/system/tenants"
|
||||||
import { middleware } from "@budibase/backend-core"
|
import { middleware } from "@budibase/backend-core"
|
||||||
|
|
||||||
const router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
router.delete(
|
router.delete(
|
||||||
"/api/system/tenants/:tenantId",
|
"/api/system/tenants/:tenantId",
|
||||||
|
@ -10,4 +10,4 @@ router.delete(
|
||||||
controller.delete
|
controller.delete
|
||||||
)
|
)
|
||||||
|
|
||||||
export default router
|
export = router
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const { joiValidator } = require("@budibase/backend-core/auth")
|
import { auth } from "@budibase/backend-core"
|
||||||
import Joi from "joi"
|
import Joi from "joi"
|
||||||
|
|
||||||
let schema: any = {
|
let schema: any = {
|
||||||
|
@ -25,7 +25,7 @@ export const buildUserSaveValidation = (isSelf = false) => {
|
||||||
_rev: Joi.string(),
|
_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) => {
|
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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
const { readStaticFile } = require("../../utilities/fileSystem")
|
import { readStaticFile } from "../../utilities/fileSystem"
|
||||||
const {
|
import {
|
||||||
EmailTemplatePurpose,
|
EmailTemplatePurpose,
|
||||||
TemplateType,
|
TemplateType,
|
||||||
TemplatePurpose,
|
TemplatePurpose,
|
||||||
GLOBAL_OWNER,
|
GLOBAL_OWNER,
|
||||||
} = require("../index")
|
} from "../index"
|
||||||
const { join } = require("path")
|
import { join } from "path"
|
||||||
const { getTemplateParams } = require("@budibase/backend-core/db")
|
import { db as dbCore, tenancy } from "@budibase/backend-core"
|
||||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
import { Template } from "@budibase/types"
|
||||||
|
|
||||||
exports.EmailTemplates = {
|
export const EmailTemplates = {
|
||||||
[EmailTemplatePurpose.PASSWORD_RECOVERY]: readStaticFile(
|
[EmailTemplatePurpose.PASSWORD_RECOVERY]: readStaticFile(
|
||||||
join(__dirname, "passwordRecovery.hbs")
|
join(__dirname, "passwordRecovery.hbs")
|
||||||
),
|
),
|
||||||
|
@ -23,7 +23,7 @@ exports.EmailTemplates = {
|
||||||
[EmailTemplatePurpose.CUSTOM]: readStaticFile(join(__dirname, "custom.hbs")),
|
[EmailTemplatePurpose.CUSTOM]: readStaticFile(join(__dirname, "custom.hbs")),
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.addBaseTemplates = (templates, type = null) => {
|
export function addBaseTemplates(templates: Template[], type?: string) {
|
||||||
let purposeList
|
let purposeList
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TemplateType.EMAIL:
|
case TemplateType.EMAIL:
|
||||||
|
@ -38,9 +38,9 @@ exports.addBaseTemplates = (templates, type = null) => {
|
||||||
if (templates.find(template => template.purpose === purpose)) {
|
if (templates.find(template => template.purpose === purpose)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (exports.EmailTemplates[purpose]) {
|
if (EmailTemplates[purpose]) {
|
||||||
templates.push({
|
templates.push({
|
||||||
contents: exports.EmailTemplates[purpose],
|
contents: EmailTemplates[purpose],
|
||||||
purpose,
|
purpose,
|
||||||
type,
|
type,
|
||||||
})
|
})
|
||||||
|
@ -49,10 +49,14 @@ exports.addBaseTemplates = (templates, type = null) => {
|
||||||
return templates
|
return templates
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getTemplates = async ({ ownerId, type, id } = {}) => {
|
export async function getTemplates({
|
||||||
const db = getGlobalDB()
|
ownerId,
|
||||||
|
type,
|
||||||
|
id,
|
||||||
|
}: { ownerId?: string; type?: string; id?: string } = {}) {
|
||||||
|
const db = tenancy.getGlobalDB()
|
||||||
const response = await db.allDocs(
|
const response = await db.allDocs(
|
||||||
getTemplateParams(ownerId || GLOBAL_OWNER, id, {
|
dbCore.getTemplateParams(ownerId || GLOBAL_OWNER, id, {
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -64,10 +68,10 @@ exports.getTemplates = async ({ ownerId, type, id } = {}) => {
|
||||||
if (type) {
|
if (type) {
|
||||||
templates = templates.filter(template => template.type === type)
|
templates = templates.filter(template => template.type === type)
|
||||||
}
|
}
|
||||||
return exports.addBaseTemplates(templates, type)
|
return addBaseTemplates(templates, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getTemplateByPurpose = async (type, purpose) => {
|
export async function getTemplateByPurpose(type: string, purpose: string) {
|
||||||
const templates = await exports.getTemplates({ type })
|
const templates = await getTemplates({ type })
|
||||||
return templates.find(template => template.purpose === purpose)
|
return templates.find((template: Template) => template.purpose === purpose)
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
// need to load environment first
|
// need to load environment first
|
||||||
const env = require("./environment")
|
import env from "./environment"
|
||||||
|
|
||||||
// enable APM if configured
|
// enable APM if configured
|
||||||
if (process.env.ELASTIC_APM_ENABLED) {
|
if (process.env.ELASTIC_APM_ENABLED) {
|
||||||
|
@ -14,19 +14,17 @@ import { Event } from "@sentry/types/dist/event"
|
||||||
import Application from "koa"
|
import Application from "koa"
|
||||||
import { bootstrap } from "global-agent"
|
import { bootstrap } from "global-agent"
|
||||||
import * as db from "./db"
|
import * as db from "./db"
|
||||||
|
import { auth, logging, events, pinoSettings } from "@budibase/backend-core"
|
||||||
db.init()
|
db.init()
|
||||||
const Koa = require("koa")
|
import Koa from "koa"
|
||||||
const destroyable = require("server-destroy")
|
import koaBody from "koa-body"
|
||||||
const koaBody = require("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 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 logger = require("koa-pino-logger")
|
||||||
const http = require("http")
|
const destroyable = require("server-destroy")
|
||||||
const api = require("./api")
|
|
||||||
const redis = require("./utilities/redis")
|
|
||||||
const Sentry = require("@sentry/node")
|
|
||||||
import { events, pinoSettings } from "@budibase/backend-core"
|
|
||||||
|
|
||||||
// this will setup http and https proxies form env variables
|
// this will setup http and https proxies form env variables
|
||||||
bootstrap()
|
bootstrap()
|
||||||
|
@ -41,8 +39,8 @@ app.use(koaSession(app))
|
||||||
app.use(logger(pinoSettings()))
|
app.use(logger(pinoSettings()))
|
||||||
|
|
||||||
// authentication
|
// authentication
|
||||||
app.use(passport.initialize())
|
app.use(auth.passport.initialize())
|
||||||
app.use(passport.session())
|
app.use(auth.passport.session())
|
||||||
|
|
||||||
// api routes
|
// api routes
|
||||||
app.use(api.routes())
|
app.use(api.routes())
|
||||||
|
@ -81,17 +79,18 @@ server.on("close", async () => {
|
||||||
|
|
||||||
const shutdown = () => {
|
const shutdown = () => {
|
||||||
server.close()
|
server.close()
|
||||||
|
// @ts-ignore
|
||||||
server.destroy()
|
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())}`)
|
console.log(`Worker running on ${JSON.stringify(server.address())}`)
|
||||||
await redis.init()
|
await redis.init()
|
||||||
})
|
})
|
||||||
|
|
||||||
process.on("uncaughtException", err => {
|
process.on("uncaughtException", err => {
|
||||||
errCode = -1
|
errCode = -1
|
||||||
logAlert("Uncaught exception.", err)
|
logging.logAlert("Uncaught exception.", err)
|
||||||
shutdown()
|
shutdown()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
const env = require("../environment")
|
import env from "../environment"
|
||||||
const { Header } = require("@budibase/backend-core/constants")
|
import { constants } from "@budibase/backend-core"
|
||||||
|
import { BBContext } from "@budibase/types"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a restricted endpoint in the cloud.
|
* This is a restricted endpoint in the cloud.
|
||||||
* Ensure that the correct API key has been supplied.
|
* 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) {
|
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) {
|
if (apiKey !== env.INTERNAL_API_KEY) {
|
||||||
ctx.throw(403, "Unauthorized")
|
ctx.throw(403, "Unauthorized")
|
||||||
}
|
}
|
|
@ -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."
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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."
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
const { readFileSync } = require("fs")
|
|
||||||
|
|
||||||
exports.readStaticFile = path => {
|
|
||||||
return readFileSync(path, "utf-8")
|
|
||||||
}
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { readFileSync } from "fs"
|
||||||
|
|
||||||
|
export function readStaticFile(path: string) {
|
||||||
|
return readFileSync(path, "utf-8")
|
||||||
|
}
|
|
@ -4,6 +4,6 @@
|
||||||
* @param {string} url The URL to test and remove any extra double slashes.
|
* @param {string} url The URL to test and remove any extra double slashes.
|
||||||
* @return {string} The updated url.
|
* @return {string} The updated url.
|
||||||
*/
|
*/
|
||||||
exports.checkSlashesInUrl = url => {
|
export function checkSlashesInUrl(url: string) {
|
||||||
return url.replace(/(https?:\/\/)|(\/)+/g, "$1$2")
|
return url.replace(/(https?:\/\/)|(\/)+/g, "$1$2")
|
||||||
}
|
}
|
|
@ -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")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue