From c57a81c6de3601e1642cca62f43c4080be4c344d Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 6 Jun 2024 11:53:58 +0100 Subject: [PATCH 1/7] Adding a global binding for globalId which is retrieved as part of the self call - making sure this is available as a binding (this is not in the user metadata table, just for bindings). --- packages/builder/src/dataBinding.js | 4 ++++ packages/server/src/api/controllers/auth.ts | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/dataBinding.js b/packages/builder/src/dataBinding.js index 64257e7a7b..6defe94108 100644 --- a/packages/builder/src/dataBinding.js +++ b/packages/builder/src/dataBinding.js @@ -30,6 +30,7 @@ import ActionDefinitions from "components/design/settings/controls/ButtonActionE import { environment, licensing } from "stores/portal" import { convertOldFieldFormat } from "components/design/settings/controls/FieldConfiguration/utils" import { FIELDS } from "constants/backend" +import { FieldType } from "@budibase/types" const { ContextScopes } = Constants @@ -555,6 +556,9 @@ const getComponentBindingCategory = (component, context, def) => { export const getUserBindings = () => { let bindings = [] const { schema } = getSchemaForDatasourcePlus(TableNames.USERS) + // add props that are not in the user metadata table schema + // but will be there for logged-in user + schema["globalId"] = { type: FieldType.STRING } const keys = Object.keys(schema).sort() const safeUser = makePropSafe("user") diff --git a/packages/server/src/api/controllers/auth.ts b/packages/server/src/api/controllers/auth.ts index 9b1b78ed9e..4ff592534d 100644 --- a/packages/server/src/api/controllers/auth.ts +++ b/packages/server/src/api/controllers/auth.ts @@ -1,7 +1,7 @@ import { outputProcessing } from "../../utilities/rowProcessor" import { InternalTables } from "../../db/utils" import { getFullUser } from "../../utilities/users" -import { roles, context } from "@budibase/backend-core" +import { roles, context, db as dbCore } from "@budibase/backend-core" import { ContextUser, Row, UserCtx } from "@budibase/types" import sdk from "../../sdk" import { processUser } from "../../utilities/global" @@ -27,6 +27,8 @@ export async function fetchSelf(ctx: UserCtx) { const appId = context.getAppId() let user: ContextUser = await getFullUser(userId) + // add globalId of user + user.globalId = dbCore.getGlobalIDFromUserMetadataID(userId) // this shouldn't be returned by the app self delete user.roles // forward the csrf token from the session From f09b6bf090580e438126a7ac9496aff3a4aa4ec9 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 6 Jun 2024 13:03:00 +0200 Subject: [PATCH 2/7] Handle times properly on time only settings for timestamps --- .../app/blocks/FormBlockComponent.svelte | 5 ++++ .../components/app/forms/DateTimeField.svelte | 28 +++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/client/src/components/app/blocks/FormBlockComponent.svelte b/packages/client/src/components/app/blocks/FormBlockComponent.svelte index 396dfcf808..58632ad1bc 100644 --- a/packages/client/src/components/app/blocks/FormBlockComponent.svelte +++ b/packages/client/src/components/app/blocks/FormBlockComponent.svelte @@ -68,6 +68,11 @@ maximum: schema?.constraints?.length?.maximum, } }, + [FieldType.DATETIME]: (_field, schema) => { + return { + valueAsTimestamp: !schema?.timeOnly, + } + }, } const fieldSchema = getFieldSchema(field) diff --git a/packages/client/src/components/app/forms/DateTimeField.svelte b/packages/client/src/components/app/forms/DateTimeField.svelte index 499f0443cb..7b6ed734fe 100644 --- a/packages/client/src/components/app/forms/DateTimeField.svelte +++ b/packages/client/src/components/app/forms/DateTimeField.svelte @@ -16,15 +16,37 @@ export let onChange export let span export let helpText = null + export let valueAsTimestamp = false let fieldState let fieldApi const handleChange = e => { - const changed = fieldApi.setValue(e.detail) - if (onChange && changed) { - onChange({ value: e.detail }) + let value = e.detail + if (timeOnly && valueAsTimestamp) { + if (!isValidDate(value)) { + // Handle time only fields that are timestamps under the hood + value = timeToDateISOString(value) + } } + + const changed = fieldApi.setValue(value) + if (onChange && changed) { + onChange({ value }) + } + } + + const isValidDate = value => !isNaN(new Date(value)) + + const timeToDateISOString = value => { + let [hours, minutes] = value.split(":").map(Number) + + const date = new Date() + date.setHours(hours) + date.setMinutes(minutes) + date.setSeconds(0) + date.setMilliseconds(0) + return date.toISOString() } From 9ad1d60850f0b7bc368c33b9a3c9df9fcecb6b04 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 6 Jun 2024 13:25:13 +0200 Subject: [PATCH 3/7] Handle dateonly by default --- .../src/components/app/blocks/FormBlockComponent.svelte | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/client/src/components/app/blocks/FormBlockComponent.svelte b/packages/client/src/components/app/blocks/FormBlockComponent.svelte index 58632ad1bc..f931319118 100644 --- a/packages/client/src/components/app/blocks/FormBlockComponent.svelte +++ b/packages/client/src/components/app/blocks/FormBlockComponent.svelte @@ -69,9 +69,13 @@ } }, [FieldType.DATETIME]: (_field, schema) => { - return { + const props = { valueAsTimestamp: !schema?.timeOnly, } + if (schema?.dateOnly) { + props.enableTime = false + } + return props }, } From 878114133c399812d22bd6abb0f44bd796618c2d Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 6 Jun 2024 12:36:57 +0100 Subject: [PATCH 4/7] Adding test. --- .../server/src/api/routes/tests/auth.spec.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/server/src/api/routes/tests/auth.spec.js b/packages/server/src/api/routes/tests/auth.spec.js index 5fbead99b7..64952db17c 100644 --- a/packages/server/src/api/routes/tests/auth.spec.js +++ b/packages/server/src/api/routes/tests/auth.spec.js @@ -1,5 +1,8 @@ const setup = require("./utilities") -const { generateUserMetadataID } = require("../../../db/utils") +const { + generateUserMetadataID, + getGlobalIDFromUserMetadataID, +} = require("../../../db/utils") describe("/authenticate", () => { let request = setup.getRequest() @@ -20,5 +23,16 @@ describe("/authenticate", () => { .expect(200) expect(res.body._id).toEqual(generateUserMetadataID(config.user._id)) }) + + it("should container the global user ID", async () => { + const res = await request + .get(`/api/self`) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200) + expect(res.body.globalId).toEqual( + getGlobalIDFromUserMetadataID(config.user._id) + ) + }) }) }) From de0a3f5b0d297f4b5f0a5b04abffb1ece4a07f24 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Thu, 6 Jun 2024 12:15:05 +0000 Subject: [PATCH 5/7] Bump version to 2.28.2 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 066df19dac..1cd6b251a8 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.28.1", + "version": "2.28.2", "npmClient": "yarn", "packages": [ "packages/*", From 944689b17d83f5b8e362c91b5b5f44213df829a4 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Thu, 6 Jun 2024 13:14:18 +0000 Subject: [PATCH 6/7] Bump version to 2.28.3 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 1cd6b251a8..8b1fa18d23 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.28.2", + "version": "2.28.3", "npmClient": "yarn", "packages": [ "packages/*", From a0727e2c2a74f2083996d418cbefc2b1a8eb3cba Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 6 Jun 2024 15:39:05 +0200 Subject: [PATCH 7/7] Remove wrong scope --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 08176fae90..5377dfc5a1 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,8 @@ "build": "NODE_OPTIONS=--max-old-space-size=1500 lerna run build --stream", "build:apps": "yarn build --scope @budibase/server --scope @budibase/worker", "build:cli": "yarn build --scope @budibase/cli", - "build:oss": "NODE_OPTIONS=--max-old-space-size=1500 lerna run build --stream --ignore @budibase/account-portal --ignore @budibase/account-portal-server --ignore @budibase/account-portal-ui", - "build:account-portal": "NODE_OPTIONS=--max-old-space-size=1500 lerna run build --stream --scope @budibase/account-portal --scope @budibase/account-portal-server --scope @budibase/account-portal-ui", + "build:oss": "NODE_OPTIONS=--max-old-space-size=1500 lerna run build --stream --ignore @budibase/account-portal-server --ignore @budibase/account-portal-ui", + "build:account-portal": "NODE_OPTIONS=--max-old-space-size=1500 lerna run build --stream --scope @budibase/account-portal-server --scope @budibase/account-portal-ui", "build:dev": "lerna run --stream prebuild && yarn nx run-many --target=build --output-style=dynamic --watch --preserveWatchOutput", "check:types": "lerna run --concurrency 2 check:types", "build:sdk": "lerna run --stream build:sdk",