| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- import { getUnsafeEntitiesInApiSql } from '@supabase/pg-meta'
- import type { EnableCheckAction, EnableCheckState } from './DataApiEnableSwitch.types'
- import { executeSql } from '@/data/sql/execute-sql-query'
- export type ExposedEntity = {
- schema: string
- name: string
- type: 'table' | 'foreign table' | 'materialized view' | 'view'
- }
- /**
- * Queries for entities that would be exposed through the Data API with
- * potential security issues: tables without RLS, foreign tables, materialized
- * views, and views without SECURITY INVOKER.
- *
- * This checks against the _target_ schemas rather than the currently active
- * PostgREST config, so it works correctly when enabling the Data API.
- */
- export async function queryUnsafeEntitiesInApi({
- projectRef,
- connectionString,
- schemas,
- }: {
- projectRef: string
- connectionString?: string | null
- schemas: Array<string>
- }): Promise<Array<ExposedEntity>> {
- if (schemas.length === 0) return []
- const { result } = await executeSql<Array<ExposedEntity>>({
- projectRef,
- connectionString,
- sql: getUnsafeEntitiesInApiSql({ schemas }),
- queryKey: ['unsafe-entities-in-api'],
- })
- return result ?? []
- }
- export const getDefaultSchemas = (dbSchema: string | null | undefined) => {
- const schemas =
- dbSchema
- ?.split(',')
- .map((schema) => schema.trim())
- .filter((schema) => schema.length > 0) ?? []
- return schemas.length > 0 ? schemas : ['public']
- }
- export function enableCheckReducer(
- state: EnableCheckState,
- action: EnableCheckAction
- ): EnableCheckState {
- switch (state.status) {
- case 'idle':
- if (action.type === 'START_CHECK') return { status: 'checking' }
- return state
- case 'checking':
- if (action.type === 'ENTITIES_FOUND')
- return { status: 'confirming', unsafeEntities: action.unsafeEntities }
- if (action.type === 'DISMISS') return { status: 'idle' }
- return state
- case 'confirming':
- if (action.type === 'DISMISS') return { status: 'idle' }
- return state
- }
- }
|