Background
I have an API where I need to authenticate the caller after input validation.
This is because for some endpoints the authorization depends on information provided in input parameters (e.g. which server side resource the caller wants to query or mutate, and whether the caller has permissions on that specific resource).
I've written some middleware which inserted after the .input()
call in the procedure call chain.
(See the .use(auth([authMethod1, authMethod2])
) in example router below.)
Note, my auth()
middleware method takes a list of functions so I can customize which types of auth are required for each endpoint. Some types of auth may depend on input params, others may not. Also, some endpoints need bearer token authorisation, others need API keys. This approach gives me the flexibility I need.
The problem with this approach is that if a developer creates a new endpoint and forgets to add the auth middleware, the endpoint will be wide open.
I'd therefore like to write a unit test which guards against this.
Question
How can I enumerate my router from within a unit test and check that my auth middleware is attached to each endpoint ?
The documentation is scant in this regard and only gives examples of auth middleware done at the top (procedure) level. As I've explained above, applying the same type of authorization to all my endpoints does not work for my use case.
Example router:
export const accountsRouter = router({
getOne: apiProcedure
.input(inputSchema...)
.use(auth([authMethod1, authMethod2]))
.mutation(() => {
// query logic
}),
getTwo: apiProcedure
.use(auth([authMethod1, authMethod3]))
.output(outputSchema...)
.query(() => {
// query logic
}),