Skip to content

Commit 93369dd

Browse files
authored
fix(auth): preserve host-established trust during handshake (#99)
1 parent 603fba0 commit 93369dd

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

packages/devframe/src/recipes/__tests__/interactive-auth.test.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ async function createTestContext(): Promise<DevframeNodeContext> {
2525
}
2626

2727
/** Starts a fully-authenticated server with one trusted-only probe method. */
28-
async function startAuthenticatedServer(banners: { code: string, url: string }[] = []) {
28+
async function startAuthenticatedServer(
29+
banners: { code: string, url: string }[] = [],
30+
preTrust = false,
31+
) {
2932
const context = await createTestContext()
3033
context.rpc.register({
3134
name: 'test:trusted-only',
@@ -38,7 +41,17 @@ async function startAuthenticatedServer(banners: { code: string, url: string }[]
3841

3942
const host = '127.0.0.1'
4043
const port = await getPort({ port: 0, host })
41-
const server = await startHttpAndWs({ context, host, port, auth })
44+
const server = await startHttpAndWs({
45+
context,
46+
host,
47+
port,
48+
auth,
49+
onPeerConnect: preTrust
50+
? (_peer, session) => {
51+
session.meta.isTrusted = true
52+
}
53+
: undefined,
54+
})
4255
return { context, auth, server, host, port }
4356
}
4457

@@ -121,6 +134,22 @@ describe('recipes/interactive-auth', () => {
121134
}
122135
})
123136

137+
it('preserves trust established by the host before the client handshake', async () => {
138+
const { server, host, port } = await startAuthenticatedServer([], true)
139+
140+
try {
141+
const client = connectClient(host, port)
142+
const handshake = await client.$call('anonymous:devframe:auth', { authToken: '', ua: 'test', origin: 'http://localhost' })
143+
144+
expect(handshake).toEqual({ isTrusted: true })
145+
await expect(client.$call('test:trusted-only' as any)).resolves.toBe('ok')
146+
client.$close()
147+
}
148+
finally {
149+
await server.close()
150+
}
151+
})
152+
124153
it('self-revoke: devframe:auth:revoke drops the caller to untrusted and invalidates the token', async () => {
125154
const { server, host, port } = await startAuthenticatedServer()
126155

packages/devframe/src/recipes/interactive-auth.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ export function createInteractiveAuth(
9696
const session = context.rpc.getCurrentRpcSession()
9797
if (!session)
9898
return { isTrusted: false }
99+
if (session.meta.isTrusted)
100+
return { isTrusted: true }
99101
if (isStaticToken(params.authToken)) {
100102
session.meta.clientAuthToken = params.authToken
101103
session.meta.isTrusted = true

0 commit comments

Comments
 (0)