0
0
mirror of https://github.com/honojs/hono.git synced 2024-11-24 11:07:29 +01:00

fix(secure-headers): optimize getPermissionsPolicyDirectives function (#3398)

This commit is contained in:
kbkn3 2024-09-09 21:54:27 +09:00 committed by GitHub
parent c2b0de42a0
commit 3c4d4c2b59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 5 deletions

View File

@ -160,7 +160,7 @@ describe('Secure Headers Middleware', () => {
expect(res.headers.get('X-XSS-Protection')).toEqual('1')
})
it('should set Permission-Policy header', async () => {
it('should set Permission-Policy header correctly', async () => {
const app = new Hono()
app.use(
'/test',
@ -173,13 +173,20 @@ describe('Secure Headers Middleware', () => {
camera: false,
microphone: true,
geolocation: ['*'],
usb: ['self', 'https://a.example.com', 'https://b.example.com'],
accelerometer: ['https://*.example.com'],
gyroscope: ['src'],
magnetometer: ['https://a.example.com', 'https://b.example.com'],
},
})
)
const res = await app.request('/test')
expect(res.headers.get('Permissions-Policy')).toEqual(
'fullscreen=(self), bluetooth=(none), payment=(self example.com), sync-xhr=(), camera=none, microphone=(), geolocation=(*)'
'fullscreen=(self), bluetooth=none, payment=(self "example.com"), sync-xhr=(), camera=none, microphone=*, ' +
'geolocation=*, usb=(self "https://a.example.com" "https://b.example.com"), ' +
'accelerometer=("https://*.example.com"), gyroscope=(src), ' +
'magnetometer=("https://a.example.com" "https://b.example.com")'
)
})
it('CSP Setting', async () => {

View File

@ -278,12 +278,18 @@ function getPermissionsPolicyDirectives(policy: PermissionsPolicyOptions): strin
const kebabDirective = camelToKebab(directive)
if (typeof value === 'boolean') {
return `${kebabDirective}=${value ? '()' : 'none'}`
return `${kebabDirective}=${value ? '*' : 'none'}`
}
if (Array.isArray(value)) {
const allowlist = value.length === 0 ? '()' : `(${value.join(' ')})`
return `${kebabDirective}=${allowlist}`
if (value.length === 0) {
return `${kebabDirective}=()`
}
if (value.length === 1 && (value[0] === '*' || value[0] === 'none')) {
return `${kebabDirective}=${value[0]}`
}
const allowlist = value.map((item) => (['self', 'src'].includes(item) ? item : `"${item}"`))
return `${kebabDirective}=(${allowlist.join(' ')})`
}
return ''