63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
import { describe, it, expect, beforeAll, afterAll } from 'vitest'
|
|
|
|
import { generateIdentity, type Identity } from '../../src/sharing/identity.js'
|
|
import { PeerStore, pairingCode } from '../../src/sharing/pairing.js'
|
|
import { ShareServer } from '../../src/sharing/share-server.js'
|
|
import { pairRequest, fetchUsage } from '../../src/sharing/client.js'
|
|
|
|
describe('pairingCode', () => {
|
|
it('is order-independent, deterministic, and 3 digits', () => {
|
|
expect(pairingCode('aaa', 'bbb')).toBe(pairingCode('bbb', 'aaa'))
|
|
expect(pairingCode('aaa', 'bbb')).toMatch(/^\d{3}$/)
|
|
expect(pairingCode('aaa', 'bbb')).toBe(pairingCode('aaa', 'bbb'))
|
|
})
|
|
})
|
|
|
|
describe('approve-style pairing (no PIN)', () => {
|
|
let server: ShareServer
|
|
let serverId: Identity
|
|
let clientId: Identity
|
|
let port: number
|
|
let seenCode = ''
|
|
|
|
beforeAll(async () => {
|
|
serverId = await generateIdentity('MacBook')
|
|
clientId = await generateIdentity('Mac Studio')
|
|
server = new ShareServer({
|
|
identity: serverId,
|
|
peers: new PeerStore(),
|
|
getUsage: async () => ({ current: { cost: 7 } }),
|
|
approve: async (req) => {
|
|
seenCode = req.code
|
|
return req.name !== 'Intruder'
|
|
},
|
|
})
|
|
port = await server.listen(0, '127.0.0.1')
|
|
})
|
|
|
|
afterAll(async () => {
|
|
await server.close()
|
|
})
|
|
|
|
const ep = () => ({ identity: clientId, host: '127.0.0.1', port, expectedFingerprint: serverId.fingerprint })
|
|
|
|
it('accepts an approved device, with the same code on both sides, and the token works', async () => {
|
|
const r = await pairRequest(ep(), 'Mac Studio')
|
|
expect(r.status).toBe(200)
|
|
const body = r.json as { token: string; code: string }
|
|
expect(body.token).toBeTruthy()
|
|
// Both ends derive the same confirmation code from the two fingerprints.
|
|
expect(body.code).toBe(pairingCode(serverId.fingerprint, clientId.fingerprint))
|
|
expect(seenCode).toBe(body.code)
|
|
|
|
const usage = await fetchUsage(ep(), body.token)
|
|
expect(usage.status).toBe(200)
|
|
expect((usage.json as { current: { cost: number } }).current.cost).toBe(7)
|
|
})
|
|
|
|
it('rejects a declined device', async () => {
|
|
const r = await pairRequest(ep(), 'Intruder')
|
|
expect(r.status).toBe(403)
|
|
})
|
|
})
|