@shopify/shopify-api
Version:
Shopify API Library for Node - accelerate development with support for authentication, graphql proxy, webhooks
92 lines (76 loc) • 2.71 kB
text/typescript
import {ConfigInterface} from '../base-types';
import {InvalidHostError, InvalidShopError} from '../error';
import {decodeHost} from '../auth/decode-host';
import {shopAdminUrlToLegacyUrl} from './shop-admin-url-helper';
import {
applyDomainTransformations,
getTransformationDomains,
} from './domain-transformer';
export function sanitizeShop(config: ConfigInterface) {
return (shop: string, throwOnInvalid = false): string | null => {
let shopUrl = shop;
const domainsRegex = [
'myshopify\\.com',
'shopify\\.com',
'myshopify\\.io',
'shop\\.dev',
];
// Add domains from transformations (both source and target)
if (config.domainTransformations) {
domainsRegex.push(...getTransformationDomains(config));
}
const shopUrlRegex = new RegExp(
`^[a-zA-Z0-9][a-zA-Z0-9-_]*\\.(${domainsRegex.join('|')})[/]*$`,
);
const shopAdminRegex = new RegExp(
`^admin\\.(${domainsRegex.join('|')})/store/([a-zA-Z0-9][a-zA-Z0-9-_]*)$`,
);
const isShopAdminUrl = shopAdminRegex.test(shopUrl);
if (isShopAdminUrl) {
shopUrl = shopAdminUrlToLegacyUrl(shopUrl) || '';
}
const sanitizedShop = shopUrlRegex.test(shopUrl) ? shopUrl : null;
if (!sanitizedShop && throwOnInvalid) {
throw new InvalidShopError('Received invalid shop argument');
}
if (sanitizedShop && config.domainTransformations) {
return applyDomainTransformations(sanitizedShop, config);
}
return sanitizedShop;
};
}
export function sanitizeHost(config: ConfigInterface) {
return (host: string, throwOnInvalid = false): string | null => {
const base64regex = /^[0-9a-zA-Z+/]+={0,2}$/;
let sanitizedHost = base64regex.test(host) ? host : null;
if (sanitizedHost) {
const {hostname} = new URL(`https://${decodeHost(sanitizedHost)}`);
const originsRegex = [
'myshopify\\.com',
'shopify\\.com',
'myshopify\\.io',
'spin\\.dev',
'shop\\.dev',
];
if (config.domainTransformations) {
const hostTransformationDomains = config.domainTransformations
.filter((t) => t.includeHost !== false)
.flatMap((t) =>
getTransformationDomains({
...config,
domainTransformations: [t],
}),
);
originsRegex.push(...hostTransformationDomains);
}
const hostRegex = new RegExp(`\\.(${originsRegex.join('|')})$`);
if (!hostRegex.test(hostname)) {
sanitizedHost = null;
}
}
if (!sanitizedHost && throwOnInvalid) {
throw new InvalidHostError('Received invalid host argument');
}
return sanitizedHost;
};
}