Skip to content

Commit aefce0e

Browse files
committed
fix oauth selector issue
1 parent 051b9ce commit aefce0e

3 files changed

Lines changed: 25 additions & 44 deletions

File tree

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workspace-header/components/promote-workspace-modal/promote-workspace-modal.tsx

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -360,21 +360,14 @@ export function PromoteWorkspaceModal({
360360
) : safeStep === 0 ? (
361361
<div className='flex flex-col gap-7 px-2'>
362362
<SettingsSection label='Sync'>
363-
<div className='flex flex-col gap-2'>
364-
<ChipDropdown
365-
value={selectedKey}
366-
onChange={setSelectedKey}
367-
options={edgeOptions}
368-
placeholder='Select action'
369-
align='start'
370-
fullWidth
371-
/>
372-
{diff.data?.drift ? (
373-
<span className='text-[var(--text-muted)] text-small'>
374-
Target changed since the last sync — syncing will overwrite those changes.
375-
</span>
376-
) : null}
377-
</div>
363+
<ChipDropdown
364+
value={selectedKey}
365+
onChange={setSelectedKey}
366+
options={edgeOptions}
367+
placeholder='Select action'
368+
align='start'
369+
fullWidth
370+
/>
378371
</SettingsSection>
379372

380373
{workflowChanges.length > 0 ? (

apps/sim/lib/workspaces/fork/lineage/authz.ts

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,35 +46,13 @@ export class ForkError extends HttpError {
4646
async function requireWorkspace(
4747
workspaceId: string,
4848
userId: string
49-
): Promise<{
50-
workspace: WorkspaceWithOwner
51-
hasAccess: boolean
52-
canWrite: boolean
53-
canAdmin: boolean
54-
}> {
49+
): Promise<{ workspace: WorkspaceWithOwner; canAdmin: boolean }> {
5550
const access = await checkWorkspaceAccess(workspaceId, userId)
5651
if (!access.exists || !access.workspace) {
5752
throw new ForkError('Workspace not found', 404)
5853
}
5954
await assertForkingEnabled(access.workspace.organizationId)
60-
return {
61-
workspace: access.workspace,
62-
hasAccess: access.hasAccess,
63-
canWrite: access.canWrite,
64-
canAdmin: access.canAdmin,
65-
}
66-
}
67-
68-
/** Require at least read access; returns the (active) workspace. */
69-
export async function assertWorkspaceReadAccess(
70-
workspaceId: string,
71-
userId: string
72-
): Promise<WorkspaceWithOwner> {
73-
const { workspace, hasAccess } = await requireWorkspace(workspaceId, userId)
74-
if (!hasAccess) {
75-
throw new ForkError('You do not have access to this workspace', 403)
76-
}
77-
return workspace
55+
return { workspace: access.workspace, canAdmin: access.canAdmin }
7856
}
7957

8058
/** Require admin access; returns the (active) workspace. */
@@ -128,9 +106,10 @@ export interface PromoteAuthorization {
128106

129107
/**
130108
* Authorize a promote along the strict edge between `currentWorkspaceId` and
131-
* `otherWorkspaceId`. Requires read on the source and admin on the target (a
132-
* force replace is destructive). `push` sends current -> other; `pull` brings
133-
* other -> current.
109+
* `otherWorkspaceId`. Requires admin on BOTH the source and the target: a sync
110+
* reads the source's deployed workflows/resources and force-replaces the target's,
111+
* and the sync surface is only ever offered to workspace admins. `push` sends
112+
* current -> other; `pull` brings other -> current.
134113
*/
135114
export async function assertCanPromote(
136115
currentWorkspaceId: string,
@@ -144,7 +123,7 @@ export async function assertCanPromote(
144123
}
145124
const sourceWorkspaceId = direction === 'push' ? currentWorkspaceId : otherWorkspaceId
146125
const targetWorkspaceId = direction === 'push' ? otherWorkspaceId : currentWorkspaceId
147-
const source = await assertWorkspaceReadAccess(sourceWorkspaceId, userId)
126+
const source = await assertWorkspaceAdminAccess(sourceWorkspaceId, userId)
148127
const target = await assertWorkspaceAdminAccess(targetWorkspaceId, userId)
149128
return { edge, source, target, sourceWorkspaceId, targetWorkspaceId }
150129
}

apps/sim/lib/workspaces/fork/mapping/mapping-service.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,16 @@ export async function getForkMappingView(
136136
(candidate) => candidate.providerId === sourceProviderId
137137
)
138138
: targetCandidates[reference.kind]
139-
const currentTargetId = resolver(reference.kind, reference.sourceId)
139+
// Drop a stored target that no longer exists in (or no longer qualifies for) the
140+
// target workspace - e.g. the parent disconnected/deleted the resource since the
141+
// mapping was set. The entry then resurfaces as needing a mapping (re-suggested or
142+
// required-empty) instead of silently pointing at a dangling id, and the stale row
143+
// is overwritten on the next sync.
144+
const storedTargetId = resolver(reference.kind, reference.sourceId)
145+
const currentTargetId =
146+
storedTargetId && candidates.some((candidate) => candidate.id === storedTargetId)
147+
? storedTargetId
148+
: null
140149
const targetId =
141150
currentTargetId ?? suggestTarget(reference.kind, sourceLabel, sourceProviderId, candidates)
142151

0 commit comments

Comments
 (0)