Skip to content
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hono",
"version": "4.11.7",
"version": "4.11.8",
"description": "Web framework built on Web Standards",
"main": "dist/cjs/index.js",
"type": "module",
Expand Down
8 changes: 6 additions & 2 deletions src/jsx/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ export const createContext = <T>(defaultValue: T): Context<T> => {
: props.children
).toString()
: ''
} finally {
} catch (e) {
values.pop()
throw e
}

if (string instanceof Promise) {
return string.then((resString) => raw(resString, (resString as HtmlEscapedString).callbacks))
return string
.finally(() => values.pop())
.then((resString) => raw(resString, (resString as HtmlEscapedString).callbacks))
} else {
values.pop()
return raw(string)
}
}) as Context<T>
Expand Down
38 changes: 38 additions & 0 deletions src/jsx/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,44 @@ d.replaceWith(c.content)
expect(nextRequest.toString()).toBe('<span>light</span>')
})
})

describe('async with html helper', () => {
it('should preserve context when using await before html helper', async () => {
// Regression test for https://github.com/honojs/hono/issues/4582
// Context was being popped before async children resolved
const AsyncParentWithHtml = async (props: { children?: any }) => {
await new Promise((r) => setTimeout(r, 10))
return html`<div>${props.children}</div>`
}

const template = (
<ThemeContext.Provider value='dark'>
<AsyncParentWithHtml>
<Consumer />
</AsyncParentWithHtml>
</ThemeContext.Provider>
)
expect((await template.toString()).toString()).toBe('<div><span>dark</span></div>')
})

it('should preserve nested context when using await before html helper', async () => {
const AsyncParentWithHtml = async (props: { children?: any }) => {
await new Promise((r) => setTimeout(r, 10))
return html`<div>${props.children}</div>`
}

const template = (
<ThemeContext.Provider value='dark'>
<AsyncParentWithHtml>
<ThemeContext.Provider value='black'>
<Consumer />
</ThemeContext.Provider>
</AsyncParentWithHtml>
</ThemeContext.Provider>
)
expect((await template.toString()).toString()).toBe('<div><span>black</span></div>')
})
})
})

describe('version', () => {
Expand Down
21 changes: 21 additions & 0 deletions src/middleware/bearer-auth/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,18 @@ describe('Bearer Auth by Middleware', () => {
expect(res.headers.get('x-custom')).toBe('foo')
})

it.each([['bearer'], ['BEARER'], ['BeArEr']])(
'Should authorize - prefix is case-insensitive: %s',
async (prefix) => {
const req = new Request('http://localhost/auth/a')
req.headers.set('Authorization', `${prefix} ${token}`)
const res = await app.request(req)
expect(res).not.toBeNull()
expect(res.status).toBe(200)
expect(handlerExecuted).toBeTruthy()
}
)

it('Should not authorize - no authorization header', async () => {
const req = new Request('http://localhost/auth/a')
const res = await app.request(req)
Expand Down Expand Up @@ -481,6 +493,15 @@ describe('Bearer Auth by Middleware', () => {
expect(res.headers.get('x-custom')).toBeNull()
})

it('Should not authorize - token is case-sensitive', async () => {
const req = new Request('http://localhost/auth/a')
req.headers.set('Authorization', `Bearer ${token.toUpperCase()}`)
const res = await app.request(req)
expect(res).not.toBeNull()
expect(res.status).toBe(401)
expect(await res.text()).toBe('Unauthorized')
})

it('Should authorize', async () => {
const req = new Request('http://localhost/authBot/a')
req.headers.set('Authorization', 'Bot abcdefg12345-._~+/=')
Expand Down
2 changes: 1 addition & 1 deletion src/middleware/bearer-auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const bearerAuth = (options: BearerAuthOptions): MiddlewareHandler => {

const realm = options.realm?.replace(/"/g, '\\"')
const prefixRegexStr = options.prefix === '' ? '' : `${options.prefix} +`
const regexp = new RegExp(`^${prefixRegexStr}(${TOKEN_STRINGS}) *$`)
const regexp = new RegExp(`^${prefixRegexStr}(${TOKEN_STRINGS}) *$`, 'i')
const wwwAuthenticatePrefix = options.prefix === '' ? '' : `${options.prefix} `

const throwHTTPException = async (
Expand Down
Loading