Skip to content

Commit eff2a95

Browse files
committed
fix(desktop): reject incomplete update feeds
1 parent 47cd071 commit eff2a95

4 files changed

Lines changed: 29 additions & 1 deletion

File tree

apps/sim/app/api/desktop/update/download/route.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@ describe('desktop update download route', () => {
126126
})
127127
})
128128

129+
it('reports an invalid feed when every release candidate is rejected', async () => {
130+
const incomplete = release('v1.4.0', DESKTOP_STABLE_RELEASE_REPOSITORY)
131+
incomplete.assets = incomplete.assets.filter((asset) => asset.name === MANIFEST_ASSET_NAME)
132+
mockReleases([incomplete])
133+
134+
const response = await getDownload()
135+
136+
expect(response.status).toBe(502)
137+
expect(await response.json()).toMatchObject({ error: 'Release installer unavailable' })
138+
})
139+
129140
it('surfaces an unreadable release list instead of redirecting', async () => {
130141
fetchMock.mockResolvedValueOnce(new Response(null, { status: 500 }))
131142

apps/sim/app/api/desktop/update/download/route.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ export const GET = withRouteHandler(async (_request: NextRequest): Promise<Respo
8787
}
8888

8989
if (!resolved.release) {
90+
if (resolved.rejectedCandidates) {
91+
return NextResponse.json({ error: 'Release installer unavailable' }, { status: 502 })
92+
}
9093
return NextResponse.json(
9194
{ error: `No desktop release for channel ${channel}` },
9295
{ status: 404 }

apps/sim/lib/desktop/update-feed.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,16 @@ describe('rewriteManifestUrls', () => {
194194
rewriteManifestUrls(manifest, 'v0.5.24', DESKTOP_STABLE_RELEASE_REPOSITORY, new Set())
195195
).toBeNull()
196196
})
197+
198+
it('rejects a manifest without an updater file entry', () => {
199+
const manifest = ['version: 0.5.24', 'files: []', 'path: Sim-0.5.24-universal.zip'].join('\n')
200+
expect(
201+
rewriteManifestUrls(
202+
manifest,
203+
'v0.5.24',
204+
DESKTOP_STABLE_RELEASE_REPOSITORY,
205+
new Set(['Sim-0.5.24-universal.zip'])
206+
)
207+
).toBeNull()
208+
})
197209
})

apps/sim/lib/desktop/update-feed.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export function rewriteManifestUrls(
131131
const version = tag.replace(/^v/, '')
132132
const expectedNames = new Set([`Sim-${version}-universal.dmg`, `Sim-${version}-universal.zip`])
133133
let valid = true
134+
let hasUpdaterFile = false
134135
const rewritten = manifest.replace(
135136
/^(\s*(?:-\s*)?(?:url|path):\s*)(\S+)\s*$/gm,
136137
(_line, prefix: string, value: string) => {
@@ -144,14 +145,15 @@ export function rewriteManifestUrls(
144145
valid = false
145146
return ''
146147
}
148+
if (/\burl:\s*$/.test(prefix)) hasUpdaterFile = true
147149
return `${prefix}${base}${encodeURIComponent(name)}`
148150
} catch {
149151
valid = false
150152
return ''
151153
}
152154
}
153155
)
154-
return valid ? rewritten : null
156+
return valid && hasUpdaterFile ? rewritten : null
155157
}
156158

157159
/**

0 commit comments

Comments
 (0)