mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-07 08:02:20 +00:00
* feat: deploy from the UI to a workspace on another instance Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep the remote deploy proxy from being spent by a link Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: key remote deploy proxy URLs instead of a global client header Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep the remote deploy proxy key out of logs and restricted hands Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: serialize remote deploy connect with account and key changes Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: key remote deploy tokens to the account and connect by signing in Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: bind remote deploy connect to its target and order its locks Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: serialize remote deploy connect with target changes Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: list every lock remote deploy connect takes in auth-surface Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: never wait on the membership lock in remote deploy connect Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep a superseded target response out of the settings form Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: void stale remote deploy tokens on read instead of locking in connect Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: void remote deploy tokens older than the last target change Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: order remote deploy connections by when their connect started Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: bind stored remote deploy tokens to the membership and target they were connected under Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: answer remote deploy connect without settings as no target Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'
|
|
import { PENDING_TTL_MS, remoteDeployAuthorizeUrl, takePendingConnect } from './remoteDeploy'
|
|
|
|
const target = { base_url: 'https://prod.example.com', workspace_id: 'prod' }
|
|
|
|
function startConnect(workspace = 'dev'): string {
|
|
const url = new URL(remoteDeployAuthorizeUrl(target, workspace, '/deploy/flow/f/a'))
|
|
return url.searchParams.get('state')!
|
|
}
|
|
|
|
describe('remote deploy connect state', () => {
|
|
beforeEach(() => {
|
|
localStorage.clear()
|
|
vi.stubGlobal('window', { location: { origin: 'https://dev.example.com' } })
|
|
})
|
|
afterEach(() => {
|
|
vi.useRealTimers()
|
|
vi.unstubAllGlobals()
|
|
})
|
|
|
|
// The state is what keeps any other page from planting a token as the user's.
|
|
it('matches only the state it issued, and only once', () => {
|
|
const state = startConnect()
|
|
expect(takePendingConnect('forged')).toBeUndefined()
|
|
expect(takePendingConnect(state)).toMatchObject({ workspace: 'dev', target })
|
|
expect(takePendingConnect(state)).toBeUndefined()
|
|
})
|
|
|
|
it('keeps concurrent attempts apart', () => {
|
|
const first = startConnect('dev')
|
|
const second = startConnect('staging')
|
|
expect(takePendingConnect(first)?.workspace).toBe('dev')
|
|
expect(takePendingConnect(second)?.workspace).toBe('staging')
|
|
})
|
|
|
|
it('expires an attempt left unfinished, and drops it from storage', () => {
|
|
vi.useFakeTimers()
|
|
const abandoned = startConnect()
|
|
vi.advanceTimersByTime(PENDING_TTL_MS + 60_000)
|
|
startConnect()
|
|
expect(localStorage.length).toBe(1)
|
|
expect(takePendingConnect(abandoned)).toBeUndefined()
|
|
})
|
|
})
|