Home / Function/ usePrivilegesState() — supabase Function Reference

usePrivilegesState() — supabase Function Reference

Architecture documentation for the usePrivilegesState() function in Privileges.utils.ts from the supabase codebase.

Entity Profile

Dependency Diagram

graph TD
  224303c5_4113_d7b1_8e35_e5de6e3707b8["usePrivilegesState()"]
  74fabeda_b256_2a1b_02d5_6fee692b14eb["addOrRemoveOperation()"]
  224303c5_4113_d7b1_8e35_e5de6e3707b8 -->|calls| 74fabeda_b256_2a1b_02d5_6fee692b14eb
  style 224303c5_4113_d7b1_8e35_e5de6e3707b8 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

apps/studio/components/interfaces/Database/Privileges/Privileges.utils.ts lines 98–266

export function usePrivilegesState({
  defaultTableCheckedStates,
  defaultColumnCheckedStates,
  tableId,
  role,
}: UsePrivilegesStateOptions) {
  const [operations, setOperations] = useState<PrivilegeOperation[]>([])

  const tableCheckedStates = operations.reduce((acc, op) => {
    if (op.object === 'table' && op.id === tableId && op.grantee === role) {
      return {
        ...acc,
        [op.privilege_type]: op.type === 'grant',
      }
    }

    return acc
  }, defaultTableCheckedStates)

  const columnCheckedStates = operations.reduce((acc, op) => {
    let curr = acc

    if (op.object === 'table' && op.grantee === role) {
      curr = Object.fromEntries(
        Object.entries(curr).map(([id, column]) => [
          id,
          Object.fromEntries(
            Object.entries(column).map(([privilege, value]) => [
              privilege,
              op.privilege_type === privilege ? op.type === 'grant' : value,
            ])
          ),
        ])
      )
    }

    if (op.object === 'column' && op.grantee === role) {
      return {
        ...curr,
        [op.id]: {
          ...curr[op.id],
          [op.privilege_type]: op.type === 'grant',
        },
      }
    }

    return curr
  }, defaultColumnCheckedStates)

  function toggleTablePrivilege(privilegeType: string) {
    const shouldGrant = !tableCheckedStates[privilegeType]

    setOperations((prevState) => {
      let state = [...prevState]

      if (COLUMN_PRIVILEGE_TYPES.includes(privilegeType as ColumnPrivilegeType)) {
        if (shouldGrant) {
          // remove all operations for the columns since
          // the table privilege will take precedence
          state = state.filter(
            (op) =>
              !(
                op.object === 'column' &&
                op.grantee === role &&
                op.privilege_type === privilegeType
              )
          )
        }
      }

      state = addOrRemoveOperation(state, {
        object: 'table',
        type: shouldGrant ? 'grant' : 'revoke',
        id: tableId,
        grantee: role,
        privilege_type: privilegeType,
      })

      return state
    })
  }

  function toggleColumnPrivilege(columnId: string, privilegeType: string) {
    const shouldGrant = !columnCheckedStates[columnId][privilegeType]

    setOperations((prevState) => {
      let state = [...prevState]

      // if the user is revoking a column and the table is enabled
      if (!shouldGrant && tableCheckedStates[privilegeType]) {
        // also revoke the table privilege
        state = addOrRemoveOperation(state, {
          object: 'table',
          type: 'revoke',
          id: tableId,
          grantee: role,
          privilege_type: privilegeType,
        })

        // grant all other enabled columns
        const operations = Object.entries(columnCheckedStates)
          .filter(([id]) => id !== columnId)
          .map(([id, column]) => ({
            object: 'column' as const,
            type: column[privilegeType] ? ('grant' as const) : ('revoke' as const),
            id,
            grantee: role,
            privilege_type: privilegeType,
          }))
        operations.forEach((op) => {
          state = addOrRemoveOperation(state, op)
        })
      }

      if (shouldGrant) {
        const areAllOtherColumnsEnabled = Object.entries(columnCheckedStates).every(
          ([id, column]) => id === columnId || column[privilegeType]
        )

        if (areAllOtherColumnsEnabled) {
          // remove all operations for the columns since
          // the table privilege will take precedence
          state = state.filter(
            (op) =>
              !(
                op.object === 'column' &&
                op.grantee === role &&
                op.privilege_type === privilegeType
              )
          )

          // grant the table privilege
          state = addOrRemoveOperation(state, {
            object: 'table',
            type: 'grant',
            id: tableId,
            grantee: role,
            privilege_type: privilegeType,
          })

          return state
        }
      }

      state = addOrRemoveOperation(state, {
        object: 'column',
        type: shouldGrant ? 'grant' : 'revoke',
        id: columnId,
        grantee: role,
        privilege_type: privilegeType,
      })

      return state
    })
  }

  const resetOperations = useCallback(() => {
    setOperations([])
  }, [])

  return {
    tableCheckedStates,
    columnCheckedStates,
    operations,
    toggleTablePrivilege,
    toggleColumnPrivilege,
    resetOperations,
  }
}

Subdomains

Frequently Asked Questions

What does usePrivilegesState() do?
usePrivilegesState() is a function in the supabase codebase.
What does usePrivilegesState() call?
usePrivilegesState() calls 1 function(s): addOrRemoveOperation.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free