@shopify/shopify-api 15.0.0 → 15.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,6 +46,7 @@ function begin(config) {
46
46
  expires: new Date(Date.now() + 60000),
47
47
  sameSite: 'lax',
48
48
  secure: true,
49
+ httpOnly: true,
49
50
  path: callbackPath,
50
51
  });
51
52
  const scopes = config.scopes ? config.scopes.toString() : '';
@@ -136,6 +137,7 @@ function callback(config) {
136
137
  expires: session.expires,
137
138
  sameSite: 'lax',
138
139
  secure: true,
140
+ httpOnly: true,
139
141
  path: cookiePath,
140
142
  });
141
143
  }
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.js","sources":["../../../../../../../lib/auth/oauth/oauth.ts"],"sourcesContent":["import {isbot} from 'isbot';\n\nimport {throwFailedRequest} from '../../clients/common';\nimport ProcessedQuery from '../../utils/processed-query';\nimport {ConfigInterface} from '../../base-types';\nimport * as ShopifyErrors from '../../error';\nimport {validateHmac} from '../../utils/hmac-validator';\nimport {sanitizeShop} from '../../utils/shop-validator';\nimport {Session} from '../../session/session';\nimport {\n abstractConvertRequest,\n abstractConvertIncomingResponse,\n abstractConvertResponse,\n abstractConvertHeaders,\n AdapterResponse,\n AdapterHeaders,\n Cookies,\n NormalizedResponse,\n NormalizedRequest,\n} from '../../../runtime/http';\nimport {logger, ShopifyLogger} from '../../logger';\nimport {DataType} from '../../clients/types';\nimport {fetchRequestFactory} from '../../utils/fetch-request';\n\nimport {\n SESSION_COOKIE_NAME,\n STATE_COOKIE_NAME,\n BeginParams,\n CallbackParams,\n AuthQuery,\n AccessTokenResponse,\n} from './types';\nimport {nonce} from './nonce';\nimport {safeCompare} from './safe-compare';\nimport {createSession} from './create-session';\n\nexport type OAuthBegin = (beginParams: BeginParams) => Promise<AdapterResponse>;\n\nexport interface CallbackResponse<T = AdapterHeaders> {\n headers: T;\n session: Session;\n}\n\nexport type OAuthCallback = <T = AdapterHeaders>(\n callbackParams: CallbackParams,\n) => Promise<CallbackResponse<T>>;\n\ninterface BotLog {\n request: NormalizedRequest;\n log: ShopifyLogger;\n func: string;\n}\n\nconst logForBot = ({request, log, func}: BotLog) => {\n log.debug(`Possible bot request to auth ${func}: `, {\n userAgent: request.headers['User-Agent'],\n });\n};\n\nexport function begin(config: ConfigInterface): OAuthBegin {\n return async ({\n shop,\n callbackPath,\n isOnline,\n ...adapterArgs\n }: BeginParams): Promise<AdapterResponse> => {\n throwIfCustomStoreApp(\n config.isCustomStoreApp,\n 'Cannot perform OAuth for private apps',\n );\n\n const log = logger(config);\n log.info('Beginning OAuth', {shop, isOnline, callbackPath});\n\n const request = await abstractConvertRequest(adapterArgs);\n const response = await abstractConvertIncomingResponse(adapterArgs);\n\n let userAgent = request.headers['User-Agent'];\n if (Array.isArray(userAgent)) {\n userAgent = userAgent[0];\n }\n if (isbot(userAgent)) {\n logForBot({request, log, func: 'begin'});\n response.statusCode = 410;\n return abstractConvertResponse(response, adapterArgs);\n }\n\n const cookies = new Cookies(request, response, {\n keys: [config.apiSecretKey],\n secure: true,\n });\n\n const state = nonce();\n\n await cookies.setAndSign(STATE_COOKIE_NAME, state, {\n expires: new Date(Date.now() + 60000),\n sameSite: 'lax',\n secure: true,\n path: callbackPath,\n });\n\n const scopes = config.scopes ? config.scopes.toString() : '';\n const query = {\n client_id: config.apiKey,\n scope: scopes,\n redirect_uri: `${config.hostScheme}://${config.hostName}${callbackPath}`,\n state,\n 'grant_options[]': isOnline ? 'per-user' : '',\n };\n const processedQuery = new ProcessedQuery();\n processedQuery.putAll(query);\n\n const cleanShop = sanitizeShop(config)(shop, true)!;\n const redirectUrl = `https://${cleanShop}/admin/oauth/authorize${processedQuery.stringify()}`;\n response.statusCode = 302;\n response.statusText = 'Found';\n response.headers = {\n ...response.headers,\n ...cookies.response.headers!,\n Location: redirectUrl,\n };\n\n log.debug(`OAuth started, redirecting to ${redirectUrl}`, {shop, isOnline});\n\n return abstractConvertResponse(response, adapterArgs);\n };\n}\n\nexport function callback(config: ConfigInterface): OAuthCallback {\n return async function callback<T = AdapterHeaders>({\n expiring,\n ...adapterArgs\n }: CallbackParams): Promise<CallbackResponse<T>> {\n throwIfCustomStoreApp(\n config.isCustomStoreApp,\n 'Cannot perform OAuth for private apps',\n );\n\n const log = logger(config);\n\n const request = await abstractConvertRequest(adapterArgs);\n\n const query = new URL(\n request.url,\n `${config.hostScheme}://${config.hostName}`,\n ).searchParams;\n const shop = query.get('shop')!;\n\n const response = {} as NormalizedResponse;\n let userAgent = request.headers['User-Agent'];\n if (Array.isArray(userAgent)) {\n userAgent = userAgent[0];\n }\n if (isbot(userAgent)) {\n logForBot({request, log, func: 'callback'});\n throw new ShopifyErrors.BotActivityDetected(\n 'Invalid OAuth callback initiated by bot',\n );\n }\n\n log.info('Completing OAuth', {shop});\n\n const cookies = new Cookies(request, response, {\n keys: [config.apiSecretKey],\n secure: true,\n });\n\n const stateFromCookie = await cookies.getAndVerify(STATE_COOKIE_NAME);\n cookies.deleteCookie(STATE_COOKIE_NAME);\n if (!stateFromCookie) {\n log.error('Could not find OAuth cookie', {shop});\n\n throw new ShopifyErrors.CookieNotFound(\n `Cannot complete OAuth process. Could not find an OAuth cookie for shop url: ${shop}`,\n );\n }\n\n const authQuery: AuthQuery = Object.fromEntries(query.entries());\n if (!(await validQuery({config, query: authQuery, stateFromCookie}))) {\n log.error('Invalid OAuth callback', {shop, stateFromCookie});\n\n throw new ShopifyErrors.InvalidOAuthError('Invalid OAuth callback.');\n }\n\n log.debug('OAuth request is valid, requesting access token', {shop});\n\n const body = {\n client_id: config.apiKey,\n client_secret: config.apiSecretKey,\n code: query.get('code'),\n expiring: expiring ? '1' : '0',\n };\n\n const cleanShop = sanitizeShop(config)(query.get('shop')!, true)!;\n\n const postResponse = await fetchRequestFactory(config)(\n `https://${cleanShop}/admin/oauth/access_token`,\n {\n method: 'POST',\n body: JSON.stringify(body),\n headers: {\n 'Content-Type': DataType.JSON,\n Accept: DataType.JSON,\n },\n },\n );\n\n if (!postResponse.ok) {\n throwFailedRequest(await postResponse.json(), false, postResponse);\n }\n\n const session: Session = createSession({\n accessTokenResponse: await postResponse.json<AccessTokenResponse>(),\n shop: cleanShop,\n state: stateFromCookie,\n config,\n });\n\n if (!config.isEmbeddedApp) {\n const cookiePath =\n typeof config.cookiePath === 'function'\n ? config.cookiePath(session)\n : (config.cookiePath ?? '/');\n await cookies.setAndSign(SESSION_COOKIE_NAME, session.id, {\n expires: session.expires,\n sameSite: 'lax',\n secure: true,\n path: cookiePath,\n });\n }\n\n return {\n headers: (await abstractConvertHeaders(\n cookies.response.headers!,\n adapterArgs,\n )) as T,\n session,\n };\n };\n}\n\nasync function validQuery({\n config,\n query,\n stateFromCookie,\n}: {\n config: ConfigInterface;\n query: AuthQuery;\n stateFromCookie: string;\n}): Promise<boolean> {\n return (\n (await validateHmac(config)(query)) &&\n safeCompare(query.state!, stateFromCookie)\n );\n}\n\nfunction throwIfCustomStoreApp(\n isCustomStoreApp: boolean,\n message: string,\n): void {\n if (isCustomStoreApp) {\n throw new ShopifyErrors.PrivateAppError(message);\n }\n}\n"],"names":["logger","abstractConvertRequest","abstractConvertIncomingResponse","isbot","abstractConvertResponse","cookies","Cookies","nonce","STATE_COOKIE_NAME","processedQuery","ProcessedQuery","sanitizeShop","ShopifyErrors.BotActivityDetected","ShopifyErrors.CookieNotFound","ShopifyErrors.InvalidOAuthError","fetchRequestFactory","DataType","throwFailedRequest","createSession","SESSION_COOKIE_NAME","abstractConvertHeaders","validateHmac","safeCompare","ShopifyErrors.PrivateAppError"],"mappings":"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"}
1
+ {"version":3,"file":"oauth.js","sources":["../../../../../../../lib/auth/oauth/oauth.ts"],"sourcesContent":["import {isbot} from 'isbot';\n\nimport {throwFailedRequest} from '../../clients/common';\nimport ProcessedQuery from '../../utils/processed-query';\nimport {ConfigInterface} from '../../base-types';\nimport * as ShopifyErrors from '../../error';\nimport {validateHmac} from '../../utils/hmac-validator';\nimport {sanitizeShop} from '../../utils/shop-validator';\nimport {Session} from '../../session/session';\nimport {\n abstractConvertRequest,\n abstractConvertIncomingResponse,\n abstractConvertResponse,\n abstractConvertHeaders,\n AdapterResponse,\n AdapterHeaders,\n Cookies,\n NormalizedResponse,\n NormalizedRequest,\n} from '../../../runtime/http';\nimport {logger, ShopifyLogger} from '../../logger';\nimport {DataType} from '../../clients/types';\nimport {fetchRequestFactory} from '../../utils/fetch-request';\n\nimport {\n SESSION_COOKIE_NAME,\n STATE_COOKIE_NAME,\n BeginParams,\n CallbackParams,\n AuthQuery,\n AccessTokenResponse,\n} from './types';\nimport {nonce} from './nonce';\nimport {safeCompare} from './safe-compare';\nimport {createSession} from './create-session';\n\nexport type OAuthBegin = (beginParams: BeginParams) => Promise<AdapterResponse>;\n\nexport interface CallbackResponse<T = AdapterHeaders> {\n headers: T;\n session: Session;\n}\n\nexport type OAuthCallback = <T = AdapterHeaders>(\n callbackParams: CallbackParams,\n) => Promise<CallbackResponse<T>>;\n\ninterface BotLog {\n request: NormalizedRequest;\n log: ShopifyLogger;\n func: string;\n}\n\nconst logForBot = ({request, log, func}: BotLog) => {\n log.debug(`Possible bot request to auth ${func}: `, {\n userAgent: request.headers['User-Agent'],\n });\n};\n\nexport function begin(config: ConfigInterface): OAuthBegin {\n return async ({\n shop,\n callbackPath,\n isOnline,\n ...adapterArgs\n }: BeginParams): Promise<AdapterResponse> => {\n throwIfCustomStoreApp(\n config.isCustomStoreApp,\n 'Cannot perform OAuth for private apps',\n );\n\n const log = logger(config);\n log.info('Beginning OAuth', {shop, isOnline, callbackPath});\n\n const request = await abstractConvertRequest(adapterArgs);\n const response = await abstractConvertIncomingResponse(adapterArgs);\n\n let userAgent = request.headers['User-Agent'];\n if (Array.isArray(userAgent)) {\n userAgent = userAgent[0];\n }\n if (isbot(userAgent)) {\n logForBot({request, log, func: 'begin'});\n response.statusCode = 410;\n return abstractConvertResponse(response, adapterArgs);\n }\n\n const cookies = new Cookies(request, response, {\n keys: [config.apiSecretKey],\n secure: true,\n });\n\n const state = nonce();\n\n await cookies.setAndSign(STATE_COOKIE_NAME, state, {\n expires: new Date(Date.now() + 60000),\n sameSite: 'lax',\n secure: true,\n httpOnly: true,\n path: callbackPath,\n });\n\n const scopes = config.scopes ? config.scopes.toString() : '';\n const query = {\n client_id: config.apiKey,\n scope: scopes,\n redirect_uri: `${config.hostScheme}://${config.hostName}${callbackPath}`,\n state,\n 'grant_options[]': isOnline ? 'per-user' : '',\n };\n const processedQuery = new ProcessedQuery();\n processedQuery.putAll(query);\n\n const cleanShop = sanitizeShop(config)(shop, true)!;\n const redirectUrl = `https://${cleanShop}/admin/oauth/authorize${processedQuery.stringify()}`;\n response.statusCode = 302;\n response.statusText = 'Found';\n response.headers = {\n ...response.headers,\n ...cookies.response.headers!,\n Location: redirectUrl,\n };\n\n log.debug(`OAuth started, redirecting to ${redirectUrl}`, {shop, isOnline});\n\n return abstractConvertResponse(response, adapterArgs);\n };\n}\n\nexport function callback(config: ConfigInterface): OAuthCallback {\n return async function callback<T = AdapterHeaders>({\n expiring,\n ...adapterArgs\n }: CallbackParams): Promise<CallbackResponse<T>> {\n throwIfCustomStoreApp(\n config.isCustomStoreApp,\n 'Cannot perform OAuth for private apps',\n );\n\n const log = logger(config);\n\n const request = await abstractConvertRequest(adapterArgs);\n\n const query = new URL(\n request.url,\n `${config.hostScheme}://${config.hostName}`,\n ).searchParams;\n const shop = query.get('shop')!;\n\n const response = {} as NormalizedResponse;\n let userAgent = request.headers['User-Agent'];\n if (Array.isArray(userAgent)) {\n userAgent = userAgent[0];\n }\n if (isbot(userAgent)) {\n logForBot({request, log, func: 'callback'});\n throw new ShopifyErrors.BotActivityDetected(\n 'Invalid OAuth callback initiated by bot',\n );\n }\n\n log.info('Completing OAuth', {shop});\n\n const cookies = new Cookies(request, response, {\n keys: [config.apiSecretKey],\n secure: true,\n });\n\n const stateFromCookie = await cookies.getAndVerify(STATE_COOKIE_NAME);\n cookies.deleteCookie(STATE_COOKIE_NAME);\n if (!stateFromCookie) {\n log.error('Could not find OAuth cookie', {shop});\n\n throw new ShopifyErrors.CookieNotFound(\n `Cannot complete OAuth process. Could not find an OAuth cookie for shop url: ${shop}`,\n );\n }\n\n const authQuery: AuthQuery = Object.fromEntries(query.entries());\n if (!(await validQuery({config, query: authQuery, stateFromCookie}))) {\n log.error('Invalid OAuth callback', {shop, stateFromCookie});\n\n throw new ShopifyErrors.InvalidOAuthError('Invalid OAuth callback.');\n }\n\n log.debug('OAuth request is valid, requesting access token', {shop});\n\n const body = {\n client_id: config.apiKey,\n client_secret: config.apiSecretKey,\n code: query.get('code'),\n expiring: expiring ? '1' : '0',\n };\n\n const cleanShop = sanitizeShop(config)(query.get('shop')!, true)!;\n\n const postResponse = await fetchRequestFactory(config)(\n `https://${cleanShop}/admin/oauth/access_token`,\n {\n method: 'POST',\n body: JSON.stringify(body),\n headers: {\n 'Content-Type': DataType.JSON,\n Accept: DataType.JSON,\n },\n },\n );\n\n if (!postResponse.ok) {\n throwFailedRequest(await postResponse.json(), false, postResponse);\n }\n\n const session: Session = createSession({\n accessTokenResponse: await postResponse.json<AccessTokenResponse>(),\n shop: cleanShop,\n state: stateFromCookie,\n config,\n });\n\n if (!config.isEmbeddedApp) {\n const cookiePath =\n typeof config.cookiePath === 'function'\n ? config.cookiePath(session)\n : (config.cookiePath ?? '/');\n await cookies.setAndSign(SESSION_COOKIE_NAME, session.id, {\n expires: session.expires,\n sameSite: 'lax',\n secure: true,\n httpOnly: true,\n path: cookiePath,\n });\n }\n\n return {\n headers: (await abstractConvertHeaders(\n cookies.response.headers!,\n adapterArgs,\n )) as T,\n session,\n };\n };\n}\n\nasync function validQuery({\n config,\n query,\n stateFromCookie,\n}: {\n config: ConfigInterface;\n query: AuthQuery;\n stateFromCookie: string;\n}): Promise<boolean> {\n return (\n (await validateHmac(config)(query)) &&\n safeCompare(query.state!, stateFromCookie)\n );\n}\n\nfunction throwIfCustomStoreApp(\n isCustomStoreApp: boolean,\n message: string,\n): void {\n if (isCustomStoreApp) {\n throw new ShopifyErrors.PrivateAppError(message);\n }\n}\n"],"names":["logger","abstractConvertRequest","abstractConvertIncomingResponse","isbot","abstractConvertResponse","cookies","Cookies","nonce","STATE_COOKIE_NAME","processedQuery","ProcessedQuery","sanitizeShop","ShopifyErrors.BotActivityDetected","ShopifyErrors.CookieNotFound","ShopifyErrors.InvalidOAuthError","fetchRequestFactory","DataType","throwFailedRequest","createSession","SESSION_COOKIE_NAME","abstractConvertHeaders","validateHmac","safeCompare","ShopifyErrors.PrivateAppError"],"mappings":"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"}
@@ -16,6 +16,7 @@ function getUserAgent(config) {
16
16
  }
17
17
  const REDACTED_LOG_VALUE = '****';
18
18
  // These headers carry reusable credentials and must not reach the logs.
19
+ // Keep in sync with SENSITIVE_HEADERS in @shopify/graphql-client.
19
20
  const SENSITIVE_LOG_HEADERS = new Set([
20
21
  'authorization',
21
22
  'cookie',
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sources":["../../../../../../lib/clients/common.ts"],"sourcesContent":["import {\n HTTPResponseLog,\n HTTPRetryLog,\n HTTPResponseGraphQLDeprecationNotice,\n LogContent,\n} from '@shopify/admin-api-client';\n\nimport * as ShopifyErrors from '../error';\nimport {LIBRARY_NAME, StatusCode} from '../types';\nimport {ConfigInterface} from '../base-types';\nimport {SHOPIFY_API_LIBRARY_VERSION} from '../version';\nimport {\n abstractRuntimeString,\n canonicalizeHeaders,\n getHeader,\n} from '../../runtime';\nimport {logger} from '../logger';\n\nexport function getUserAgent(config: ConfigInterface): string {\n let userAgentPrefix = `${LIBRARY_NAME} v${SHOPIFY_API_LIBRARY_VERSION} | ${abstractRuntimeString()}`;\n if (config.userAgentPrefix) {\n userAgentPrefix = `${config.userAgentPrefix} | ${userAgentPrefix}`;\n }\n\n return userAgentPrefix;\n}\n\nconst REDACTED_LOG_VALUE = '****';\n\n// These headers carry reusable credentials and must not reach the logs.\nconst SENSITIVE_LOG_HEADERS = new Set([\n 'authorization',\n 'cookie',\n 'set-cookie',\n 'shopify-storefront-private-token',\n 'x-shopify-access-token',\n 'x-shopify-storefront-access-token',\n]);\n\nfunction sanitizeHeaderValue(name: string, value: unknown): unknown {\n return SENSITIVE_LOG_HEADERS.has(name.toLowerCase())\n ? REDACTED_LOG_VALUE\n : value;\n}\n\n// Keep the original serialized shape of request headers. A Headers instance\n// has no own enumerable properties, so it stays opaque here, the same as\n// JSON.stringify shows it.\nfunction sanitizeHeaders(headers: any): any {\n if (!headers || typeof headers !== 'object') {\n return headers;\n }\n\n if (Array.isArray(headers)) {\n return headers.map((header) =>\n Array.isArray(header)\n ? [header[0], sanitizeHeaderValue(header[0], header[1])]\n : header,\n );\n }\n\n return Object.fromEntries(\n Object.entries(headers).map(([name, value]) => [\n name,\n sanitizeHeaderValue(name, value),\n ]),\n );\n}\n\n// Response headers were always enumerated in the log, so keep that and\n// redact the credential values.\nfunction sanitizeEnumerableHeaders(headers: any): any {\n if (typeof headers?.entries === 'function' && !Array.isArray(headers)) {\n return Object.fromEntries(\n [...headers.entries()].map(([name, value]: [string, string]) => [\n name,\n sanitizeHeaderValue(name, value),\n ]),\n );\n }\n\n return sanitizeHeaders(headers);\n}\n\nfunction sanitizeRequestParams<T>(requestParams: T): T {\n if (Array.isArray(requestParams)) {\n return requestParams.map((param) =>\n param && typeof param === 'object' && 'headers' in param\n ? {...param, headers: sanitizeHeaders(param.headers)}\n : param,\n ) as T;\n }\n\n if (\n requestParams &&\n typeof requestParams === 'object' &&\n 'headers' in requestParams\n ) {\n return {\n ...requestParams,\n headers: sanitizeHeaders((requestParams as {headers: any}).headers),\n };\n }\n\n return requestParams;\n}\n\nfunction serializeResponse(response: Response | any) {\n if (!response) {\n return {error: 'No response object provided'};\n }\n\n try {\n const {status, statusText, ok, redirected, type, url, headers} = response;\n\n const serialized: any = {\n status,\n statusText,\n ok,\n redirected,\n type,\n url,\n };\n\n if (headers) {\n serialized.headers = sanitizeEnumerableHeaders(headers);\n }\n\n return serialized;\n } catch {\n return response;\n }\n}\n\nexport function clientLoggerFactory(config: ConfigInterface) {\n return (logContent: LogContent) => {\n if (config.logger.httpRequests) {\n switch (logContent.type) {\n case 'HTTP-Response': {\n const responseLog: HTTPResponseLog['content'] = logContent.content;\n logger(config).debug('Received response for HTTP request', {\n requestParams: JSON.stringify(\n sanitizeRequestParams(responseLog.requestParams),\n ),\n response: JSON.stringify(serializeResponse(responseLog.response)),\n });\n break;\n }\n case 'HTTP-Retry': {\n const responseLog: HTTPRetryLog['content'] = logContent.content;\n logger(config).debug('Retrying HTTP request', {\n requestParams: JSON.stringify(\n sanitizeRequestParams(responseLog.requestParams),\n ),\n retryAttempt: responseLog.retryAttempt,\n maxRetries: responseLog.maxRetries,\n response: responseLog.lastResponse\n ? JSON.stringify(serializeResponse(responseLog.lastResponse))\n : 'undefined',\n });\n break;\n }\n case 'HTTP-Response-GraphQL-Deprecation-Notice': {\n const responseLog: HTTPResponseGraphQLDeprecationNotice['content'] =\n logContent.content;\n logger(config).debug(\n 'Received response containing Deprecated GraphQL Notice',\n {\n requestParams: JSON.stringify(\n sanitizeRequestParams(responseLog.requestParams),\n ),\n deprecationNotice: responseLog.deprecationNotice,\n },\n );\n break;\n }\n default: {\n logger(config).debug(`HTTP request event: ${logContent.content}`);\n break;\n }\n }\n }\n };\n}\n\nexport function throwFailedRequest(\n body: any,\n atMaxRetries: boolean,\n response?: Response,\n): never {\n if (typeof response === 'undefined') {\n const message = body?.errors?.message ?? '';\n throw new ShopifyErrors.HttpRequestError(\n `Http request error, no response available: ${message}`,\n );\n }\n\n const responseHeaders = canonicalizeHeaders(\n Object.fromEntries(response.headers.entries() ?? []),\n );\n\n if (response.status === StatusCode.Ok && body.errors.graphQLErrors) {\n throw new ShopifyErrors.GraphqlQueryError({\n message:\n body.errors.graphQLErrors?.[0].message ?? 'GraphQL operation failed',\n response: response as Record<string, any>,\n headers: responseHeaders,\n body: body as Record<string, any>,\n });\n }\n\n const errorMessages: string[] = [];\n if (body.errors) {\n errorMessages.push(JSON.stringify(body.errors, null, 2));\n }\n const xRequestId = getHeader(responseHeaders, 'x-request-id');\n if (xRequestId) {\n errorMessages.push(\n `If you report this error, please include this id: ${xRequestId}`,\n );\n }\n\n const errorMessage = errorMessages.length\n ? `:\\n${errorMessages.join('\\n')}`\n : '';\n const code = response.status;\n const statusText = response.statusText;\n\n switch (true) {\n case response.status === StatusCode.TooManyRequests: {\n if (atMaxRetries) {\n throw new ShopifyErrors.HttpMaxRetriesError(\n 'Attempted the maximum number of retries for HTTP request.',\n );\n } else {\n const retryAfter = getHeader(responseHeaders, 'Retry-After');\n throw new ShopifyErrors.HttpThrottlingError({\n message: `Shopify is throttling requests ${errorMessage}`,\n code,\n statusText,\n body,\n headers: responseHeaders,\n retryAfter: retryAfter ? parseFloat(retryAfter) : undefined,\n });\n }\n }\n case response.status >= StatusCode.InternalServerError:\n if (atMaxRetries) {\n throw new ShopifyErrors.HttpMaxRetriesError(\n 'Attempted the maximum number of retries for HTTP request.',\n );\n } else {\n throw new ShopifyErrors.HttpInternalError({\n message: `Shopify internal error${errorMessage}`,\n code,\n statusText,\n body,\n headers: responseHeaders,\n });\n }\n default:\n throw new ShopifyErrors.HttpResponseError({\n message: `Received an error response (${response.status} ${response.statusText}) from Shopify${errorMessage}`,\n code,\n statusText,\n body,\n headers: responseHeaders,\n });\n }\n}\n"],"names":["LIBRARY_NAME","SHOPIFY_API_LIBRARY_VERSION","abstractRuntimeString","logger","ShopifyErrors.HttpRequestError","canonicalizeHeaders","StatusCode","ShopifyErrors.GraphqlQueryError","getHeader","ShopifyErrors.HttpMaxRetriesError","ShopifyErrors.HttpThrottlingError","ShopifyErrors.HttpInternalError","ShopifyErrors.HttpResponseError"],"mappings":"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"}
1
+ {"version":3,"file":"common.js","sources":["../../../../../../lib/clients/common.ts"],"sourcesContent":["import {\n HTTPResponseLog,\n HTTPRetryLog,\n HTTPResponseGraphQLDeprecationNotice,\n LogContent,\n} from '@shopify/admin-api-client';\n\nimport * as ShopifyErrors from '../error';\nimport {LIBRARY_NAME, StatusCode} from '../types';\nimport {ConfigInterface} from '../base-types';\nimport {SHOPIFY_API_LIBRARY_VERSION} from '../version';\nimport {\n abstractRuntimeString,\n canonicalizeHeaders,\n getHeader,\n} from '../../runtime';\nimport {logger} from '../logger';\n\nexport function getUserAgent(config: ConfigInterface): string {\n let userAgentPrefix = `${LIBRARY_NAME} v${SHOPIFY_API_LIBRARY_VERSION} | ${abstractRuntimeString()}`;\n if (config.userAgentPrefix) {\n userAgentPrefix = `${config.userAgentPrefix} | ${userAgentPrefix}`;\n }\n\n return userAgentPrefix;\n}\n\nconst REDACTED_LOG_VALUE = '****';\n\n// These headers carry reusable credentials and must not reach the logs.\n// Keep in sync with SENSITIVE_HEADERS in @shopify/graphql-client.\nconst SENSITIVE_LOG_HEADERS = new Set([\n 'authorization',\n 'cookie',\n 'set-cookie',\n 'shopify-storefront-private-token',\n 'x-shopify-access-token',\n 'x-shopify-storefront-access-token',\n]);\n\nfunction sanitizeHeaderValue(name: string, value: unknown): unknown {\n return SENSITIVE_LOG_HEADERS.has(name.toLowerCase())\n ? REDACTED_LOG_VALUE\n : value;\n}\n\n// Keep the original serialized shape of request headers. A Headers instance\n// has no own enumerable properties, so it stays opaque here, the same as\n// JSON.stringify shows it.\nfunction sanitizeHeaders(headers: any): any {\n if (!headers || typeof headers !== 'object') {\n return headers;\n }\n\n if (Array.isArray(headers)) {\n return headers.map((header) =>\n Array.isArray(header)\n ? [header[0], sanitizeHeaderValue(header[0], header[1])]\n : header,\n );\n }\n\n return Object.fromEntries(\n Object.entries(headers).map(([name, value]) => [\n name,\n sanitizeHeaderValue(name, value),\n ]),\n );\n}\n\n// Response headers were always enumerated in the log, so keep that and\n// redact the credential values.\nfunction sanitizeEnumerableHeaders(headers: any): any {\n if (typeof headers?.entries === 'function' && !Array.isArray(headers)) {\n return Object.fromEntries(\n [...headers.entries()].map(([name, value]: [string, string]) => [\n name,\n sanitizeHeaderValue(name, value),\n ]),\n );\n }\n\n return sanitizeHeaders(headers);\n}\n\nfunction sanitizeRequestParams<T>(requestParams: T): T {\n if (Array.isArray(requestParams)) {\n return requestParams.map((param) =>\n param && typeof param === 'object' && 'headers' in param\n ? {...param, headers: sanitizeHeaders(param.headers)}\n : param,\n ) as T;\n }\n\n if (\n requestParams &&\n typeof requestParams === 'object' &&\n 'headers' in requestParams\n ) {\n return {\n ...requestParams,\n headers: sanitizeHeaders((requestParams as {headers: any}).headers),\n };\n }\n\n return requestParams;\n}\n\nfunction serializeResponse(response: Response | any) {\n if (!response) {\n return {error: 'No response object provided'};\n }\n\n try {\n const {status, statusText, ok, redirected, type, url, headers} = response;\n\n const serialized: any = {\n status,\n statusText,\n ok,\n redirected,\n type,\n url,\n };\n\n if (headers) {\n serialized.headers = sanitizeEnumerableHeaders(headers);\n }\n\n return serialized;\n } catch {\n return response;\n }\n}\n\nexport function clientLoggerFactory(config: ConfigInterface) {\n return (logContent: LogContent) => {\n if (config.logger.httpRequests) {\n switch (logContent.type) {\n case 'HTTP-Response': {\n const responseLog: HTTPResponseLog['content'] = logContent.content;\n logger(config).debug('Received response for HTTP request', {\n requestParams: JSON.stringify(\n sanitizeRequestParams(responseLog.requestParams),\n ),\n response: JSON.stringify(serializeResponse(responseLog.response)),\n });\n break;\n }\n case 'HTTP-Retry': {\n const responseLog: HTTPRetryLog['content'] = logContent.content;\n logger(config).debug('Retrying HTTP request', {\n requestParams: JSON.stringify(\n sanitizeRequestParams(responseLog.requestParams),\n ),\n retryAttempt: responseLog.retryAttempt,\n maxRetries: responseLog.maxRetries,\n response: responseLog.lastResponse\n ? JSON.stringify(serializeResponse(responseLog.lastResponse))\n : 'undefined',\n });\n break;\n }\n case 'HTTP-Response-GraphQL-Deprecation-Notice': {\n const responseLog: HTTPResponseGraphQLDeprecationNotice['content'] =\n logContent.content;\n logger(config).debug(\n 'Received response containing Deprecated GraphQL Notice',\n {\n requestParams: JSON.stringify(\n sanitizeRequestParams(responseLog.requestParams),\n ),\n deprecationNotice: responseLog.deprecationNotice,\n },\n );\n break;\n }\n default: {\n logger(config).debug(`HTTP request event: ${logContent.content}`);\n break;\n }\n }\n }\n };\n}\n\nexport function throwFailedRequest(\n body: any,\n atMaxRetries: boolean,\n response?: Response,\n): never {\n if (typeof response === 'undefined') {\n const message = body?.errors?.message ?? '';\n throw new ShopifyErrors.HttpRequestError(\n `Http request error, no response available: ${message}`,\n );\n }\n\n const responseHeaders = canonicalizeHeaders(\n Object.fromEntries(response.headers.entries() ?? []),\n );\n\n if (response.status === StatusCode.Ok && body.errors.graphQLErrors) {\n throw new ShopifyErrors.GraphqlQueryError({\n message:\n body.errors.graphQLErrors?.[0].message ?? 'GraphQL operation failed',\n response: response as Record<string, any>,\n headers: responseHeaders,\n body: body as Record<string, any>,\n });\n }\n\n const errorMessages: string[] = [];\n if (body.errors) {\n errorMessages.push(JSON.stringify(body.errors, null, 2));\n }\n const xRequestId = getHeader(responseHeaders, 'x-request-id');\n if (xRequestId) {\n errorMessages.push(\n `If you report this error, please include this id: ${xRequestId}`,\n );\n }\n\n const errorMessage = errorMessages.length\n ? `:\\n${errorMessages.join('\\n')}`\n : '';\n const code = response.status;\n const statusText = response.statusText;\n\n switch (true) {\n case response.status === StatusCode.TooManyRequests: {\n if (atMaxRetries) {\n throw new ShopifyErrors.HttpMaxRetriesError(\n 'Attempted the maximum number of retries for HTTP request.',\n );\n } else {\n const retryAfter = getHeader(responseHeaders, 'Retry-After');\n throw new ShopifyErrors.HttpThrottlingError({\n message: `Shopify is throttling requests ${errorMessage}`,\n code,\n statusText,\n body,\n headers: responseHeaders,\n retryAfter: retryAfter ? parseFloat(retryAfter) : undefined,\n });\n }\n }\n case response.status >= StatusCode.InternalServerError:\n if (atMaxRetries) {\n throw new ShopifyErrors.HttpMaxRetriesError(\n 'Attempted the maximum number of retries for HTTP request.',\n );\n } else {\n throw new ShopifyErrors.HttpInternalError({\n message: `Shopify internal error${errorMessage}`,\n code,\n statusText,\n body,\n headers: responseHeaders,\n });\n }\n default:\n throw new ShopifyErrors.HttpResponseError({\n message: `Received an error response (${response.status} ${response.statusText}) from Shopify${errorMessage}`,\n code,\n statusText,\n body,\n headers: responseHeaders,\n });\n }\n}\n"],"names":["LIBRARY_NAME","SHOPIFY_API_LIBRARY_VERSION","abstractRuntimeString","logger","ShopifyErrors.HttpRequestError","canonicalizeHeaders","StatusCode","ShopifyErrors.GraphqlQueryError","getHeader","ShopifyErrors.HttpMaxRetriesError","ShopifyErrors.HttpThrottlingError","ShopifyErrors.HttpInternalError","ShopifyErrors.HttpResponseError"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const SHOPIFY_API_LIBRARY_VERSION = '15.0.0';
3
+ const SHOPIFY_API_LIBRARY_VERSION = '15.0.1';
4
4
 
5
5
  exports.SHOPIFY_API_LIBRARY_VERSION = SHOPIFY_API_LIBRARY_VERSION;
6
6
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sources":["../../../../../lib/version.ts"],"sourcesContent":["export const SHOPIFY_API_LIBRARY_VERSION = '15.0.0';\n"],"names":[],"mappings":";;AAAO,MAAM,2BAA2B,GAAG;;;;"}
1
+ {"version":3,"file":"version.js","sources":["../../../../../lib/version.ts"],"sourcesContent":["export const SHOPIFY_API_LIBRARY_VERSION = '15.0.1';\n"],"names":[],"mappings":";;AAAO,MAAM,2BAA2B,GAAG;;;;"}
@@ -35,7 +35,11 @@ class Cookies {
35
35
  {
36
36
  name,
37
37
  value,
38
- ...Object.fromEntries(opts.map((opt) => utils.splitN(opt, '=', 2).map((value) => value.trim()))),
38
+ ...Object.fromEntries(opts.map((opt) => {
39
+ const [key, value] = utils.splitN(opt, '=', 2).map((value) => value.trim());
40
+ // Flag attributes like HttpOnly have no value
41
+ return [key, value ?? true];
42
+ })),
39
43
  },
40
44
  ];
41
45
  });
@@ -51,8 +55,9 @@ class Cookies {
51
55
  let result = '';
52
56
  result += `${data.name}=${data.value};`;
53
57
  result += Object.entries(data)
54
- .filter(([key]) => !['name', 'value', 'expires'].includes(key))
55
- .map(([key, value]) => `${key}=${value}`)
58
+ .filter(([key, value]) => !['name', 'value', 'expires'].includes(key) && value !== false)
59
+ // Boolean attributes are flags, so only write them when true
60
+ .map(([key, value]) => (value === true ? key : `${key}=${value}`))
56
61
  .join('; ');
57
62
  if (data.expires) {
58
63
  result += ';';
@@ -105,6 +110,7 @@ class Cookies {
105
110
  }
106
111
  set(name, value, opts = {}) {
107
112
  this.outgoingCookieJar[name] = {
113
+ httpOnly: true,
108
114
  ...opts,
109
115
  name,
110
116
  value,
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.js","sources":["../../../../../../runtime/http/cookies.ts"],"sourcesContent":["// import type {Headers} from \"./headers\";\nimport {createSHA256HMAC, deriveSHA256HMACKey} from '../crypto/utils';\n\nimport {splitN} from './utils';\nimport {getHeader, getHeaders, removeHeader, addHeader} from './headers';\n\nimport type {NormalizedRequest, NormalizedResponse} from '.';\n\nexport interface CookieData {\n name: string;\n value: string;\n /**\n * a number representing the milliseconds from Date.now() for expiry\n */\n maxAge?: number;\n /**\n * a Date object indicating the cookie's expiration\n * date (expires at the end of session by default).\n */\n expires?: Date;\n /**\n * a string indicating the path of the cookie (/ by default).\n */\n path?: string;\n /**\n * a string indicating the domain of the cookie (no default).\n */\n domain?: string;\n /**\n * a boolean indicating whether the cookie is only to be sent\n * over HTTPS (false by default for HTTP, true by default for HTTPS).\n */\n secure?: boolean;\n /**\n * a boolean indicating whether the cookie is only to be sent over HTTP(S),\n * and not made available to client JavaScript (true by default).\n */\n httpOnly?: boolean;\n /**\n * a boolean or string indicating whether the cookie is a \"same site\" cookie (false by default).\n * This can be set to 'strict', 'lax', or true (which maps to 'strict').\n */\n sameSite?: 'strict' | 'lax' | 'none';\n}\n\nexport type CookieJar = Record<string, CookieData>;\n\nconst COOKIE_SIGNING_INFO = 'shopify-app-js/cookie-signing/v1';\n\nasync function createCookieSignature(\n key: string,\n value: string,\n): Promise<string> {\n const cookieSigningKey = await deriveSHA256HMACKey(key, COOKIE_SIGNING_INFO);\n return createSHA256HMAC(cookieSigningKey, value);\n}\n\nconst signatureEncoder = new TextEncoder();\n\nfunction safelyCompareSignatures(signatureA: string, signatureB: string) {\n const buffA = signatureEncoder.encode(signatureA);\n const buffB = signatureEncoder.encode(signatureB);\n\n if (buffA.length !== buffB.length) return false;\n\n let out = 0;\n for (let i = 0; i < buffA.length; i++) {\n out |= buffA[i] ^ buffB[i];\n }\n\n return out === 0;\n}\n\ninterface CookiesOptions {\n keys: string[];\n // Ignored. Only for type-compatibility with the node package for now.\n secure: boolean;\n}\nexport class Cookies {\n static parseCookies(hdrs: string[]): CookieJar {\n const entries = hdrs\n .filter((hdr) => hdr.trim().length > 0)\n .map((cookieDef) => {\n const [keyval, ...opts] = cookieDef.split(';');\n const [name, value] = splitN(keyval, '=', 2).map((value) =>\n value.trim(),\n );\n return [\n name,\n {\n name,\n value,\n ...Object.fromEntries(\n opts.map((opt) =>\n splitN(opt, '=', 2).map((value) => value.trim()),\n ),\n ),\n },\n ];\n });\n const jar = Object.fromEntries(entries) as CookieJar;\n for (const cookie of Object.values(jar)) {\n if (typeof cookie.expires === 'string') {\n cookie.expires = new Date(cookie.expires);\n }\n }\n return jar;\n }\n\n static encodeCookie(data: CookieData): string {\n let result = '';\n result += `${data.name}=${data.value};`;\n result += Object.entries(data)\n .filter(([key]) => !['name', 'value', 'expires'].includes(key))\n .map(([key, value]) => `${key}=${value}`)\n .join('; ');\n if (data.expires) {\n result += ';';\n result += `expires=${data.expires.toUTCString()}`;\n }\n return result;\n }\n\n receivedCookieJar: CookieJar = {};\n outgoingCookieJar: CookieJar = {};\n private keys: string[] = [];\n\n constructor(\n request: NormalizedRequest,\n public response: NormalizedResponse,\n {keys = []}: Partial<CookiesOptions> = {},\n ) {\n if (keys) this.keys = keys;\n\n const cookieReqHdr = getHeader(request.headers, 'Cookie') ?? '';\n this.receivedCookieJar = Cookies.parseCookies(cookieReqHdr.split(';'));\n const cookieResHdr = getHeaders(response.headers, 'Set-Cookie') ?? [];\n this.outgoingCookieJar = Cookies.parseCookies(cookieResHdr);\n }\n\n toHeaders(): string[] {\n return Object.values(this.outgoingCookieJar).map((cookie) =>\n Cookies.encodeCookie(cookie),\n );\n }\n\n updateHeader() {\n if (!this.response.headers) {\n this.response.headers = {};\n }\n removeHeader(this.response.headers, 'Set-Cookie');\n this.toHeaders().map((hdr) =>\n addHeader(this.response.headers!, 'Set-Cookie', hdr),\n );\n }\n\n get(name: string): string | undefined {\n return this.receivedCookieJar[name]?.value;\n }\n\n deleteCookie(name: string) {\n this.set(name, '', {\n path: '/',\n expires: new Date(0),\n });\n }\n\n async getAndVerify(name: string): Promise<string | undefined> {\n const value = this.get(name);\n if (!value) return undefined;\n if (!(await this.isSignedCookieValid(name))) {\n return undefined;\n }\n return value;\n }\n\n private get canSign() {\n return this.keys?.length > 0;\n }\n\n set(name: string, value: string, opts: Partial<CookieData> = {}): void {\n this.outgoingCookieJar[name] = {\n ...opts,\n name,\n value,\n };\n this.updateHeader();\n }\n\n async setAndSign(\n name: string,\n value: string,\n opts: Partial<CookieData> = {},\n ): Promise<void> {\n if (!this.canSign) {\n throw Error('No keys provided for signing.');\n }\n this.set(name, value, opts);\n const sigName = `${name}.sig`;\n const signature = await createCookieSignature(this.keys[0], value);\n this.set(sigName, signature, opts);\n this.updateHeader();\n }\n\n async isSignedCookieValid(cookieName: string): Promise<boolean> {\n const signedCookieName = `${cookieName}.sig`;\n if (\n !this.cookieExists(cookieName) ||\n !this.cookieExists(signedCookieName)\n ) {\n this.deleteInvalidCookies(cookieName, signedCookieName);\n return false;\n }\n const cookieValue = this.get(cookieName);\n const signature = this.get(signedCookieName);\n\n if (!cookieValue || !signature) {\n this.deleteInvalidCookies(cookieName, signedCookieName);\n return false;\n }\n\n const allCheckSignatures = await Promise.all(\n this.keys.map((key) => createCookieSignature(key, cookieValue)),\n );\n\n const validSignature = allCheckSignatures.some((checkSignature) =>\n safelyCompareSignatures(checkSignature, signature),\n );\n\n if (!validSignature) {\n this.deleteInvalidCookies(cookieName, signedCookieName);\n return false;\n }\n\n return true;\n }\n\n private cookieExists(cookieName: string) {\n return Boolean(this.get(cookieName));\n }\n\n private deleteInvalidCookies(...cookieNames: string[]): void {\n cookieNames.forEach((cookieName) => this.deleteCookie(cookieName));\n }\n}\n"],"names":["deriveSHA256HMACKey","createSHA256HMAC","splitN","getHeader","getHeaders","removeHeader","addHeader"],"mappings":"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"}
1
+ {"version":3,"file":"cookies.js","sources":["../../../../../../runtime/http/cookies.ts"],"sourcesContent":["// import type {Headers} from \"./headers\";\nimport {createSHA256HMAC, deriveSHA256HMACKey} from '../crypto/utils';\n\nimport {splitN} from './utils';\nimport {getHeader, getHeaders, removeHeader, addHeader} from './headers';\n\nimport type {NormalizedRequest, NormalizedResponse} from '.';\n\nexport interface CookieData {\n name: string;\n value: string;\n /**\n * a number representing the milliseconds from Date.now() for expiry\n */\n maxAge?: number;\n /**\n * a Date object indicating the cookie's expiration\n * date (expires at the end of session by default).\n */\n expires?: Date;\n /**\n * a string indicating the path of the cookie (/ by default).\n */\n path?: string;\n /**\n * a string indicating the domain of the cookie (no default).\n */\n domain?: string;\n /**\n * a boolean indicating whether the cookie is only to be sent\n * over HTTPS (false by default for HTTP, true by default for HTTPS).\n */\n secure?: boolean;\n /**\n * a boolean indicating whether the cookie is only to be sent over HTTP(S),\n * and not made available to client JavaScript (true by default).\n */\n httpOnly?: boolean;\n /**\n * a boolean or string indicating whether the cookie is a \"same site\" cookie (false by default).\n * This can be set to 'strict', 'lax', or true (which maps to 'strict').\n */\n sameSite?: 'strict' | 'lax' | 'none';\n}\n\nexport type CookieJar = Record<string, CookieData>;\n\nconst COOKIE_SIGNING_INFO = 'shopify-app-js/cookie-signing/v1';\n\nasync function createCookieSignature(\n key: string,\n value: string,\n): Promise<string> {\n const cookieSigningKey = await deriveSHA256HMACKey(key, COOKIE_SIGNING_INFO);\n return createSHA256HMAC(cookieSigningKey, value);\n}\n\nconst signatureEncoder = new TextEncoder();\n\nfunction safelyCompareSignatures(signatureA: string, signatureB: string) {\n const buffA = signatureEncoder.encode(signatureA);\n const buffB = signatureEncoder.encode(signatureB);\n\n if (buffA.length !== buffB.length) return false;\n\n let out = 0;\n for (let i = 0; i < buffA.length; i++) {\n out |= buffA[i] ^ buffB[i];\n }\n\n return out === 0;\n}\n\ninterface CookiesOptions {\n keys: string[];\n // Ignored. Only for type-compatibility with the node package for now.\n secure: boolean;\n}\nexport class Cookies {\n static parseCookies(hdrs: string[]): CookieJar {\n const entries = hdrs\n .filter((hdr) => hdr.trim().length > 0)\n .map((cookieDef) => {\n const [keyval, ...opts] = cookieDef.split(';');\n const [name, value] = splitN(keyval, '=', 2).map((value) =>\n value.trim(),\n );\n return [\n name,\n {\n name,\n value,\n ...Object.fromEntries(\n opts.map((opt) => {\n const [key, value] = splitN(opt, '=', 2).map((value) =>\n value.trim(),\n );\n // Flag attributes like HttpOnly have no value\n return [key, value ?? true];\n }),\n ),\n },\n ];\n });\n const jar = Object.fromEntries(entries) as CookieJar;\n for (const cookie of Object.values(jar)) {\n if (typeof cookie.expires === 'string') {\n cookie.expires = new Date(cookie.expires);\n }\n }\n return jar;\n }\n\n static encodeCookie(data: CookieData): string {\n let result = '';\n result += `${data.name}=${data.value};`;\n result += Object.entries(data)\n .filter(\n ([key, value]) =>\n !['name', 'value', 'expires'].includes(key) && value !== false,\n )\n // Boolean attributes are flags, so only write them when true\n .map(([key, value]) => (value === true ? key : `${key}=${value}`))\n .join('; ');\n if (data.expires) {\n result += ';';\n result += `expires=${data.expires.toUTCString()}`;\n }\n return result;\n }\n\n receivedCookieJar: CookieJar = {};\n outgoingCookieJar: CookieJar = {};\n private keys: string[] = [];\n\n constructor(\n request: NormalizedRequest,\n public response: NormalizedResponse,\n {keys = []}: Partial<CookiesOptions> = {},\n ) {\n if (keys) this.keys = keys;\n\n const cookieReqHdr = getHeader(request.headers, 'Cookie') ?? '';\n this.receivedCookieJar = Cookies.parseCookies(cookieReqHdr.split(';'));\n const cookieResHdr = getHeaders(response.headers, 'Set-Cookie') ?? [];\n this.outgoingCookieJar = Cookies.parseCookies(cookieResHdr);\n }\n\n toHeaders(): string[] {\n return Object.values(this.outgoingCookieJar).map((cookie) =>\n Cookies.encodeCookie(cookie),\n );\n }\n\n updateHeader() {\n if (!this.response.headers) {\n this.response.headers = {};\n }\n removeHeader(this.response.headers, 'Set-Cookie');\n this.toHeaders().map((hdr) =>\n addHeader(this.response.headers!, 'Set-Cookie', hdr),\n );\n }\n\n get(name: string): string | undefined {\n return this.receivedCookieJar[name]?.value;\n }\n\n deleteCookie(name: string) {\n this.set(name, '', {\n path: '/',\n expires: new Date(0),\n });\n }\n\n async getAndVerify(name: string): Promise<string | undefined> {\n const value = this.get(name);\n if (!value) return undefined;\n if (!(await this.isSignedCookieValid(name))) {\n return undefined;\n }\n return value;\n }\n\n private get canSign() {\n return this.keys?.length > 0;\n }\n\n set(name: string, value: string, opts: Partial<CookieData> = {}): void {\n this.outgoingCookieJar[name] = {\n httpOnly: true,\n ...opts,\n name,\n value,\n };\n this.updateHeader();\n }\n\n async setAndSign(\n name: string,\n value: string,\n opts: Partial<CookieData> = {},\n ): Promise<void> {\n if (!this.canSign) {\n throw Error('No keys provided for signing.');\n }\n this.set(name, value, opts);\n const sigName = `${name}.sig`;\n const signature = await createCookieSignature(this.keys[0], value);\n this.set(sigName, signature, opts);\n this.updateHeader();\n }\n\n async isSignedCookieValid(cookieName: string): Promise<boolean> {\n const signedCookieName = `${cookieName}.sig`;\n if (\n !this.cookieExists(cookieName) ||\n !this.cookieExists(signedCookieName)\n ) {\n this.deleteInvalidCookies(cookieName, signedCookieName);\n return false;\n }\n const cookieValue = this.get(cookieName);\n const signature = this.get(signedCookieName);\n\n if (!cookieValue || !signature) {\n this.deleteInvalidCookies(cookieName, signedCookieName);\n return false;\n }\n\n const allCheckSignatures = await Promise.all(\n this.keys.map((key) => createCookieSignature(key, cookieValue)),\n );\n\n const validSignature = allCheckSignatures.some((checkSignature) =>\n safelyCompareSignatures(checkSignature, signature),\n );\n\n if (!validSignature) {\n this.deleteInvalidCookies(cookieName, signedCookieName);\n return false;\n }\n\n return true;\n }\n\n private cookieExists(cookieName: string) {\n return Boolean(this.get(cookieName));\n }\n\n private deleteInvalidCookies(...cookieNames: string[]): void {\n cookieNames.forEach((cookieName) => this.deleteCookie(cookieName));\n }\n}\n"],"names":["deriveSHA256HMACKey","createSHA256HMAC","splitN","getHeader","getHeaders","removeHeader","addHeader"],"mappings":"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"}