Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b4b9f4e
fix(admin): reflow security page dropdowns between title and descript…
jmelahman Aug 11, 2026
a7eb39c
feat(web): allow production builds to skip type checking (#13848)
jmelahman Aug 11, 2026
8dda380
fix(highspot): surface plain-text API errors and xfail the 403 tests …
Subash-Mohan Aug 11, 2026
74a6878
fix(admin): prevent date range picker pills from clipping in narrow h…
rohoswagger Aug 11, 2026
0d8ca41
fix(web): stop rendering "Anonymous" while the current user is unreso…
nmgarza5 Aug 11, 2026
e212595
fix(craft): restore stale skills after turn failure (#13859)
wenxi-onyx Aug 11, 2026
31aa7b1
fix: preserve HTML table and link boundaries (#13864)
evan-onyx Aug 11, 2026
23dbf48
fix(web): fix react-doctor error-class findings and enforce via oxlin…
nmgarza5 Aug 11, 2026
92f7966
chore: remove spending limits page and make cost-budget API Enterpris…
rohoswagger Aug 11, 2026
f7144e3
fix(web): show the container host note on all self-hosted providers (…
jmelahman Aug 11, 2026
5584748
feat: avoid redundant SharePoint list item lookups (#13851)
evan-onyx Aug 11, 2026
d952f40
ci: skip type checking in the Playwright web image build (#13871)
jmelahman Aug 11, 2026
08ad3e4
chore(deps-dev): bump tailwindcss from 4.3.1 to 4.3.3 in /web (#13569)
dependabot[bot] Aug 11, 2026
8a20a31
chore(deps): bump marked from 18.0.5 to 18.0.7 (#13568)
dependabot[bot] Aug 11, 2026
eea2337
chore(deps-dev): bump @typescript/native-preview from 7.0.0-dev.20260…
dependabot[bot] Aug 11, 2026
8a7d9ed
chore(deps): bump actions/setup-python from 6.3.0 to 7.0.0 (#13574)
dependabot[bot] Aug 11, 2026
5ff8ea9
chore(deps-dev): bump typescript from 6.0.3 to 7.0.2 (#13571)
dependabot[bot] Aug 11, 2026
35f0626
chore(deps): bump azure/setup-helm from 5.0.0 to 5.0.1 (#13573)
dependabot[bot] Aug 11, 2026
8b7458d
chore(web): upgrade Next.js to 16.3.0 to cut dev server memory (#13868)
jmelahman Aug 11, 2026
8a69f41
chore(deps): bump lucide-react from 1.21.0 to 1.25.0 in /web (#13572)
dependabot[bot] Aug 11, 2026
dd96757
chore(deps): bump astral-sh/setup-uv from 8.2.0 to 9.0.0 (#13565)
dependabot[bot] Aug 11, 2026
bb0f25d
feat(connector-stability): slack source operations gateway (#13772)
acaprau Aug 11, 2026
e8e2300
chore(deps): bump gitpython from 3.1.57 to 3.1.58 (#13820)
dependabot[bot] Aug 11, 2026
88e1c2f
chore(deps): bump h2 from 4.3.0 to 4.4.1 (#13799)
dependabot[bot] Aug 11, 2026
81f9af6
chore(deps-dev): bump pypdf from 6.14.2 to 6.15.0 (#13822)
dependabot[bot] Aug 11, 2026
43e1bd4
chore(deps-dev): bump aiohttp from 3.14.1 to 3.14.3 (#13723)
dependabot[bot] Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
persist-credentials: false

- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # ratchet:astral-sh/setup-uv@v8.2.0
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # ratchet:astral-sh/setup-uv@v9.0.0
with:
version: "0.11.25"
enable-cache: false
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
fetch-tags: true

- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # ratchet:astral-sh/setup-uv@v8.2.0
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # ratchet:astral-sh/setup-uv@v9.0.0
with:
version: "0.11.25"
enable-cache: false
Expand Down Expand Up @@ -169,7 +169,7 @@ jobs:
persist-credentials: false

- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # ratchet:astral-sh/setup-uv@v8.2.0
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # ratchet:astral-sh/setup-uv@v9.0.0
with:
version: "0.11.25"
enable-cache: false
Expand Down Expand Up @@ -198,7 +198,7 @@ jobs:
fetch-depth: 0

- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # ratchet:astral-sh/setup-uv@v8.2.0
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # ratchet:astral-sh/setup-uv@v9.0.0
with:
version: "0.11.25"
# NOTE: This isn't caching much and zizmor suggests this could be poisoned, so disable.
Expand Down Expand Up @@ -2027,7 +2027,7 @@ jobs:

- name: Setup uv
if: steps.should-run.outputs.run == 'true'
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # ratchet:astral-sh/setup-uv@v8.2.0
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # ratchet:astral-sh/setup-uv@v9.0.0
with:
version: "0.11.25"
enable-cache: false
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/helm-chart-releases.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
persist-credentials: false

- name: Install Helm CLI
uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # ratchet:azure/setup-helm@v5.0.0
uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # ratchet:azure/setup-helm@v5.0.1
with:
version: v3.12.1

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/post-merge-beta-cherry-pick.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ jobs:
token: ${{ steps.app-token.outputs.token }}

- name: Install the latest version of uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
with:
enable-cache: false
version: "0.11.25"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-external-dependency-unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:

- name: Setup Helm
if: matrix.test-dir == 'craft_helm'
uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # ratchet:azure/setup-helm@v5.0.0
uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # ratchet:azure/setup-helm@v5.0.1
with:
version: v3.19.0

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-helm-chart-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
persist-credentials: false

- name: Set up Helm
uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # ratchet:azure/setup-helm@v5.0.0
uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # ratchet:azure/setup-helm@v5.0.1
with:
version: v3.19.0

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/pr-playwright-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}

# SKIP_TYPE_CHECK cuts the build time of this image. Types are still checked
# by the `typescript-check` prek hook in the Quality Checks PR workflow.
- name: Build and push Web Docker image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a
with:
Expand All @@ -215,6 +217,7 @@ jobs:
push: true
build-args: |
BASE_IMAGE_REGISTRY=${{ env.BASE_IMAGE_REGISTRY }}
SKIP_TYPE_CHECK=1
cache-from: |
type=registry,ref=${{ env.RUNS_ON_ECR_CACHE }}:web-cache-${{ github.event.pull_request.head.sha || github.sha }}
type=registry,ref=${{ env.RUNS_ON_ECR_CACHE }}:web-cache-${{ steps.format-branch.outputs.cache-suffix }}
Expand Down Expand Up @@ -988,7 +991,7 @@ jobs:
aws-region: us-east-2

- name: Install the latest version of uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # ratchet:astral-sh/setup-uv@v8.2.0
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # ratchet:astral-sh/setup-uv@v9.0.0
with:
enable-cache: false
version: "0.11.25"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-quality-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # ratchet:actions/setup-python@v6
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # ratchet:actions/setup-python@v7.0.0
with:
python-version: "3.13"
- name: Setup Terraform
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # ratchet:actions/checkout@v6
with:
persist-credentials: false
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # ratchet:astral-sh/setup-uv@v8.2.0
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # ratchet:astral-sh/setup-uv@v9.0.0
with:
enable-cache: false
version: "0.11.25"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release-devtools.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # ratchet:actions/checkout@v6
with:
persist-credentials: false
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # ratchet:astral-sh/setup-uv@v8.2.0
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # ratchet:astral-sh/setup-uv@v9.0.0
with:
enable-cache: false
version: "0.11.25"
Expand Down Expand Up @@ -74,7 +74,7 @@ jobs:
token: ${{ steps.app-token.outputs.token }}

- name: Install the latest version of uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # ratchet:astral-sh/setup-uv@v8.2.0
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # ratchet:astral-sh/setup-uv@v9.0.0
with:
enable-cache: false
version: "0.11.25"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/zizmor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
persist-credentials: false

- name: Install the latest version of uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # ratchet:astral-sh/setup-uv@v8.2.0
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # ratchet:astral-sh/setup-uv@v9.0.0
with:
enable-cache: false
version: "0.11.25"
Expand Down
21 changes: 10 additions & 11 deletions backend/ee/onyx/external_permissions/sharepoint/permission_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
from onyx.connectors.sharepoint.connector import (
GRAPH_API_MAX_RETRIES,
GRAPH_API_RETRYABLE_STATUSES,
LIST_ITEM_ID_PROPERTY,
SHARED_DOCUMENTS_MAP_REVERSE,
SHAREPOINT_IDS_PROPERTY,
sleep_and_retry,
)
from onyx.connectors.sharepoint.connector_utils import (
Expand All @@ -50,6 +52,7 @@
MICROSOFT_DOMAIN = ".onmicrosoft"
SHAREPOINT_GROUP_SCOPE_SEPARATOR = "::"
GROUP_CACHE_KEY_SEPARATOR = ":"
GET_SHAREPOINT_LIST_ITEM_ID_LABEL = "get_sharepoint_list_item_id"
# PnP RoleType defines Guest=1 and RestrictedGuest=9:
# https://github.com/pnp/pnpcore/blob/4e4f58fcac797f2957bfcd14fedcecd690dfe7ee/src/sdk/PnP.Core/Model/SharePoint/Core/Public/Enums/RoleType.cs
LIMITED_ACCESS_ROLE_TYPES = frozenset({1, 9})
Expand Down Expand Up @@ -224,24 +227,20 @@ def _get_group_guid_from_identifier(

def _get_sharepoint_list_item_id(drive_item: DriveItem) -> str | None:
try:
# First try to get the list item directly from the drive item
properties = getattr(drive_item, "properties", None)
sharepoint_ids = properties.get(SHAREPOINT_IDS_PROPERTY) if properties else None
if isinstance(sharepoint_ids, dict):
if list_item_id := sharepoint_ids.get(LIST_ITEM_ID_PROPERTY):
return str(list_item_id)

if hasattr(drive_item, "listItem"):
list_item = drive_item.listItem
if list_item:
# Load the list item properties to get the ID
sleep_and_retry(list_item.get(), "get_sharepoint_list_item_id")
sleep_and_retry(list_item.get(), GET_SHAREPOINT_LIST_ITEM_ID_LABEL)
if hasattr(list_item, "id") and list_item.id:
return str(list_item.id)

# The SharePoint list item ID is typically available in the sharepointIds property
sharepoint_ids = getattr(drive_item, "sharepoint_ids", None)
if sharepoint_ids and hasattr(sharepoint_ids, "listItemId"):
return sharepoint_ids.listItemId

# Alternative: try to get it from the properties
properties = getattr(drive_item, "properties", None)
if properties:
# Sometimes the SharePoint list item ID is in the properties
for prop_name, prop_value in properties.items():
if "listitemid" in prop_name.lower():
return str(prop_value)
Expand Down
19 changes: 6 additions & 13 deletions backend/ee/onyx/external_permissions/slack/channel_access.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
from slack_sdk import WebClient

from onyx.access.models import ExternalAccess
from onyx.connectors.models import BasicExpertInfo
from onyx.connectors.slack.connector import ChannelType, channel_team_ids
from onyx.connectors.slack.utils import (
expert_info_from_slack_id,
make_paginated_slack_api_call,
)
from onyx.connectors.slack.source_operations import SlackSourceOperations
from onyx.connectors.slack.utils import expert_info_from_slack_id


def get_channel_access(
client: WebClient,
slack_client: SlackSourceOperations,
channel: ChannelType,
user_cache: dict[str, BasicExpertInfo | None],
team_id_to_user_emails: dict[str, set[str]] | None = None,
Expand Down Expand Up @@ -45,17 +41,14 @@ def get_channel_access(
channel_id = channel["id"]

member_ids = []
for result in make_paginated_slack_api_call(
client.conversations_members,
channel=channel_id,
):
member_ids.extend(result.get("members", []))
for result in slack_client.list_channel_members(channel_id=channel_id):
member_ids.extend(result.members)

member_emails = set()
for member_id in member_ids:
user_info = expert_info_from_slack_id(
user_id=member_id,
client=client,
fetch_user_info=slack_client.fetch_user_info,
user_cache=user_cache,
)
if user_info and user_info.email:
Expand Down
62 changes: 25 additions & 37 deletions backend/ee/onyx/external_permissions/slack/doc_sync.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from collections.abc import Generator

from slack_sdk import WebClient

from ee.onyx.external_permissions.perm_sync_types import (
FetchAllDocumentsFunction,
FetchAllDocumentsIdsFunction,
Expand All @@ -11,9 +9,9 @@
fetch_team_user_emails,
fetch_user_id_to_email_map,
)
from ee.onyx.external_permissions.utils import credential_json
from onyx.access.models import DocExternalAccess, ExternalAccess
from onyx.connectors.credentials_provider import OnyxDBCredentialsProvider
from onyx.configs.constants import DocumentSource
from onyx.connectors.credentials_provider import build_db_credentials_provider
from onyx.connectors.interfaces import SecondsSinceUnixEpoch
from onyx.connectors.models import HierarchyNode
from onyx.connectors.slack.connector import (
Expand All @@ -22,14 +20,12 @@
get_channels,
get_channels_across_teams,
list_grid_team_ids,
make_paginated_slack_api_call,
)
from onyx.connectors.slack.models import ChannelType
from onyx.connectors.slack.source_operations import SlackSourceOperations
from onyx.db.models import ConnectorCredentialPair
from onyx.indexing.indexing_heartbeat import IndexingHeartbeatInterface
from onyx.redis.redis_pool import get_redis_client
from onyx.utils.logger import setup_logger
from shared_configs.contextvars import get_current_tenant_id

logger = setup_logger()

Expand Down Expand Up @@ -87,7 +83,7 @@ def _filter_channels_for_permissions(


def _fetch_channel_permissions(
slack_client: WebClient,
slack_client: SlackSourceOperations,
workspace_permissions: ExternalAccess, # noqa: ARG001
user_id_to_email_map: dict[str, str],
team_ids: list[str] | None = None,
Expand All @@ -100,25 +96,25 @@ def _fetch_channel_permissions(
channel_permissions = {}
if team_ids:
public_channels = get_channels_across_teams(
client=slack_client,
slack_client=slack_client,
team_ids=team_ids,
get_public=True,
get_private=False,
)
private_channels = get_channels_across_teams(
client=slack_client,
slack_client=slack_client,
team_ids=team_ids,
get_public=False,
get_private=True,
)
else:
public_channels = get_channels(
client=slack_client,
slack_client=slack_client,
get_public=True,
get_private=False,
)
private_channels = get_channels(
client=slack_client,
slack_client=slack_client,
get_public=False,
get_private=True,
)
Expand All @@ -142,7 +138,7 @@ def _fetch_channel_permissions(
continue
if team_id_to_user_emails:
channel_permissions[channel_id] = get_channel_access(
client=slack_client,
slack_client=slack_client,
channel=channel,
user_cache={},
team_id_to_user_emails=team_id_to_user_emails,
Expand All @@ -158,11 +154,8 @@ def _fetch_channel_permissions(
for channel_id in private_channel_ids:
# Collect all member ids for the channel pagination calls
member_ids = []
for result in make_paginated_slack_api_call(
slack_client.conversations_members,
channel=channel_id,
):
member_ids.extend(result.get("members", []))
for result in slack_client.list_channel_members(channel_id=channel_id):
member_ids.extend(result.members)

# Collect all member emails for the channel
member_emails = set()
Expand All @@ -173,8 +166,8 @@ def _fetch_channel_permissions(
# If the user is an external user, they wont get returned from the
# conversations_members call so we need to make a separate call to users_info
# and add them to the user_id_to_email_map
member_info = slack_client.users_info(user=member_id)
member_email = member_info["user"]["profile"].get("email")
member_info = slack_client.fetch_user_info(member_id)
member_email = member_info.user["profile"].get("email")
if not member_email:
# If no email is found, we skip the user
continue
Expand Down Expand Up @@ -241,30 +234,25 @@ def slack_doc_sync(
callback: IndexingHeartbeatInterface | None,
) -> Generator[DocExternalAccess, None, None]:
"""
Adds the external permissions to the documents in postgres
if the document doesn't already exists in postgres, we create
it in postgres so that when it gets created later, the permissions are
already populated
Adds the external permissions to the documents in postgres if the document
doesn't already exists in postgres, we create it in postgres so that when it
gets created later, the permissions are already populated
"""
# Use credentials provider instead of directly loading credentials

tenant_id = get_current_tenant_id()
provider = OnyxDBCredentialsProvider(tenant_id, "slack", cc_pair.credential.id)
r = get_redis_client(tenant_id=tenant_id)
creds = credential_json(cc_pair)
slack_client = SlackConnector.make_slack_web_client(
provider.get_provider_key(),
creds["slack_bot_token"],
SlackConnector.MAX_RETRIES,
r,
# One provider and one gateway-owned client, shared with the indexing path:
# the connector's rotation lock and rate-limit delay keys now coordinate
# with running indexing jobs instead of living under perm-sync-only keys.
provider = build_db_credentials_provider(
DocumentSource.SLACK, cc_pair.credential.id
)
slack_connector = SlackConnector(**cc_pair.connector.connector_specific_config)
slack_connector.set_credentials_provider(provider)
slack_client = slack_connector.slack_client
assert slack_client is not None, "set_credentials_provider builds the gateway."

grid_team_ids: list[str] | None = None
try:
auth_response = slack_client.auth_test()
if auth_response.get("enterprise_id"):
auth_response = slack_client.check_auth()
if auth_response.enterprise_id:
grid_team_ids = list_grid_team_ids(slack_client)
except Exception as e:
logger.warning("Slack Grid detection during perm sync failed: %s", e)
Expand Down
Loading
Loading