Skip to content
Merged
2 changes: 1 addition & 1 deletion apps/docs/content/docs/cli/files.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ Enable or disable sharing for a file (OAuth login or personal API key required)
| --- | --- | --- |
| `--is-active <true\|false>` | Yes | Whether the share should resolve. Disabling preserves the token and the whole access configuration, so re-enabling restores the share as it was; enabling rewrites the credentials the resulting mode does not use. Accepted values: `true`, `false`. |
| `--auth-type <value>` | No | How access to the share is gated. The stored mode is kept when omitted. Enabling `public` clears the stored password and empties `allowedEmails`; `password` empties `allowedEmails`; `email` and `sso` clear the stored password. Accepted values: `public`, `password`, `email`, `sso`. |
| `--password <value>` | No | Password for a password-gated share. Kept when omitted; enabling `password` with neither a supplied nor a stored password is a 400. |
| `--password <value>` | No | Password of 15 to 1024 characters for a password-gated share. Kept when omitted; enabling `password` with neither a supplied nor a stored password is a 400. Taken literally, except that a request from the Sim agent resolves a whole-value `&#123;&#123;ENV_VAR&#125;&#125;` reference to that variable before the rules apply. |
| `--allowed-emails <value...>` | No | Allowed addresses or `@domain` patterns for email and SSO shares. Kept when omitted; enabling `email` or `sso` with an empty resulting list is a 400. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). |

</CommandTable>
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/docs/cli/knowledge.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -657,8 +657,8 @@ Create Knowledge Connector (OAuth login or personal API key required)
| Option | Required | Description |
| --- | --- | --- |
| `--connector-type <value>` | Yes | Registered connector type. |
| `--credential-id <value>` | No | OAuth credential identifier for connectors that require OAuth. |
| `--api-key <value>` | No | Write-only API key for connectors that use API-key authentication. |
| `--credential-id <value>` | No | OAuth credential identifier for connector types whose `auth.mode` is `oauth` (see connector types); omit it for `apiKey` connectors. |
| `--api-key <value>` | No | Write-only API key for connector types whose `auth.mode` is `apiKey` (see connector types), or a personal access token for an OAuth connector that also accepts one, such as GitHub. Send it instead of `credentialId`. Pass a raw key, or a secret reference written as the whole value `&#123;&#123;SECRET_NAME&#125;&#125;`, which the server resolves; `$SECRET_NAME` is not a reference. |
| `--source-config <json\|@file>` | Yes | Connector-specific source selection and filtering configuration. (JSON, or @path / @- to read a file or stdin). |
| `--sync-interval-minutes <value>` | No | Scheduled synchronization interval in minutes; zero disables scheduling. |

Expand Down
8 changes: 4 additions & 4 deletions apps/docs/content/docs/cli/reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1185,7 +1185,7 @@ sim files share set <fileId> [options]
| --- | --- | --- |
| `--is-active <true\|false>` | Yes | Whether the share should resolve. Disabling preserves the token and the whole access configuration, so re-enabling restores the share as it was; enabling rewrites the credentials the resulting mode does not use. Accepted values: `true`, `false`. |
| `--auth-type <value>` | No | How access to the share is gated. The stored mode is kept when omitted. Enabling `public` clears the stored password and empties `allowedEmails`; `password` empties `allowedEmails`; `email` and `sso` clear the stored password. Accepted values: `public`, `password`, `email`, `sso`. |
| `--password <value>` | No | Password for a password-gated share. Kept when omitted; enabling `password` with neither a supplied nor a stored password is a 400. |
| `--password <value>` | No | Password of 15 to 1024 characters for a password-gated share. Kept when omitted; enabling `password` with neither a supplied nor a stored password is a 400. Taken literally, except that a request from the Sim agent resolves a whole-value `&#123;&#123;ENV_VAR&#125;&#125;` reference to that variable before the rules apply. |
| `--allowed-emails <value...>` | No | Allowed addresses or `@domain` patterns for email and SSO shares. Kept when omitted; enabling `email` or `sso` with an empty resulting list is a 400. (space-separated, or @path / @- with one value per line; @@value for a literal leading @). |

</CommandTable>
Expand Down Expand Up @@ -2162,8 +2162,8 @@ sim knowledge connectors create <knowledgeBaseId> [options]
| Option | Required | Description |
| --- | --- | --- |
| `--connector-type <value>` | Yes | Registered connector type. |
| `--credential-id <value>` | No | OAuth credential identifier for connectors that require OAuth. |
| `--api-key <value>` | No | Write-only API key for connectors that use API-key authentication. |
| `--credential-id <value>` | No | OAuth credential identifier for connector types whose `auth.mode` is `oauth` (see connector types); omit it for `apiKey` connectors. |
| `--api-key <value>` | No | Write-only API key for connector types whose `auth.mode` is `apiKey` (see connector types), or a personal access token for an OAuth connector that also accepts one, such as GitHub. Send it instead of `credentialId`. Pass a raw key, or a secret reference written as the whole value `&#123;&#123;SECRET_NAME&#125;&#125;`, which the server resolves; `$SECRET_NAME` is not a reference. |
| `--source-config <json\|@file>` | Yes | Connector-specific source selection and filtering configuration. (JSON, or @path / @- to read a file or stdin). |
| `--sync-interval-minutes <value>` | No | Scheduled synchronization interval in minutes; zero disables scheduling. |

Expand Down Expand Up @@ -6469,7 +6469,7 @@ sim workflows chat publish <workflowId> [options]
| `--description <value>` | No | Description shown to visitors. Omitted clears it. |
| `--customizations <json\|@file>` | No | Presentation overrides. Omitted fields take platform defaults. (JSON, or @path / @- to read a file or stdin). |
| `--auth-type <value>` | No | How visitors are gated. `public` leaves the chat open to anyone holding the URL. Accepted values: `public`, `password`, `email`, `sso`. |
| `--password <value>` | No | Write-only password. Required whenever `authType` is `password`, and rejected otherwise. Never readable back. |
| `--password <value>` | No | Write-only password of 15 to 1024 characters, not only whitespace. Required whenever `authType` is `password`, and rejected otherwise. Never readable back. Taken literally, except that a request from the Sim agent resolves a whole-value `&#123;&#123;ENV_VAR&#125;&#125;` reference to that variable before the rules apply. |
| `--allowed-emails <json\|@file>` | No | Email addresses or domains admitted under `email` and `sso` gating. At least one is required for those modes. (JSON, or @path / @- to read a file or stdin). |
| `--output-configs <json\|@file>` | No | Block outputs to surface to visitors. Omitted surfaces none. (JSON, or @path / @- to read a file or stdin). |
| `--include-thinking` | No | Allow visitors to receive provider thinking events. |
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/cli/workflows.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ Publish or replace a workflow’s chat deployment (OAuth login or personal API k
| `--description <value>` | No | Description shown to visitors. Omitted clears it. |
| `--customizations <json\|@file>` | No | Presentation overrides. Omitted fields take platform defaults. (JSON, or @path / @- to read a file or stdin). |
| `--auth-type <value>` | No | How visitors are gated. `public` leaves the chat open to anyone holding the URL. Accepted values: `public`, `password`, `email`, `sso`. |
| `--password <value>` | No | Write-only password. Required whenever `authType` is `password`, and rejected otherwise. Never readable back. |
| `--password <value>` | No | Write-only password of 15 to 1024 characters, not only whitespace. Required whenever `authType` is `password`, and rejected otherwise. Never readable back. Taken literally, except that a request from the Sim agent resolves a whole-value `&#123;&#123;ENV_VAR&#125;&#125;` reference to that variable before the rules apply. |
| `--allowed-emails <json\|@file>` | No | Email addresses or domains admitted under `email` and `sso` gating. At least one is required for those modes. (JSON, or @path / @- to read a file or stdin). |
| `--output-configs <json\|@file>` | No | Block outputs to surface to visitors. Omitted surfaces none. (JSON, or @path / @- to read a file or stdin). |
| `--include-thinking` | No | Allow visitors to receive provider thinking events. |
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/docs/search/google-calendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ https://www.googleapis.com/auth/calendar.readonly
https://www.googleapis.com/auth/admin.directory.user.readonly
```

`calendar.readonly` is needed for calendar metadata and the CalendarList picker; event-read scope alone is insufficient. See [CalendarList authorization](https://developers.google.com/workspace/calendar/api/v3/reference/calendarList/list).
Search reads events with `calendar.events.readonly`. The calendar picker also needs `calendar.readonly` to list the delegated administrator's calendars. See [CalendarList authorization](https://developers.google.com/workspace/calendar/api/v3/reference/calendarList/list).

3. In **Settings → Sources → Google Calendar**, choose **Service account**, then **Add connection**. Add or select the Google credential and set **Delegated administrator** to an active Workspace administrator with Directory user-read access.
4. Select calendars, users, a date range, and optional event-text and attendee settings. Save and select this connection as the service source.
Expand All @@ -44,7 +44,7 @@ Sim does not copy the organizer's richer event details into an attendee's view o

| Problem | Next step |
| --- | --- |
| Calendar picker or metadata read fails | Include `calendar.readonly` in delegation, along with the other scopes above. |
| Calendar picker fails | Include `calendar.readonly` in delegation, along with the other scopes above. |
| A member gets no matches | Check their personal connection, primary Workspace identity, Users selection, calendars, and source date window. |
| Shared calendar is missing | Confirm both the member and delegated source identity can access that calendar ID. |
| Event is outside the configured range | Adjust the service source's range or narrow the user's query to its allowed window. |
Expand Down
3 changes: 1 addition & 2 deletions apps/docs/openapi-v2-files-audit.json
Original file line number Diff line number Diff line change
Expand Up @@ -5785,9 +5785,8 @@
"enum": ["public", "password", "email", "sso"]
},
"password": {
"description": "Password for a password-gated share. Kept when omitted; enabling `password` with neither a supplied nor a stored password is a 400.",
"description": "Password of 15 to 1024 characters for a password-gated share. Kept when omitted; enabling `password` with neither a supplied nor a stored password is a 400. Taken literally, except that a request from the Sim agent resolves a whole-value `{{ENV_VAR}}` reference to that variable before the rules apply.",
"type": "string",
"minLength": 15,
"maxLength": 1024
},
"allowedEmails": {
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/openapi-v2-knowledge.json
Original file line number Diff line number Diff line change
Expand Up @@ -5449,13 +5449,13 @@
"description": "Registered connector type."
},
"credentialId": {
"description": "OAuth credential identifier for connectors that require OAuth.",
"description": "OAuth credential identifier for connector types whose `auth.mode` is `oauth` (see connector types); omit it for `apiKey` connectors.",
"type": "string",
"minLength": 1,
"maxLength": 255
},
"apiKey": {
"description": "Write-only API key for connectors that use API-key authentication.",
"description": "Write-only API key for connector types whose `auth.mode` is `apiKey` (see connector types), or a personal access token for an OAuth connector that also accepts one, such as GitHub. Send it instead of `credentialId`. Pass a raw key, or a secret reference written as the whole value `{{SECRET_NAME}}`, which the server resolves; `$SECRET_NAME` is not a reference.",
"type": "string",
"minLength": 1,
"maxLength": 10000
Expand Down
8 changes: 4 additions & 4 deletions apps/docs/openapi-v2-resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -15414,7 +15414,7 @@
"mode": {
"type": "string",
"const": "oauth",
"description": "Authenticates with an OAuth credential."
"description": "Authenticates with an OAuth credential; pass `credentialId` when creating the connector."
},
"provider": {
"type": "string",
Expand All @@ -15437,7 +15437,7 @@
"mode": {
"type": "string",
"const": "apiKey",
"description": "Authenticates with a stored API key."
"description": "Authenticates with a stored API key; pass `apiKey`, and no `credentialId`, when creating the connector."
},
"label": {
"description": "Label shown above the key field.",
Expand All @@ -15456,7 +15456,7 @@
"additionalProperties": false
}
],
"description": "How the connector authenticates against its source."
"description": "How the connector authenticates against its source: `oauth` connectors take `credentialId` (GitHub also accepts a personal access token as `apiKey`), `apiKey` connectors take `apiKey`."
},
"configFields": {
"type": "array",
Expand Down Expand Up @@ -15634,7 +15634,7 @@
"mode": {
"type": "string",
"enum": ["oauth", "apiKey"],
"description": "How the connector authenticates against its source."
"description": "How the connector authenticates against its source: `oauth` connectors take `credentialId` (GitHub also accepts a personal access token as `apiKey`), `apiKey` connectors take `apiKey`."
}
},
"required": ["mode"],
Expand Down
3 changes: 1 addition & 2 deletions apps/docs/openapi-v2-workflows.json
Original file line number Diff line number Diff line change
Expand Up @@ -11558,9 +11558,8 @@
"enum": ["public", "password", "email", "sso"]
},
"password": {
"description": "Write-only password. Required whenever `authType` is `password`, and rejected otherwise. Never readable back.",
"description": "Write-only password of 15 to 1024 characters, not only whitespace. Required whenever `authType` is `password`, and rejected otherwise. Never readable back. Taken literally, except that a request from the Sim agent resolves a whole-value `{{ENV_VAR}}` reference to that variable before the rules apply.",
"type": "string",
"minLength": 1,
"maxLength": 1024
},
"allowedEmails": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
* @vitest-environment node
*/
import {
environmentUtilsMockFns,
MockV2ApiKeyUnauthenticatedError,
resetDbChainMock,
resetEnvironmentUtilsMock,
resetEnvMock,
setEnv,
V2_OPERATION_RATE_LIMIT_ALLOWED,
Expand Down Expand Up @@ -72,6 +74,8 @@ vi.mock('@/ee/access-control/utils/permission-check', () => ({
vi.mock('@/lib/api/server/routes/v2-api-key-auth', () => v2ApiKeyAuthModuleMock)
vi.mock('@/lib/core/rate-limiter', () => v2RateLimiterModuleMock)

import { markCopilotRequest } from '@/lib/api/server/routes/copilot-request'
import { performChatDeploy as realPerformChatDeploy } from '@/lib/workflows/orchestration/chat-deploy'
import { DELETE, GET, PUT } from '@/app/api/v2/workflows/[workflowId]/deployments/chat/route'

const WORKSPACE_ID = 'workspace-1'
Expand Down Expand Up @@ -481,6 +485,91 @@ describe('/api/v2/workflows/[workflowId]/deployments/chat', () => {

expect(mocks.validateChatDeployAuth).not.toHaveBeenCalled()
})

describe('password references', () => {
const passwordBody = (password: string) => ({ ...validBody, authType: 'password', password })

/** Admitted exactly as the Sim agent's in-process CLI transport admits its calls. */
const agentPut = (body: unknown) => {
const request = new NextRequest(PATH, {
method: 'PUT',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(body),
})
markCopilotRequest(request, { userId: 'user-1', workspaceId: WORKSPACE_ID, chatId: 'c-1' })
return PUT(request, routeContext)
}

const environment = (variables: Record<string, string>) =>
environmentUtilsMockFns.mockResolveEffectiveEnvironmentVariables.mockResolvedValueOnce(
Object.fromEntries(
Object.entries(variables).map(([name, value]) => [
name,
{ value, scope: 'workspace', visible: false },
])
)
)

afterEach(resetEnvironmentUtilsMock)

it("deploys with the value of the agent's referenced variable", async () => {
environment({ CHAT_PW: 'resolved-chat-password' })

const response = await agentPut(passwordBody('{{CHAT_PW}}'))

expect(response.status).toBe(200)
expect(
environmentUtilsMockFns.mockResolveEffectiveEnvironmentVariables
).toHaveBeenCalledWith('user-1', WORKSPACE_ID, ['CHAT_PW'])
expect(mocks.performChatDeploy.mock.calls[0][0].password).toBe('resolved-chat-password')
})

it('refuses an unset variable by name instead of deploying the placeholder', async () => {
const response = await agentPut(passwordBody('{{CHAT_PW}}'))

expect(response.status).toBe(400)
expect((await response.json()).error.message).toBe(
'Environment variable "CHAT_PW" referenced by password is not set for this workspace or user. Set it first, or pass the raw value.'
)
expect(mocks.performChatDeploy).not.toHaveBeenCalled()
})

it('holds the resolved value to the chat password rules', async () => {
mocks.performChatDeploy.mockImplementation(realPerformChatDeploy)
environment({ CHAT_PW: 'short' })

const response = await agentPut(passwordBody('{{CHAT_PW}}'))

expect(response.status).toBe(400)
expect((await response.json()).error.message).toBe(
'Password must be at least 15 characters'
)
})

it('keeps a reference literal for an API key caller, under the same rules', async () => {
mocks.performChatDeploy.mockImplementation(realPerformChatDeploy)

const response = await put(passwordBody('{{SHORT}}'))

expect(response.status).toBe(400)
expect((await response.json()).error.message).toBe(
'Password must be at least 15 characters'
)
expect(
environmentUtilsMockFns.mockResolveEffectiveEnvironmentVariables
).not.toHaveBeenCalled()
})

it('stores a long literal reference verbatim for an API key caller', async () => {
const response = await put(passwordBody('{{A_LONG_LITERAL_NAME}}'))

expect(response.status).toBe(200)
expect(mocks.performChatDeploy.mock.calls[0][0].password).toBe('{{A_LONG_LITERAL_NAME}}')
expect(
environmentUtilsMockFns.mockResolveEffectiveEnvironmentVariables
).not.toHaveBeenCalled()
})
})
})

describe('DELETE', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ describe('results-only search layout', () => {
const filters = mocks.search.mock.calls.at(-1)![2]
expect(filters.source).toBe('slack')
expect(mocks.searchChange).toHaveBeenLastCalledWith({ scope, query: 'Orion', filters })
expect(mocks.search).toHaveBeenLastCalledWith(scope, 'Orion', filters, 20)
expect(mocks.search).toHaveBeenLastCalledWith(scope, 'Orion', filters, 20, {
retainAcrossLimits: true,
})
})
it('summarizes the selected document through Home without duplicating search state', async () => {
await render('?q=Orion')
Expand Down
4 changes: 3 additions & 1 deletion apps/sim/app/o/[organizationId]/search/search.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ async function editDraft(value: string) {
function expectVisibleQuery(query: string) {
expect(searchInput().value).toBe(query)
expect(container.querySelector('a[data-source-link]')?.textContent).toBe(`${query} launch plan`)
expect(mocks.search).toHaveBeenLastCalledWith(scope, query, {}, 20)
expect(mocks.search).toHaveBeenLastCalledWith(scope, query, {}, 20, {
retainAcrossLimits: true,
})
expect(document.activeElement).toBe(searchInput())
}

Expand Down
Loading
Loading