diff --git a/.DS_Store b/.DS_Store index 606a28c2c..802c59b69 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/packages/access-controls/biome.json b/packages/access-controls/biome.json index b242fa54d..fd4e132e2 100644 --- a/packages/access-controls/biome.json +++ b/packages/access-controls/biome.json @@ -1,7 +1,7 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "extends": ["../../biome.json"], + "$schema": "https://biomejs.dev/schemas/2.2.5/schema.json", + "extends": ["../../biome2.json"], "files": { - "include": ["src/**/*"] + "includes": ["src/**/*"] } } diff --git a/packages/access-controls/package.json b/packages/access-controls/package.json index 232bc84f4..586c1cb62 100644 --- a/packages/access-controls/package.json +++ b/packages/access-controls/package.json @@ -32,7 +32,8 @@ "@buster/env-utils": "workspace:*", "@buster/typescript-config": "workspace:*", "@buster/vitest-config": "workspace:*", - "lru-cache": "^11.1.0", + "@biomejs/biome": "2.2.5", + "lru-cache": "^11.2.2", "node-sql-parser": "^5.3.12", "yaml": "^2.8.1", "zod": "catalog:", diff --git a/packages/access-controls/src/access-controls.ts b/packages/access-controls/src/access-controls.ts index 554a2e365..6372dfa87 100644 --- a/packages/access-controls/src/access-controls.ts +++ b/packages/access-controls/src/access-controls.ts @@ -464,11 +464,8 @@ export async function hasAllDatasetsAccess(userId: string, datasetIds: string[]) // --- Step 3: Check specific permissions for each dataset --- for (const datasetId of input.datasetIds) { const datasetOrgId = datasetInfos.find( - (info: { - id: string; - organizationId: string; - deletedAt: string | null; - }) => info.id === datasetId + (info: { id: string; organizationId: string; deletedAt: string | null }) => + info.id === datasetId )?.organizationId; if (!datasetOrgId) { diff --git a/packages/access-controls/src/assets/cache.test.ts b/packages/access-controls/src/assets/cache.test.ts index c7872b343..ae7dd212f 100644 --- a/packages/access-controls/src/assets/cache.test.ts +++ b/packages/access-controls/src/assets/cache.test.ts @@ -1,9 +1,9 @@ import { beforeEach, describe, expect, it } from 'vitest'; import { clearAllCaches, - getCacheStats, getCachedCascadingPermission, getCachedPermission, + getCacheStats, invalidateAsset, invalidateOnPermissionChange, invalidateUser, diff --git a/packages/access-controls/src/assets/cascading-permissions.ts b/packages/access-controls/src/assets/cascading-permissions.ts index f9554ba1f..90b851398 100644 --- a/packages/access-controls/src/assets/cascading-permissions.ts +++ b/packages/access-controls/src/assets/cascading-permissions.ts @@ -1,10 +1,10 @@ +import type { User } from '@buster/database/queries'; import { checkChatsContainingAsset, checkCollectionsContainingAsset, checkDashboardsContainingMetric, checkReportsContainingMetric, } from '@buster/database/queries'; -import type { User } from '@buster/database/queries'; import type { AssetType } from '@buster/database/schema-types'; import type { AssetPermissionRole, WorkspaceSharing } from '../types/asset-permissions'; import { AccessControlError } from '../types/errors'; diff --git a/packages/access-controls/src/assets/checks.test.ts b/packages/access-controls/src/assets/checks.test.ts index 1baad34bd..2e56ed958 100644 --- a/packages/access-controls/src/assets/checks.test.ts +++ b/packages/access-controls/src/assets/checks.test.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { checkPermission, computeEffectivePermission } from './checks'; import type { AssetPermissionResult } from './checks'; +import { checkPermission, computeEffectivePermission } from './checks'; // Mock database queries vi.mock('@buster/database/queries', () => ({ diff --git a/packages/access-controls/src/assets/checks.ts b/packages/access-controls/src/assets/checks.ts index 20d91e818..b0a629a6b 100644 --- a/packages/access-controls/src/assets/checks.ts +++ b/packages/access-controls/src/assets/checks.ts @@ -1,9 +1,9 @@ +import type { User } from '@buster/database/queries'; import { type CheckAssetPermissionParams, checkAssetPermission as checkDbAssetPermission, getUserOrganizationsByUserId, } from '@buster/database/queries'; -import type { User } from '@buster/database/queries'; import type { AssetType } from '@buster/database/schema-types'; import type { AssetPermissionRole, OrganizationMembership, WorkspaceSharing } from '../types'; import { getHighestPermission, isPermissionSufficient } from '../types/asset-permissions'; diff --git a/packages/access-controls/src/assets/index.ts b/packages/access-controls/src/assets/index.ts index 5b0cfddae..a0dbb3d5c 100644 --- a/packages/access-controls/src/assets/index.ts +++ b/packages/access-controls/src/assets/index.ts @@ -1,6 +1,6 @@ // Asset permissions module exports -export * from './permissions'; -export * from './checks'; -export * from './cascading-permissions'; export * from './cache'; +export * from './cascading-permissions'; +export * from './checks'; +export * from './permissions'; diff --git a/packages/access-controls/src/assets/permissions-cached.ts b/packages/access-controls/src/assets/permissions-cached.ts index 0c697773c..beaf07320 100644 --- a/packages/access-controls/src/assets/permissions-cached.ts +++ b/packages/access-controls/src/assets/permissions-cached.ts @@ -1,5 +1,5 @@ -import { checkPermission } from './checks'; import type { AssetPermissionCheck } from './checks'; +import { checkPermission } from './checks'; /** * Cached version of hasAssetPermission diff --git a/packages/access-controls/src/assets/permissions.ts b/packages/access-controls/src/assets/permissions.ts index ff8389d75..60976f2c9 100644 --- a/packages/access-controls/src/assets/permissions.ts +++ b/packages/access-controls/src/assets/permissions.ts @@ -1,10 +1,10 @@ import { - type ListAssetPermissionsParams, - type RemoveAssetPermissionParams, bulkCreateAssetPermissions, createAssetPermission, findUserByEmail, + type ListAssetPermissionsParams, listAssetPermissions, + type RemoveAssetPermissionParams, removeAssetPermission, } from '@buster/database/queries'; import type { AssetType } from '@buster/database/schema-types'; diff --git a/packages/access-controls/src/datasets/cache.test.ts b/packages/access-controls/src/datasets/cache.test.ts index 44d677ed2..deca2d101 100644 --- a/packages/access-controls/src/datasets/cache.test.ts +++ b/packages/access-controls/src/datasets/cache.test.ts @@ -2,9 +2,9 @@ import { beforeEach, describe, expect, it } from 'vitest'; import type { PermissionedDataset } from '../types/dataset-permissions'; import { clearAllCaches, - getCacheStats, getCachedDatasetAccess, getCachedPermissionedDatasets, + getCacheStats, invalidateDataset, invalidateOnPermissionChange, invalidateUser, diff --git a/packages/access-controls/src/datasets/index.ts b/packages/access-controls/src/datasets/index.ts index 8a4f28838..d4d0db63f 100644 --- a/packages/access-controls/src/datasets/index.ts +++ b/packages/access-controls/src/datasets/index.ts @@ -1,4 +1,4 @@ // Dataset permissions module exports -export * from './permissions'; export * from './cache'; +export * from './permissions'; diff --git a/packages/access-controls/src/index.ts b/packages/access-controls/src/index.ts index 00a92eb89..6694a1932 100644 --- a/packages/access-controls/src/index.ts +++ b/packages/access-controls/src/index.ts @@ -1,89 +1,80 @@ // Export all types -export * from './types'; - -// Export asset permissions (excluding cache functions to avoid conflicts) -export { - // From permissions.ts - hasAssetPermission, - createPermission, - createPermissionByEmail, - removePermission, - removePermissionByEmail, - listPermissions, - // From checks.ts - checkPermission, - computeEffectivePermission, - type AssetPermissionCheck, - type AssetPermissionResult, - // From cascading-permissions.ts - checkCascadingPermissions, - checkMetricDashboardAccess, - checkMetricChatAccess, - checkMetricCollectionAccess, - checkMetricReportAccess, - checkDashboardChatAccess, - checkDashboardCollectionAccess, -} from './assets'; - -// Export dataset permissions -export * from './datasets'; - -// Export user utilities -export * from './users'; - -// Export SQL permissions -export * from './sql-permissions'; - -// Export cache functions separately -export { - clearAllCaches, - invalidateUser, - invalidateOnPermissionChange, - getCacheStats as getAssetCacheStats, -} from './assets/cache'; - -// Export legacy access control functionality (for backward compatibility) -export { - AccessControlsError, - type Permission, - type Role, - type AccessControlOptions, -} from './types'; // Export legacy access control functions export { checkPermission as legacyCheckPermission, - hasRole, - validateAccess, getPermissionedDatasets as legacyGetPermissionedDatasets, - hasDatasetAccess as legacyHasDatasetAccess, hasAllDatasetsAccess as legacyHasAllDatasetsAccess, + hasDatasetAccess as legacyHasDatasetAccess, + hasRole, type PermissionedDataset as LegacyPermissionedDataset, + validateAccess, } from './access-controls'; +// Export asset permissions (excluding cache functions to avoid conflicts) +export { + type AssetPermissionCheck, + type AssetPermissionResult, + // From cascading-permissions.ts + checkCascadingPermissions, + checkDashboardChatAccess, + checkDashboardCollectionAccess, + checkMetricChatAccess, + checkMetricCollectionAccess, + checkMetricDashboardAccess, + checkMetricReportAccess, + // From checks.ts + checkPermission, + computeEffectivePermission, + createPermission, + createPermissionByEmail, + // From permissions.ts + hasAssetPermission, + listPermissions, + removePermission, + removePermissionByEmail, +} from './assets'; +// Export cache functions separately +export { + clearAllCaches, + getCacheStats as getAssetCacheStats, + invalidateOnPermissionChange, + invalidateUser, +} from './assets/cache'; export { canUserAccessChat } from './chats'; - // Export cached version and cache management functions export { canUserAccessChatCached, - getCacheStats, - resetCacheStats, clearCache, + getCacheStats, invalidateAccess, - invalidateUserAccess, invalidateChatAccess, + invalidateUserAccess, + resetCacheStats, } from './chats-cached'; - -// Export utility functions -export { formatPermissionName, buildAccessQuery } from './utils'; - +// Export dataset permissions +export * from './datasets'; +// Export SQL permissions +export * from './sql-permissions'; +export * from './types'; +// Export legacy access control functionality (for backward compatibility) +export { + type AccessControlOptions, + AccessControlsError, + type Permission, + type Role, +} from './types'; // Export user organization functions export { - checkUserInOrganization, - getUserOrganizations, checkEmailDomainForOrganization, - getOrganizationWithDefaults, + checkUserInOrganization, createUserInOrganization, - type UserOrganizationInfo, + getOrganizationWithDefaults, + getUserOrganizations, type OrganizationWithDefaults, + type UserOrganizationInfo, } from './user-organizations'; +// Export user utilities +export * from './users'; +// Export utility functions +export { buildAccessQuery, formatPermissionName } from './utils'; diff --git a/packages/access-controls/src/sql-permissions/index.ts b/packages/access-controls/src/sql-permissions/index.ts index ff92b2e46..3583ce7e7 100644 --- a/packages/access-controls/src/sql-permissions/index.ts +++ b/packages/access-controls/src/sql-permissions/index.ts @@ -1,3 +1,3 @@ +export * from './execute-with-permission-check'; export * from './parser-helpers'; export * from './validator'; -export * from './execute-with-permission-check'; diff --git a/packages/access-controls/src/sql-permissions/parser-helpers.ts b/packages/access-controls/src/sql-permissions/parser-helpers.ts index 6168fd01a..bc88dc75e 100644 --- a/packages/access-controls/src/sql-permissions/parser-helpers.ts +++ b/packages/access-controls/src/sql-permissions/parser-helpers.ts @@ -1,10 +1,13 @@ import pkg from 'node-sql-parser'; + const { Parser } = pkg; + import type { BaseFrom, ColumnRefItem, Join, Select } from 'node-sql-parser'; import * as yaml from 'yaml'; + +export type { QueryTypeCheckResult } from '@buster/data-source'; // Import checkQueryIsReadOnly from data-source package export { checkQueryIsReadOnly } from '@buster/data-source'; -export type { QueryTypeCheckResult } from '@buster/data-source'; export interface ParsedTable { database?: string; @@ -155,7 +158,7 @@ export function extractPhysicalTables(sql: string, dataSourceSyntax?: string): P */ export function parseTableReference(tableRef: string): ParsedTable { // Remove any quotes and trim - let cleanRef = tableRef.replace(/["'`\[\]]/g, '').trim(); + let cleanRef = tableRef.replace(/["'`[\]]/g, '').trim(); // Handle node-sql-parser format: "type::database::table" or "type::table" if (cleanRef.includes('::')) { diff --git a/packages/access-controls/src/sql-permissions/validator.ts b/packages/access-controls/src/sql-permissions/validator.ts index 187f05315..d4441df2a 100644 --- a/packages/access-controls/src/sql-permissions/validator.ts +++ b/packages/access-controls/src/sql-permissions/validator.ts @@ -1,12 +1,12 @@ import { getPermissionedDatasets } from '../datasets/permissions'; import { - type ParsedDataset, - type ParsedTable, checkQueryIsReadOnly, extractColumnReferences, extractDatasetsFromYml, extractPhysicalTables, extractTablesFromYml, + type ParsedDataset, + type ParsedTable, tablesMatch, validateWildcardUsage, } from './parser-helpers'; diff --git a/packages/access-controls/src/types.ts b/packages/access-controls/src/types.ts index 1c0613f60..57ee22222 100644 --- a/packages/access-controls/src/types.ts +++ b/packages/access-controls/src/types.ts @@ -2,8 +2,8 @@ import { z } from 'zod'; // Re-export all internal types export * from './types/asset-permissions'; -export * from './types/dataset-permissions'; export * from './types/cascading-permissions'; +export * from './types/dataset-permissions'; export * from './types/errors'; // Custom error class for access control operations (legacy - use AccessControlError instead) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ca67ac59..17b59e2c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1016,6 +1016,9 @@ importers: packages/access-controls: dependencies: + '@biomejs/biome': + specifier: 2.2.5 + version: 2.2.5 '@buster/data-source': specifier: workspace:* version: link:../data-source @@ -1035,8 +1038,8 @@ importers: specifier: 'catalog:' version: 0.44.5(@opentelemetry/api@1.9.0)(@types/pg@8.15.4)(bun-types@1.2.23(@types/react@19.1.13))(mysql2@3.14.1)(pg@8.16.3)(postgres@3.4.7) lru-cache: - specifier: ^11.1.0 - version: 11.1.0 + specifier: ^11.2.2 + version: 11.2.2 node-sql-parser: specifier: ^5.3.12 version: 5.3.12 @@ -9419,10 +9422,6 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.1.0: - resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} - engines: {node: 20 || >=22} - lru-cache@11.2.2: resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==} engines: {node: 20 || >=22} @@ -22666,8 +22665,6 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.1.0: {} - lru-cache@11.2.2: {} lru-cache@5.1.1: