From 9d4c2be54e5db95f46777016d05380b0c6f067e8 Mon Sep 17 00:00:00 2001 From: XavM Date: Mon, 6 Jun 2022 12:39:57 +0200 Subject: [PATCH 1/2] Fix Azure Cookie - Handle single or multiple cookies at once headers['set-cookie'] can be a string of one cookie, or an array of cookies headerCookies should always be an array --- .../azure/http-function-runtime-v3.js | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/event-sources/azure/http-function-runtime-v3.js b/src/event-sources/azure/http-function-runtime-v3.js index de1c7384..ddc36770 100644 --- a/src/event-sources/azure/http-function-runtime-v3.js +++ b/src/event-sources/azure/http-function-runtime-v3.js @@ -42,54 +42,54 @@ function getResponseToHttpFunction ({ statusCode, body, headers = {}, isBase64En } const cookies = [] - const headerCookies = headers['set-cookie'] - + // headers['set-cookie'] can be a string of one cookie, or an array of cookies + // headerCookies should always be an array + const headerCookies = [].concat(headers['set-cookie'] || []) + // Convert 'set-cookie' to Azure Function 3.x cookie object array // https://github.com/Azure/azure-functions-nodejs-worker/blob/v3.x/types/index.d.ts#L150 - if (headerCookies) { - for (const headerCookie of headerCookies) { - const parsedCookie = parseCookie(headerCookie) - const nameValueTuple = headerCookie.split(';')[0].split('=') - - const cookie = { name: nameValueTuple[0], value: nameValueTuple[1] } + for (const headerCookie of headerCookies) { + const parsedCookie = parseCookie(headerCookie) + const nameValueTuple = headerCookie.split(';')[0].split('=') - if (headerCookie.toLowerCase().includes('httponly')) { - cookie.httpOnly = true - } + const cookie = { name: nameValueTuple[0], value: nameValueTuple[1] } - if (headerCookie.toLowerCase().includes('secure')) { - cookie.secure = true - } + if (headerCookie.toLowerCase().includes('httponly')) { + cookie.httpOnly = true + } - if (parsedCookie['max-age']) { - cookie.maxAge = parsedCookie['max-age'] - } + if (headerCookie.toLowerCase().includes('secure')) { + cookie.secure = true + } - if (parsedCookie.samesite) { - cookie.sameSite = parsedCookie.samesite - } + if (parsedCookie['max-age']) { + cookie.maxAge = parsedCookie['max-age'] + } - if (parsedCookie.expires && typeof parsedCookie.expires === 'string') { - cookie.expires = new Date(parsedCookie.expires) - } else if (parsedCookie.expires && typeof value === 'number') { - cookie.expires = parsedCookie.expires - } + if (parsedCookie.samesite) { + cookie.sameSite = parsedCookie.samesite + } - if (parsedCookie.path) { - cookie.path = parsedCookie.path - } + if (parsedCookie.expires && typeof parsedCookie.expires === 'string') { + cookie.expires = new Date(parsedCookie.expires) + } else if (parsedCookie.expires && typeof value === 'number') { + cookie.expires = parsedCookie.expires + } - if (parsedCookie.domain) { - cookie.domain = parsedCookie.domain - } + if (parsedCookie.path) { + cookie.path = parsedCookie.path + } - cookies.push(cookie) + if (parsedCookie.domain) { + cookie.domain = parsedCookie.domain } - responseToHttpFunction.cookies = cookies - delete headers['set-cookie'] + cookies.push(cookie) } + responseToHttpFunction.cookies = cookies + delete headers['set-cookie'] + responseToHttpFunction.headers = getCommaDelimitedHeaders({ headersMap: headers }) return responseToHttpFunction From e5f79de1a641e281af8691286f4e417b72dbcf5a Mon Sep 17 00:00:00 2001 From: XavM Date: Tue, 7 Jun 2022 19:53:47 +0200 Subject: [PATCH 2/2] Fix tests - No more "response.cookies: []" when no cookie Sorry about that --- .../azure/http-function-runtime-v3.js | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/event-sources/azure/http-function-runtime-v3.js b/src/event-sources/azure/http-function-runtime-v3.js index ddc36770..4e44c86e 100644 --- a/src/event-sources/azure/http-function-runtime-v3.js +++ b/src/event-sources/azure/http-function-runtime-v3.js @@ -48,48 +48,50 @@ function getResponseToHttpFunction ({ statusCode, body, headers = {}, isBase64En // Convert 'set-cookie' to Azure Function 3.x cookie object array // https://github.com/Azure/azure-functions-nodejs-worker/blob/v3.x/types/index.d.ts#L150 - for (const headerCookie of headerCookies) { - const parsedCookie = parseCookie(headerCookie) - const nameValueTuple = headerCookie.split(';')[0].split('=') + if (headerCookies.length > 0) { + for (const headerCookie of headerCookies) { + const parsedCookie = parseCookie(headerCookie) + const nameValueTuple = headerCookie.split(';')[0].split('=') - const cookie = { name: nameValueTuple[0], value: nameValueTuple[1] } + const cookie = { name: nameValueTuple[0], value: nameValueTuple[1] } - if (headerCookie.toLowerCase().includes('httponly')) { - cookie.httpOnly = true - } + if (headerCookie.toLowerCase().includes('httponly')) { + cookie.httpOnly = true + } - if (headerCookie.toLowerCase().includes('secure')) { - cookie.secure = true - } + if (headerCookie.toLowerCase().includes('secure')) { + cookie.secure = true + } - if (parsedCookie['max-age']) { - cookie.maxAge = parsedCookie['max-age'] - } + if (parsedCookie['max-age']) { + cookie.maxAge = parsedCookie['max-age'] + } - if (parsedCookie.samesite) { - cookie.sameSite = parsedCookie.samesite - } + if (parsedCookie.samesite) { + cookie.sameSite = parsedCookie.samesite + } - if (parsedCookie.expires && typeof parsedCookie.expires === 'string') { - cookie.expires = new Date(parsedCookie.expires) - } else if (parsedCookie.expires && typeof value === 'number') { - cookie.expires = parsedCookie.expires - } + if (parsedCookie.expires && typeof parsedCookie.expires === 'string') { + cookie.expires = new Date(parsedCookie.expires) + } else if (parsedCookie.expires && typeof value === 'number') { + cookie.expires = parsedCookie.expires + } - if (parsedCookie.path) { - cookie.path = parsedCookie.path - } + if (parsedCookie.path) { + cookie.path = parsedCookie.path + } - if (parsedCookie.domain) { - cookie.domain = parsedCookie.domain + if (parsedCookie.domain) { + cookie.domain = parsedCookie.domain + } + + cookies.push(cookie) } - cookies.push(cookie) + responseToHttpFunction.cookies = cookies + delete headers['set-cookie'] } - responseToHttpFunction.cookies = cookies - delete headers['set-cookie'] - responseToHttpFunction.headers = getCommaDelimitedHeaders({ headersMap: headers }) return responseToHttpFunction