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; }; }