Some major reworks towards higher levels of typescript.
This commit is contained in:
parent
c6366c573a
commit
535fab7997
|
@ -3,7 +3,7 @@ const LocalStrategy = require("passport-local").Strategy
|
||||||
const JwtStrategy = require("passport-jwt").Strategy
|
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 { Configs } from "./constants"
|
import { Config } from "./constants"
|
||||||
import { getScopedConfig } from "./db/utils"
|
import { getScopedConfig } from "./db/utils"
|
||||||
import {
|
import {
|
||||||
jwt,
|
jwt,
|
||||||
|
@ -76,7 +76,7 @@ async function refreshOIDCAccessToken(
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
refresh.requestNewAccessToken(
|
refresh.requestNewAccessToken(
|
||||||
Configs.OIDC,
|
Config.OIDC,
|
||||||
refreshToken,
|
refreshToken,
|
||||||
(err: any, accessToken: string, refreshToken: any, params: any) => {
|
(err: any, accessToken: string, refreshToken: any, params: any) => {
|
||||||
resolve({ err, accessToken, refreshToken, params })
|
resolve({ err, accessToken, refreshToken, params })
|
||||||
|
@ -106,7 +106,7 @@ async function refreshGoogleAccessToken(
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
refresh.requestNewAccessToken(
|
refresh.requestNewAccessToken(
|
||||||
Configs.GOOGLE,
|
Config.GOOGLE,
|
||||||
refreshToken,
|
refreshToken,
|
||||||
(err: any, accessToken: string, refreshToken: string, params: any) => {
|
(err: any, accessToken: string, refreshToken: string, params: any) => {
|
||||||
resolve({ err, accessToken, refreshToken, params })
|
resolve({ err, accessToken, refreshToken, params })
|
||||||
|
@ -129,7 +129,7 @@ async function refreshOAuthToken(
|
||||||
|
|
||||||
let chosenConfig = {}
|
let chosenConfig = {}
|
||||||
let refreshResponse
|
let refreshResponse
|
||||||
if (configType === Configs.OIDC) {
|
if (configType === Config.OIDC) {
|
||||||
// configId - retrieved from cookie.
|
// configId - retrieved from cookie.
|
||||||
chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0]
|
chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0]
|
||||||
if (!chosenConfig) {
|
if (!chosenConfig) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import API from "./api"
|
import API from "./api"
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import { Headers } from "../constants"
|
import { Header } from "../constants"
|
||||||
import { CloudAccount } from "@budibase/types"
|
import { CloudAccount } from "@budibase/types"
|
||||||
|
|
||||||
const api = new API(env.ACCOUNT_PORTAL_URL)
|
const api = new API(env.ACCOUNT_PORTAL_URL)
|
||||||
|
@ -14,7 +14,7 @@ export const getAccount = async (
|
||||||
const response = await api.post(`/api/accounts/search`, {
|
const response = await api.post(`/api/accounts/search`, {
|
||||||
body: payload,
|
body: payload,
|
||||||
headers: {
|
headers: {
|
||||||
[Headers.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
|
[Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ export const getAccountByTenantId = async (
|
||||||
const response = await api.post(`/api/accounts/search`, {
|
const response = await api.post(`/api/accounts/search`, {
|
||||||
body: payload,
|
body: payload,
|
||||||
headers: {
|
headers: {
|
||||||
[Headers.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
|
[Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ export const getAccountByTenantId = async (
|
||||||
export const getStatus = async () => {
|
export const getStatus = async () => {
|
||||||
const response = await api.get(`/api/status`, {
|
const response = await api.get(`/api/status`, {
|
||||||
headers: {
|
headers: {
|
||||||
[Headers.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
|
[Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
exports.UserStatus = {
|
|
||||||
ACTIVE: "active",
|
|
||||||
INACTIVE: "inactive",
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.Cookies = {
|
|
||||||
CurrentApp: "budibase:currentapp",
|
|
||||||
Auth: "budibase:auth",
|
|
||||||
Init: "budibase:init",
|
|
||||||
ACCOUNT_RETURN_URL: "budibase:account:returnurl",
|
|
||||||
DatasourceAuth: "budibase:datasourceauth",
|
|
||||||
OIDC_CONFIG: "budibase:oidc:config",
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.Headers = {
|
|
||||||
API_KEY: "x-budibase-api-key",
|
|
||||||
LICENSE_KEY: "x-budibase-license-key",
|
|
||||||
API_VER: "x-budibase-api-version",
|
|
||||||
APP_ID: "x-budibase-app-id",
|
|
||||||
TYPE: "x-budibase-type",
|
|
||||||
PREVIEW_ROLE: "x-budibase-role",
|
|
||||||
TENANT_ID: "x-budibase-tenant-id",
|
|
||||||
TOKEN: "x-budibase-token",
|
|
||||||
CSRF_TOKEN: "x-csrf-token",
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.GlobalRoles = {
|
|
||||||
OWNER: "owner",
|
|
||||||
ADMIN: "admin",
|
|
||||||
BUILDER: "builder",
|
|
||||||
WORKSPACE_MANAGER: "workspace_manager",
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.Configs = {
|
|
||||||
SETTINGS: "settings",
|
|
||||||
ACCOUNT: "account",
|
|
||||||
SMTP: "smtp",
|
|
||||||
GOOGLE: "google",
|
|
||||||
OIDC: "oidc",
|
|
||||||
OIDC_LOGOS: "logos_oidc",
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.MAX_VALID_DATE = new Date(2147483647000)
|
|
||||||
exports.DEFAULT_TENANT_ID = "default"
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
export enum UserStatus {
|
||||||
|
ACTIVE = "active",
|
||||||
|
INACTIVE = "inactive",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Cookie {
|
||||||
|
CurrentApp = "budibase:currentapp",
|
||||||
|
Auth = "budibase:auth",
|
||||||
|
Init = "budibase:init",
|
||||||
|
ACCOUNT_RETURN_URL = "budibase:account:returnurl",
|
||||||
|
DatasourceAuth = "budibase:datasourceauth",
|
||||||
|
OIDC_CONFIG = "budibase:oidc:config",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Header {
|
||||||
|
API_KEY = "x-budibase-api-key",
|
||||||
|
LICENSE_KEY = "x-budibase-license-key",
|
||||||
|
API_VER = "x-budibase-api-version",
|
||||||
|
APP_ID = "x-budibase-app-id",
|
||||||
|
TYPE = "x-budibase-type",
|
||||||
|
PREVIEW_ROLE = "x-budibase-role",
|
||||||
|
TENANT_ID = "x-budibase-tenant-id",
|
||||||
|
TOKEN = "x-budibase-token",
|
||||||
|
CSRF_TOKEN = "x-csrf-token",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum GlobalRole {
|
||||||
|
OWNER = "owner",
|
||||||
|
ADMIN = "admin",
|
||||||
|
BUILDER = "builder",
|
||||||
|
WORKSPACE_MANAGER = "workspace_manager",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Config {
|
||||||
|
SETTINGS = "settings",
|
||||||
|
ACCOUNT = "account",
|
||||||
|
SMTP = "smtp",
|
||||||
|
GOOGLE = "google",
|
||||||
|
OIDC = "oidc",
|
||||||
|
OIDC_LOGOS = "logos_oidc",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MAX_VALID_DATE = new Date(2147483647000)
|
||||||
|
export const DEFAULT_TENANT_ID = "default"
|
|
@ -105,11 +105,12 @@ export async function doInAppContext(appId: string, task: any): Promise<any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const tenantId = getTenantIDFromAppID(appId)
|
const tenantId = getTenantIDFromAppID(appId)
|
||||||
|
const updates: ContextMap = { appId }
|
||||||
|
if (tenantId) {
|
||||||
|
updates.tenantId = tenantId
|
||||||
|
}
|
||||||
return newContext(
|
return newContext(
|
||||||
{
|
updates,
|
||||||
tenantId,
|
|
||||||
appId,
|
|
||||||
},
|
|
||||||
task
|
task
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
require("../../../tests/utilities/TestConfiguration")
|
require("../../../tests")
|
||||||
const context = require("../")
|
const context = require("../")
|
||||||
const { DEFAULT_TENANT_ID } = require("../../constants")
|
const { DEFAULT_TENANT_ID } = require("../../constants")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const dbCore = require("../../db")
|
|
||||||
|
|
||||||
describe("context", () => {
|
describe("context", () => {
|
||||||
describe("doInTenant", () => {
|
describe("doInTenant", () => {
|
||||||
|
|
|
@ -9,7 +9,7 @@ const {
|
||||||
getScopedConfig
|
getScopedConfig
|
||||||
} = require("../utils")
|
} = require("../utils")
|
||||||
const tenancy = require("../../tenancy")
|
const tenancy = require("../../tenancy")
|
||||||
const { Configs, DEFAULT_TENANT_ID } = require("../../constants")
|
const { Config, DEFAULT_TENANT_ID } = require("../../constants")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
|
|
||||||
describe("utils", () => {
|
describe("utils", () => {
|
||||||
|
@ -77,7 +77,7 @@ const setDbPlatformUrl = async () => {
|
||||||
const db = tenancy.getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
db.put({
|
db.put({
|
||||||
_id: "config_settings",
|
_id: "config_settings",
|
||||||
type: Configs.SETTINGS,
|
type: Config.SETTINGS,
|
||||||
config: {
|
config: {
|
||||||
platformUrl: DB_URL
|
platformUrl: DB_URL
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ describe("getScopedConfig", () => {
|
||||||
await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
|
await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
|
||||||
await setDbPlatformUrl()
|
await setDbPlatformUrl()
|
||||||
const db = tenancy.getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const config = await getScopedConfig(db, { type: Configs.SETTINGS })
|
const config = await getScopedConfig(db, { type: Config.SETTINGS })
|
||||||
expect(config.platformUrl).toBe(DB_URL)
|
expect(config.platformUrl).toBe(DB_URL)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -186,7 +186,7 @@ describe("getScopedConfig", () => {
|
||||||
it("returns the platform url without an existing config", async () => {
|
it("returns the platform url without an existing config", async () => {
|
||||||
await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
|
await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
|
||||||
const db = tenancy.getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
const config = await getScopedConfig(db, { type: Configs.SETTINGS })
|
const config = await getScopedConfig(db, { type: Config.SETTINGS })
|
||||||
expect(config.platformUrl).toBe(DEFAULT_URL)
|
expect(config.platformUrl).toBe(DEFAULT_URL)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { newid } from "../hashing"
|
import { newid } from "../hashing"
|
||||||
import { DEFAULT_TENANT_ID, Configs } from "../constants"
|
import { DEFAULT_TENANT_ID, Config } from "../constants"
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import {
|
import {
|
||||||
SEPARATOR,
|
SEPARATOR,
|
||||||
|
@ -491,7 +491,7 @@ export const getScopedFullConfig = async function (
|
||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
// custom logic for settings doc
|
// custom logic for settings doc
|
||||||
if (type === Configs.SETTINGS) {
|
if (type === Config.SETTINGS) {
|
||||||
if (scopedConfig && scopedConfig.doc) {
|
if (scopedConfig && scopedConfig.doc) {
|
||||||
// overrides affected by environment variables
|
// overrides affected by environment variables
|
||||||
scopedConfig.doc.config.platformUrl = await getPlatformUrl({
|
scopedConfig.doc.config.platformUrl = await getPlatformUrl({
|
||||||
|
@ -530,7 +530,7 @@ export const getPlatformUrl = async (opts = { tenantAware: true }) => {
|
||||||
// get the doc directly instead of with getScopedConfig to prevent loop
|
// get the doc directly instead of with getScopedConfig to prevent loop
|
||||||
let settings
|
let settings
|
||||||
try {
|
try {
|
||||||
settings = await db.get(generateConfigID({ type: Configs.SETTINGS }))
|
settings = await db.get(generateConfigID({ type: Config.SETTINGS }))
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (e.status !== 404) {
|
if (e.status !== 404) {
|
||||||
throw e
|
throw e
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import tenancy from "../tenancy"
|
import tenancy from "../tenancy"
|
||||||
import * as dbUtils from "../db/utils"
|
import * as dbUtils from "../db/utils"
|
||||||
import { Configs } from "../constants"
|
import { Config } from "../constants"
|
||||||
import { withCache, TTL, CacheKeys } from "../cache/generic"
|
import { withCache, TTL, CacheKeys } from "../cache/generic"
|
||||||
|
|
||||||
export const enabled = async () => {
|
export const enabled = async () => {
|
||||||
|
@ -46,7 +46,7 @@ const getSettingsDoc = async () => {
|
||||||
let settings
|
let settings
|
||||||
try {
|
try {
|
||||||
settings = await db.get(
|
settings = await db.get(
|
||||||
dbUtils.generateConfigID({ type: Configs.SETTINGS })
|
dbUtils.generateConfigID({ type: Config.SETTINGS })
|
||||||
)
|
)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (e.status !== 404) {
|
if (e.status !== 404) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ import {
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { processors } from "./processors"
|
import { processors } from "./processors"
|
||||||
import * as dbUtils from "../db/utils"
|
import * as dbUtils from "../db/utils"
|
||||||
import { Configs } from "../constants"
|
import { Config } from "../constants"
|
||||||
import * as hashing from "../hashing"
|
import * as hashing from "../hashing"
|
||||||
import * as installation from "../installation"
|
import * as installation from "../installation"
|
||||||
import { withCache, TTL, CacheKeys } from "../cache/generic"
|
import { withCache, TTL, CacheKeys } from "../cache/generic"
|
||||||
|
@ -273,7 +273,7 @@ const getUniqueTenantId = async (tenantId: string): Promise<string> => {
|
||||||
return withCache(CacheKeys.UNIQUE_TENANT_ID, TTL.ONE_DAY, async () => {
|
return withCache(CacheKeys.UNIQUE_TENANT_ID, TTL.ONE_DAY, async () => {
|
||||||
const db = context.getGlobalDB()
|
const db = context.getGlobalDB()
|
||||||
const config: SettingsConfig = await dbUtils.getScopedFullConfig(db, {
|
const config: SettingsConfig = await dbUtils.getScopedFullConfig(db, {
|
||||||
type: Configs.SETTINGS,
|
type: Config.SETTINGS,
|
||||||
})
|
})
|
||||||
|
|
||||||
let uniqueTenantId: string
|
let uniqueTenantId: string
|
||||||
|
|
|
@ -13,7 +13,7 @@ import featureFlags from "./featureFlags"
|
||||||
import * as sessions from "./security/sessions"
|
import * as sessions from "./security/sessions"
|
||||||
import * as deprovisioning from "./context/deprovision"
|
import * as deprovisioning from "./context/deprovision"
|
||||||
import auth from "./auth"
|
import auth from "./auth"
|
||||||
import constants from "./constants"
|
import * as constants from "./constants"
|
||||||
import * as dbConstants from "./db/constants"
|
import * as dbConstants from "./db/constants"
|
||||||
import * as logging from "./logging"
|
import * as logging from "./logging"
|
||||||
import pino from "./pino"
|
import pino from "./pino"
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import { Cookies, Headers } from "../constants"
|
import { Cookie, Header } from "../constants"
|
||||||
import { getCookie, clearCookie, openJwt } from "../utils"
|
import { getCookie, clearCookie, openJwt } from "../utils"
|
||||||
import { getUser } from "../cache/user"
|
import { getUser } from "../cache/user"
|
||||||
import { getSession, updateSessionTTL } from "../security/sessions"
|
import { getSession, updateSessionTTL } from "../security/sessions"
|
||||||
import { buildMatcherRegex, matches } from "./matchers"
|
import { buildMatcherRegex, matches } from "./matchers"
|
||||||
import { SEPARATOR } from "../db/constants"
|
import { SEPARATOR, queryGlobalView, ViewName } from "../db"
|
||||||
import { ViewName } from "../db/utils"
|
|
||||||
import { queryGlobalView } from "../db/views"
|
|
||||||
import { getGlobalDB, doInTenant } from "../tenancy"
|
import { getGlobalDB, doInTenant } from "../tenancy"
|
||||||
import { decrypt } from "../security/encryption"
|
import { decrypt } from "../security/encryption"
|
||||||
const identity = require("../context/identity")
|
const identity = require("../context/identity")
|
||||||
|
@ -74,7 +72,7 @@ export = (
|
||||||
const noAuthOptions = noAuthPatterns ? buildMatcherRegex(noAuthPatterns) : []
|
const noAuthOptions = noAuthPatterns ? buildMatcherRegex(noAuthPatterns) : []
|
||||||
return async (ctx: any, next: any) => {
|
return async (ctx: any, next: any) => {
|
||||||
let publicEndpoint = false
|
let publicEndpoint = false
|
||||||
const version = ctx.request.headers[Headers.API_VER]
|
const version = ctx.request.headers[Header.API_VER]
|
||||||
// the path is not authenticated
|
// the path is not authenticated
|
||||||
const found = matches(ctx, noAuthOptions)
|
const found = matches(ctx, noAuthOptions)
|
||||||
if (found) {
|
if (found) {
|
||||||
|
@ -82,10 +80,10 @@ export = (
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// check the actual user is authenticated first, try header or cookie
|
// check the actual user is authenticated first, try header or cookie
|
||||||
const headerToken = ctx.request.headers[Headers.TOKEN]
|
const headerToken = ctx.request.headers[Header.TOKEN]
|
||||||
const authCookie = getCookie(ctx, Cookies.Auth) || openJwt(headerToken)
|
const authCookie = getCookie(ctx, Cookie.Auth) || openJwt(headerToken)
|
||||||
const apiKey = ctx.request.headers[Headers.API_KEY]
|
const apiKey = ctx.request.headers[Header.API_KEY]
|
||||||
const tenantId = ctx.request.headers[Headers.TENANT_ID]
|
const tenantId = ctx.request.headers[Header.TENANT_ID]
|
||||||
let authenticated = false,
|
let authenticated = false,
|
||||||
user = null,
|
user = null,
|
||||||
internal = false
|
internal = false
|
||||||
|
@ -116,7 +114,7 @@ export = (
|
||||||
authenticated = false
|
authenticated = false
|
||||||
console.error("Auth Error", err?.message || err)
|
console.error("Auth Error", err?.message || err)
|
||||||
// remove the cookie as the user does not exist anymore
|
// remove the cookie as the user does not exist anymore
|
||||||
clearCookie(ctx, Cookies.Auth)
|
clearCookie(ctx, Cookie.Auth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this is an internal request, no user made it
|
// this is an internal request, no user made it
|
||||||
|
@ -140,7 +138,7 @@ export = (
|
||||||
delete user.password
|
delete user.password
|
||||||
}
|
}
|
||||||
// be explicit
|
// be explicit
|
||||||
if (authenticated !== true) {
|
if (!authenticated) {
|
||||||
authenticated = false
|
authenticated = false
|
||||||
}
|
}
|
||||||
// isAuthenticated is a function, so use a variable to be able to check authed state
|
// isAuthenticated is a function, so use a variable to be able to check authed state
|
||||||
|
@ -155,7 +153,7 @@ export = (
|
||||||
console.error("Auth Error", err?.message || err)
|
console.error("Auth Error", err?.message || err)
|
||||||
// invalid token, clear the cookie
|
// invalid token, clear the cookie
|
||||||
if (err && err.name === "JsonWebTokenError") {
|
if (err && err.name === "JsonWebTokenError") {
|
||||||
clearCookie(ctx, Cookies.Auth)
|
clearCookie(ctx, Cookie.Auth)
|
||||||
}
|
}
|
||||||
// allow configuring for public access
|
// allow configuring for public access
|
||||||
if ((opts && opts.publicAllowed) || publicEndpoint) {
|
if ((opts && opts.publicAllowed) || publicEndpoint) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const { Headers } = require("../constants")
|
const { Header } = require("../constants")
|
||||||
const { buildMatcherRegex, matches } = require("./matchers")
|
const { buildMatcherRegex, matches } = require("./matchers")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,7 +68,7 @@ module.exports = (opts = { noCsrfPatterns: [] }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// reject if no token in request or mismatch
|
// reject if no token in request or mismatch
|
||||||
const requestToken = ctx.get(Headers.CSRF_TOKEN)
|
const requestToken = ctx.get(Header.CSRF_TOKEN)
|
||||||
if (!requestToken || requestToken !== userToken) {
|
if (!requestToken || requestToken !== userToken) {
|
||||||
ctx.throw(403, "Invalid CSRF token")
|
ctx.throw(403, "Invalid CSRF token")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
const { Headers } = require("../constants")
|
const { Header } = require("../constants")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API Key only endpoint.
|
* API Key only endpoint.
|
||||||
*/
|
*/
|
||||||
module.exports = async (ctx, next) => {
|
module.exports = async (ctx, next) => {
|
||||||
const apiKey = ctx.request.headers[Headers.API_KEY]
|
const apiKey = ctx.request.headers[Header.API_KEY]
|
||||||
if (apiKey !== env.INTERNAL_API_KEY) {
|
if (apiKey !== env.INTERNAL_API_KEY) {
|
||||||
ctx.throw(403, "Unauthorized")
|
ctx.throw(403, "Unauthorized")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const google = require("../google")
|
const google = require("../google")
|
||||||
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy
|
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy
|
||||||
const { Cookies, Configs } = require("../../../constants")
|
const { Cookie, Config } = require("../../../constants")
|
||||||
const { clearCookie, getCookie } = require("../../../utils")
|
const { clearCookie, getCookie } = require("../../../utils")
|
||||||
const { getScopedConfig, getPlatformUrl } = require("../../../db/utils")
|
const { getScopedConfig, getPlatformUrl } = require("../../../db/utils")
|
||||||
const { doWithDB } = require("../../../db")
|
const { doWithDB } = require("../../../db")
|
||||||
|
@ -11,7 +11,7 @@ async function fetchGoogleCreds() {
|
||||||
// try and get the config from the tenant
|
// try and get the config from the tenant
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
const googleConfig = await getScopedConfig(db, {
|
const googleConfig = await getScopedConfig(db, {
|
||||||
type: Configs.GOOGLE,
|
type: Config.GOOGLE,
|
||||||
})
|
})
|
||||||
// or fall back to env variables
|
// or fall back to env variables
|
||||||
return (
|
return (
|
||||||
|
@ -47,7 +47,7 @@ async function postAuth(passport, ctx, next) {
|
||||||
const platformUrl = await getPlatformUrl({ tenantAware: false })
|
const platformUrl = await getPlatformUrl({ tenantAware: false })
|
||||||
|
|
||||||
let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback`
|
let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback`
|
||||||
const authStateCookie = getCookie(ctx, Cookies.DatasourceAuth)
|
const authStateCookie = getCookie(ctx, Cookie.DatasourceAuth)
|
||||||
|
|
||||||
return passport.authenticate(
|
return passport.authenticate(
|
||||||
new GoogleStrategy(
|
new GoogleStrategy(
|
||||||
|
@ -57,7 +57,7 @@ async function postAuth(passport, ctx, next) {
|
||||||
callbackURL: callbackUrl,
|
callbackURL: callbackUrl,
|
||||||
},
|
},
|
||||||
(accessToken, refreshToken, profile, done) => {
|
(accessToken, refreshToken, profile, done) => {
|
||||||
clearCookie(ctx, Cookies.DatasourceAuth)
|
clearCookie(ctx, Cookie.DatasourceAuth)
|
||||||
done(null, { accessToken, refreshToken })
|
done(null, { accessToken, refreshToken })
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy
|
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy
|
||||||
const { ssoCallbackUrl } = require("./utils")
|
const { ssoCallbackUrl } = require("./utils")
|
||||||
const { authenticateThirdParty } = require("./third-party-common")
|
const { authenticateThirdParty } = require("./third-party-common")
|
||||||
const { Configs } = require("../../../constants")
|
const { Config } = require("../../../constants")
|
||||||
|
|
||||||
const buildVerifyFn = saveUserFn => {
|
const buildVerifyFn = saveUserFn => {
|
||||||
return (accessToken, refreshToken, profile, done) => {
|
return (accessToken, refreshToken, profile, done) => {
|
||||||
|
@ -60,7 +60,7 @@ exports.strategyFactory = async function (config, callbackUrl, saveUserFn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getCallbackUrl = async function (db, config) {
|
exports.getCallbackUrl = async function (db, config) {
|
||||||
return ssoCallbackUrl(db, config, Configs.GOOGLE)
|
return ssoCallbackUrl(db, config, Config.GOOGLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// expose for testing
|
// expose for testing
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
const { Cookies } = require("../../constants")
|
const { Cookie } = require("../../constants")
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const { authError } = require("./utils")
|
const { authError } = require("./utils")
|
||||||
|
|
||||||
exports.options = {
|
exports.options = {
|
||||||
secretOrKey: env.JWT_SECRET,
|
secretOrKey: env.JWT_SECRET,
|
||||||
jwtFromRequest: function (ctx) {
|
jwtFromRequest: function (ctx) {
|
||||||
return ctx.cookies.get(Cookies.Auth)
|
return ctx.cookies.get(Cookie.Auth)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ const fetch = require("node-fetch")
|
||||||
const OIDCStrategy = require("@techpass/passport-openidconnect").Strategy
|
const OIDCStrategy = require("@techpass/passport-openidconnect").Strategy
|
||||||
const { authenticateThirdParty } = require("./third-party-common")
|
const { authenticateThirdParty } = require("./third-party-common")
|
||||||
const { ssoCallbackUrl } = require("./utils")
|
const { ssoCallbackUrl } = require("./utils")
|
||||||
const { Configs } = require("../../../constants")
|
const { Config } = require("../../../constants")
|
||||||
|
|
||||||
const buildVerifyFn = saveUserFn => {
|
const buildVerifyFn = saveUserFn => {
|
||||||
/**
|
/**
|
||||||
|
@ -140,7 +140,7 @@ exports.fetchStrategyConfig = async function (enrichedConfig, callbackUrl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getCallbackUrl = async function (db, config) {
|
exports.getCallbackUrl = async function (db, config) {
|
||||||
return ssoCallbackUrl(db, config, Configs.OIDC)
|
return ssoCallbackUrl(db, config, Config.OIDC)
|
||||||
}
|
}
|
||||||
|
|
||||||
// expose for testing
|
// expose for testing
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const { isMultiTenant, getTenantId } = require("../../tenancy")
|
const { isMultiTenant, getTenantId } = require("../../tenancy")
|
||||||
const { getScopedConfig } = require("../../db/utils")
|
const { getScopedConfig } = require("../../db/utils")
|
||||||
const { Configs } = require("../../constants")
|
const { Config } = require("../../constants")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility to handle authentication errors.
|
* Utility to handle authentication errors.
|
||||||
|
@ -24,7 +24,7 @@ exports.ssoCallbackUrl = async (db, config, type) => {
|
||||||
return config.callbackURL
|
return config.callbackURL
|
||||||
}
|
}
|
||||||
const publicConfig = await getScopedConfig(db, {
|
const publicConfig = await getScopedConfig(db, {
|
||||||
type: Configs.SETTINGS,
|
type: Config.SETTINGS,
|
||||||
})
|
})
|
||||||
|
|
||||||
let callbackUrl = `/api/global/auth`
|
let callbackUrl = `/api/global/auth`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const { doInTenant, isMultiTenant, DEFAULT_TENANT_ID } = require("../tenancy")
|
const { doInTenant, isMultiTenant, DEFAULT_TENANT_ID } = require("../tenancy")
|
||||||
const { buildMatcherRegex, matches } = require("./matchers")
|
const { buildMatcherRegex, matches } = require("./matchers")
|
||||||
const { Headers } = require("../constants")
|
const { Header } = require("../constants")
|
||||||
|
|
||||||
const getTenantID = (ctx, opts = { allowQs: false, allowNoTenant: false }) => {
|
const getTenantID = (ctx, opts = { allowQs: false, allowNoTenant: false }) => {
|
||||||
// exit early if not multi-tenant
|
// exit early if not multi-tenant
|
||||||
|
@ -11,7 +11,7 @@ const getTenantID = (ctx, opts = { allowQs: false, allowNoTenant: false }) => {
|
||||||
let tenantId
|
let tenantId
|
||||||
const allowQs = opts && opts.allowQs
|
const allowQs = opts && opts.allowQs
|
||||||
const allowNoTenant = opts && opts.allowNoTenant
|
const allowNoTenant = opts && opts.allowNoTenant
|
||||||
const header = ctx.request.headers[Headers.TENANT_ID]
|
const header = ctx.request.headers[Header.TENANT_ID]
|
||||||
const user = ctx.user || {}
|
const user = ctx.user || {}
|
||||||
if (allowQs) {
|
if (allowQs) {
|
||||||
const query = ctx.request.query || {}
|
const query = ctx.request.query || {}
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
import * as generic from "../cache/generic"
|
import * as generic from "../cache/generic"
|
||||||
import * as user from "../cache/user"
|
import * as user from "../cache/user"
|
||||||
import * as app from "../cache/appMetadata"
|
import * as app from "../cache/appMetadata"
|
||||||
|
import * as writethrough from "../cache/writethrough"
|
||||||
|
|
||||||
export = {
|
export = {
|
||||||
app,
|
app,
|
||||||
user,
|
user,
|
||||||
|
writethrough,
|
||||||
...generic,
|
...generic,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ const { DocumentType, SEPARATOR, ViewName, getAllApps } = require("./db/utils")
|
||||||
const jwt = require("jsonwebtoken")
|
const jwt = require("jsonwebtoken")
|
||||||
const { options } = require("./middleware/passport/jwt")
|
const { options } = require("./middleware/passport/jwt")
|
||||||
const { queryGlobalView } = require("./db/views")
|
const { queryGlobalView } = require("./db/views")
|
||||||
const { Headers, Cookies, MAX_VALID_DATE } = require("./constants")
|
const { Header, Cookie, MAX_VALID_DATE } = require("./constants")
|
||||||
const env = require("./environment")
|
const env = require("./environment")
|
||||||
const userCache = require("./cache/user")
|
const userCache = require("./cache/user")
|
||||||
const {
|
const {
|
||||||
|
@ -61,7 +61,7 @@ exports.isServingApp = ctx => {
|
||||||
*/
|
*/
|
||||||
exports.getAppIdFromCtx = async ctx => {
|
exports.getAppIdFromCtx = async ctx => {
|
||||||
// look in headers
|
// look in headers
|
||||||
const options = [ctx.headers[Headers.APP_ID]]
|
const options = [ctx.headers[Header.APP_ID]]
|
||||||
let appId
|
let appId
|
||||||
for (let option of options) {
|
for (let option of options) {
|
||||||
appId = confirmAppId(option)
|
appId = confirmAppId(option)
|
||||||
|
@ -157,7 +157,7 @@ exports.clearCookie = (ctx, name) => {
|
||||||
* @return {boolean} returns true if the call is from the client lib (a built app rather than the builder).
|
* @return {boolean} returns true if the call is from the client lib (a built app rather than the builder).
|
||||||
*/
|
*/
|
||||||
exports.isClient = ctx => {
|
exports.isClient = ctx => {
|
||||||
return ctx.headers[Headers.TYPE] === "client"
|
return ctx.headers[Header.TYPE] === "client"
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBuilders = async () => {
|
const getBuilders = async () => {
|
||||||
|
@ -187,7 +187,7 @@ exports.getBuildersCount = async () => {
|
||||||
exports.platformLogout = async ({ ctx, userId, keepActiveSession }) => {
|
exports.platformLogout = async ({ ctx, userId, keepActiveSession }) => {
|
||||||
if (!ctx) throw new Error("Koa context must be supplied to logout.")
|
if (!ctx) throw new Error("Koa context must be supplied to logout.")
|
||||||
|
|
||||||
const currentSession = exports.getCookie(ctx, Cookies.Auth)
|
const currentSession = exports.getCookie(ctx, Cookie.Auth)
|
||||||
let sessions = await getSessionsForUser(userId)
|
let sessions = await getSessionsForUser(userId)
|
||||||
|
|
||||||
if (keepActiveSession) {
|
if (keepActiveSession) {
|
||||||
|
@ -196,8 +196,8 @@ exports.platformLogout = async ({ ctx, userId, keepActiveSession }) => {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// clear cookies
|
// clear cookies
|
||||||
exports.clearCookie(ctx, Cookies.Auth)
|
exports.clearCookie(ctx, Cookie.Auth)
|
||||||
exports.clearCookie(ctx, Cookies.CurrentApp)
|
exports.clearCookie(ctx, Cookie.CurrentApp)
|
||||||
}
|
}
|
||||||
|
|
||||||
const sessionIds = sessions.map(({ sessionId }) => sessionId)
|
const sessionIds = sessions.map(({ sessionId }) => sessionId)
|
||||||
|
|
|
@ -112,13 +112,13 @@ export async function find(ctx: any) {
|
||||||
|
|
||||||
//Required to discern between OIDC OAuth config entries
|
//Required to discern between OIDC OAuth config entries
|
||||||
function getOAuthConfigCookieId(ctx: any) {
|
function getOAuthConfigCookieId(ctx: any) {
|
||||||
if (ctx.user.providerType === constants.Configs.OIDC) {
|
if (ctx.user.providerType === constants.Config.OIDC) {
|
||||||
return utils.getCookie(ctx, constants.Cookies.OIDC_CONFIG)
|
return utils.getCookie(ctx, constants.Cookie.OIDC_CONFIG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAuthConfig(ctx: any) {
|
function getAuthConfig(ctx: any) {
|
||||||
const authCookie = utils.getCookie(ctx, constants.Cookies.Auth)
|
const authCookie = utils.getCookie(ctx, constants.Cookie.Auth)
|
||||||
let authConfigCtx: any = {}
|
let authConfigCtx: any = {}
|
||||||
authConfigCtx["configId"] = getOAuthConfigCookieId(ctx)
|
authConfigCtx["configId"] = getOAuthConfigCookieId(ctx)
|
||||||
authConfigCtx["sessionId"] = authCookie ? authCookie.sessionId : null
|
authConfigCtx["sessionId"] = authCookie ? authCookie.sessionId : null
|
||||||
|
|
|
@ -43,7 +43,7 @@ describe("/static", () => {
|
||||||
|
|
||||||
it("should ping from app", async () => {
|
it("should ping from app", async () => {
|
||||||
const headers = config.defaultHeaders()
|
const headers = config.defaultHeaders()
|
||||||
headers[constants.Headers.APP_ID] = config.prodAppId
|
headers[constants.Header.APP_ID] = config.prodAppId
|
||||||
|
|
||||||
await request
|
await request
|
||||||
.post("/api/bbtel/ping")
|
.post("/api/bbtel/ping")
|
||||||
|
|
|
@ -46,7 +46,7 @@ describe("/static", () => {
|
||||||
|
|
||||||
it("should serve the app by id", async () => {
|
it("should serve the app by id", async () => {
|
||||||
const headers = config.defaultHeaders()
|
const headers = config.defaultHeaders()
|
||||||
delete headers[constants.Headers.APP_ID]
|
delete headers[constants.Header.APP_ID]
|
||||||
|
|
||||||
const res = await request
|
const res = await request
|
||||||
.get(`/${config.prodAppId}`)
|
.get(`/${config.prodAppId}`)
|
||||||
|
@ -58,7 +58,7 @@ describe("/static", () => {
|
||||||
|
|
||||||
it("should serve the app by url", async () => {
|
it("should serve the app by url", async () => {
|
||||||
const headers = config.defaultHeaders()
|
const headers = config.defaultHeaders()
|
||||||
delete headers[constants.Headers.APP_ID]
|
delete headers[constants.Header.APP_ID]
|
||||||
|
|
||||||
const res = await request
|
const res = await request
|
||||||
.get(`/app${config.prodApp.url}`)
|
.get(`/app${config.prodApp.url}`)
|
||||||
|
|
|
@ -12,10 +12,7 @@ import { buildExternalTableId } from "./utils"
|
||||||
import { DataSourceOperation, FieldTypes } from "../constants"
|
import { DataSourceOperation, FieldTypes } from "../constants"
|
||||||
import { GoogleSpreadsheet } from "google-spreadsheet"
|
import { GoogleSpreadsheet } from "google-spreadsheet"
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
|
import { tenancy, db as dbCore, constants } from "@budibase/backend-core"
|
||||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
|
||||||
const { getScopedConfig } = require("@budibase/backend-core/db")
|
|
||||||
const { Configs } = require("@budibase/backend-core/constants")
|
|
||||||
const fetch = require("node-fetch")
|
const fetch = require("node-fetch")
|
||||||
|
|
||||||
interface GoogleSheetsConfig {
|
interface GoogleSheetsConfig {
|
||||||
|
@ -176,9 +173,9 @@ class GoogleSheetsIntegration implements DatasourcePlus {
|
||||||
async connect() {
|
async connect() {
|
||||||
try {
|
try {
|
||||||
// Initialise oAuth client
|
// Initialise oAuth client
|
||||||
const db = getGlobalDB()
|
const db = tenancy.getGlobalDB()
|
||||||
let googleConfig = await getScopedConfig(db, {
|
let googleConfig = await dbCore.getScopedConfig(db, {
|
||||||
type: Configs.GOOGLE,
|
type: constants.Config.GOOGLE,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!googleConfig) {
|
if (!googleConfig) {
|
||||||
|
|
|
@ -18,9 +18,9 @@ export = async (ctx: BBContext, next: any) => {
|
||||||
// get app cookie if it exists
|
// get app cookie if it exists
|
||||||
let appCookie: { appId?: string } | undefined
|
let appCookie: { appId?: string } | undefined
|
||||||
try {
|
try {
|
||||||
appCookie = utils.getCookie(ctx, constants.Cookies.CurrentApp)
|
appCookie = utils.getCookie(ctx, constants.Cookie.CurrentApp)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
utils.clearCookie(ctx, constants.Cookies.CurrentApp)
|
utils.clearCookie(ctx, constants.Cookie.CurrentApp)
|
||||||
}
|
}
|
||||||
if (!appCookie && !requestAppId) {
|
if (!appCookie && !requestAppId) {
|
||||||
return next()
|
return next()
|
||||||
|
@ -30,7 +30,7 @@ export = async (ctx: BBContext, next: any) => {
|
||||||
const appId = appCookie.appId
|
const appId = appCookie.appId
|
||||||
const exists = await dbCore.dbExists(appId)
|
const exists = await dbCore.dbExists(appId)
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
utils.clearCookie(ctx, constants.Cookies.CurrentApp)
|
utils.clearCookie(ctx, constants.Cookie.CurrentApp)
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
// if the request app ID wasn't set, update it with the cookie
|
// if the request app ID wasn't set, update it with the cookie
|
||||||
|
@ -44,7 +44,7 @@ export = async (ctx: BBContext, next: any) => {
|
||||||
!isWebhookEndpoint(ctx) &&
|
!isWebhookEndpoint(ctx) &&
|
||||||
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
||||||
) {
|
) {
|
||||||
utils.clearCookie(ctx, constants.Cookies.CurrentApp)
|
utils.clearCookie(ctx, constants.Cookie.CurrentApp)
|
||||||
return ctx.redirect("/")
|
return ctx.redirect("/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ export = async (ctx: BBContext, next: any) => {
|
||||||
const isDevApp = appId && isDevAppID(appId)
|
const isDevApp = appId && isDevAppID(appId)
|
||||||
const roleHeader =
|
const roleHeader =
|
||||||
ctx.request &&
|
ctx.request &&
|
||||||
(ctx.request.headers[constants.Headers.PREVIEW_ROLE] as string)
|
(ctx.request.headers[constants.Header.PREVIEW_ROLE] as string)
|
||||||
if (isBuilder && isDevApp && roleHeader) {
|
if (isBuilder && isDevApp && roleHeader) {
|
||||||
// Ensure the role is valid by ensuring a definition exists
|
// Ensure the role is valid by ensuring a definition exists
|
||||||
try {
|
try {
|
||||||
|
@ -132,7 +132,7 @@ export = async (ctx: BBContext, next: any) => {
|
||||||
appCookie.appId !== requestAppId) &&
|
appCookie.appId !== requestAppId) &&
|
||||||
!skipCookie
|
!skipCookie
|
||||||
) {
|
) {
|
||||||
utils.setCookie(ctx, { appId }, constants.Cookies.CurrentApp)
|
utils.setCookie(ctx, { appId }, constants.Cookie.CurrentApp)
|
||||||
}
|
}
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const { Headers } = require("@budibase/backend-core/constants")
|
const { Header } = require("@budibase/backend-core/constants")
|
||||||
const { getAppIdFromCtx } = require("@budibase/backend-core/utils")
|
const { getAppIdFromCtx } = require("@budibase/backend-core/utils")
|
||||||
|
|
||||||
module.exports = function ({ requiresAppId } = {}) {
|
module.exports = function ({ requiresAppId } = {}) {
|
||||||
|
@ -7,13 +7,13 @@ module.exports = function ({ requiresAppId } = {}) {
|
||||||
if (requiresAppId && !appId) {
|
if (requiresAppId && !appId) {
|
||||||
ctx.throw(
|
ctx.throw(
|
||||||
400,
|
400,
|
||||||
`Invalid app ID provided, please check the ${Headers.APP_ID} header.`
|
`Invalid app ID provided, please check the ${Header.APP_ID} header.`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (!ctx.headers[Headers.API_KEY]) {
|
if (!ctx.headers[Header.API_KEY]) {
|
||||||
ctx.throw(
|
ctx.throw(
|
||||||
400,
|
400,
|
||||||
`Invalid API key provided, please check the ${Headers.API_KEY} header.`
|
`Invalid API key provided, please check the ${Header.API_KEY} header.`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return next()
|
return next()
|
|
@ -16,7 +16,7 @@ const {
|
||||||
const controllers = require("./controllers")
|
const controllers = require("./controllers")
|
||||||
const supertest = require("supertest")
|
const supertest = require("supertest")
|
||||||
const { cleanup } = require("../../utilities/fileSystem")
|
const { cleanup } = require("../../utilities/fileSystem")
|
||||||
const { Cookies, Headers } = require("@budibase/backend-core/constants")
|
const { Cookie, Headers } = require("@budibase/backend-core/constants")
|
||||||
const { jwt } = require("@budibase/backend-core/auth")
|
const { jwt } = require("@budibase/backend-core/auth")
|
||||||
const { doInTenant, doWithGlobalDB } = require("@budibase/backend-core/tenancy")
|
const { doInTenant, doWithGlobalDB } = require("@budibase/backend-core/tenancy")
|
||||||
const { createASession } = require("@budibase/backend-core/sessions")
|
const { createASession } = require("@budibase/backend-core/sessions")
|
||||||
|
@ -256,10 +256,10 @@ class TestConfiguration {
|
||||||
return {
|
return {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
Cookie: [
|
Cookie: [
|
||||||
`${Cookies.Auth}=${authToken}`,
|
`${Cookie.Auth}=${authToken}`,
|
||||||
`${Cookies.CurrentApp}=${appToken}`,
|
`${Cookie.CurrentApp}=${appToken}`,
|
||||||
],
|
],
|
||||||
[Headers.APP_ID]: appId,
|
[Header.APP_ID]: appId,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -279,14 +279,14 @@ class TestConfiguration {
|
||||||
const headers = {
|
const headers = {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
Cookie: [
|
Cookie: [
|
||||||
`${Cookies.Auth}=${authToken}`,
|
`${Cookie.Auth}=${authToken}`,
|
||||||
`${Cookies.CurrentApp}=${appToken}`,
|
`${Cookie.CurrentApp}=${appToken}`,
|
||||||
],
|
],
|
||||||
[Headers.CSRF_TOKEN]: CSRF_TOKEN,
|
[Header.CSRF_TOKEN]: CSRF_TOKEN,
|
||||||
...extras,
|
...extras,
|
||||||
}
|
}
|
||||||
if (this.appId) {
|
if (this.appId) {
|
||||||
headers[Headers.APP_ID] = this.appId
|
headers[Header.APP_ID] = this.appId
|
||||||
}
|
}
|
||||||
return headers
|
return headers
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ class TestConfiguration {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
}
|
}
|
||||||
if (appId) {
|
if (appId) {
|
||||||
headers[Headers.APP_ID] = appId
|
headers[Header.APP_ID] = appId
|
||||||
}
|
}
|
||||||
return headers
|
return headers
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ function request(ctx, request) {
|
||||||
request.headers = {}
|
request.headers = {}
|
||||||
}
|
}
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
request.headers[Headers.API_KEY] = env.INTERNAL_API_KEY
|
request.headers[Header.API_KEY] = env.INTERNAL_API_KEY
|
||||||
if (isTenantIdSet()) {
|
if (isTenantIdSet()) {
|
||||||
request.headers[Headers.TENANT_ID] = getTenantId()
|
request.headers[Header.TENANT_ID] = getTenantId()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (request.body && Object.keys(request.body).length > 0) {
|
if (request.body && Object.keys(request.body).length > 0) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
const core = require("@budibase/backend-core")
|
const core = require("@budibase/backend-core")
|
||||||
const { Configs, EmailTemplatePurpose } = require("../../../constants")
|
const { Config, EmailTemplatePurpose } = require("../../../constants")
|
||||||
const { sendEmail, isEmailConfigured } = require("../../../utilities/email")
|
const { sendEmail, isEmailConfigured } = require("../../../utilities/email")
|
||||||
const { setCookie, getCookie, clearCookie, hash, platformLogout } = core.utils
|
const { setCookie, getCookie, clearCookie, hash, platformLogout } = core.utils
|
||||||
const { Cookies, Headers } = core.constants
|
const { Cookie, Headers } = core.constants
|
||||||
const { passport, ssoCallbackUrl, google, oidc } = core.auth
|
const { passport, ssoCallbackUrl, google, oidc } = core.auth
|
||||||
const { checkResetPasswordCode } = require("../../../utilities/redis")
|
const { checkResetPasswordCode } = require("../../../utilities/redis")
|
||||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
||||||
|
@ -30,13 +30,13 @@ async function authInternal(ctx: any, user: any, err = null, info = null) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set a cookie for browser access
|
// set a cookie for browser access
|
||||||
setCookie(ctx, user.token, Cookies.Auth, { sign: false })
|
setCookie(ctx, user.token, Cookie.Auth, { sign: false })
|
||||||
// set the token in a header as well for APIs
|
// set the token in a header as well for APIs
|
||||||
ctx.set(Headers.TOKEN, user.token)
|
ctx.set(Header.TOKEN, user.token)
|
||||||
// get rid of any app cookies on login
|
// get rid of any app cookies on login
|
||||||
// have to check test because this breaks cypress
|
// have to check test because this breaks cypress
|
||||||
if (!env.isTest()) {
|
if (!env.isTest()) {
|
||||||
clearCookie(ctx, Cookies.CurrentApp)
|
clearCookie(ctx, Cookie.CurrentApp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,15 +55,15 @@ export const authenticate = async (ctx: any, next: any) => {
|
||||||
|
|
||||||
export const setInitInfo = (ctx: any) => {
|
export const setInitInfo = (ctx: any) => {
|
||||||
const initInfo = ctx.request.body
|
const initInfo = ctx.request.body
|
||||||
setCookie(ctx, initInfo, Cookies.Init)
|
setCookie(ctx, initInfo, Cookie.Init)
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getInitInfo = (ctx: any) => {
|
export const getInitInfo = (ctx: any) => {
|
||||||
try {
|
try {
|
||||||
ctx.body = getCookie(ctx, Cookies.Init) || {}
|
ctx.body = getCookie(ctx, Cookie.Init) || {}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
clearCookie(ctx, Cookies.Init)
|
clearCookie(ctx, Cookie.Init)
|
||||||
ctx.body = {}
|
ctx.body = {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,14 +141,14 @@ export const datasourcePreAuth = async (ctx: any, next: any) => {
|
||||||
appId: ctx.query.appId,
|
appId: ctx.query.appId,
|
||||||
datasourceId: ctx.query.datasourceId,
|
datasourceId: ctx.query.datasourceId,
|
||||||
},
|
},
|
||||||
Cookies.DatasourceAuth
|
Cookie.DatasourceAuth
|
||||||
)
|
)
|
||||||
|
|
||||||
return handler.preAuth(passport, ctx, next)
|
return handler.preAuth(passport, ctx, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const datasourceAuth = async (ctx: any, next: any) => {
|
export const datasourceAuth = async (ctx: any, next: any) => {
|
||||||
const authStateCookie = getCookie(ctx, Cookies.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/middleware`)
|
||||||
const handler = middleware.datasource[provider]
|
const handler = middleware.datasource[provider]
|
||||||
|
@ -163,7 +163,7 @@ export const googlePreAuth = async (ctx: any, next: any) => {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
|
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await core.db.getScopedConfig(db, {
|
||||||
type: Configs.GOOGLE,
|
type: Config.GOOGLE,
|
||||||
workspace: ctx.query.workspace,
|
workspace: ctx.query.workspace,
|
||||||
})
|
})
|
||||||
let callbackUrl = await exports.googleCallbackUrl(config)
|
let callbackUrl = await exports.googleCallbackUrl(config)
|
||||||
|
@ -184,7 +184,7 @@ export const googleAuth = async (ctx: any, next: any) => {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
|
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await core.db.getScopedConfig(db, {
|
||||||
type: Configs.GOOGLE,
|
type: Config.GOOGLE,
|
||||||
workspace: ctx.query.workspace,
|
workspace: ctx.query.workspace,
|
||||||
})
|
})
|
||||||
const callbackUrl = await exports.googleCallbackUrl(config)
|
const callbackUrl = await exports.googleCallbackUrl(config)
|
||||||
|
@ -210,7 +210,7 @@ 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 = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await core.db.getScopedConfig(db, {
|
||||||
type: Configs.OIDC,
|
type: Config.OIDC,
|
||||||
group: ctx.query.group,
|
group: ctx.query.group,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -233,11 +233,11 @@ export const oidcPreAuth = async (ctx: any, next: any) => {
|
||||||
const { configId } = ctx.params
|
const { configId } = ctx.params
|
||||||
const strategy = await oidcStrategyFactory(ctx, configId)
|
const strategy = await oidcStrategyFactory(ctx, configId)
|
||||||
|
|
||||||
setCookie(ctx, configId, Cookies.OIDC_CONFIG)
|
setCookie(ctx, configId, Cookie.OIDC_CONFIG)
|
||||||
|
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await core.db.getScopedConfig(db, {
|
||||||
type: Configs.OIDC,
|
type: Config.OIDC,
|
||||||
group: ctx.query.group,
|
group: ctx.query.group,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ export const oidcPreAuth = async (ctx: any, next: any) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const oidcAuth = async (ctx: any, next: any) => {
|
export const oidcAuth = async (ctx: any, next: any) => {
|
||||||
const configId = getCookie(ctx, Cookies.OIDC_CONFIG)
|
const configId = getCookie(ctx, Cookie.OIDC_CONFIG)
|
||||||
const strategy = await oidcStrategyFactory(ctx, configId)
|
const strategy = await oidcStrategyFactory(ctx, configId)
|
||||||
|
|
||||||
return passport.authenticate(
|
return passport.authenticate(
|
||||||
|
|
|
@ -4,7 +4,7 @@ const {
|
||||||
getScopedFullConfig,
|
getScopedFullConfig,
|
||||||
getAllApps,
|
getAllApps,
|
||||||
} = require("@budibase/backend-core/db")
|
} = require("@budibase/backend-core/db")
|
||||||
const { Configs } = require("../../../constants")
|
const { Config } = require("../../../constants")
|
||||||
const email = require("../../../utilities/email")
|
const email = require("../../../utilities/email")
|
||||||
const {
|
const {
|
||||||
upload,
|
upload,
|
||||||
|
@ -33,25 +33,25 @@ const getEventFns = async (db, config) => {
|
||||||
|
|
||||||
if (!existing) {
|
if (!existing) {
|
||||||
switch (config.type) {
|
switch (config.type) {
|
||||||
case Configs.SMTP: {
|
case Config.SMTP: {
|
||||||
fns.push(events.email.SMTPCreated)
|
fns.push(events.email.SMTPCreated)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Configs.GOOGLE: {
|
case Config.GOOGLE: {
|
||||||
fns.push(() => events.auth.SSOCreated(type))
|
fns.push(() => events.auth.SSOCreated(type))
|
||||||
if (config.config.activated) {
|
if (config.config.activated) {
|
||||||
fns.push(() => events.auth.SSOActivated(type))
|
fns.push(() => events.auth.SSOActivated(type))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Configs.OIDC: {
|
case Config.OIDC: {
|
||||||
fns.push(() => events.auth.SSOCreated(type))
|
fns.push(() => events.auth.SSOCreated(type))
|
||||||
if (config.config.configs[0].activated) {
|
if (config.config.configs[0].activated) {
|
||||||
fns.push(() => events.auth.SSOActivated(type))
|
fns.push(() => events.auth.SSOActivated(type))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Configs.SETTINGS: {
|
case Config.SETTINGS: {
|
||||||
// company
|
// company
|
||||||
const company = config.config.company
|
const company = config.config.company
|
||||||
if (company && company !== "Budibase") {
|
if (company && company !== "Budibase") {
|
||||||
|
@ -78,11 +78,11 @@ const getEventFns = async (db, config) => {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (config.type) {
|
switch (config.type) {
|
||||||
case Configs.SMTP: {
|
case Config.SMTP: {
|
||||||
fns.push(events.email.SMTPUpdated)
|
fns.push(events.email.SMTPUpdated)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Configs.GOOGLE: {
|
case Config.GOOGLE: {
|
||||||
fns.push(() => events.auth.SSOUpdated(type))
|
fns.push(() => events.auth.SSOUpdated(type))
|
||||||
if (!existing.config.activated && config.config.activated) {
|
if (!existing.config.activated && config.config.activated) {
|
||||||
fns.push(() => events.auth.SSOActivated(type))
|
fns.push(() => events.auth.SSOActivated(type))
|
||||||
|
@ -91,7 +91,7 @@ const getEventFns = async (db, config) => {
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Configs.OIDC: {
|
case Config.OIDC: {
|
||||||
fns.push(() => events.auth.SSOUpdated(type))
|
fns.push(() => events.auth.SSOUpdated(type))
|
||||||
if (
|
if (
|
||||||
!existing.config.configs[0].activated &&
|
!existing.config.configs[0].activated &&
|
||||||
|
@ -106,7 +106,7 @@ const getEventFns = async (db, config) => {
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case Configs.SETTINGS: {
|
case Config.SETTINGS: {
|
||||||
// company
|
// company
|
||||||
const existingCompany = existing.config.company
|
const existingCompany = existing.config.company
|
||||||
const company = config.config.company
|
const company = config.config.company
|
||||||
|
@ -155,7 +155,7 @@ exports.save = async function (ctx) {
|
||||||
try {
|
try {
|
||||||
// verify the configuration
|
// verify the configuration
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Configs.SMTP:
|
case Config.SMTP:
|
||||||
await email.verifyConfig(config)
|
await email.verifyConfig(config)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ exports.publicOidc = async function (ctx) {
|
||||||
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 getScopedFullConfig(db, {
|
||||||
type: Configs.OIDC,
|
type: Config.OIDC,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!oidcConfig) {
|
if (!oidcConfig) {
|
||||||
|
@ -260,15 +260,15 @@ exports.publicSettings = async function (ctx) {
|
||||||
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 getScopedFullConfig(db, {
|
||||||
type: Configs.SETTINGS,
|
type: Config.SETTINGS,
|
||||||
})
|
})
|
||||||
|
|
||||||
const googleConfig = await getScopedFullConfig(db, {
|
const googleConfig = await getScopedFullConfig(db, {
|
||||||
type: Configs.GOOGLE,
|
type: Config.GOOGLE,
|
||||||
})
|
})
|
||||||
|
|
||||||
const oidcConfig = await getScopedFullConfig(db, {
|
const oidcConfig = await getScopedFullConfig(db, {
|
||||||
type: Configs.OIDC,
|
type: Config.OIDC,
|
||||||
})
|
})
|
||||||
|
|
||||||
let config
|
let config
|
||||||
|
@ -390,17 +390,17 @@ exports.configChecklist = async function (ctx) {
|
||||||
|
|
||||||
// They have set up SMTP
|
// They have set up SMTP
|
||||||
const smtpConfig = await getScopedFullConfig(db, {
|
const smtpConfig = await getScopedFullConfig(db, {
|
||||||
type: Configs.SMTP,
|
type: Config.SMTP,
|
||||||
})
|
})
|
||||||
|
|
||||||
// They have set up Google Auth
|
// They have set up Google Auth
|
||||||
const googleConfig = await getScopedFullConfig(db, {
|
const googleConfig = await getScopedFullConfig(db, {
|
||||||
type: Configs.GOOGLE,
|
type: Config.GOOGLE,
|
||||||
})
|
})
|
||||||
|
|
||||||
// They have set up OIDC
|
// They have set up OIDC
|
||||||
const oidcConfig = await getScopedFullConfig(db, {
|
const oidcConfig = await getScopedFullConfig(db, {
|
||||||
type: Configs.OIDC,
|
type: Config.OIDC,
|
||||||
})
|
})
|
||||||
|
|
||||||
// They have set up an global user
|
// They have set up an global user
|
||||||
|
|
|
@ -73,12 +73,12 @@ export async function fetchAPIKey(ctx: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkCurrentApp = (ctx: any) => {
|
const checkCurrentApp = (ctx: any) => {
|
||||||
const appCookie = getCookie(ctx, constants.Cookies.CurrentApp)
|
const appCookie = getCookie(ctx, constants.Cookie.CurrentApp)
|
||||||
if (appCookie && !tenancy.isUserInAppTenant(appCookie.appId)) {
|
if (appCookie && !tenancy.isUserInAppTenant(appCookie.appId)) {
|
||||||
// there is a currentapp cookie from another tenant
|
// there is a currentapp cookie from another tenant
|
||||||
// remove the cookie as this is incompatible with the builder
|
// remove the cookie as this is incompatible with the builder
|
||||||
// due to builder and admin permissions being removed
|
// due to builder and admin permissions being removed
|
||||||
clearCookie(ctx, constants.Cookies.CurrentApp)
|
clearCookie(ctx, constants.Cookie.CurrentApp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ const controller = require("../../controllers/global/configs")
|
||||||
const { joiValidator } = require("@budibase/backend-core/auth")
|
const { joiValidator } = require("@budibase/backend-core/auth")
|
||||||
const { adminOnly } = require("@budibase/backend-core/auth")
|
const { adminOnly } = require("@budibase/backend-core/auth")
|
||||||
const Joi = require("joi")
|
const Joi = require("joi")
|
||||||
const { Configs } = require("../../../constants")
|
const { Config } = require("../../../constants")
|
||||||
|
|
||||||
const router = new Router()
|
const router = new Router()
|
||||||
|
|
||||||
|
@ -65,17 +65,17 @@ function buildConfigSaveValidation() {
|
||||||
_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(Configs)).required(),
|
type: Joi.string().valid(...Object.values(Config)).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: Configs.SMTP, then: smtpValidation() },
|
{ is: Config.SMTP, then: smtpValidation() },
|
||||||
{ is: Configs.SETTINGS, then: settingValidation() },
|
{ is: Config.SETTINGS, then: settingValidation() },
|
||||||
{ is: Configs.ACCOUNT, then: Joi.object().unknown(true) },
|
{ is: Config.ACCOUNT, then: Joi.object().unknown(true) },
|
||||||
{ is: Configs.GOOGLE, then: googleValidation() },
|
{ is: Config.GOOGLE, then: googleValidation() },
|
||||||
{ is: Configs.OIDC, then: oidcValidation() }
|
{ is: Config.OIDC, then: oidcValidation() }
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
}).required().unknown(true),
|
}).required().unknown(true),
|
||||||
|
@ -85,7 +85,7 @@ function buildConfigSaveValidation() {
|
||||||
function buildUploadValidation() {
|
function buildUploadValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.params(Joi.object({
|
return joiValidator.params(Joi.object({
|
||||||
type: Joi.string().valid(...Object.values(Configs)).required(),
|
type: Joi.string().valid(...Object.values(Config)).required(),
|
||||||
name: Joi.string().required(),
|
name: Joi.string().required(),
|
||||||
}).required().unknown(true))
|
}).required().unknown(true))
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ function buildUploadValidation() {
|
||||||
function buildConfigGetValidation() {
|
function buildConfigGetValidation() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return joiValidator.params(Joi.object({
|
return joiValidator.params(Joi.object({
|
||||||
type: Joi.string().valid(...Object.values(Configs)).required()
|
type: Joi.string().valid(...Object.values(Config)).required()
|
||||||
}).required().unknown(true))
|
}).required().unknown(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
jest.mock("nodemailer")
|
jest.mock("nodemailer")
|
||||||
import { TestConfiguration, structures, mocks, API } from "../../../../tests"
|
import { TestConfiguration, structures, mocks, API } from "../../../../tests"
|
||||||
mocks.email.mock()
|
mocks.email.mock()
|
||||||
import { Configs, events } from "@budibase/backend-core"
|
import { Config, events } from "@budibase/backend-core"
|
||||||
|
|
||||||
describe("configs", () => {
|
describe("configs", () => {
|
||||||
const config = new TestConfiguration()
|
const config = new TestConfiguration()
|
||||||
|
@ -50,20 +50,20 @@ describe("configs", () => {
|
||||||
it("should create activated google config", async () => {
|
it("should create activated google config", async () => {
|
||||||
await saveGoogleConfig()
|
await saveGoogleConfig()
|
||||||
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOCreated).toBeCalledWith(Configs.GOOGLE)
|
expect(events.auth.SSOCreated).toBeCalledWith(Config.GOOGLE)
|
||||||
expect(events.auth.SSODeactivated).not.toBeCalled()
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
||||||
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOActivated).toBeCalledWith(Configs.GOOGLE)
|
expect(events.auth.SSOActivated).toBeCalledWith(Config.GOOGLE)
|
||||||
await config.deleteConfig(Configs.GOOGLE)
|
await config.deleteConfig(Config.GOOGLE)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should create deactivated google config", async () => {
|
it("should create deactivated google config", async () => {
|
||||||
await saveGoogleConfig({ activated: false })
|
await saveGoogleConfig({ activated: false })
|
||||||
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOCreated).toBeCalledWith(Configs.GOOGLE)
|
expect(events.auth.SSOCreated).toBeCalledWith(Config.GOOGLE)
|
||||||
expect(events.auth.SSOActivated).not.toBeCalled()
|
expect(events.auth.SSOActivated).not.toBeCalled()
|
||||||
expect(events.auth.SSODeactivated).not.toBeCalled()
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
||||||
await config.deleteConfig(Configs.GOOGLE)
|
await config.deleteConfig(Config.GOOGLE)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -77,11 +77,11 @@ describe("configs", () => {
|
||||||
googleConf._rev
|
googleConf._rev
|
||||||
)
|
)
|
||||||
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOUpdated).toBeCalledWith(Configs.GOOGLE)
|
expect(events.auth.SSOUpdated).toBeCalledWith(Config.GOOGLE)
|
||||||
expect(events.auth.SSOActivated).not.toBeCalled()
|
expect(events.auth.SSOActivated).not.toBeCalled()
|
||||||
expect(events.auth.SSODeactivated).toBeCalledTimes(1)
|
expect(events.auth.SSODeactivated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSODeactivated).toBeCalledWith(Configs.GOOGLE)
|
expect(events.auth.SSODeactivated).toBeCalledWith(Config.GOOGLE)
|
||||||
await config.deleteConfig(Configs.GOOGLE)
|
await config.deleteConfig(Config.GOOGLE)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should update google config to activated", async () => {
|
it("should update google config to activated", async () => {
|
||||||
|
@ -93,11 +93,11 @@ describe("configs", () => {
|
||||||
googleConf._rev
|
googleConf._rev
|
||||||
)
|
)
|
||||||
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOUpdated).toBeCalledWith(Configs.GOOGLE)
|
expect(events.auth.SSOUpdated).toBeCalledWith(Config.GOOGLE)
|
||||||
expect(events.auth.SSODeactivated).not.toBeCalled()
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
||||||
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOActivated).toBeCalledWith(Configs.GOOGLE)
|
expect(events.auth.SSOActivated).toBeCalledWith(Config.GOOGLE)
|
||||||
await config.deleteConfig(Configs.GOOGLE)
|
await config.deleteConfig(Config.GOOGLE)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -116,20 +116,20 @@ describe("configs", () => {
|
||||||
it("should create activated OIDC config", async () => {
|
it("should create activated OIDC config", async () => {
|
||||||
await saveOIDCConfig()
|
await saveOIDCConfig()
|
||||||
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOCreated).toBeCalledWith(Configs.OIDC)
|
expect(events.auth.SSOCreated).toBeCalledWith(Config.OIDC)
|
||||||
expect(events.auth.SSODeactivated).not.toBeCalled()
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
||||||
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOActivated).toBeCalledWith(Configs.OIDC)
|
expect(events.auth.SSOActivated).toBeCalledWith(Config.OIDC)
|
||||||
await config.deleteConfig(Configs.OIDC)
|
await config.deleteConfig(Config.OIDC)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should create deactivated OIDC config", async () => {
|
it("should create deactivated OIDC config", async () => {
|
||||||
await saveOIDCConfig({ activated: false })
|
await saveOIDCConfig({ activated: false })
|
||||||
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOCreated).toBeCalledWith(Configs.OIDC)
|
expect(events.auth.SSOCreated).toBeCalledWith(Config.OIDC)
|
||||||
expect(events.auth.SSOActivated).not.toBeCalled()
|
expect(events.auth.SSOActivated).not.toBeCalled()
|
||||||
expect(events.auth.SSODeactivated).not.toBeCalled()
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
||||||
await config.deleteConfig(Configs.OIDC)
|
await config.deleteConfig(Config.OIDC)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -143,11 +143,11 @@ describe("configs", () => {
|
||||||
oidcConf._rev
|
oidcConf._rev
|
||||||
)
|
)
|
||||||
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOUpdated).toBeCalledWith(Configs.OIDC)
|
expect(events.auth.SSOUpdated).toBeCalledWith(Config.OIDC)
|
||||||
expect(events.auth.SSOActivated).not.toBeCalled()
|
expect(events.auth.SSOActivated).not.toBeCalled()
|
||||||
expect(events.auth.SSODeactivated).toBeCalledTimes(1)
|
expect(events.auth.SSODeactivated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSODeactivated).toBeCalledWith(Configs.OIDC)
|
expect(events.auth.SSODeactivated).toBeCalledWith(Config.OIDC)
|
||||||
await config.deleteConfig(Configs.OIDC)
|
await config.deleteConfig(Config.OIDC)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should update OIDC config to activated", async () => {
|
it("should update OIDC config to activated", async () => {
|
||||||
|
@ -159,11 +159,11 @@ describe("configs", () => {
|
||||||
oidcConf._rev
|
oidcConf._rev
|
||||||
)
|
)
|
||||||
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOUpdated).toBeCalledWith(Configs.OIDC)
|
expect(events.auth.SSOUpdated).toBeCalledWith(Config.OIDC)
|
||||||
expect(events.auth.SSODeactivated).not.toBeCalled()
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
||||||
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOActivated).toBeCalledWith(Configs.OIDC)
|
expect(events.auth.SSOActivated).toBeCalledWith(Config.OIDC)
|
||||||
await config.deleteConfig(Configs.OIDC)
|
await config.deleteConfig(Config.OIDC)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -180,11 +180,11 @@ describe("configs", () => {
|
||||||
|
|
||||||
describe("create", () => {
|
describe("create", () => {
|
||||||
it("should create SMTP config", async () => {
|
it("should create SMTP config", async () => {
|
||||||
await config.deleteConfig(Configs.SMTP)
|
await config.deleteConfig(Config.SMTP)
|
||||||
await saveSMTPConfig()
|
await saveSMTPConfig()
|
||||||
expect(events.email.SMTPUpdated).not.toBeCalled()
|
expect(events.email.SMTPUpdated).not.toBeCalled()
|
||||||
expect(events.email.SMTPCreated).toBeCalledTimes(1)
|
expect(events.email.SMTPCreated).toBeCalledTimes(1)
|
||||||
await config.deleteConfig(Configs.SMTP)
|
await config.deleteConfig(Config.SMTP)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ describe("configs", () => {
|
||||||
await saveSMTPConfig(smtpConf.config, smtpConf._id, smtpConf._rev)
|
await saveSMTPConfig(smtpConf.config, smtpConf._id, smtpConf._rev)
|
||||||
expect(events.email.SMTPCreated).not.toBeCalled()
|
expect(events.email.SMTPCreated).not.toBeCalled()
|
||||||
expect(events.email.SMTPUpdated).toBeCalledTimes(1)
|
expect(events.email.SMTPUpdated).toBeCalledTimes(1)
|
||||||
await config.deleteConfig(Configs.SMTP)
|
await config.deleteConfig(Config.SMTP)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -212,7 +212,7 @@ describe("configs", () => {
|
||||||
|
|
||||||
describe("create", () => {
|
describe("create", () => {
|
||||||
it("should create settings config with default settings", async () => {
|
it("should create settings config with default settings", async () => {
|
||||||
await config.deleteConfig(Configs.SETTINGS)
|
await config.deleteConfig(Config.SETTINGS)
|
||||||
|
|
||||||
await saveSettingsConfig()
|
await saveSettingsConfig()
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ describe("configs", () => {
|
||||||
|
|
||||||
it("should create settings config with non-default settings", async () => {
|
it("should create settings config with non-default settings", async () => {
|
||||||
config.modeSelf()
|
config.modeSelf()
|
||||||
await config.deleteConfig(Configs.SETTINGS)
|
await config.deleteConfig(Config.SETTINGS)
|
||||||
const conf = {
|
const conf = {
|
||||||
company: "acme",
|
company: "acme",
|
||||||
logoUrl: "http://example.com",
|
logoUrl: "http://example.com",
|
||||||
|
@ -242,7 +242,7 @@ describe("configs", () => {
|
||||||
describe("update", () => {
|
describe("update", () => {
|
||||||
it("should update settings config", async () => {
|
it("should update settings config", async () => {
|
||||||
config.modeSelf()
|
config.modeSelf()
|
||||||
await config.deleteConfig(Configs.SETTINGS)
|
await config.deleteConfig(Config.SETTINGS)
|
||||||
const settingsConfig = await saveSettingsConfig()
|
const settingsConfig = await saveSettingsConfig()
|
||||||
settingsConfig.config.company = "acme"
|
settingsConfig.config.company = "acme"
|
||||||
settingsConfig.config.logoUrl = "http://example.com"
|
settingsConfig.config.logoUrl = "http://example.com"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const { Configs } = require("@budibase/backend-core/constants")
|
const { Config } = require("@budibase/backend-core/constants")
|
||||||
|
|
||||||
exports.LOGO_URL =
|
exports.LOGO_URL =
|
||||||
"https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg"
|
"https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg"
|
||||||
|
@ -8,7 +8,7 @@ exports.UserStatus = {
|
||||||
INACTIVE: "inactive",
|
INACTIVE: "inactive",
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.Configs = Configs
|
exports.Config = Config
|
||||||
|
|
||||||
exports.ConfigUploads = {
|
exports.ConfigUploads = {
|
||||||
LOGO: "logo",
|
LOGO: "logo",
|
||||||
|
|
|
@ -7,7 +7,7 @@ const { Headers } = require("@budibase/backend-core/constants")
|
||||||
*/
|
*/
|
||||||
module.exports = async (ctx, next) => {
|
module.exports = async (ctx, next) => {
|
||||||
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
||||||
const apiKey = ctx.request.headers[Headers.API_KEY]
|
const apiKey = ctx.request.headers[Header.API_KEY]
|
||||||
if (apiKey !== env.INTERNAL_API_KEY) {
|
if (apiKey !== env.INTERNAL_API_KEY) {
|
||||||
ctx.throw(403, "Unauthorized")
|
ctx.throw(403, "Unauthorized")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@ dbConfig.init()
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import controllers from "./controllers"
|
import controllers from "./controllers"
|
||||||
const supertest = require("supertest")
|
const supertest = require("supertest")
|
||||||
import { Configs } from "../constants"
|
import { Config } from "../constants"
|
||||||
import {
|
import {
|
||||||
users,
|
users,
|
||||||
tenancy,
|
tenancy,
|
||||||
Cookies,
|
Cookie,
|
||||||
Headers,
|
Header,
|
||||||
sessions,
|
sessions,
|
||||||
auth,
|
auth,
|
||||||
} from "@budibase/backend-core"
|
} from "@budibase/backend-core"
|
||||||
|
@ -163,8 +163,8 @@ class TestConfiguration {
|
||||||
const authCookie = auth.jwt.sign(authToken, env.JWT_SECRET)
|
const authCookie = auth.jwt.sign(authToken, env.JWT_SECRET)
|
||||||
return {
|
return {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
...this.cookieHeader([`${Cookies.Auth}=${authCookie}`]),
|
...this.cookieHeader([`${Cookie.Auth}=${authCookie}`]),
|
||||||
[Headers.CSRF_TOKEN]: CSRF_TOKEN,
|
[Header.CSRF_TOKEN]: CSRF_TOKEN,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ class TestConfiguration {
|
||||||
// CONFIGS - SETTINGS
|
// CONFIGS - SETTINGS
|
||||||
|
|
||||||
async saveSettingsConfig() {
|
async saveSettingsConfig() {
|
||||||
await this.deleteConfig(Configs.SETTINGS)
|
await this.deleteConfig(Config.SETTINGS)
|
||||||
await this._req(
|
await this._req(
|
||||||
structures.configs.settings(),
|
structures.configs.settings(),
|
||||||
null,
|
null,
|
||||||
|
@ -234,7 +234,7 @@ class TestConfiguration {
|
||||||
// CONFIGS - GOOGLE
|
// CONFIGS - GOOGLE
|
||||||
|
|
||||||
async saveGoogleConfig() {
|
async saveGoogleConfig() {
|
||||||
await this.deleteConfig(Configs.GOOGLE)
|
await this.deleteConfig(Config.GOOGLE)
|
||||||
await this._req(structures.configs.google(), null, controllers.config.save)
|
await this._req(structures.configs.google(), null, controllers.config.save)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,11 +242,11 @@ class TestConfiguration {
|
||||||
|
|
||||||
getOIDConfigCookie(configId: string) {
|
getOIDConfigCookie(configId: string) {
|
||||||
const token = auth.jwt.sign(configId, env.JWT_SECRET)
|
const token = auth.jwt.sign(configId, env.JWT_SECRET)
|
||||||
return this.cookieHeader([[`${Cookies.OIDC_CONFIG}=${token}`]])
|
return this.cookieHeader([[`${Cookie.OIDC_CONFIG}=${token}`]])
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveOIDCConfig() {
|
async saveOIDCConfig() {
|
||||||
await this.deleteConfig(Configs.OIDC)
|
await this.deleteConfig(Config.OIDC)
|
||||||
const config = structures.configs.oidc()
|
const config = structures.configs.oidc()
|
||||||
|
|
||||||
await this._req(config, null, controllers.config.save)
|
await this._req(config, null, controllers.config.save)
|
||||||
|
@ -256,12 +256,12 @@ class TestConfiguration {
|
||||||
// CONFIGS - SMTP
|
// CONFIGS - SMTP
|
||||||
|
|
||||||
async saveSmtpConfig() {
|
async saveSmtpConfig() {
|
||||||
await this.deleteConfig(Configs.SMTP)
|
await this.deleteConfig(Config.SMTP)
|
||||||
await this._req(structures.configs.smtp(), null, controllers.config.save)
|
await this._req(structures.configs.smtp(), null, controllers.config.save)
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveEtherealSmtpConfig() {
|
async saveEtherealSmtpConfig() {
|
||||||
await this.deleteConfig(Configs.SMTP)
|
await this.deleteConfig(Config.SMTP)
|
||||||
await this._req(
|
await this._req(
|
||||||
structures.configs.smtpEthereal(),
|
structures.configs.smtpEthereal(),
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
const { Configs } = require("../../constants")
|
const { Config } = require("../../constants")
|
||||||
const { utils } = require("@budibase/backend-core")
|
const { utils } = require("@budibase/backend-core")
|
||||||
|
|
||||||
exports.oidc = conf => {
|
exports.oidc = conf => {
|
||||||
return {
|
return {
|
||||||
type: Configs.OIDC,
|
type: Config.OIDC,
|
||||||
config: {
|
config: {
|
||||||
configs: [
|
configs: [
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,7 @@ exports.oidc = conf => {
|
||||||
|
|
||||||
exports.google = conf => {
|
exports.google = conf => {
|
||||||
return {
|
return {
|
||||||
type: Configs.GOOGLE,
|
type: Config.GOOGLE,
|
||||||
config: {
|
config: {
|
||||||
clientID: "clientId",
|
clientID: "clientId",
|
||||||
clientSecret: "clientSecret",
|
clientSecret: "clientSecret",
|
||||||
|
@ -35,7 +35,7 @@ exports.google = conf => {
|
||||||
|
|
||||||
exports.smtp = conf => {
|
exports.smtp = conf => {
|
||||||
return {
|
return {
|
||||||
type: Configs.SMTP,
|
type: Config.SMTP,
|
||||||
config: {
|
config: {
|
||||||
port: 12345,
|
port: 12345,
|
||||||
host: "smtptesthost.com",
|
host: "smtptesthost.com",
|
||||||
|
@ -49,7 +49,7 @@ exports.smtp = conf => {
|
||||||
|
|
||||||
exports.smtpEthereal = () => {
|
exports.smtpEthereal = () => {
|
||||||
return {
|
return {
|
||||||
type: Configs.SMTP,
|
type: Config.SMTP,
|
||||||
config: {
|
config: {
|
||||||
port: 587,
|
port: 587,
|
||||||
host: "smtp.ethereal.email",
|
host: "smtp.ethereal.email",
|
||||||
|
@ -65,7 +65,7 @@ exports.smtpEthereal = () => {
|
||||||
|
|
||||||
exports.settings = conf => {
|
exports.settings = conf => {
|
||||||
return {
|
return {
|
||||||
type: Configs.SETTINGS,
|
type: Config.SETTINGS,
|
||||||
config: {
|
config: {
|
||||||
platformUrl: "http://localhost:10000",
|
platformUrl: "http://localhost:10000",
|
||||||
logoUrl: "",
|
logoUrl: "",
|
||||||
|
|
|
@ -9,9 +9,9 @@ async function makeAppRequest(url, method, body) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const request = { headers: {} }
|
const request = { headers: {} }
|
||||||
request.headers[Headers.API_KEY] = env.INTERNAL_API_KEY
|
request.headers[Header.API_KEY] = env.INTERNAL_API_KEY
|
||||||
if (isTenantIdSet()) {
|
if (isTenantIdSet()) {
|
||||||
request.headers[Headers.TENANT_ID] = getTenantId()
|
request.headers[Header.TENANT_ID] = getTenantId()
|
||||||
}
|
}
|
||||||
if (body) {
|
if (body) {
|
||||||
request.headers["Content-Type"] = "application/json"
|
request.headers["Content-Type"] = "application/json"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const nodemailer = require("nodemailer")
|
const nodemailer = require("nodemailer")
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
const { getScopedConfig } = require("@budibase/backend-core/db")
|
const { getScopedConfig } = require("@budibase/backend-core/db")
|
||||||
const { EmailTemplatePurpose, TemplateTypes, Configs } = require("../constants")
|
const { EmailTemplatePurpose, TemplateTypes, Config } = require("../constants")
|
||||||
const { getTemplateByPurpose } = require("../constants/templates")
|
const { getTemplateByPurpose } = require("../constants/templates")
|
||||||
const { getSettingsTemplateContext } = require("./templates")
|
const { getSettingsTemplateContext } = require("./templates")
|
||||||
const { processString } = require("@budibase/string-templates")
|
const { processString } = require("@budibase/string-templates")
|
||||||
|
@ -115,7 +115,7 @@ async function buildEmail(purpose, email, context, { user, contents } = {}) {
|
||||||
*/
|
*/
|
||||||
async function getSmtpConfiguration(db, workspaceId = null, automation) {
|
async function getSmtpConfiguration(db, workspaceId = null, automation) {
|
||||||
const params = {
|
const params = {
|
||||||
type: Configs.SMTP,
|
type: Config.SMTP,
|
||||||
}
|
}
|
||||||
if (workspaceId) {
|
if (workspaceId) {
|
||||||
params.workspace = workspaceId
|
params.workspace = workspaceId
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const { getScopedConfig } = require("@budibase/backend-core/db")
|
const { getScopedConfig } = require("@budibase/backend-core/db")
|
||||||
const {
|
const {
|
||||||
Configs,
|
Config,
|
||||||
InternalTemplateBindings,
|
InternalTemplateBindings,
|
||||||
LOGO_URL,
|
LOGO_URL,
|
||||||
EmailTemplatePurpose,
|
EmailTemplatePurpose,
|
||||||
|
@ -15,7 +15,7 @@ const BASE_COMPANY = "Budibase"
|
||||||
exports.getSettingsTemplateContext = async (purpose, code = null) => {
|
exports.getSettingsTemplateContext = async (purpose, code = null) => {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
// TODO: use more granular settings in the future if required
|
// TODO: use more granular settings in the future if required
|
||||||
let settings = (await getScopedConfig(db, { type: Configs.SETTINGS })) || {}
|
let settings = (await getScopedConfig(db, { type: Config.SETTINGS })) || {}
|
||||||
const URL = settings.platformUrl
|
const URL = settings.platformUrl
|
||||||
const context = {
|
const context = {
|
||||||
[InternalTemplateBindings.LOGO_URL]:
|
[InternalTemplateBindings.LOGO_URL]:
|
||||||
|
|
Loading…
Reference in New Issue