@shopify/shopify-api
Version:
Shopify API Library for Node - accelerate development with support for authentication, graphql proxy, webhooks
86 lines (83 loc) • 4.05 kB
JavaScript
import { HashFormat } from '../runtime/crypto/types.mjs';
import { createSHA256HMAC } from '../runtime/crypto/utils.mjs';
import { getShopValue } from './get-shop-value.mjs';
import { getHostValue } from './get-host-value.mjs';
import { getJwt } from './get-jwt.mjs';
import { getHmac } from './get-hmac.mjs';
var RequestType;
(function (RequestType) {
RequestType[RequestType["Admin"] = 0] = "Admin";
RequestType[RequestType["Bearer"] = 1] = "Bearer";
RequestType[RequestType["Extension"] = 2] = "Extension";
RequestType[RequestType["Public"] = 3] = "Public";
})(RequestType || (RequestType = {}));
/**
* Duplicates a Request object and decorates the duplicated object with fake authorization headers or query string parameters.
*
* @param {ValidRequestOptions} options Provides the type of authorization method to fake for the provided Request, and the inputs required to fake the authorization.
* @param {Request} request The Request object to be decorated with fake authorization headers or query string parameters.
* @returns {Request} A duplicate of the provided Request object with faked authorization headers or query string parameters.
*/
async function setUpValidRequest(options, request) {
let authenticatedRequest;
switch (options.type) {
case RequestType.Admin:
authenticatedRequest = await adminRequest(request, options.store, options.apiKey, options.apiSecretKey);
break;
case RequestType.Bearer:
authenticatedRequest = await bearerRequest(request, options.store, options.apiKey, options.apiSecretKey);
break;
case RequestType.Extension:
authenticatedRequest = extensionRequest(request, options.store, options.apiSecretKey, options.body, options.headers);
break;
case RequestType.Public:
authenticatedRequest = await publicRequest(request, options.store, options.apiSecretKey);
break;
}
return authenticatedRequest;
}
async function adminRequest(request, store, apiKey, apiSecretKey) {
const { token } = await getJwt(store, apiKey, apiSecretKey);
const url = new URL(request.url);
url.searchParams.set('embedded', '1');
url.searchParams.set('shop', getShopValue(store));
url.searchParams.set('host', getHostValue(store));
url.searchParams.set('id_token', token);
return new Request(url.href, request);
}
async function bearerRequest(request, store, apiKey, apiSecretKey) {
const { token } = await getJwt(store, apiKey, apiSecretKey);
const authenticatedRequest = new Request(request);
authenticatedRequest.headers.set('authorization', `Bearer ${token}`);
return authenticatedRequest;
}
function extensionRequest(request, store, apiSecretKey, body, headers) {
const bodyString = JSON.stringify(body);
const authenticatedRequest = new Request(request, {
method: 'POST',
body: bodyString,
});
authenticatedRequest.headers.set('X-Shopify-Hmac-Sha256', getHmac(bodyString, apiSecretKey));
authenticatedRequest.headers.set('X-Shopify-Shop-Domain', getShopValue(store));
if (headers) {
for (const [key, value] of Object.entries(headers)) {
authenticatedRequest.headers.set(key, value);
}
}
return authenticatedRequest;
}
async function publicRequest(request, store, apiSecretKey) {
const url = new URL(request.url);
url.searchParams.set('shop', getShopValue(store));
url.searchParams.set('timestamp', String(Math.trunc(Date.now() / 1000) - 1));
const params = Object.fromEntries(url.searchParams.entries());
const string = Object.entries(params)
.sort(([val1], [val2]) => val1.localeCompare(val2))
.reduce((acc, [key, value]) => {
return `${acc}${key}=${value}`;
}, '');
url.searchParams.set('signature', await createSHA256HMAC(apiSecretKey, string, HashFormat.Hex));
return new Request(url.href, request);
}
export { RequestType, setUpValidRequest };
//# sourceMappingURL=setup-valid-request.mjs.map