UNPKG

@snap/camera-kit

Version:
124 lines 5.61 kB
import { isEmptyString } from "../../common/typeguards"; import { RemoteEndpoint_HttpRequestMethod } from "../../generated-proto/pb_schema/camera_kit/v3/remote_api_spec"; import { RemoteParameter_ParameterLocation } from "../../generated-proto/pb_schema/camera_kit/v3/remote_api_spec"; import { namedError } from "../../namedErrors"; export const requestValidationErrorName = "RequestValidationError"; export const requestValidationError = namedError(requestValidationErrorName); export function validateRequest(request, specs, validationStrategy = "strict") { var _a; if (validationStrategy === "deny") { throw requestValidationError("All lens HTTP requests are denied by the current validation strategy."); } if (validationStrategy === "unrestricted") { return; } const url = new URL(request.uri); for (const spec of specs) { if (url.host !== spec.host || url.protocol !== (spec.tlsRequired ? "https:" : "http:")) { continue; } if (validationStrategy === "host") { return; } const path = url.pathname.replace(/^\/|\/$/g, ""); for (const endpoint of spec.endpoints) { const endpointPath = endpoint.path.replace(/^\/|\/$/g, ""); if (!path.startsWith(endpointPath)) continue; const method = (_a = RemoteEndpoint_HttpRequestMethod[request.method]) !== null && _a !== void 0 ? _a : RemoteEndpoint_HttpRequestMethod.UNRECOGNIZED; if (!endpoint.methods.includes(method)) continue; validatePath(path.split(endpointPath)[1], endpoint.parameters); if (validationStrategy === "route") { return; } validateHeaders(request.metadata, endpoint.parameters); validateQuery(url.searchParams, endpoint.parameters); return; } } throw requestValidationError("The request does not match any of the Remote API specifications."); } export function validatePath(path, parameters) { const pathComponents = path.split("/").filter(Boolean); let paramIndex = 0; for (const param of parameters) { if (param.location !== RemoteParameter_ParameterLocation.PATH) continue; const paramNameComponent = pathComponents[paramIndex]; const paramValueComponent = pathComponents[paramIndex + 1]; if (param.constant) { if (paramNameComponent === param.name && paramValueComponent === param.defaultValue) { paramIndex += 2; } else { throw requestValidationError(`Expected constant parameter '${param.name}' with value '${param.defaultValue}' ` + `at position ${paramIndex}, but found '${paramNameComponent}' and '${paramValueComponent}'.`); } } else if (param.optional) { if (paramNameComponent === param.name) { if (paramValueComponent !== undefined) { paramIndex += 2; } else { paramIndex += 1; } } } else { if (paramNameComponent === param.name && paramValueComponent !== undefined) { paramIndex += 2; } else { throw requestValidationError(`Expected parameter '${param.name}' with a value at position ${paramIndex}, ` + `but found '${paramNameComponent}' and '${paramValueComponent}'.`); } } } if (paramIndex !== pathComponents.length) { const invalidPath = pathComponents.slice(paramIndex).join("/"); throw requestValidationError(`Unexpected extra path components starting at position ${paramIndex}: '${invalidPath}'.`); } } export function validateHeaders(headers, parameters) { for (const param of parameters) { if (param.location !== RemoteParameter_ParameterLocation.HEADER) continue; const headerValue = headers[param.name]; if (param.constant) { if (headerValue !== param.defaultValue) { throw requestValidationError(`Expected constant header '${param.name}' with value '${param.defaultValue}', ` + `but found '${headerValue !== null && headerValue !== void 0 ? headerValue : "undefined"}'.`); } } else if (param.optional) { } else { if (headerValue == undefined || isEmptyString(headerValue)) { throw requestValidationError(`Required header '${param.name}' is missing or empty.`); } } } } export function validateQuery(queryParams, parameters) { for (const param of parameters) { if (param.location !== RemoteParameter_ParameterLocation.QUERY) continue; const paramValue = queryParams.get(param.name); if (param.constant) { if (paramValue !== param.defaultValue) { throw requestValidationError(`Expected constant query parameter '${param.name}' with value '${param.defaultValue}', ` + `but found '${paramValue !== null && paramValue !== void 0 ? paramValue : "undefined"}'.`); } } else if (param.optional) { } else { if (paramValue == undefined || isEmptyString(paramValue)) { throw requestValidationError(`Required query parameter '${param.name}' is missing or empty.`); } } } } //# sourceMappingURL=httpValidators.js.map