OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-proto-peer / test / sessions.test.js

35 lines · javascript ref:
// bsky-login session auth (the swarm's create/refresh-session, relayed by the keyless bridge). The
// peer verifies the app-password against a scrypt hash + mints/verifies JWTs with its own secret.

import '../lib/bare-globals.js'
import test from 'brittle'
import { makeSessions } from '../lib/sessions.js'
import { hashPassword } from 'atproto-identity/lib/auth.js'

const DID = 'did:plc:sessions22222222222222'
const HANDLE = 'sess.test'
const PW = 'correct-horse-battery-staple'
const cfg = { did: DID, handle: HANDLE, appPasswordHash: hashPassword(PW), jwtSecret: 'a'.repeat(64) }

test('sessions: create verifies the app-password + mints tokens; refresh re-mints; bad creds rejected', (t) => {
  const s = makeSessions(cfg)
  t.ok(s.canLogin, 'canLogin when hash + secret present')

  const sess = s.createSession({ identifier: HANDLE, password: PW })
  t.is(sess.did, DID, 'session carries the did')
  t.ok(sess.accessJwt && sess.refreshJwt, 'mints access + refresh tokens')

  t.exception(() => s.createSession({ identifier: HANDLE, password: 'wrong' }), /invalid credentials/, 'wrong password rejected')
  t.exception(() => s.createSession({ identifier: 'someone.else', password: PW }), /unknown identifier/, 'wrong identifier rejected')

  const refreshed = s.refreshSession(sess.refreshJwt)
  t.ok(refreshed.accessJwt, 'refresh re-mints an access token')
  t.exception(() => s.refreshSession(sess.accessJwt), /not a refresh token/, 'an access token is rejected as a refresh token')

  const payload = s.verifyAccess(sess.accessJwt)
  t.is(payload.sub, DID, 'verifyAccess accepts a valid access token for this did')
  t.exception(() => s.verifyAccess(sess.refreshJwt), /not an access token/, 'a refresh token is rejected as access')

  t.absent(makeSessions({ did: DID, handle: HANDLE }).canLogin, 'no canLogin without the secrets (secure default)')
})