Support native HTTPS Web listeners
This commit is contained in:
1 parent
4f8e70f936
commit
ac080346f0
71 files changed
+1355
-337
No files matched your search
@@ -76,11 +76,12 @@ function request(url: string, authority = '127.0.0.1:3080', init?: {
|
||||
function exchange(
|
||||
auth: BrowserAuth,
|
||||
authority = '127.0.0.1:3080',
|
||||
secure = false,
|
||||
): { cookie: string; launchUrl: string; state: ResponseState } {
|
||||
const launchUrl = auth.authenticatedUrl(`http://${authority}`)
|
||||
const target = new URL(launchUrl)
|
||||
const res = response()
|
||||
expect(auth.authorizeIndex(request(`${target.pathname}${target.search}`, authority), res.value)).toBe(false)
|
||||
expect(auth.authorizeIndex(request(`${target.pathname}${target.search}`, authority), res.value, secure)).toBe(false)
|
||||
const setCookie = res.state.headers?.['set-cookie']
|
||||
if (setCookie === undefined) throw new Error('token exchange did not set a cookie')
|
||||
return { cookie: setCookie.split(';', 1)[0]!, launchUrl, state: res.state }
|
||||
@@ -140,6 +141,34 @@ describe('BrowserAuth', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps HTTPS port 443 distinct from HTTP port 80 with one signing secret', async () => {
|
||||
const auth = await createAuth(new RecordCredentials())
|
||||
const plain = exchange(auth, 'harness.example')
|
||||
const tls = exchange(auth, 'harness.example', true)
|
||||
expect(auth.isAuthenticated(request('/', 'harness.example', { cookie: plain.cookie }), true)).toBe(false)
|
||||
expect(auth.isAuthenticated(request('/', 'harness.example', { cookie: tls.cookie }), true)).toBe(true)
|
||||
expect(auth.isAuthenticated(request('/', 'harness.example:443', { cookie: tls.cookie }), true)).toBe(true)
|
||||
expect(auth.isAuthenticated(request('/', 'harness.example', { cookie: tls.cookie }))).toBe(false)
|
||||
})
|
||||
|
||||
it('rejects HTTP cookie replay after enabling TLS on the same authority', async () => {
|
||||
const store = new RecordCredentials()
|
||||
const authority = 'harness.example:3080'
|
||||
const plain = exchange(await createAuth(store), authority)
|
||||
const restarted = await createAuth(store)
|
||||
const denied = response()
|
||||
expect(restarted.authorizeIndex(request('/', authority, { cookie: plain.cookie }), denied.value, true)).toBe(false)
|
||||
expect(denied.state.status).toBe(401)
|
||||
|
||||
const tls = exchange(restarted, authority, true)
|
||||
expect(tls.state.headers?.['set-cookie']).toContain('; Secure')
|
||||
expect(restarted.isAuthenticated(request('/', authority, { cookie: tls.cookie }), true)).toBe(true)
|
||||
expect(restarted.isAuthenticated(request('/', authority, { cookie: tls.cookie }))).toBe(false)
|
||||
const tlsName = tls.cookie.slice(0, tls.cookie.indexOf('='))
|
||||
const plainValue = plain.cookie.slice(plain.cookie.indexOf('=') + 1)
|
||||
expect(restarted.isAuthenticated(request('/', authority, { cookie: `${tlsName}=${plainValue}` }), true)).toBe(false)
|
||||
})
|
||||
|
||||
it('preserves the caller authority and mount while adding only this process token', async () => {
|
||||
const auth = await createAuth(new RecordCredentials())
|
||||
const mounted = new URL(auth.authenticatedUrl('https://gateway.example/tools/dsh/'))
|
||||
|
||||
Reference in new issue
Block a user