diff --git a/lerna.json b/lerna.json index 4895e529aa..7870ebe15a 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.8.6-alpha.6", + "version": "2.8.9", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/src/db/lucene.ts b/packages/backend-core/src/db/lucene.ts index d501bb2166..a491451a62 100644 --- a/packages/backend-core/src/db/lucene.ts +++ b/packages/backend-core/src/db/lucene.ts @@ -433,6 +433,9 @@ export class QueryBuilder { if (!value) { return null } + if (typeof value === "boolean") { + return `(*:* AND !${key}:${value})` + } return `!${key}:${builder.preprocess(value, allPreProcessingOpts)}` }) } diff --git a/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte index ce6a3f0c51..b96738ab1a 100644 --- a/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte +++ b/packages/builder/src/components/backend/DataTable/buttons/TableFilterButton.svelte @@ -17,7 +17,7 @@ $: text = getText(filters) const getText = filters => { - const count = filters?.length + const count = filters?.filter(filter => filter.field)?.length return count ? `Filter (${count})` : "Filter" } diff --git a/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte b/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte index 9d48789947..88c3842f54 100644 --- a/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte @@ -20,7 +20,7 @@ $: datasource = getDatasourceForProvider($currentAsset, componentInstance) $: schema = getSchemaForDatasource($currentAsset, datasource)?.schema $: schemaFields = Object.values(schema || {}) - $: text = getText(value) + $: text = getText(value?.filter(filter => filter.field)) async function saveFilter() { dispatch("change", tempValue) diff --git a/packages/server/src/integrations/microsoftSqlServer.ts b/packages/server/src/integrations/microsoftSqlServer.ts index 17cbf10e90..c9e3b82a9f 100644 --- a/packages/server/src/integrations/microsoftSqlServer.ts +++ b/packages/server/src/integrations/microsoftSqlServer.ts @@ -27,11 +27,14 @@ const DEFAULT_SCHEMA = "dbo" import { ConfidentialClientApplication } from "@azure/msal-node" +import { utils } from "@budibase/shared-core" + enum MSSQLConfigAuthType { - ACTIVE_DIRECTORY = "Active Directory", + AZURE_ACTIVE_DIRECTORY = "Azure Active Directory", + NTLM = "NTLM", } -interface MSSQLConfig { +interface BasicMSSQLConfig { user: string password: string server: string @@ -40,13 +43,30 @@ interface MSSQLConfig { schema: string encrypt?: boolean authType?: MSSQLConfigAuthType - adConfig?: { +} + +interface AzureADMSSQLConfig extends BasicMSSQLConfig { + authType: MSSQLConfigAuthType.AZURE_ACTIVE_DIRECTORY + adConfig: { clientId: string clientSecret: string tenantId: string } } +interface NTLMMSSQLConfig extends BasicMSSQLConfig { + authType: MSSQLConfigAuthType.NTLM + ntlmConfig: { + domain?: string + trustServerCertificate?: boolean + } +} + +type MSSQLConfig = + | (BasicMSSQLConfig & { authType: undefined }) + | AzureADMSSQLConfig + | NTLMMSSQLConfig + const SCHEMA: Integration = { docs: "https://github.com/tediousjs/node-mssql", plus: true, @@ -93,13 +113,18 @@ const SCHEMA: Integration = { authType: { type: DatasourceFieldType.SELECT, display: "Advanced auth", - config: { options: [MSSQLConfigAuthType.ACTIVE_DIRECTORY] }, + config: { + options: [ + MSSQLConfigAuthType.AZURE_ACTIVE_DIRECTORY, + MSSQLConfigAuthType.NTLM, + ], + }, }, adConfig: { type: DatasourceFieldType.FIELD_GROUP, default: true, display: "Configure Active Directory", - hidden: "'{{authType}}' !== 'Active Directory'", + hidden: `'{{authType}}' !== '${MSSQLConfigAuthType.AZURE_ACTIVE_DIRECTORY}'`, config: { openByDefault: true, nestedFields: true, @@ -122,6 +147,28 @@ const SCHEMA: Integration = { }, }, }, + ntlmConfig: { + type: DatasourceFieldType.FIELD_GROUP, + default: true, + display: "Configure NTLM", + hidden: `'{{authType}}' !== '${MSSQLConfigAuthType.NTLM}'`, + config: { + openByDefault: true, + nestedFields: true, + }, + fields: { + domain: { + type: DatasourceFieldType.STRING, + required: false, + display: "Domain", + }, + trustServerCertificate: { + type: DatasourceFieldType.BOOLEAN, + required: false, + display: "Trust server certificate", + }, + }, + }, }, query: { create: { @@ -199,26 +246,43 @@ class SqlServerIntegration extends Sql implements DatasourcePlus { } delete clientCfg.encrypt - if (this.config.authType === MSSQLConfigAuthType.ACTIVE_DIRECTORY) { - const { clientId, tenantId, clientSecret } = this.config.adConfig! - const clientApp = new ConfidentialClientApplication({ - auth: { - clientId, - authority: `https://login.microsoftonline.com/${tenantId}`, - clientSecret, - }, - }) + switch (this.config.authType) { + case MSSQLConfigAuthType.AZURE_ACTIVE_DIRECTORY: + const { clientId, tenantId, clientSecret } = this.config.adConfig + const clientApp = new ConfidentialClientApplication({ + auth: { + clientId, + authority: `https://login.microsoftonline.com/${tenantId}`, + clientSecret, + }, + }) - const response = await clientApp.acquireTokenByClientCredential({ - scopes: ["https://database.windows.net/.default"], - }) + const response = await clientApp.acquireTokenByClientCredential({ + scopes: ["https://database.windows.net/.default"], + }) - clientCfg.authentication = { - type: "azure-active-directory-access-token", - options: { - token: response!.accessToken, - }, - } + clientCfg.authentication = { + type: "azure-active-directory-access-token", + options: { + token: response!.accessToken, + }, + } + break + case MSSQLConfigAuthType.NTLM: + const { domain, trustServerCertificate } = this.config.ntlmConfig + clientCfg.authentication = { + type: "ntlm", + options: { + domain, + }, + } + clientCfg.options ??= {} + clientCfg.options.trustServerCertificate = trustServerCertificate + break + case undefined: + break + default: + utils.unreachable(this.config) } const pool = new sqlServer.ConnectionPool(clientCfg)