Disabling js interop in Typescript build of backend-core and worker, fixing build issues.
This commit is contained in:
parent
3ce9df0d25
commit
90362b65c1
|
@ -2,3 +2,4 @@ export * as generic from "./generic"
|
|||
export * as user from "./user"
|
||||
export * as app from "./appMetadata"
|
||||
export * as writethrough from "./writethrough"
|
||||
export * from "./generic"
|
||||
|
|
|
@ -2,22 +2,21 @@ import {
|
|||
IdentityContext,
|
||||
IdentityType,
|
||||
User,
|
||||
UserContext,
|
||||
isCloudAccount,
|
||||
Account,
|
||||
AccountUserContext,
|
||||
} from "@budibase/types"
|
||||
import * as context from "."
|
||||
|
||||
export const getIdentity = (): IdentityContext | undefined => {
|
||||
export function getIdentity(): IdentityContext | undefined {
|
||||
return context.getIdentity()
|
||||
}
|
||||
|
||||
export const doInIdentityContext = (identity: IdentityContext, task: any) => {
|
||||
export function doInIdentityContext(identity: IdentityContext, task: any) {
|
||||
return context.doInIdentityContext(identity, task)
|
||||
}
|
||||
|
||||
export const doInUserContext = (user: User, task: any) => {
|
||||
export function doInUserContext(user: User, task: any) {
|
||||
const userContext: any = {
|
||||
...user,
|
||||
_id: user._id as string,
|
||||
|
@ -26,7 +25,7 @@ export const doInUserContext = (user: User, task: any) => {
|
|||
return doInIdentityContext(userContext, task)
|
||||
}
|
||||
|
||||
export const doInAccountContext = (account: Account, task: any) => {
|
||||
export function doInAccountContext(account: Account, task: any) {
|
||||
const _id = getAccountUserId(account)
|
||||
const tenantId = account.tenantId
|
||||
const accountContext: AccountUserContext = {
|
||||
|
@ -38,12 +37,12 @@ export const doInAccountContext = (account: Account, task: any) => {
|
|||
return doInIdentityContext(accountContext, task)
|
||||
}
|
||||
|
||||
export const getAccountUserId = (account: Account) => {
|
||||
export function getAccountUserId(account: Account) {
|
||||
let userId: string
|
||||
if (isCloudAccount(account)) {
|
||||
userId = account.budibaseUserId
|
||||
} else {
|
||||
// use account id as user id for self hosting
|
||||
// use account id as user id for self-hosting
|
||||
userId = account.accountId
|
||||
}
|
||||
return userId
|
||||
|
|
|
@ -1,223 +1,3 @@
|
|||
import env from "../environment"
|
||||
import {
|
||||
SEPARATOR,
|
||||
DocumentType,
|
||||
getDevelopmentAppID,
|
||||
getProdAppID,
|
||||
baseGlobalDBName,
|
||||
getDB,
|
||||
} from "../db"
|
||||
import Context from "./Context"
|
||||
import { IdentityContext, Database } from "@budibase/types"
|
||||
import { DEFAULT_TENANT_ID as _DEFAULT_TENANT_ID } from "../constants"
|
||||
import { ContextMap } from "./constants"
|
||||
export const DEFAULT_TENANT_ID = _DEFAULT_TENANT_ID
|
||||
|
||||
// some test cases call functions directly, need to
|
||||
// store an app ID to pretend there is a context
|
||||
let TEST_APP_ID: string | null = null
|
||||
|
||||
export function isMultiTenant() {
|
||||
return env.MULTI_TENANCY
|
||||
}
|
||||
|
||||
export function isTenantIdSet() {
|
||||
const context = Context.get()
|
||||
return !!context?.tenantId
|
||||
}
|
||||
|
||||
export function isTenancyEnabled() {
|
||||
return env.MULTI_TENANCY
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an app ID this will attempt to retrieve the tenant ID from it.
|
||||
* @return {null|string} The tenant ID found within the app ID.
|
||||
*/
|
||||
export function getTenantIDFromAppID(appId: string) {
|
||||
if (!appId) {
|
||||
return undefined
|
||||
}
|
||||
if (!isMultiTenant()) {
|
||||
return DEFAULT_TENANT_ID
|
||||
}
|
||||
const split = appId.split(SEPARATOR)
|
||||
const hasDev = split[1] === DocumentType.DEV
|
||||
if ((hasDev && split.length === 3) || (!hasDev && split.length === 2)) {
|
||||
return undefined
|
||||
}
|
||||
if (hasDev) {
|
||||
return split[2]
|
||||
} else {
|
||||
return split[1]
|
||||
}
|
||||
}
|
||||
|
||||
function updateContext(updates: ContextMap) {
|
||||
let context: ContextMap
|
||||
try {
|
||||
context = Context.get()
|
||||
} catch (err) {
|
||||
// no context, start empty
|
||||
context = {}
|
||||
}
|
||||
context = {
|
||||
...context,
|
||||
...updates,
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
async function newContext(updates: ContextMap, task: any) {
|
||||
// see if there already is a context setup
|
||||
let context: ContextMap = updateContext(updates)
|
||||
return Context.run(context, task)
|
||||
}
|
||||
|
||||
export async function doInContext(appId: string, task: any): Promise<any> {
|
||||
const tenantId = getTenantIDFromAppID(appId)
|
||||
return newContext(
|
||||
{
|
||||
tenantId,
|
||||
appId,
|
||||
},
|
||||
task
|
||||
)
|
||||
}
|
||||
|
||||
export async function doInTenant(
|
||||
tenantId: string | null,
|
||||
task: any
|
||||
): Promise<any> {
|
||||
// make sure default always selected in single tenancy
|
||||
if (!env.MULTI_TENANCY) {
|
||||
tenantId = tenantId || DEFAULT_TENANT_ID
|
||||
}
|
||||
|
||||
const updates = tenantId ? { tenantId } : {}
|
||||
return newContext(updates, task)
|
||||
}
|
||||
|
||||
export async function doInAppContext(appId: string, task: any): Promise<any> {
|
||||
if (!appId) {
|
||||
throw new Error("appId is required")
|
||||
}
|
||||
|
||||
const tenantId = getTenantIDFromAppID(appId)
|
||||
const updates: ContextMap = { appId }
|
||||
if (tenantId) {
|
||||
updates.tenantId = tenantId
|
||||
}
|
||||
return newContext(updates, task)
|
||||
}
|
||||
|
||||
export async function doInIdentityContext(
|
||||
identity: IdentityContext,
|
||||
task: any
|
||||
): Promise<any> {
|
||||
if (!identity) {
|
||||
throw new Error("identity is required")
|
||||
}
|
||||
|
||||
const context: ContextMap = {
|
||||
identity,
|
||||
}
|
||||
if (identity.tenantId) {
|
||||
context.tenantId = identity.tenantId
|
||||
}
|
||||
return newContext(context, task)
|
||||
}
|
||||
|
||||
export function getIdentity(): IdentityContext | undefined {
|
||||
try {
|
||||
const context = Context.get()
|
||||
return context?.identity
|
||||
} catch (e) {
|
||||
// do nothing - identity is not in context
|
||||
}
|
||||
}
|
||||
|
||||
export function getTenantId(): string {
|
||||
if (!isMultiTenant()) {
|
||||
return DEFAULT_TENANT_ID
|
||||
}
|
||||
const context = Context.get()
|
||||
const tenantId = context?.tenantId
|
||||
if (!tenantId) {
|
||||
throw new Error("Tenant id not found")
|
||||
}
|
||||
return tenantId
|
||||
}
|
||||
|
||||
export function getAppId(): string | undefined {
|
||||
const context = Context.get()
|
||||
const foundId = context?.appId
|
||||
if (!foundId && env.isTest() && TEST_APP_ID) {
|
||||
return TEST_APP_ID
|
||||
} else {
|
||||
return foundId
|
||||
}
|
||||
}
|
||||
|
||||
export function updateTenantId(tenantId?: string) {
|
||||
let context: ContextMap = updateContext({
|
||||
tenantId,
|
||||
})
|
||||
Context.set(context)
|
||||
}
|
||||
|
||||
export function updateAppId(appId: string) {
|
||||
let context: ContextMap = updateContext({
|
||||
appId,
|
||||
})
|
||||
try {
|
||||
Context.set(context)
|
||||
} catch (err) {
|
||||
if (env.isTest()) {
|
||||
TEST_APP_ID = appId
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getGlobalDB(): Database {
|
||||
const context = Context.get()
|
||||
if (!context || (env.MULTI_TENANCY && !context.tenantId)) {
|
||||
throw new Error("Global DB not found")
|
||||
}
|
||||
return getDB(baseGlobalDBName(context?.tenantId))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the app database based on whatever the request
|
||||
* contained, dev or prod.
|
||||
*/
|
||||
export function getAppDB(opts?: any): Database {
|
||||
const appId = getAppId()
|
||||
return getDB(appId, opts)
|
||||
}
|
||||
|
||||
/**
|
||||
* This specifically gets the prod app ID, if the request
|
||||
* contained a development app ID, this will get the prod one.
|
||||
*/
|
||||
export function getProdAppDB(opts?: any): Database {
|
||||
const appId = getAppId()
|
||||
if (!appId) {
|
||||
throw new Error("Unable to retrieve prod DB - no app ID.")
|
||||
}
|
||||
return getDB(getProdAppID(appId), opts)
|
||||
}
|
||||
|
||||
/**
|
||||
* This specifically gets the dev app ID, if the request
|
||||
* contained a prod app ID, this will get the dev one.
|
||||
*/
|
||||
export function getDevAppDB(opts?: any): Database {
|
||||
const appId = getAppId()
|
||||
if (!appId) {
|
||||
throw new Error("Unable to retrieve dev DB - no app ID.")
|
||||
}
|
||||
return getDB(getDevelopmentAppID(appId), opts)
|
||||
}
|
||||
export { DEFAULT_TENANT_ID } from "../constants"
|
||||
export * as identity from "./identity"
|
||||
export * from "./mainContext"
|
||||
|
|
|
@ -0,0 +1,222 @@
|
|||
// some test cases call functions directly, need to
|
||||
// store an app ID to pretend there is a context
|
||||
import env from "../environment"
|
||||
import Context from "./Context"
|
||||
import {
|
||||
baseGlobalDBName,
|
||||
DocumentType,
|
||||
getDB,
|
||||
getDevelopmentAppID,
|
||||
getProdAppID,
|
||||
SEPARATOR,
|
||||
} from "../db"
|
||||
import { ContextMap } from "./constants"
|
||||
import { Database, IdentityContext } from "@budibase/types"
|
||||
import { DEFAULT_TENANT_ID } from "./index"
|
||||
|
||||
let TEST_APP_ID: string | null = null
|
||||
|
||||
export function isMultiTenant() {
|
||||
return env.MULTI_TENANCY
|
||||
}
|
||||
|
||||
export function isTenantIdSet() {
|
||||
const context = Context.get()
|
||||
return !!context?.tenantId
|
||||
}
|
||||
|
||||
export function isTenancyEnabled() {
|
||||
return env.MULTI_TENANCY
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an app ID this will attempt to retrieve the tenant ID from it.
|
||||
* @return {null|string} The tenant ID found within the app ID.
|
||||
*/
|
||||
export function getTenantIDFromAppID(appId: string) {
|
||||
if (!appId) {
|
||||
return undefined
|
||||
}
|
||||
if (!isMultiTenant()) {
|
||||
return DEFAULT_TENANT_ID
|
||||
}
|
||||
const split = appId.split(SEPARATOR)
|
||||
const hasDev = split[1] === DocumentType.DEV
|
||||
if ((hasDev && split.length === 3) || (!hasDev && split.length === 2)) {
|
||||
return undefined
|
||||
}
|
||||
if (hasDev) {
|
||||
return split[2]
|
||||
} else {
|
||||
return split[1]
|
||||
}
|
||||
}
|
||||
|
||||
function updateContext(updates: ContextMap) {
|
||||
let context: ContextMap
|
||||
try {
|
||||
context = Context.get()
|
||||
} catch (err) {
|
||||
// no context, start empty
|
||||
context = {}
|
||||
}
|
||||
context = {
|
||||
...context,
|
||||
...updates,
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
async function newContext(updates: ContextMap, task: any) {
|
||||
// see if there already is a context setup
|
||||
let context: ContextMap = updateContext(updates)
|
||||
return Context.run(context, task)
|
||||
}
|
||||
|
||||
export async function doInContext(appId: string, task: any): Promise<any> {
|
||||
const tenantId = getTenantIDFromAppID(appId)
|
||||
return newContext(
|
||||
{
|
||||
tenantId,
|
||||
appId,
|
||||
},
|
||||
task
|
||||
)
|
||||
}
|
||||
|
||||
export async function doInTenant(
|
||||
tenantId: string | null,
|
||||
task: any
|
||||
): Promise<any> {
|
||||
// make sure default always selected in single tenancy
|
||||
if (!env.MULTI_TENANCY) {
|
||||
tenantId = tenantId || DEFAULT_TENANT_ID
|
||||
}
|
||||
|
||||
const updates = tenantId ? { tenantId } : {}
|
||||
return newContext(updates, task)
|
||||
}
|
||||
|
||||
export async function doInAppContext(appId: string, task: any): Promise<any> {
|
||||
if (!appId) {
|
||||
throw new Error("appId is required")
|
||||
}
|
||||
|
||||
const tenantId = getTenantIDFromAppID(appId)
|
||||
const updates: ContextMap = { appId }
|
||||
if (tenantId) {
|
||||
updates.tenantId = tenantId
|
||||
}
|
||||
return newContext(updates, task)
|
||||
}
|
||||
|
||||
export async function doInIdentityContext(
|
||||
identity: IdentityContext,
|
||||
task: any
|
||||
): Promise<any> {
|
||||
if (!identity) {
|
||||
throw new Error("identity is required")
|
||||
}
|
||||
|
||||
const context: ContextMap = {
|
||||
identity,
|
||||
}
|
||||
if (identity.tenantId) {
|
||||
context.tenantId = identity.tenantId
|
||||
}
|
||||
return newContext(context, task)
|
||||
}
|
||||
|
||||
export function getIdentity(): IdentityContext | undefined {
|
||||
try {
|
||||
const context = Context.get()
|
||||
return context?.identity
|
||||
} catch (e) {
|
||||
// do nothing - identity is not in context
|
||||
}
|
||||
}
|
||||
|
||||
export function getTenantId(): string {
|
||||
if (!isMultiTenant()) {
|
||||
return DEFAULT_TENANT_ID
|
||||
}
|
||||
const context = Context.get()
|
||||
const tenantId = context?.tenantId
|
||||
if (!tenantId) {
|
||||
throw new Error("Tenant id not found")
|
||||
}
|
||||
return tenantId
|
||||
}
|
||||
|
||||
export function getAppId(): string | undefined {
|
||||
const context = Context.get()
|
||||
const foundId = context?.appId
|
||||
if (!foundId && env.isTest() && TEST_APP_ID) {
|
||||
return TEST_APP_ID
|
||||
} else {
|
||||
return foundId
|
||||
}
|
||||
}
|
||||
|
||||
export function updateTenantId(tenantId?: string) {
|
||||
let context: ContextMap = updateContext({
|
||||
tenantId,
|
||||
})
|
||||
Context.set(context)
|
||||
}
|
||||
|
||||
export function updateAppId(appId: string) {
|
||||
let context: ContextMap = updateContext({
|
||||
appId,
|
||||
})
|
||||
try {
|
||||
Context.set(context)
|
||||
} catch (err) {
|
||||
if (env.isTest()) {
|
||||
TEST_APP_ID = appId
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getGlobalDB(): Database {
|
||||
const context = Context.get()
|
||||
if (!context || (env.MULTI_TENANCY && !context.tenantId)) {
|
||||
throw new Error("Global DB not found")
|
||||
}
|
||||
return getDB(baseGlobalDBName(context?.tenantId))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the app database based on whatever the request
|
||||
* contained, dev or prod.
|
||||
*/
|
||||
export function getAppDB(opts?: any): Database {
|
||||
const appId = getAppId()
|
||||
return getDB(appId, opts)
|
||||
}
|
||||
|
||||
/**
|
||||
* This specifically gets the prod app ID, if the request
|
||||
* contained a development app ID, this will get the prod one.
|
||||
*/
|
||||
export function getProdAppDB(opts?: any): Database {
|
||||
const appId = getAppId()
|
||||
if (!appId) {
|
||||
throw new Error("Unable to retrieve prod DB - no app ID.")
|
||||
}
|
||||
return getDB(getProdAppID(appId), opts)
|
||||
}
|
||||
|
||||
/**
|
||||
* This specifically gets the dev app ID, if the request
|
||||
* contained a prod app ID, this will get the dev one.
|
||||
*/
|
||||
export function getDevAppDB(opts?: any): Database {
|
||||
const appId = getAppId()
|
||||
if (!appId) {
|
||||
throw new Error("Unable to retrieve dev DB - no app ID.")
|
||||
}
|
||||
return getDB(getDevelopmentAppID(appId), opts)
|
||||
}
|
|
@ -19,7 +19,7 @@ export async function created(
|
|||
const properties: AutomationCreatedEvent = {
|
||||
appId: automation.appId,
|
||||
automationId: automation._id as string,
|
||||
triggerId: automation.definition?.trigger?.id,
|
||||
triggerId: automation.definition?.trigger?.id!,
|
||||
triggerType: automation.definition?.trigger?.stepId,
|
||||
}
|
||||
await publishEvent(Event.AUTOMATION_CREATED, properties, timestamp)
|
||||
|
@ -29,7 +29,7 @@ export async function triggerUpdated(automation: Automation) {
|
|||
const properties: AutomationTriggerUpdatedEvent = {
|
||||
appId: automation.appId,
|
||||
automationId: automation._id as string,
|
||||
triggerId: automation.definition?.trigger?.id,
|
||||
triggerId: automation.definition?.trigger?.id!,
|
||||
triggerType: automation.definition?.trigger?.stepId,
|
||||
}
|
||||
await publishEvent(Event.AUTOMATION_TRIGGER_UPDATED, properties)
|
||||
|
@ -39,7 +39,7 @@ export async function deleted(automation: Automation) {
|
|||
const properties: AutomationDeletedEvent = {
|
||||
appId: automation.appId,
|
||||
automationId: automation._id as string,
|
||||
triggerId: automation.definition?.trigger?.id,
|
||||
triggerId: automation.definition?.trigger?.id!,
|
||||
triggerType: automation.definition?.trigger?.stepId,
|
||||
}
|
||||
await publishEvent(Event.AUTOMATION_DELETED, properties)
|
||||
|
@ -49,7 +49,7 @@ export async function tested(automation: Automation) {
|
|||
const properties: AutomationTestedEvent = {
|
||||
appId: automation.appId,
|
||||
automationId: automation._id as string,
|
||||
triggerId: automation.definition?.trigger?.id,
|
||||
triggerId: automation.definition?.trigger?.id!,
|
||||
triggerType: automation.definition?.trigger?.stepId,
|
||||
}
|
||||
await publishEvent(Event.AUTOMATION_TESTED, properties)
|
||||
|
@ -70,9 +70,9 @@ export async function stepCreated(
|
|||
const properties: AutomationStepCreatedEvent = {
|
||||
appId: automation.appId,
|
||||
automationId: automation._id as string,
|
||||
triggerId: automation.definition?.trigger?.id,
|
||||
triggerId: automation.definition?.trigger?.id!,
|
||||
triggerType: automation.definition?.trigger?.stepId,
|
||||
stepId: step.id,
|
||||
stepId: step.id!,
|
||||
stepType: step.stepId,
|
||||
}
|
||||
await publishEvent(Event.AUTOMATION_STEP_CREATED, properties, timestamp)
|
||||
|
@ -85,9 +85,9 @@ export async function stepDeleted(
|
|||
const properties: AutomationStepDeletedEvent = {
|
||||
appId: automation.appId,
|
||||
automationId: automation._id as string,
|
||||
triggerId: automation.definition?.trigger?.id,
|
||||
triggerId: automation.definition?.trigger?.id!,
|
||||
triggerType: automation.definition?.trigger?.stepId,
|
||||
stepId: step.id,
|
||||
stepId: step.id!,
|
||||
stepType: step.stepId,
|
||||
}
|
||||
await publishEvent(Event.AUTOMATION_STEP_DELETED, properties)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { BBContext } from "@budibase/types"
|
||||
|
||||
export = async (ctx: BBContext, next: any) => {
|
||||
export = async (ctx: BBContext | any, next: any) => {
|
||||
// Placeholder for audit log middleware
|
||||
return next()
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import { getGlobalDB, doInTenant } from "../tenancy"
|
|||
import { decrypt } from "../security/encryption"
|
||||
import * as identity from "../context/identity"
|
||||
import env from "../environment"
|
||||
import { BBContext, EndpointMatcher } from "@budibase/types"
|
||||
|
||||
const ONE_MINUTE = env.SESSION_UPDATE_PERIOD
|
||||
? parseInt(env.SESSION_UPDATE_PERIOD)
|
||||
|
@ -65,14 +66,14 @@ async function checkApiKey(apiKey: string, populateUser?: Function) {
|
|||
* The tenancy modules should not be used here and it should be assumed that the tenancy context
|
||||
* has not yet been populated.
|
||||
*/
|
||||
export = (
|
||||
noAuthPatterns = [],
|
||||
export = function (
|
||||
noAuthPatterns: EndpointMatcher[] = [],
|
||||
opts: { publicAllowed: boolean; populateUser?: Function } = {
|
||||
publicAllowed: false,
|
||||
}
|
||||
) => {
|
||||
) {
|
||||
const noAuthOptions = noAuthPatterns ? buildMatcherRegex(noAuthPatterns) : []
|
||||
return async (ctx: any, next: any) => {
|
||||
return async (ctx: BBContext | any, next: any) => {
|
||||
let publicEndpoint = false
|
||||
const version = ctx.request.headers[Header.API_VER]
|
||||
// the path is not authenticated
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Header } from "../constants"
|
||||
import { buildMatcherRegex, matches } from "./matchers"
|
||||
import { BBContext } from "@budibase/types"
|
||||
import { BBContext, EndpointMatcher } from "@budibase/types"
|
||||
|
||||
/**
|
||||
* GET, HEAD and OPTIONS methods are considered safe operations
|
||||
|
@ -32,9 +32,11 @@ const INCLUDED_CONTENT_TYPES = [
|
|||
* https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern
|
||||
*
|
||||
*/
|
||||
export = (opts = { noCsrfPatterns: [] }) => {
|
||||
export = function (
|
||||
opts: { noCsrfPatterns: EndpointMatcher[] } = { noCsrfPatterns: [] }
|
||||
) {
|
||||
const noCsrfOptions = buildMatcherRegex(opts.noCsrfPatterns)
|
||||
return async (ctx: BBContext, next: any) => {
|
||||
return async (ctx: BBContext | any, next: any) => {
|
||||
// don't apply for excluded paths
|
||||
const found = matches(ctx, noCsrfOptions)
|
||||
if (found) {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import Joi, { ObjectSchema } from "joi"
|
||||
import { BBContext } from "@budibase/types"
|
||||
|
||||
function validate(schema: Joi.ObjectSchema, property: string) {
|
||||
function validate(
|
||||
schema: Joi.ObjectSchema | Joi.ArraySchema,
|
||||
property: string
|
||||
) {
|
||||
// Return a Koa middleware function
|
||||
return (ctx: BBContext, next: any) => {
|
||||
if (!schema) {
|
||||
|
@ -17,8 +20,8 @@ function validate(schema: Joi.ObjectSchema, property: string) {
|
|||
}
|
||||
|
||||
// not all schemas have the append property e.g. array schemas
|
||||
if (schema.append) {
|
||||
schema = schema.append({
|
||||
if ((schema as Joi.ObjectSchema).append) {
|
||||
schema = (schema as Joi.ObjectSchema).append({
|
||||
createdAt: Joi.any().optional(),
|
||||
updatedAt: Joi.any().optional(),
|
||||
})
|
||||
|
@ -33,10 +36,10 @@ function validate(schema: Joi.ObjectSchema, property: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export function body(schema: Joi.ObjectSchema) {
|
||||
export function body(schema: Joi.ObjectSchema | Joi.ArraySchema) {
|
||||
return validate(schema, "body")
|
||||
}
|
||||
|
||||
export function params(schema: Joi.ObjectSchema) {
|
||||
export function params(schema: Joi.ObjectSchema | Joi.ArraySchema) {
|
||||
return validate(schema, "params")
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
Database,
|
||||
SSOProfile,
|
||||
ThirdPartyUser,
|
||||
OIDCConfiguration,
|
||||
} from "@budibase/types"
|
||||
const OIDCStrategy = require("@techpass/passport-openidconnect").Strategy
|
||||
|
||||
|
@ -103,7 +104,10 @@ function validEmail(value: string) {
|
|||
* from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.
|
||||
* @returns Dynamically configured Passport OIDC Strategy
|
||||
*/
|
||||
export async function strategyFactory(config: Config, saveUserFn?: Function) {
|
||||
export async function strategyFactory(
|
||||
config: OIDCConfiguration,
|
||||
saveUserFn?: Function
|
||||
) {
|
||||
try {
|
||||
const verify = buildVerifyFn(saveUserFn)
|
||||
const strategy = new OIDCStrategy(config, verify)
|
||||
|
@ -118,7 +122,7 @@ export async function strategyFactory(config: Config, saveUserFn?: Function) {
|
|||
export async function fetchStrategyConfig(
|
||||
enrichedConfig: OIDCInnerCfg,
|
||||
callbackUrl?: string
|
||||
) {
|
||||
): Promise<OIDCConfiguration> {
|
||||
try {
|
||||
const { clientID, clientSecret, configUrl } = enrichedConfig
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ export function authError(done: Function, message: string, err?: any) {
|
|||
|
||||
export async function ssoCallbackUrl(
|
||||
db: Database,
|
||||
config: { callbackURL?: string },
|
||||
type: ConfigType
|
||||
config?: { callbackURL?: string },
|
||||
type?: ConfigType
|
||||
) {
|
||||
// incase there is a callback URL from before
|
||||
if (config && config.callbackURL) {
|
||||
|
|
|
@ -8,15 +8,15 @@ import {
|
|||
TenantResolutionStrategy,
|
||||
} from "@budibase/types"
|
||||
|
||||
const tenancy = (
|
||||
export = function (
|
||||
allowQueryStringPatterns: EndpointMatcher[],
|
||||
noTenancyPatterns: EndpointMatcher[],
|
||||
opts = { noTenancyRequired: false }
|
||||
) => {
|
||||
opts: { noTenancyRequired?: boolean } = { noTenancyRequired: false }
|
||||
) {
|
||||
const allowQsOptions = buildMatcherRegex(allowQueryStringPatterns)
|
||||
const noTenancyOptions = buildMatcherRegex(noTenancyPatterns)
|
||||
|
||||
return async function (ctx: BBContext, next: any) {
|
||||
return async function (ctx: BBContext | any, next: any) {
|
||||
const allowNoTenant =
|
||||
opts.noTenancyRequired || !!matches(ctx, noTenancyOptions)
|
||||
const tenantOpts: GetTenantIdOptions = {
|
||||
|
@ -33,5 +33,3 @@ const tenancy = (
|
|||
return doInTenant(tenantId, next)
|
||||
}
|
||||
}
|
||||
|
||||
export = tenancy
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"lib": ["es2020"],
|
||||
"allowJs": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"esModuleInterop": true,
|
||||
|
|
|
@ -31,6 +31,16 @@ export interface GoogleConfig extends Config {
|
|||
}
|
||||
}
|
||||
|
||||
export interface OIDCConfiguration {
|
||||
issuer: string
|
||||
authorizationURL: string
|
||||
tokenURL: string
|
||||
userInfoURL: string
|
||||
clientID: string
|
||||
clientSecret: string
|
||||
callbackURL: string
|
||||
}
|
||||
|
||||
export interface OIDCInnerCfg {
|
||||
configUrl: string
|
||||
clientID: string
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"lib": ["es2020"],
|
||||
"allowJs": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"esModuleInterop": true,
|
||||
|
|
|
@ -1,26 +1,30 @@
|
|||
import { utils, constants, auth, db as dbCore } from "@budibase/backend-core"
|
||||
import {
|
||||
events,
|
||||
users as usersCore,
|
||||
auth,
|
||||
constants,
|
||||
context,
|
||||
db as dbCore,
|
||||
events,
|
||||
tenancy,
|
||||
users as usersCore,
|
||||
utils,
|
||||
} from "@budibase/backend-core"
|
||||
import { EmailTemplatePurpose } from "../../../constants"
|
||||
import { sendEmail, isEmailConfigured } from "../../../utilities/email"
|
||||
import { isEmailConfigured, sendEmail } from "../../../utilities/email"
|
||||
import { checkResetPasswordCode } from "../../../utilities/redis"
|
||||
import env from "../../../environment"
|
||||
import sdk from "../../../sdk"
|
||||
import { User, Config, ConfigType } from "@budibase/types"
|
||||
import { Config, ConfigType, User } from "@budibase/types"
|
||||
|
||||
const { setCookie, getCookie, clearCookie, hash, platformLogout } = utils
|
||||
const { Cookie, Header } = constants
|
||||
const { passport, ssoCallbackUrl, google, oidc } = auth
|
||||
|
||||
export async function googleCallbackUrl(config?: Config) {
|
||||
return ssoCallbackUrl(tenancy.getGlobalDB(), config, "google")
|
||||
export async function googleCallbackUrl(config?: { callbackURL?: string }) {
|
||||
return ssoCallbackUrl(tenancy.getGlobalDB(), config, ConfigType.GOOGLE)
|
||||
}
|
||||
|
||||
export async function oidcCallbackUrl(config?: Config) {
|
||||
return ssoCallbackUrl(tenancy.getGlobalDB(), config, "oidc")
|
||||
export async function oidcCallbackUrl(config?: { callbackURL?: string }) {
|
||||
return ssoCallbackUrl(tenancy.getGlobalDB(), config, ConfigType.OIDC)
|
||||
}
|
||||
|
||||
async function authInternal(ctx: any, user: any, err = null, info = null) {
|
||||
|
|
|
@ -371,7 +371,7 @@ export async function destroy(ctx: BBContext) {
|
|||
const { id, rev } = ctx.params
|
||||
try {
|
||||
await db.remove(id, rev)
|
||||
await cache.delete(cache.CacheKey.CHECKLIST)
|
||||
await cache.destroy(cache.CacheKey.CHECKLIST)
|
||||
ctx.body = { message: "Config deleted successfully" }
|
||||
} catch (err: any) {
|
||||
ctx.throw(err.status, err)
|
||||
|
|
|
@ -85,7 +85,7 @@ if (!environment.APPS_URL) {
|
|||
}
|
||||
|
||||
// clean up any environment variable edge cases
|
||||
for (let [key, value] of Object.entries(env)) {
|
||||
for (let [key, value] of Object.entries(environment)) {
|
||||
// handle the edge case of "0" to disable an environment variable
|
||||
if (value === "0") {
|
||||
// @ts-ignore
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"lib": ["es2020"],
|
||||
"allowJs": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"esModuleInterop": true,
|
||||
|
|
Loading…
Reference in New Issue