From eee2991b098bfc55d87aa032d02d372eb86b387d Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 9 Oct 2024 12:57:14 +0100 Subject: [PATCH] Rejib IP fetching. --- .../backend-core/src/context/mainContext.ts | 9 ++++ packages/backend-core/src/context/types.ts | 1 + .../backend-core/src/features/features.ts | 47 ++++--------------- packages/backend-core/src/middleware/index.ts | 1 + packages/backend-core/src/middleware/ip.ts | 12 +++++ packages/server/src/koa.ts | 1 + packages/worker/src/index.ts | 1 + 7 files changed, 33 insertions(+), 39 deletions(-) create mode 100644 packages/backend-core/src/middleware/ip.ts diff --git a/packages/backend-core/src/context/mainContext.ts b/packages/backend-core/src/context/mainContext.ts index 25b273e51c..64ba240fa5 100644 --- a/packages/backend-core/src/context/mainContext.ts +++ b/packages/backend-core/src/context/mainContext.ts @@ -253,6 +253,11 @@ export function getAppId(): string | undefined { } } +export function getIP(): string | undefined { + const context = Context.get() + return context?.ip +} + export const getProdAppId = () => { const appId = getAppId() if (!appId) { @@ -281,6 +286,10 @@ export function doInScimContext(task: any) { return newContext(updates, task) } +export function doInIPContext(ip: string, task: any) { + return newContext({ ip }, task) +} + export async function ensureSnippetContext(enabled = !env.isTest()) { const ctx = getCurrentContext() diff --git a/packages/backend-core/src/context/types.ts b/packages/backend-core/src/context/types.ts index ee84b49459..5549a47ff7 100644 --- a/packages/backend-core/src/context/types.ts +++ b/packages/backend-core/src/context/types.ts @@ -9,6 +9,7 @@ export type ContextMap = { identity?: IdentityContext environmentVariables?: Record isScim?: boolean + ip?: string automationId?: string isMigrating?: boolean vm?: VM diff --git a/packages/backend-core/src/features/features.ts b/packages/backend-core/src/features/features.ts index 305c53ff3a..5f2ba50f67 100644 --- a/packages/backend-core/src/features/features.ts +++ b/packages/backend-core/src/features/features.ts @@ -2,7 +2,7 @@ import env from "../environment" import * as crypto from "crypto" import * as context from "../context" import { PostHog, PostHogOptions } from "posthog-node" -import { FeatureFlag, UserCtx } from "@budibase/types" +import { FeatureFlag } from "@budibase/types" import tracer from "dd-trace" import { Duration } from "../utils" @@ -142,23 +142,17 @@ export class FlagSet, T extends { [key: string]: V }> { return this.flagSchema[name as keyof T] !== undefined } - async get( - key: K, - ctx?: UserCtx - ): Promise[K]> { - const flags = await this.fetch(ctx) + async get(key: K): Promise[K]> { + const flags = await this.fetch() return flags[key] } - async isEnabled>( - key: K, - ctx?: UserCtx - ): Promise { - const flags = await this.fetch(ctx) + async isEnabled>(key: K): Promise { + const flags = await this.fetch() return flags[key] } - async fetch(ctx?: UserCtx): Promise> { + async fetch(): Promise> { return await tracer.trace("features.fetch", async span => { const cachedFlags = context.getFeatureFlags>(this.setId) if (cachedFlags) { @@ -199,36 +193,11 @@ export class FlagSet, T extends { [key: string]: V }> { tags[`flags.${key}.source`] = "environment" } - const license = ctx?.user?.license - if (license) { - tags[`readFromLicense`] = true - - for (const feature of license.features) { - if (!this.isFlagName(feature)) { - continue - } - - if ( - flagValues[feature] === true || - specificallySetFalse.has(feature) - ) { - // If the flag is already set to through environment variables, we - // don't want to override it back to false here. - continue - } - - // @ts-expect-error - TS does not like you writing into a generic type, - // but we know that it's okay in this case because it's just an object. - flagValues[feature] = true - tags[`flags.${feature}.source`] = "license" - } - } - const identity = context.getIdentity() let userId = identity?._id - if (!userId && ctx?.ip) { - userId = crypto.createHash("sha512").update(ctx.ip).digest("hex") + if (!userId) { + userId = context.getIP() } let tenantId = identity?.tenantId diff --git a/packages/backend-core/src/middleware/index.ts b/packages/backend-core/src/middleware/index.ts index e1eb7f1d26..20c2125b13 100644 --- a/packages/backend-core/src/middleware/index.ts +++ b/packages/backend-core/src/middleware/index.ts @@ -20,3 +20,4 @@ export { default as correlation } from "../logging/correlation/middleware" export { default as errorHandling } from "./errorHandling" export { default as querystringToBody } from "./querystringToBody" export * as joiValidator from "./joi-validator" +export { default as ip } from "./ip" diff --git a/packages/backend-core/src/middleware/ip.ts b/packages/backend-core/src/middleware/ip.ts new file mode 100644 index 0000000000..69a0a2da38 --- /dev/null +++ b/packages/backend-core/src/middleware/ip.ts @@ -0,0 +1,12 @@ +import { Ctx } from "@budibase/types" +import { doInIPContext } from "../context" + +export default async (ctx: Ctx, next: any) => { + if (ctx.ip) { + doInIPContext(ctx.ip, () => { + return next() + }) + } else { + return next() + } +} diff --git a/packages/server/src/koa.ts b/packages/server/src/koa.ts index 9f90c04b50..dd8063795d 100644 --- a/packages/server/src/koa.ts +++ b/packages/server/src/koa.ts @@ -35,6 +35,7 @@ export default function createKoaApp() { app.use(middleware.correlation) app.use(middleware.pino) + app.use(middleware.ip) app.use(userAgent) const server = http.createServer(app.callback()) diff --git a/packages/worker/src/index.ts b/packages/worker/src/index.ts index 79e6f4493d..9c3c053baf 100644 --- a/packages/worker/src/index.ts +++ b/packages/worker/src/index.ts @@ -54,6 +54,7 @@ app.use(koaBody({ multipart: true })) app.use(koaSession(app)) app.use(middleware.correlation) app.use(middleware.pino) +app.use(middleware.ip) app.use(userAgent) // authentication