@snap/camera-kit
Version:
Camera Kit Web
124 lines • 5.61 kB
JavaScript
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