Move browser authentication behind a generated-contract BFF

This commit is contained in:
ms2k 2026-07-19 18:21:17 +09:00
commit fa7220ee33

View file

@ -1,6 +1,7 @@
import { createPrivateKey, sign } from 'node:crypto'
import { createPrivateKey, randomBytes, sign } from 'node:crypto'
import { expect, test } from '@playwright/test'
import { createClient } from 'redis'
test('authenticates and completes a deployed job lifecycle through ingress', async ({
page,
@ -8,28 +9,49 @@ test('authenticates and completes a deployed job lifecycle through ingress', asy
const token = await mintZitadelToken()
const claims = jwtClaims(token)
const issuer = requiredEnv('REMORA_OIDC_ISSUER')
const sessionId = randomBytes(32).toString('base64url')
const csrfToken = randomBytes(24).toString('base64url')
const coordination = createClient({
url: requiredEnv('REMORA_COORDINATION_URL'),
})
await coordination.connect()
await coordination.set(
`${requiredEnv('REMORA_COORDINATION_NAMESPACE')}web-session:${sessionId}`,
JSON.stringify({
kind: 'authenticated',
identity: `${issuer}\u0000${stringValue(claims.sub, 'subject')}`,
csrfToken,
accessToken: token,
refreshToken: null,
idToken: 'qualification-session',
accessExpiresAt: Number(claims.exp),
}),
{ EX: 3600 },
)
await coordination.quit()
await page.context().addCookies([
{
name: 'remora-qualification-session',
value: sessionId,
url: requiredEnv('REMORA_SYSTEM_BASE_URL'),
sameSite: 'Strict',
},
])
const assetResponse = page.waitForResponse((response) => {
const path = new URL(response.url()).pathname
return path.startsWith('/assets/') && path.endsWith('.js')
})
await page.goto('/')
await page.evaluate(
({ accessToken, authority, profile }) => {
sessionStorage.setItem(
`oidc.user:${authority}:remora-web`,
JSON.stringify({
access_token: accessToken,
token_type: 'Bearer',
scope: 'openid profile',
profile,
expires_at: Number(profile.exp),
}),
)
},
{ accessToken: token, authority: issuer, profile: claims },
expect(['br', 'gzip']).toContain(
(await assetResponse).headers()['content-encoding'],
)
await page.reload()
await expect(page.getByRole('heading', { name: 'Remora' })).toBeVisible()
await expect(page.getByRole('button', { name: 'Sign out' })).toBeVisible()
await expect(page.getByLabel('Synchronization status')).toHaveText('live')
await expect(page.getByLabel('Synchronization status')).toHaveText('live', {
timeout: 30_000,
})
await expect(page.getByText('deployment-coordination-rebuild')).toBeVisible()
await page.getByRole('button', { name: 'Submit job' }).click()
@ -39,7 +61,7 @@ test('authenticates and completes a deployed job lifecycle through ingress', asy
const submitted = page.waitForResponse(
(response) =>
response.request().method() === 'POST' &&
new URL(response.url()).pathname === '/v1/jobs',
new URL(response.url()).pathname === '/bff/api/jobs',
)
await page.getByRole('button', { name: 'Submit job now' }).click()
const response = await submitted