Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@metlo/testing

Package Overview
Dependencies
Maintainers
2
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@metlo/testing - npm Package Compare versions

Comparing version 0.2.15 to 0.2.16

dist/data/index.d.ts

2

dist/index.d.ts

@@ -12,2 +12,2 @@ import { FailedAssertion, FailedRequest, TestConfig, TestResult } from "./types/test";

export { TestTemplate } from "./templates/types";
export { runTest } from "./runner";
export { runTest, estimateTest } from "./runner";
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runTest = exports.TestStepBuilder = exports.TestBuilder = exports.TestConfigSchema = exports.ExtractorType = exports.AssertionType = exports.getFailedRequests = exports.getFailedAssertions = exports.loadTestConfig = exports.dumpTestConfig = void 0;
exports.estimateTest = exports.runTest = exports.TestStepBuilder = exports.TestBuilder = exports.TestConfigSchema = exports.ExtractorType = exports.AssertionType = exports.getFailedRequests = exports.getFailedAssertions = exports.loadTestConfig = exports.dumpTestConfig = void 0;
const tslib_1 = require("tslib");

@@ -114,2 +114,3 @@ const chalk_1 = tslib_1.__importDefault(require("chalk"));

Object.defineProperty(exports, "runTest", { enumerable: true, get: function () { return runner_1.runTest; } });
Object.defineProperty(exports, "estimateTest", { enumerable: true, get: function () { return runner_1.estimateTest; } });
//# sourceMappingURL=index.js.map
import { TestConfig, TestResult } from "../types/test";
export declare const estimateTest: (test: TestConfig, env?: Record<string, string | object>) => number;
export declare const runTest: (test: TestConfig, env?: Record<string, string | object>) => Promise<TestResult>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runTest = void 0;
exports.runTest = exports.estimateTest = void 0;
const tslib_1 = require("tslib");

@@ -11,2 +11,21 @@ const step_1 = require("./step");

});
const estimateTest = (test, env) => {
const context = {
cookies: {},
envVars: env || {},
};
if (test.env) {
context.envVars = Object.fromEntries(Object.entries(context.envVars).concat(test.env.map(e => [e.name, e.value])));
}
const testStack = [...test.test];
if (testStack.length > 0) {
const firstStep = testStack.shift();
const config = test.config;
return (0, step_1.runStepComplexity)(0, firstStep, testStack, context, config);
}
else {
throw new Error("No item to test in stack");
}
};
exports.estimateTest = estimateTest;
const runTest = (test, env) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {

@@ -25,3 +44,4 @@ const context = {

const firstStep = testStack.shift();
const resp = yield (0, step_1.runStep)(0, firstStep, testStack, context);
const config = test.config || {};
const resp = yield (0, step_1.runStep)(0, firstStep, testStack, context, config);
return {

@@ -31,2 +51,3 @@ test,

results: resp.results,
abortedAt: resp.abortedAt,
};

@@ -33,0 +54,0 @@ }

@@ -5,3 +5,26 @@ "use strict";

exports.makeRequest = void 0;
const tslib_1 = require("tslib");
const axios_1 = tslib_1.__importDefault(require("axios"));
const utils_1 = require("../utils");
axios_1.default.interceptors.request.use(function (config) {
// @ts-ignore
config.metadata = { startTime: new Date() };
return config;
}, function (error) {
return Promise.reject(error);
});
axios_1.default.interceptors.response.use(function (response) {
// @ts-ignore
response.config.metadata.endTime = new Date();
// @ts-ignore
response.duration =
// @ts-ignore
response.config.metadata.endTime - response.config.metadata.startTime;
return response;
}, function (error) {
error.config.metadata.endTime = new Date();
error.duration =
error.config.metadata.endTime - error.config.metadata.startTime;
return Promise.reject(error);
});
const BLOCKED_HOSTS = new Set((_a = process.env.METLO_TEST_BLOCKED_HOSTS) === null || _a === void 0 ? void 0 : _a.split(","));

@@ -8,0 +31,0 @@ const makeRequest = (req, ctx) => {

@@ -1,3 +0,4 @@

import { TestStep, TestResult } from "../types/test";
import { TestStep, TestResult, Config } from "../types/test";
import { Context } from "../types/context";
export declare const runStep: (idx: number, step: TestStep, nextSteps: TestStep[], ctx: Context) => Promise<TestResult>;
export declare const runStep: (idx: number, step: TestStep, nextSteps: TestStep[], ctx: Context, config: Config) => Promise<TestResult>;
export declare function runStepComplexity(idx: number, step: TestStep, nextSteps: TestStep[], ctx: Context, config: Config): number;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runStep = void 0;
exports.runStepComplexity = exports.runStep = void 0;
const tslib_1 = require("tslib");

@@ -9,2 +9,4 @@ const axios_1 = tslib_1.__importDefault(require("axios"));

const extractors_1 = require("./extractors");
const data_1 = require("../data");
const utils_1 = require("./utils");
const axiosRespToStepResponse = (res) => ({

@@ -28,7 +30,49 @@ data: res.data,

});
const runStep = (idx, step, nextSteps, ctx) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const runStepPayloads = (idx, step, nextSteps, ctx, config) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const payloadValues = {};
step.payload = step.payload;
step.payload.forEach(payloadEntry => {
const payload = payloadEntry.value;
if (payloadEntry.key in payloadValues) {
payloadValues[payloadEntry.key].push(...(0, data_1.getValues)(payload));
}
else {
payloadValues[payloadEntry.key] = [...(0, data_1.getValues)(payload)];
}
});
const results = yield Promise.all((0, utils_1.cartesian)(payloadValues).map(data => {
const newCtx = Object.assign(Object.assign({}, ctx), { envVars: Object.assign(Object.assign({}, ctx.envVars), data) });
return (0, exports.runStep)(idx, {
extract: step.extract,
assert: step.assert,
request: step.request,
}, nextSteps, newCtx, config);
}));
const flatResults = results.map(e => e.results.flat()).flat();
const groupedResults = {};
flatResults.forEach(res => {
if (res.idx in groupedResults) {
groupedResults[res.idx].push(res);
}
else {
groupedResults[res.idx] = [res];
}
});
const combinedResults = Object.entries(groupedResults)
.sort(([key1, res1], [key2, res2]) => (key1 < key2 ? 1 : -1))
.map(([key, res]) => res);
return {
success: results.every(e => e),
results: combinedResults,
};
});
const runStep = (idx, step, nextSteps, ctx, config) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
var _a;
if (step.payload) {
return runStepPayloads(idx, step, nextSteps, ctx, config);
}
let res = null;
let err = undefined;
let errStack = undefined;
let abortedAt = undefined;
const reqConfig = (0, request_1.makeRequest)(step.request, ctx);

@@ -59,6 +103,16 @@ const stepRequest = {

ctx.cookies[host] = currUrlCookies;
let assertions = Array((step.assert || []).length).fill(false);
for (const e of step.extract || []) {
ctx = (0, extractors_1.runExtractor)(e, res, ctx);
}
let assertions = (step.assert || []).map(e => (0, assertions_1.runAssertion)(e, res, ctx));
let i = 0;
for (const _step of step.assert || []) {
const asserted = (0, assertions_1.runAssertion)(_step, res, ctx);
assertions[i] = asserted;
i++;
if (config.stopOnFailedAssertion && !asserted) {
abortedAt = i;
break;
}
}
stepResult = {

@@ -85,6 +139,7 @@ idx,

const nextStep = nextSteps.shift();
if (!nextStep) {
if (!nextStep || abortedAt) {
return {
success: stepResult.success,
results: [[stepResult]],
abortedAt,
};

@@ -96,9 +151,41 @@ }

cookies: cookiesCopy,
});
}, config);
return {
success: stepResult.success && nextRes.success,
results: [[stepResult]].concat(nextRes.results),
abortedAt: nextRes.abortedAt,
};
});
exports.runStep = runStep;
function runStepComplexity(idx, step, nextSteps, ctx, config) {
if (step.payload) {
const payloadValues = {};
step.payload.forEach(payloadEntry => {
const payload = payloadEntry.value;
if (payloadEntry.key in payloadValues) {
payloadValues[payloadEntry.key].push(...(0, data_1.getValues)(payload));
}
else {
payloadValues[payloadEntry.key] = [...(0, data_1.getValues)(payload)];
}
});
const results = (0, utils_1.cartesian)(payloadValues).map(data => {
const newCtx = Object.assign(Object.assign({}, ctx), { envVars: Object.assign(Object.assign({}, ctx.envVars), data) });
return runStepComplexity(idx, {
extract: step.extract,
assert: step.assert,
request: step.request,
}, nextSteps, newCtx, config);
});
return results.reduce((prev, curr) => prev + curr, 0);
}
else {
const next = nextSteps.shift();
if (!next) {
return 1;
}
return 1 + runStepComplexity(idx + 1, next, nextSteps, ctx, config);
}
}
exports.runStepComplexity = runStepComplexity;
//# sourceMappingURL=step.js.map
import { AxiosResponse } from "axios";
import { Context } from "../types/context";
export declare const getKeyValue: (key: string, resp: AxiosResponse, ctx: Context) => any;
export declare function cartesian(takeProductOf: {
[k: string]: Array<string>;
}): {
[k: string]: string;
}[];
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getKeyValue = void 0;
exports.cartesian = exports.getKeyValue = void 0;
const tslib_1 = require("tslib");

@@ -12,2 +12,22 @@ const lodash_get_1 = tslib_1.__importDefault(require("lodash.get"));

exports.getKeyValue = getKeyValue;
function cartesian(takeProductOf) {
const separatedKeys = Object.entries(takeProductOf).map(([key, entries]) => ({
[key]: entries,
}));
function cartesianInner(part, index) {
var k = Object.keys(separatedKeys[index])[0];
separatedKeys[index][k].forEach(function (a) {
var p = Object.assign({}, part, { [k]: a });
if (index + 1 === separatedKeys.length) {
res.push(p);
return;
}
cartesianInner(p, index + 1);
});
}
let res = [];
cartesianInner({}, 0);
return res;
}
exports.cartesian = cartesian;
//# sourceMappingURL=utils.js.map

@@ -6,1 +6,3 @@ import { z } from "zod";

export declare const ExtractorType: z.ZodEnum<["VALUE", "JS", "REGEXP", "HTML"]>;
export declare const PredefinedPayloadTypeArray: [string, ...string[]];
export declare const PredefinedPayloadType: z.ZodEnum<[string, ...string[]]>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtractorType = exports.AssertionType = exports.Method = exports.Severity = void 0;
exports.PredefinedPayloadType = exports.PredefinedPayloadTypeArray = exports.ExtractorType = exports.AssertionType = exports.Method = exports.Severity = void 0;
const zod_1 = require("zod");

@@ -19,2 +19,9 @@ exports.Severity = zod_1.z.enum(["LOW", "MEDIUM", "HIGH", "CRITICAL"]);

exports.ExtractorType = zod_1.z.enum(["VALUE", "JS", "REGEXP", "HTML"]);
exports.PredefinedPayloadTypeArray = [
"XSS",
"SQLI",
"SQLI_AUTH_BYPASS",
"SQLI_TIME",
];
exports.PredefinedPayloadType = zod_1.z.enum(exports.PredefinedPayloadTypeArray);
//# sourceMappingURL=enums.js.map

@@ -120,2 +120,12 @@ import { z } from "zod";

}>, z.ZodString]>;
export declare const PayloadSchema: z.ZodArray<z.ZodObject<{
key: z.ZodString;
value: z.ZodUnion<[z.ZodEnum<[string, ...string[]]>, z.ZodString]>;
}, "strip", z.ZodTypeAny, {
value: string;
key: string;
}, {
value: string;
key: string;
}>, "many">;
export declare const TestStepSchema: z.ZodObject<{

@@ -215,2 +225,12 @@ request: z.ZodObject<{

}>, z.ZodString]>, "many">>;
payload: z.ZodOptional<z.ZodArray<z.ZodObject<{
key: z.ZodString;
value: z.ZodUnion<[z.ZodEnum<[string, ...string[]]>, z.ZodString]>;
}, "strip", z.ZodTypeAny, {
value: string;
key: string;
}, {
value: string;
key: string;
}>, "many">>;
}, "strip", z.ZodTypeAny, {

@@ -227,2 +247,6 @@ extract?: {

})[] | undefined;
payload?: {
value: string;
key: string;
}[] | undefined;
request: {

@@ -256,2 +280,6 @@ data?: string | undefined;

})[] | undefined;
payload?: {
value: string;
key: string;
}[] | undefined;
request: {

@@ -275,2 +303,9 @@ data?: string | undefined;

}>;
export declare const ConfigSchema: z.ZodObject<{
stopOnFailedAssertion: z.ZodOptional<z.ZodBoolean>;
}, "strip", z.ZodTypeAny, {
stopOnFailedAssertion?: boolean | undefined;
}, {
stopOnFailedAssertion?: boolean | undefined;
}>;
export declare const TestConfigSchema: z.ZodObject<{

@@ -395,2 +430,12 @@ id: z.ZodString;

}>, z.ZodString]>, "many">>;
payload: z.ZodOptional<z.ZodArray<z.ZodObject<{
key: z.ZodString;
value: z.ZodUnion<[z.ZodEnum<[string, ...string[]]>, z.ZodString]>;
}, "strip", z.ZodTypeAny, {
value: string;
key: string;
}, {
value: string;
key: string;
}>, "many">>;
}, "strip", z.ZodTypeAny, {

@@ -407,2 +452,6 @@ extract?: {

})[] | undefined;
payload?: {
value: string;
key: string;
}[] | undefined;
request: {

@@ -436,2 +485,6 @@ data?: string | undefined;

})[] | undefined;
payload?: {
value: string;
key: string;
}[] | undefined;
request: {

@@ -455,2 +508,9 @@ data?: string | undefined;

}>, "many">;
config: z.ZodOptional<z.ZodObject<{
stopOnFailedAssertion: z.ZodOptional<z.ZodBoolean>;
}, "strip", z.ZodTypeAny, {
stopOnFailedAssertion?: boolean | undefined;
}, {
stopOnFailedAssertion?: boolean | undefined;
}>>;
}, "strip", z.ZodTypeAny, {

@@ -466,2 +526,5 @@ meta?: {

}[] | undefined;
config?: {
stopOnFailedAssertion?: boolean | undefined;
} | undefined;
id: string;

@@ -479,2 +542,6 @@ test: {

})[] | undefined;
payload?: {
value: string;
key: string;
}[] | undefined;
request: {

@@ -508,2 +575,5 @@ data?: string | undefined;

}[] | undefined;
config?: {
stopOnFailedAssertion?: boolean | undefined;
} | undefined;
id: string;

@@ -521,2 +591,6 @@ test: {

})[] | undefined;
payload?: {
value: string;
key: string;
}[] | undefined;
request: {

@@ -544,2 +618,3 @@ data?: string | undefined;

export type Assertion = z.infer<typeof AssertionSchema>;
export type PayloadType = z.infer<typeof PayloadSchema>;
export type KeyValType = z.infer<typeof KeyValSchema>;

@@ -549,2 +624,3 @@ export type TestRequest = z.infer<typeof RequestSchema>;

export type TestConfig = z.infer<typeof TestConfigSchema>;
export type Config = z.infer<typeof ConfigSchema>;
export interface StepRequest {

@@ -593,2 +669,3 @@ url: string;

results: StepResult[][];
abortedAt?: number;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestConfigSchema = exports.TestStepSchema = exports.AssertionSchema = exports.ExtractorSchema = exports.RequestSchema = exports.KeyValSchema = exports.MetaSchema = exports.PrimitiveValueSchema = void 0;
exports.TestConfigSchema = exports.ConfigSchema = exports.TestStepSchema = exports.PayloadSchema = exports.AssertionSchema = exports.ExtractorSchema = exports.RequestSchema = exports.KeyValSchema = exports.MetaSchema = exports.PrimitiveValueSchema = void 0;
const zod_1 = require("zod");

@@ -47,2 +47,8 @@ const enums_1 = require("./enums");

]);
exports.PayloadSchema = zod_1.z
.object({
key: zod_1.z.string(),
value: zod_1.z.union([enums_1.PredefinedPayloadType, zod_1.z.string()]),
})
.array();
exports.TestStepSchema = zod_1.z.object({

@@ -52,3 +58,7 @@ request: exports.RequestSchema,

assert: exports.AssertionSchema.array().optional(),
payload: exports.PayloadSchema.optional(),
});
exports.ConfigSchema = zod_1.z.object({
stopOnFailedAssertion: zod_1.z.boolean().optional(),
});
exports.TestConfigSchema = zod_1.z.object({

@@ -59,3 +69,4 @@ id: zod_1.z.string().regex(constants_1.IDRegex),

test: exports.TestStepSchema.array(),
config: exports.ConfigSchema.optional(),
});
//# sourceMappingURL=test.js.map
{
"name": "@metlo/testing",
"version": "0.2.15",
"version": "0.2.16",
"license": "MIT",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc