Skip to content

Commit 9c9151f

Browse files
committed
fix(extension): retain drafts through permission-policy outages
1 parent e078c36 commit 9c9151f

2 files changed

Lines changed: 43 additions & 19 deletions

File tree

‎apps/sim/ee/access-requests/components/permission-access-boundary.tsx‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ReactNode } from 'react'
44
import { Chip } from '@sim/emcn'
55
import { useParams, useRouter } from 'next/navigation'
66
import { EmptyState } from '@/components/empty-state/empty-state'
7+
import { isApiClientError } from '@/lib/api/client/errors'
78
import type { BooleanPermissionGroupConfigKey } from '@/lib/permission-groups/features'
89
import { FilesEmptyState } from '@/app/workspace/[workspaceId]/components/resource/components/resource-empty-state/files-empty-state'
910
import { KnowledgeEmptyState } from '@/app/workspace/[workspaceId]/components/resource/components/resource-empty-state/knowledge-empty-state'
@@ -53,7 +54,9 @@ export function PermissionAccessBoundary({ configKey, children }: PermissionAcce
5354
<EmptyState title='Checking access' description='Loading your organization access policy.' />
5455
)
5556
}
56-
if (policy.isError) {
57+
const transientPolicyError =
58+
!isApiClientError(policy.error) || (policy.error.status >= 500 && policy.error.status < 600)
59+
if (policy.isError && (!policy.data || !transientPolicyError)) {
5760
return (
5861
<EmptyState
5962
title='Unable to check access'

‎apps/sim/scripts/test-browser-extension-e2e.ts‎

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,11 +1418,12 @@ try {
14181418
}
14191419
})
14201420
await check(
1421-
'Transient session and workspace refetch failures preserve the mounted composer and page draft',
1421+
'Transient session, workspace, and permission-policy refetch failures preserve the mounted composer and page draft',
14221422
async () => {
1423-
for (const [path, attempts] of [
1424-
['/api/auth/get-session', 1],
1425-
[`/api/workspaces/${alphaId}/host-context`, 2],
1423+
for (const [path, attempts, scope] of [
1424+
['/api/auth/get-session', 1, 'session'],
1425+
[`/api/workspaces/${alphaId}/host-context`, 2, 'workspace'],
1426+
['/api/permission-groups/user', 4, 'permission-policy'],
14261427
] as const) {
14271428
await navigate(`${base.origin}/extension/${alphaId}`)
14281429
const editor = frame().getByRole('textbox', { name: 'Message', exact: true })
@@ -1457,9 +1458,7 @@ try {
14571458
)
14581459
await expect(editor).toHaveValue('Keep this draft through a temporary network failure.')
14591460
await expect(attachments()).toHaveCount(1)
1460-
await screenshot(
1461-
path.includes('get-session') ? 'session-refetch-outage' : 'workspace-refetch-outage'
1462-
)
1461+
await screenshot(`${scope}-refetch-outage`)
14631462
} finally {
14641463
await browserContext.unroute(`${endpoint}*`)
14651464
await shell.clock.setFixedTime(Date.now())
@@ -1469,13 +1468,17 @@ try {
14691468
}
14701469
)
14711470
await check(
1472-
'Explicit session and workspace access failures clear captured context after refetch',
1471+
'Explicit session, workspace, and permission-policy failures clear captured context after refetch',
14731472
async () => {
1474-
for (const [path, status] of [
1475-
['/api/auth/get-session', 401],
1476-
['/api/auth/get-session', 403],
1477-
[`/api/workspaces/${alphaId}/host-context`, 403],
1478-
[`/api/workspaces/${alphaId}/host-context`, 404],
1473+
for (const [path, status, scope] of [
1474+
['/api/auth/get-session', 401, 'session'],
1475+
['/api/auth/get-session', 403, 'session'],
1476+
[`/api/workspaces/${alphaId}/host-context`, 403, 'workspace'],
1477+
[`/api/workspaces/${alphaId}/host-context`, 404, 'workspace'],
1478+
['/api/permission-groups/user', 401, 'permission-policy'],
1479+
['/api/permission-groups/user', 403, 'permission-policy'],
1480+
['/api/permission-groups/user', 404, 'permission-policy'],
1481+
['/api/permission-groups/user', 200, 'permission-policy'],
14791482
] as const) {
14801483
await navigate(`${base.origin}/extension/${alphaId}`)
14811484
await expect(frame().getByRole('textbox', { name: 'Message', exact: true })).toBeVisible()
@@ -1491,16 +1494,17 @@ try {
14911494
try {
14921495
await shell.clock.setFixedTime(Date.now() + 360_000)
14931496
await reconnect()
1494-
if (path.includes('get-session'))
1497+
if (scope === 'session')
14951498
await expect(frame().getByRole('link', { name: 'Sign in', exact: true })).toBeVisible()
1496-
else await expect(frame().getByText('This workspace is unavailable.')).toBeVisible()
1499+
else if (scope === 'workspace')
1500+
await expect(frame().getByText('This workspace is unavailable.')).toBeVisible()
1501+
else
1502+
await expect(frame().getByText('Unable to check access', { exact: true })).toBeVisible()
14971503
await expect(frame().getByRole('textbox', { name: 'Message', exact: true })).toHaveCount(
14981504
0
14991505
)
15001506
await expect(attachments()).toHaveCount(0)
1501-
await screenshot(
1502-
`${path.includes('get-session') ? 'session' : 'workspace'}-revoked-${status}`
1503-
)
1507+
await screenshot(`${scope}-revoked-${status}`)
15041508
} finally {
15051509
await browserContext.unroute(`${endpoint}*`)
15061510
await shell.clock.setFixedTime(Date.now())
@@ -1510,6 +1514,23 @@ try {
15101514
await expect(frame().getByRole('textbox', { name: 'Message', exact: true })).toBeVisible()
15111515
}
15121516
)
1517+
await check('An initial permission-policy outage keeps chat inaccessible', async () => {
1518+
const endpoint = `${base.origin}/api/permission-groups/user*`
1519+
await browserContext.route(endpoint, async (route) => {
1520+
injectedRequests.add(route.request())
1521+
await route.fulfill({ status: 503, json: { error: 'QA initial policy outage' } })
1522+
})
1523+
try {
1524+
await navigate(`${base.origin}/extension/${alphaId}`)
1525+
await expect(frame().getByText('Unable to check access', { exact: true })).toBeVisible()
1526+
await expect(frame().getByRole('textbox', { name: 'Message', exact: true })).toHaveCount(0)
1527+
await screenshot('permission-policy-initial-outage')
1528+
} finally {
1529+
await browserContext.unroute(endpoint)
1530+
}
1531+
await navigate(`${base.origin}/extension/${alphaId}`)
1532+
await expect(frame().getByRole('textbox', { name: 'Message', exact: true })).toBeVisible()
1533+
})
15131534
await check('Signing out removes authenticated chat and captured page context', async () => {
15141535
await capture()
15151536
const response = await browserContext.request.post(`${base.origin}/api/auth/sign-out`, {

0 commit comments

Comments
 (0)