mirror of
https://github.com/cypress-io/cypress.git
synced 2026-01-26 08:59:03 -06:00
fix(server): fix setCookie with __Host- prefix, __Secure- prefix (#8526)
Co-authored-by: Zach Bloomquist <github@chary.us>
This commit is contained in:
@@ -8,12 +8,6 @@ describe('src/cy/commands/cookies', () => {
|
||||
})
|
||||
|
||||
context('test:before:run:async', () => {
|
||||
it('can test unstubbed, real server', () => {
|
||||
Cypress.automation.restore()
|
||||
|
||||
cy.setCookie('foo', 'bar')
|
||||
})
|
||||
|
||||
it('clears cookies before each test run', () => {
|
||||
Cypress.automation
|
||||
.withArgs('get:cookies', { domain: 'localhost' })
|
||||
|
||||
86
packages/driver/cypress/integration/e2e/e2e_cookies_spec.js
Normal file
86
packages/driver/cypress/integration/e2e/e2e_cookies_spec.js
Normal file
@@ -0,0 +1,86 @@
|
||||
describe('e2e cookies spec', () => {
|
||||
it('simple cookie', () => {
|
||||
cy.setCookie('foo', 'bar')
|
||||
cy.getCookie('foo', 'bar')
|
||||
.then((cookie) => expect(cookie).exist)
|
||||
})
|
||||
|
||||
context('__Host- prefix', () => {
|
||||
// https://github.com/cypress-io/cypress/issues/8261
|
||||
it('can set __Host- cookie', () => {
|
||||
cy.visit('https://example.com')
|
||||
cy.setCookie('__Host-foobar', 'someval', {
|
||||
domain: 'example.com',
|
||||
sameSite: 'strict',
|
||||
secure: true,
|
||||
})
|
||||
|
||||
cy.getCookie('__Host-foobar').then(((cookie) => {
|
||||
expect(cookie).exist
|
||||
expect(cookie.domain).match(/^\.?example\.com$/)
|
||||
expect(cookie.path).eq('/')
|
||||
expect(cookie.secure).is.true
|
||||
}))
|
||||
})
|
||||
|
||||
it('errors when __Host- cookie and secure:false', (done) => {
|
||||
cy.visit('https://example.com')
|
||||
cy.setCookie('__Host-foobar', 'someval')
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message)
|
||||
.contain('__Host-')
|
||||
.contain('must be set with `{ secure: true }`')
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('errors when __Host- cookie and path', (done) => {
|
||||
cy.visit('https://example.com')
|
||||
cy.setCookie('__Host-foobar', 'someval', {
|
||||
secure: true,
|
||||
path: '/foo',
|
||||
})
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).contain('__Host-').contain('the path must be')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
context('__Secure- prefix', () => {
|
||||
it('can set __Secure- cookie', () => {
|
||||
cy.visit('https://example.com')
|
||||
cy.setCookie('__Secure-foobar', 'someval', {
|
||||
domain: 'example.com',
|
||||
path: '/foo',
|
||||
secure: true,
|
||||
})
|
||||
|
||||
cy.getCookie('__Secure-foobar').then(((cookie) => {
|
||||
expect(cookie).exist
|
||||
expect(cookie.domain).match(/^\.?example\.com$/)
|
||||
expect(cookie.path).eq('/foo')
|
||||
expect(cookie.secure).is.true
|
||||
}))
|
||||
})
|
||||
|
||||
it('errors when __Secure- cookie secure:false', (done) => {
|
||||
cy.visit('https://example.com')
|
||||
cy.setCookie('__Secure-foobar', 'someval', {
|
||||
domain: 'example.com',
|
||||
path: '/foo',
|
||||
})
|
||||
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message)
|
||||
.contain('__Secure-')
|
||||
.contain('must be set with `{ secure: true }`')
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -57,6 +57,14 @@ const normalizeSameSite = (sameSite) => {
|
||||
return sameSite
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Attributes
|
||||
function cookieValidatesHostPrefix (options) {
|
||||
return options.secure === false || (options.path && options.path !== '/')
|
||||
}
|
||||
function cookieValidatesSecurePrefix (options) {
|
||||
return options.secure === false
|
||||
}
|
||||
|
||||
module.exports = function (Commands, Cypress, cy, state, config) {
|
||||
const automateCookies = function (event, obj = {}, log, timeout) {
|
||||
const automate = () => {
|
||||
@@ -285,6 +293,14 @@ module.exports = function (Commands, Cypress, cy, state, config) {
|
||||
$errUtils.throwErrByPath('setCookie.invalid_arguments', { onFail })
|
||||
}
|
||||
|
||||
if (options.name.startsWith('__Secure-') && cookieValidatesSecurePrefix(options)) {
|
||||
$errUtils.throwErrByPath('setCookie.secure_prefix', { onFail })
|
||||
}
|
||||
|
||||
if (options.name.startsWith('__Host-') && cookieValidatesHostPrefix(options)) {
|
||||
$errUtils.throwErrByPath('setCookie.host_prefix', { onFail })
|
||||
}
|
||||
|
||||
return automateCookies('set:cookie', cookie, options._log, options.timeout)
|
||||
.then((resp) => {
|
||||
options.cookie = resp
|
||||
|
||||
@@ -1480,6 +1480,14 @@ module.exports = {
|
||||
docsUrl: 'https://on.cypress.io/setcookie',
|
||||
}
|
||||
},
|
||||
host_prefix: {
|
||||
message: 'Cookies starting with the `__Host-` prefix must be set with `{ secure: true }`, and the path must be `/`',
|
||||
docsUrl: 'https://on.cypress.io/setcookie',
|
||||
},
|
||||
secure_prefix: {
|
||||
message: 'Cookies starting with the `__Secure-` prefix must be set with `{ secure: true }`',
|
||||
docsUrl: 'https://on.cypress.io/setcookie',
|
||||
},
|
||||
},
|
||||
|
||||
shadow: {
|
||||
|
||||
@@ -116,6 +116,11 @@ export const CdpAutomation = (sendDebuggerCommandFn: SendDebuggerCommand) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (setCookieRequest.name.startsWith('__Host-')) {
|
||||
setCookieRequest.url = `https://${cookie.domain}`
|
||||
delete setCookieRequest.domain
|
||||
}
|
||||
|
||||
return setCookieRequest
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user