Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(fastify): flatten byu jwt authenticator options #156

Merged
merged 1 commit into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions packages/fastify/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,20 @@ fastify.register(ByuJwtProvider, {
prefix: '/example/v1',
development: process.env.NODE_ENV === 'development',
/** May pass in ByuJwt options from @byu-oit/jwt */
byuJwtOptions: {
issuer: 'https://api.byu.edu',
additionalValidations: [() => {
if(false) throw new Error('This will never happen')
}]
}

issuer: 'https://api.byu.edu',
additionalValidations: [(jwt) => {
if(false) throw new Error('This will never happen')
}]
})

await fastify.listen({ port: 3000 }).catch(console.error)
```

## Options
In addition to the three properties below, you can also pass in any options that are defined in [BYU JWT](https://byu-oit.github.io/byu-jwt-nodejs/modules/BYU_JWT.html#md:options) documentation as well.

| property | type | default | description |
|-----------------------|---------|-------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| prefix | string | `undefined` | Will only authenticate routes matching this prefix. |
| development | boolean | false | skips JWT verification for development purposes but will throw an error if NODE_ENV is set to `production`. |
| basePath | string | `undefined` | will validate that the audience starts with the provided basePath in production. |
| byuJwtOptions | object | `undefined` | an object that contains any ByuJwt options passed in. See the [BYU JWT](https://byu-oit.github.io/byu-jwt-nodejs/modules/BYU_JWT.html#md:options) Documentation for a full list of those options. |
| property | type | default | description |
|------------------|---------|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| prefix | string | `undefined` | Will only authenticate routes matching this prefix. |
| development | boolean | false | skips JWT verification for development purposes but will throw an error if NODE_ENV is set to `production`. |
| basePath | string | `undefined` | will validate that the audience starts with the provided basePath in production. |
6 changes: 2 additions & 4 deletions packages/fastify/src/ByuJwtAuthenticator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { TokenError } from 'fast-jwt'
import { type IncomingHttpHeaders } from 'http'
import { BYU_JWT_ERROR_CODES, ByuJwtError } from './ByuJwtError.js'

export interface ByuJwtAuthenticatorOptions {
byuJwtOptions?: CreateByuJwtOptions
export interface ByuJwtAuthenticatorOptions extends CreateByuJwtOptions {
development?: boolean
basePath?: string
}
Expand All @@ -16,9 +15,8 @@ export class ByuJwtAuthenticator {
private readonly ByuJwt: typeof ByuJwt
private readonly development: boolean

constructor ({ development, basePath, byuJwtOptions = {} }: ByuJwtAuthenticatorOptions = {}) {
constructor ({ development, basePath, ...byuJwtOptions }: ByuJwtAuthenticatorOptions = {}) {
this.development = development ?? false

/** Extra validation step if basePath is provided */
if (basePath != null) {
if (byuJwtOptions.additionalValidations == null) {
Expand Down
6 changes: 3 additions & 3 deletions packages/fastify/test/ByuJwtProvider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const errorHandler = (error: ByuJwtError, request: FastifyRequest, reply: Fastif

test('authenticated user', async t => {
const fastify = Fastify()
await fastify.register(ByuJwtProvider, { byuJwtOptions: { issuer }, development })
await fastify.register(ByuJwtProvider, { issuer, development })
fastify.get('/', (request) => request.caller)
const result = await fastify.inject({ url: '/', headers: { 'x-jwt-assertion': expiredJwt } }).then(res => res.json())
t.is(result.netId, 'stuft2')
})

test('cannot fetch key', async t => {
const fastify = Fastify()
await fastify.register(ByuJwtProvider, { byuJwtOptions: { issuer }, basePath: '/test' })
await fastify.register(ByuJwtProvider, { issuer, basePath: '/test' })
fastify.get('/', (request) => request.caller)
const result = await fastify.inject({ url: '/', headers: { 'x-jwt-assertion': expiredJwt } }).then(res => res.json())
t.is(result.message, 'Cannot fetch key.')
Expand All @@ -30,7 +30,7 @@ test('cannot fetch key', async t => {
test('missing expected JWT', async t => {
const fastify = Fastify()
fastify.setErrorHandler(errorHandler)
await fastify.register(ByuJwtProvider, { byuJwtOptions: { issuer }, development })
await fastify.register(ByuJwtProvider, { issuer, development })
fastify.get('/', () => true)
const result = await fastify.inject('/').then(res => res.json<ByuJwtError>())
t.is(result.message, 'Missing expected JWT')
Expand Down