Closed enri90 closed 1 year ago
Please create a reproduction on CodeSandbox or StackBlitz,.
getting same error when using whatwg-node/server-plugin-cookies with graphql-yoga, i'm not even setting any cookie just including useCookies() in graphql-yoga plugins array, then I get this error when loading graphiql in browser:
TypeError: Invalid value "undefined" for header "set-cookie"
at storeHeader (node:_http_outgoing:577:5)
at processHeader (node:_http_outgoing:572:3)
at ServerResponse._storeHeader (node:_http_outgoing:448:11)
at ServerResponse.writeHead (node:_http_server:416:8)
at sendNodeResponse (C:\Users\marcu\projects\cookbook\node_modules\.pnpm\@whatwg-node+server@0.7.5\node_modules\@whatwg-node\server\cjs\utils.js:184:20)
at requestListener (C:\Users\marcu\projects\cookbook\node_modules\.pnpm\@whatwg-node+server@0.7.5\node_modules\@whatwg-node\server\cjs\createServerAdapter.js:102:51)
at processTicksAndRejections (node:internal/process/task_queues:95:5) {
code: 'ERR_HTTP_INVALID_HEADER_VALUE
from graphql-yoga docs comments:
Then checking carefully the plugin presents various bugs
request.cookieStore.cookieString is undefined In the useCookies function in onResponse request.cookieStore.cookieString is undefined by setting the condition the error message mentioned above disappears
request.cookieStore.cookieString !== ''
import { CookieStore } from '@whatwg-node/cookie-store';
import { ServerAdapterPlugin } from '@whatwg-node/server';
declare global {
interface Request {
cookieStore?: CookieStore;
}
}
export function useCookies<TServerContext>(): ServerAdapterPlugin<TServerContext> {
return {
onRequest({ request }) {
request.cookieStore = new CookieStore(request.headers.get('cookie') || '');
},
onResponse({ request, response }) {
if (request.cookieStore && request.cookieStore.cookieString !== '') {
response.headers.set('set-cookie', request.cookieStore.cookieString);
}
},
};
}
Ability to enter all subdomains Domain=.test.local;
If I use more cookies in the request it doesn't work it only reads the first the second is not visible there is some error in cookie serialization
set-cookie: token=TOKEN; Domain=.test.local; Path=/; Expires=Tue, 09 May 2023 04:22:05 GMT; SameSite=Strict; refreshToken=ba001321-41ca-47ca-bff7-b0b1214750ad; Domain=.test.local; Path=/; Expires=Fri, 19 May 2023 02:22:05 GMT; SameSite=Strict
and for the expiration date of the cookie it util to enter the expiration minutes as in the npm cookie https://www.npmjs.com/package/cookie
I created my own plugin which fixes this issue as well as another one where the server sends the set-cookie header for cookies that hasn't been changed.
import { Plugin } from 'graphql-yoga';
import { CookieStore, CookieList } from '@whatwg-node/cookie-store';
declare global {
interface Request {
cookieStore?: CookieStore;
}
}
export function cookiePlugin() {
const cache = new WeakMap<Request, CookieList>();
const cookiePlugin: Plugin = {
onRequest({ request }) {
const store = new CookieStore(request.headers.get('cookie') || '');
request.cookieStore = store;
const cookies: CookieList = [];
cache.set(request, cookies);
store.onchange = (event) => {
cookies.push(...event.changed, ...event.deleted);
};
},
async onResponse({ response, request }) {
const cookies = cache.get(request);
if (cookies) {
const store = new CookieStore('');
for (const cookie of cookies) {
await store.set(cookie);
}
response.headers.set('set-cookie', store.cookieString);
}
},
};
return cookiePlugin;
}
Fixed in the latest release! Thanks for the feedback!
@ardatan
I still want to highlight that the plugin sets cookies incorrectly. When the browser sends a cookie like _ga=123456;
the server will always send the set-cookie
header with _ga=123456;
. This means that whatever properties that was initially specified for that cookie will now be reset/removed. Eg if the cookie had Expires
, it will now be reset to be a session cookie.
So if the server initially sets a cookie and the user reload, the server will set that cookie again but with default values.
the problem of subdomains still remains
Cookie domain cannot start with "."
TypeError: Cookie domain cannot start with "."
at CookieStore.set (/server/node_modules/@whatwg-node/cookie-store/cjs/CookieStore.js:47:23)
at setCookies (/server/src/modules/builder/utils/cookie.ts:17:36)
at resolve (/server/src/modules/auth/auth.mutation.ts:97:25)
at /server/node_modules/@pothos/plugin-errors/src/index.ts:214:17
at /server/node_modules/@envelop/core/cjs/orchestrator.js:376:27
at YogaServer.getResultForParams (/server/node_modules/graphql-yoga/cjs/server.js:331:26)
at YogaServer.handle (/server/node_modules/graphql-yoga/cjs/server.js:78:29)
at handlerWithErrorHandling (/server/node_modules/@whatwg-node/server/cjs/plugins/useErrorHandling.js:33:38)
at handleRequest (/server/node_modules/@whatwg-node/server/cjs/createServerAdapter.js:73:24)
at requestListener (/server/node_modules/@whatwg-node/server/cjs/createServerAdapter.js:100:26)
Ok if you have differnt problems, please create new issues with reproduction. Thanks!
if i use res.setHeader('Set-Cookie', serializedCookies); it works
instead through your plugin it error