/**
 * NOSQL context patterns.
 *
 * Detects injection vectors specific to NoSQL databases (primarily MongoDB)
 * and JavaScript-evaluated queries.
 *
 * Attack categories:
 *   1. MongoDB query operator injection: $where, $ne, $gt, $regex, $or, $and, etc.
 *      These operators, when injected into a JSON query object, can bypass
 *      authentication or exfiltrate data without knowing passwords.
 *
 *   2. JavaScript execution: $where clauses execute arbitrary JS server-side.
 *
 *   3. Prototype pollution: __proto__, constructor.prototype — can corrupt
 *      the prototype chain of all objects in the Node.js process.
 *
 * Pattern note: MongoDB operators appear as JSON keys. In JSON, keys are
 * quoted: {"$where": ...} so the pattern must allow an optional closing
 * quote between the operator name and the colon: /\$where["'\s]*:/
 */

// Shared suffix: optional closing quote/whitespace before the colon
// Handles: $op: (bare), "$op": (JSON), '$op': (single-quoted)
const SEP = /["'\s]*:/;
const sep = '["\'\\s]*:';

const NOSQL_PATTERNS = [
  // ─── MongoDB $ operator injection ────────────────────────────────────────
  {
    id: 'nosql-where-operator',
    description: '$where — executes arbitrary JavaScript server-side in MongoDB',
    pattern: new RegExp(`\\$where${sep}`, 'i'),
  },
  {
    id: 'nosql-ne-operator',
    description: '$ne — "not equal" operator used to bypass equality checks',
    pattern: new RegExp(`\\$ne${sep}`, 'i'),
  },
  {
    id: 'nosql-gt-operator',
    description: '$gt — "greater than" used to bypass password/value checks',
    pattern: new RegExp(`\\$gte?${sep}`, 'i'),
  },
  {
    id: 'nosql-lt-operator',
    description: '$lt / $lte — "less than" bypass variants',
    pattern: new RegExp(`\\$lte?${sep}`, 'i'),
  },
  {
    id: 'nosql-regex-operator',
    description: '$regex — can be used to extract data character by character (blind injection)',
    pattern: new RegExp(`\\$regex${sep}`, 'i'),
  },
  {
    id: 'nosql-or-operator',
    description: '$or — logical OR; used to create always-true conditions',
    pattern: new RegExp(`\\$or${sep}\\s*\\[`, 'i'),
  },
  {
    id: 'nosql-and-operator',
    description: '$and — logical AND operator injection',
    pattern: new RegExp(`\\$and${sep}\\s*\\[`, 'i'),
  },
  {
    id: 'nosql-nor-operator',
    description: '$nor — logical NOR operator injection',
    pattern: new RegExp(`\\$nor${sep}\\s*\\[`, 'i'),
  },
  {
    id: 'nosql-exists-operator',
    description: '$exists — can enumerate fields to determine schema',
    pattern: new RegExp(`\\$exists${sep}`, 'i'),
  },
  {
    id: 'nosql-in-operator',
    description: '$in — matches any value in a list; can enumerate values',
    pattern: new RegExp(`\\$in${sep}\\s*\\[`, 'i'),
  },
  {
    id: 'nosql-expr-operator',
    description: '$expr — allows aggregation expressions in queries (MongoDB 3.6+)',
    pattern: new RegExp(`\\$expr${sep}`, 'i'),
  },
  {
    id: 'nosql-function-operator',
    description: '$function — executes arbitrary JavaScript in MongoDB 4.4+',
    pattern: new RegExp(`\\$function${sep}`, 'i'),
  },
  {
    id: 'nosql-accumulator-operator',
    description: '$accumulator — custom aggregation with arbitrary JS execution',
    pattern: new RegExp(`\\$accumulator${sep}`, 'i'),
  },
  // ─── Prototype pollution ─────────────────────────────────────────────────
  {
    id: 'nosql-proto-pollution',
    description: '__proto__ — prototype pollution via object key injection',
    pattern: /__proto__/,
  },
  {
    id: 'nosql-constructor-prototype',
    description: 'constructor.prototype — alternative prototype pollution vector (dot notation or JSON key)',
    // Matches dot-notation (obj.constructor.prototype) and JSON key adjacency
    // ("constructor": {"prototype": ...})
    pattern: /constructor[\s"':.,{\[]*prototype/i,
  },
  {
    id: 'nosql-proto-bracket',
    description: '["__proto__"] — bracket-notation prototype pollution',
    pattern: /\[["']__proto__["']\]/,
  },
];

export default NOSQL_PATTERNS;
