diff --git a/packages/apps/shopify-api/runtime/http/cookies.ts b/packages/apps/shopify-api/runtime/http/cookies.ts index f3f4786c2..0c34b343a 100644 --- a/packages/apps/shopify-api/runtime/http/cookies.ts +++ b/packages/apps/shopify-api/runtime/http/cookies.ts @@ -175,25 +175,40 @@ export class Cookies { this.updateHeader(); } + private cookieExists(cookieName: string) { + return !!this.get(cookieName); + } + + private deleteInvalidCookies(...cookieNames: string[]): void { + cookieNames.forEach((cookieName) => this.deleteCookie(cookieName)); + } + async isSignedCookieValid(cookieName: string): Promise { const signedCookieName = `${cookieName}.sig`; - // No cookie or no signature cookie makes the cookie it invalid. - if (!this.get(cookieName) || !this.get(signedCookieName)) { - this.deleteCookie(signedCookieName); - this.deleteCookie(cookieName); + if ( + !this.cookieExists(cookieName) || + !this.cookieExists(signedCookieName) + ) { + this.deleteInvalidCookies(cookieName, signedCookieName); + return false; + } + const cookieValue = this.get(cookieName); + const signature = this.get(signedCookieName); + + if (!cookieValue || !signature) { + this.deleteInvalidCookies(cookieName, signedCookieName); return false; } - const value = this.get(cookieName)!; - const signature = this.get(signedCookieName)!; const allCheckSignatures = await Promise.all( - this.keys.map((key) => createSHA256HMAC(key, value)), + this.keys.map((key) => createSHA256HMAC(key, cookieValue)), ); + if (!allCheckSignatures.includes(signature)) { - this.deleteCookie(signedCookieName); - this.deleteCookie(cookieName); + this.deleteInvalidCookies(cookieName, signedCookieName); return false; } + return true; } } diff --git a/packages/apps/shopify-api/runtime/http/headers.ts b/packages/apps/shopify-api/runtime/http/headers.ts index 3288245e8..14f2db01f 100644 --- a/packages/apps/shopify-api/runtime/http/headers.ts +++ b/packages/apps/shopify-api/runtime/http/headers.ts @@ -89,7 +89,11 @@ export function removeHeader(headers: Headers, needle: string) { // ... ] */ -export function flatHeaders(headers: Headers): [string, string][] { +export function flatHeaders( + headers: Headers | undefined | null, +): [string, string][] { + if (!headers) return []; + return Object.entries(headers).flatMap(([header, values]) => Array.isArray(values) ? values.map((value): [string, string] => [header, value])