Task Summary
agent-service/src/api/ currently has no test coverage — none of its four
modules (auth-api.ts, backend-api.ts, workflow-api.ts, execution-api.ts)
has a corresponding .spec.ts. It is the only directory in the service without
any tests; src/agent/tools/ and src/agent/util/ are both covered.
This task covers auth-api.ts only, so the change stays small. The remaining
three modules are HTTP clients that need a stubbed fetch, and are better
handled as a follow-up.
auth-api.ts is the authentication gate for the whole service. Every request
that asks the agent to act on a user's behalf passes through it in
server.ts:187-195:
const userToken = extractBearerToken(headers.authorization);
if (!userToken) throw new Error("Authorization header ... is required");
if (!validateToken(userToken)) throw new Error("Invalid or expired token");
const userInfo = extractUserFromToken(userToken);
The exported functions are pure and dependency-free, so they can be tested
directly with no mocking or network access.
Proposed cases
extractBearerToken
- returns the token from a well-formed
Bearer <token> header
- accepts any casing of the scheme (
bearer, BEARER)
- returns
undefined for a missing header, a non-Bearer scheme, and a
Bearer header with no token
extractUserFromToken
- maps the backend claim names (
userId, sub, email, role, set in
JwtAuth.jwtClaims) onto UserInfo
- applies the empty-email and
REGULAR-role fallbacks when those claims are
absent
- throws on a token that is not three segments, and on a non-JSON payload
validateToken
- accepts an
exp in the future, rejects one in the past
- rejects a malformed token
- pins current behaviour for a token carrying no
exp claim (see question
below)
Open question
validateToken only checks expiry — it never verifies the signature, and
isTokenExpired (auth-api.ts:49) treats a token with no exp claim as
never expiring. Both look intentional, since the Scala backend verifies the
signature properly and JwtAuth.jwtClaims always sets an expiry. I plan to
write the tests against current behaviour and flag it here rather than change
anything. Happy to be corrected if either is actually a gap.
Notes
Tests run with bun test from agent-service/, following the existing style
in src/agent/util/context-utils.spec.ts. No production code changes.
Task Type
Task Summary
agent-service/src/api/currently has no test coverage — none of its fourmodules (
auth-api.ts,backend-api.ts,workflow-api.ts,execution-api.ts)has a corresponding
.spec.ts. It is the only directory in the service withoutany tests;
src/agent/tools/andsrc/agent/util/are both covered.This task covers
auth-api.tsonly, so the change stays small. The remainingthree modules are HTTP clients that need a stubbed
fetch, and are betterhandled as a follow-up.
auth-api.tsis the authentication gate for the whole service. Every requestthat asks the agent to act on a user's behalf passes through it in
server.ts:187-195:The exported functions are pure and dependency-free, so they can be tested
directly with no mocking or network access.
Proposed cases
extractBearerTokenBearer <token>headerbearer,BEARER)undefinedfor a missing header, a non-Bearer scheme, and aBearerheader with no tokenextractUserFromTokenuserId,sub,email,role, set inJwtAuth.jwtClaims) ontoUserInfoREGULAR-role fallbacks when those claims areabsent
validateTokenexpin the future, rejects one in the pastexpclaim (see questionbelow)
Open question
validateTokenonly checks expiry — it never verifies the signature, andisTokenExpired(auth-api.ts:49) treats a token with noexpclaim asnever expiring. Both look intentional, since the Scala backend verifies the
signature properly and
JwtAuth.jwtClaimsalways sets an expiry. I plan towrite the tests against current behaviour and flag it here rather than change
anything. Happy to be corrected if either is actually a gap.
Notes
Tests run with
bun testfromagent-service/, following the existing stylein
src/agent/util/context-utils.spec.ts. No production code changes.Task Type