Skip to content

Commit

Permalink
fix: html urls should not be absolute (#178)
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidTanner authored Oct 15, 2024
1 parent 6f9c61a commit 6383dcf
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 22 deletions.
6 changes: 4 additions & 2 deletions lib/index-html.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use strict'

function indexHtml (opts) {
return (hasTrailingSlash) => {
const prefix = hasTrailingSlash ? `.${opts.staticPrefix}` : `${opts.prefix}${opts.staticPrefix}`
const hasLeadingSlash = /^\//.test(opts.prefix)
return (url) => {
const hasTrailingSlash = /\/$/.test(url)
const prefix = hasTrailingSlash ? `.${opts.staticPrefix}` : `${hasLeadingSlash ? '.' : ''}${opts.prefix}${opts.staticPrefix}`
return `<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
Expand Down
3 changes: 1 addition & 2 deletions lib/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,9 @@ function fastifySwagger (fastify, opts, done) {
schema: { hide: true },
...hooks,
handler: (req, reply) => {
const hasTrailingSlash = /\/$/.test(req.url)
reply
.header('content-type', 'text/html; charset=utf-8')
.send(indexHtmlContent(hasTrailingSlash)) // trailing slash alters the relative urls generated in the html
.send(indexHtmlContent(req.url)) // trailing slash alters the relative urls generated in the html
}
})

Expand Down
87 changes: 74 additions & 13 deletions test/route.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ test('should return empty log level of route /documentation', async (t) => {
})

test('/documentation should display index html with correct asset urls', async (t) => {
t.plan(4)
t.plan(6)
const fastify = Fastify()
await fastify.register(fastifySwagger, swaggerOption)
await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] } })
Expand All @@ -549,10 +549,54 @@ test('/documentation should display index html with correct asset urls', async (
url: '/documentation'
})

t.assert.deepStrictEqual(res.payload.includes('href="/documentation/static/index.css"'), true)
t.assert.deepStrictEqual(res.payload.includes('src="/documentation/static/theme/theme-js.js"'), true)
t.assert.deepStrictEqual(res.payload.includes('href="/documentation/index.css"'), false)
t.assert.deepStrictEqual(res.payload.includes('src="/documentation/theme/theme-js.js"'), false)
t.assert.deepStrictEqual(res.payload.includes('href="./documentation/static/index.css"'), true)
t.assert.deepStrictEqual(res.payload.includes('src="./documentation/static/theme/theme-js.js"'), true)
t.assert.deepStrictEqual(res.payload.includes('href="./documentation/index.css"'), false)
t.assert.deepStrictEqual(res.payload.includes('src="./documentation/theme/theme-js.js"'), false)

let cssRes = await fastify.inject({
method: 'GET',
url: '/documentation/static/index.css'
})
t.assert.equal(cssRes.statusCode, 200)
cssRes = await fastify.inject({
method: 'GET',
url: './documentation/static/index.css'
})
t.assert.equal(cssRes.statusCode, 200)
})

/**
* This emulates when the server is inside an NGINX application that routes by path
*/
test('/documentation should display index html with correct asset urls when nested', async (t) => {
t.plan(5)
const fastify = Fastify()
await fastify.register(
async () => {
await fastify.register(fastifySwagger, swaggerOption)
await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] } })
},
{
prefix: '/swagger-app'
}
)

const res = await fastify.inject({
method: 'GET',
url: '/swagger-app/documentation'
})

t.assert.deepStrictEqual(res.payload.includes('href="./documentation/static/index.css"'), true)
t.assert.deepStrictEqual(res.payload.includes('src="./documentation/static/theme/theme-js.js"'), true)
t.assert.deepStrictEqual(res.payload.includes('href="./documentation/index.css"'), false)
t.assert.deepStrictEqual(res.payload.includes('src="./documentation/theme/theme-js.js"'), false)

const cssRes = await fastify.inject({
method: 'GET',
url: '/swagger-app/documentation/static/index.css'
})
t.assert.equal(cssRes.statusCode, 200)
})

test('/documentation/ should display index html with correct asset urls', async (t) => {
Expand Down Expand Up @@ -583,10 +627,27 @@ test('/docs should display index html with correct asset urls when documentation
url: '/docs'
})

t.assert.strictEqual(res.payload.includes('href="/docs/static/index.css"'), true)
t.assert.strictEqual(res.payload.includes('src="/docs/static/theme/theme-js.js"'), true)
t.assert.strictEqual(res.payload.includes('href="/docs/index.css"'), false)
t.assert.strictEqual(res.payload.includes('src="/docs/theme/theme-js.js"'), false)
t.assert.strictEqual(res.payload.includes('href="./docs/static/index.css"'), true)
t.assert.strictEqual(res.payload.includes('src="./docs/static/theme/theme-js.js"'), true)
t.assert.strictEqual(res.payload.includes('href="./docs/index.css"'), false)
t.assert.strictEqual(res.payload.includes('src="./docs/theme/theme-js.js"'), false)
})

test('/docs should display index html with correct asset urls when documentation prefix is set with no leading slash', async (t) => {
t.plan(4)
const fastify = Fastify()
await fastify.register(fastifySwagger, swaggerOption)
await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] }, routePrefix: 'docs' })

const res = await fastify.inject({
method: 'GET',
url: '/docs'
})

t.assert.strictEqual(res.payload.includes('href="docs/static/index.css"'), true)
t.assert.strictEqual(res.payload.includes('src="docs/static/theme/theme-js.js"'), true)
t.assert.strictEqual(res.payload.includes('href="docs/index.css"'), false)
t.assert.strictEqual(res.payload.includes('src="docs/theme/theme-js.js"'), false)
})

test('/docs/ should display index html with correct asset urls when documentation prefix is set', async (t) => {
Expand Down Expand Up @@ -634,10 +695,10 @@ test('/docs should display index html with correct asset urls when documentation
url: '/docs'
})

t.assert.strictEqual(res.payload.includes('href="/docs/static/index.css"'), true)
t.assert.strictEqual(res.payload.includes('src="/docs/static/theme/theme-js.js"'), true)
t.assert.strictEqual(res.payload.includes('href="/docs/index.css"'), false)
t.assert.strictEqual(res.payload.includes('src="/docs/theme/theme-js.js"'), false)
t.assert.strictEqual(res.payload.includes('href="./docs/static/index.css"'), true)
t.assert.strictEqual(res.payload.includes('src="./docs/static/theme/theme-js.js"'), true)
t.assert.strictEqual(res.payload.includes('href="./docs/index.css"'), false)
t.assert.strictEqual(res.payload.includes('src="./docs/theme/theme-js.js"'), false)
})

test('/docs/ should display index html with correct asset urls when documentation prefix is set', async (t) => {
Expand Down
25 changes: 20 additions & 5 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
/// <reference lib="dom" />

import { FastifyPluginCallback, FastifyReply, FastifyRequest, onRequestHookHandler, preHandlerHookHandler } from 'fastify';
import {
FastifyPluginCallback,
FastifyReply,
FastifyRequest,
onRequestHookHandler,
preHandlerHookHandler,
RegisterOptions,
} from 'fastify';

/**
* Swagger-UI Vendor Extensions
Expand Down Expand Up @@ -31,13 +38,17 @@ declare module 'fastify' {
type FastifySwaggerUi = FastifyPluginCallback<fastifySwaggerUi.FastifySwaggerUiOptions>;

declare namespace fastifySwaggerUi {
export interface FastifySwaggerUiOptions {
export interface FastifySwaggerUiOptions extends Omit<RegisterOptions, 'prefix' | 'hooks'> {
baseDir?: string;
/**
* Overwrite the swagger url end-point
* @default /documentation
*/
routePrefix?: string;
/**
* Make it explicit that this plugin overrides the prefix value
*/
prefix?: never;
/**
* Swagger UI Config
*/
Expand All @@ -52,6 +63,10 @@ declare namespace fastifySwaggerUi {
* route hooks
*/
uiHooks?: FastifySwaggerUiHooksOptions
/**
* Make it explicit that this plugin overrides the prefix value
*/
hooks?: never;

theme?: FastifySwaggerUiTheme

Expand All @@ -62,7 +77,7 @@ declare namespace fastifySwaggerUi {

/**
* Use this parameter to set a validator URL
*
*
* @default false
*/
validatorUrl?: string | false
Expand Down Expand Up @@ -441,15 +456,15 @@ declare namespace fastifySwaggerUi {
/**
* scope separator for passing scopes, encoded before calling, default
* value is a space (encoded value %20).
*
*
* @default ' '
*/
scopeSeparator?: string;

/**
* string array or scope separator (i.e. space) separated string of
* initially selected oauth scopes
*
*
* @default []
*/
scopes?: string | string[];
Expand Down

0 comments on commit 6383dcf

Please sign in to comment.