From d6f087efadbb07517ea235b7a7185e80e9de032a Mon Sep 17 00:00:00 2001 From: Kirill Date: Fri, 3 Jul 2026 11:47:06 +0300 Subject: [PATCH 01/13] Validate empty Show On Map options (#2631) --- src/core/operations/ShowOnMap.mjs | 6 ++++-- tests/operations/tests/ShowOnMap.mjs | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/core/operations/ShowOnMap.mjs b/src/core/operations/ShowOnMap.mjs index 2eab5140..708ad058 100644 --- a/src/core/operations/ShowOnMap.mjs +++ b/src/core/operations/ShowOnMap.mjs @@ -36,7 +36,8 @@ class ShowOnMap extends Operation { { name: "Input Format", type: "option", - value: ["Auto"].concat(FORMATS) + value: ["Auto"].concat(FORMATS), + allowEmpty: false }, { name: "Input Delimiter", @@ -49,7 +50,8 @@ class ShowOnMap extends Operation { "Comma", "Semi-colon", "Colon" - ] + ], + allowEmpty: false } ]; } diff --git a/tests/operations/tests/ShowOnMap.mjs b/tests/operations/tests/ShowOnMap.mjs index 8605ae70..329ed345 100644 --- a/tests/operations/tests/ShowOnMap.mjs +++ b/tests/operations/tests/ShowOnMap.mjs @@ -36,4 +36,26 @@ TestRegister.addTests([ }, ], }, + { + name: "Show on map: empty input format is rejected", + input: "1, 24", + expectedOutput: "Input Format cannot be empty.", + recipeConfig: [ + { + op: "Show on map", + args: [13, "", "Auto"] + }, + ], + }, + { + name: "Show on map: empty input delimiter is rejected", + input: "1, 24", + expectedOutput: "Input Delimiter cannot be empty.", + recipeConfig: [ + { + op: "Show on map", + args: [13, "Auto", ""] + }, + ], + }, ]); From 6f95a2e17db7dd45789be96385ca19faa42fbf05 Mon Sep 17 00:00:00 2001 From: Zain Nadeem Date: Fri, 3 Jul 2026 13:52:04 +0500 Subject: [PATCH 02/13] Handle invalid bcrypt salt errors in Bcrypt compare (#2615) --- src/core/operations/BcryptCompare.mjs | 16 +++++++++++----- tests/operations/tests/Hash.mjs | 11 +++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/core/operations/BcryptCompare.mjs b/src/core/operations/BcryptCompare.mjs index 824316ae..9720976a 100644 --- a/src/core/operations/BcryptCompare.mjs +++ b/src/core/operations/BcryptCompare.mjs @@ -5,6 +5,7 @@ */ import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; import bcrypt from "bcryptjs"; import { isWorkerEnvironment } from "../Utils.mjs"; @@ -43,11 +44,16 @@ class BcryptCompare extends Operation { async run(input, args) { const hash = args[0]; - const match = await bcrypt.compare(input, hash, undefined, p => { - // Progress callback - if (isWorkerEnvironment()) - self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`); - }); + let match; + try { + match = await bcrypt.compare(input, hash, undefined, p => { + // Progress callback + if (isWorkerEnvironment()) + self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`); + }); + } catch (err) { + throw new OperationError(err.toString()); + } return match ? "Match: " + input : "No match"; diff --git a/tests/operations/tests/Hash.mjs b/tests/operations/tests/Hash.mjs index ba502934..1ffb749c 100644 --- a/tests/operations/tests/Hash.mjs +++ b/tests/operations/tests/Hash.mjs @@ -993,6 +993,17 @@ TestRegister.addTests([ } ] }, + { + name: "Bcrypt compare: invalid salt version", + input: "password", + expectedOutput: "Error: Invalid salt version: $a", + recipeConfig: [ + { + op: "Bcrypt compare", + args: ["$ab$04$K.H1WlFDQ/iIo/PiprT/puwluJ5rzuSE5q8D/Fk3NuLgU2aXiGR9m"] + } + ] + }, { name: "Scrypt: RFC test vector 1", input: "", From 3104e6073ff4ce6f8e5b0ce04896d45d1ee0344f Mon Sep 17 00:00:00 2001 From: alleria173 Date: Fri, 3 Jul 2026 09:54:38 +0100 Subject: [PATCH 03/13] Fixes #2446 hotp otpauth uri validation (#2614) --- src/core/operations/GenerateHOTP.mjs | 18 +++++-- tests/node/tests/operations.mjs | 3 +- tests/operations/tests/OTP.mjs | 70 +++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/core/operations/GenerateHOTP.mjs b/src/core/operations/GenerateHOTP.mjs index 75f5329f..c506dbd1 100644 --- a/src/core/operations/GenerateHOTP.mjs +++ b/src/core/operations/GenerateHOTP.mjs @@ -27,17 +27,23 @@ class GenerateHOTP extends Operation { { "name": "Name", "type": "string", - "value": "" + "value": "Account", + "allowEmpty": false }, { "name": "Code length", "type": "number", - "value": 6 + "value": 6, + "min": 6, + "max": 8, + "integer": true }, { "name": "Counter", "type": "number", - "value": 0 + "value": 0, + "min": 0, + "integer": true } ]; } @@ -47,7 +53,9 @@ class GenerateHOTP extends Operation { */ run(input, args) { const secretStr = new TextDecoder("utf-8").decode(input).trim(); - const secret = secretStr ? secretStr.toUpperCase().replace(/\s+/g, "") : ""; + const secret = secretStr ? + OTPAuth.Secret.fromBase32(secretStr.toUpperCase().replace(/\s+/g, "")) : + new OTPAuth.Secret(); const hotp = new OTPAuth.HOTP({ issuer: "", @@ -55,7 +63,7 @@ class GenerateHOTP extends Operation { algorithm: "SHA1", digits: args[1], counter: args[2], - secret: OTPAuth.Secret.fromBase32(secret) + secret }); const uri = hotp.toString(); diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index 6cf85718..4dd95246 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -605,8 +605,9 @@ Top Drawer`, { it("Generate HOTP", () => { const result = chef.generateHOTP("JBSWY3DPEHPK3PXP", { + name: "Account", }); - const expected = `URI: otpauth://hotp/?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&counter=0 + const expected = `URI: otpauth://hotp/Account?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&counter=0 Password: 282760`; assert.strictEqual(result.toString(), expected); diff --git a/tests/operations/tests/OTP.mjs b/tests/operations/tests/OTP.mjs index 6e9739e4..59ca9fec 100644 --- a/tests/operations/tests/OTP.mjs +++ b/tests/operations/tests/OTP.mjs @@ -12,11 +12,77 @@ TestRegister.addTests([ { name: "Generate HOTP", input: "JBSWY3DPEHPK3PXP", - expectedOutput: `URI: otpauth://hotp/?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&counter=0\n\nPassword: 282760`, + expectedOutput: `URI: otpauth://hotp/Account?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&counter=0\n\nPassword: 282760`, recipeConfig: [ { op: "Generate HOTP", - args: ["", 6, 0], // [Name, Code length, Counter] + args: ["Account", 6, 0], // [Name, Code length, Counter] + }, + ], + }, + { + name: "Generate HOTP - empty name rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Name cannot be empty.", + recipeConfig: [ + { + op: "Generate HOTP", + args: ["", 6, 0], + }, + ], + }, + { + name: "Generate HOTP - code length below minimum rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Code length must be greater than or equal to 6.", + recipeConfig: [ + { + op: "Generate HOTP", + args: ["Account", -6, 0], + }, + ], + }, + { + name: "Generate HOTP - code length above maximum rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Code length must be less than or equal to 8.", + recipeConfig: [ + { + op: "Generate HOTP", + args: ["Account", 9, 0], + }, + ], + }, + { + name: "Generate HOTP - non-integer code length rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Code length must be an integer.", + recipeConfig: [ + { + op: "Generate HOTP", + args: ["Account", 6.5, 0], + }, + ], + }, + { + name: "Generate HOTP - negative counter rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Counter must be greater than or equal to 0.", + recipeConfig: [ + { + op: "Generate HOTP", + args: ["Account", 6, -1], + }, + ], + }, + { + name: "Generate HOTP - special characters in name are URI-encoded", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: `URI: otpauth://hotp/user%40example.com?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&counter=0\n\nPassword: 282760`, + recipeConfig: [ + { + op: "Generate HOTP", + args: ["user@example.com", 6, 0], }, ], }, From 961bbab682413ba78d17056708858895f0cbef65 Mon Sep 17 00:00:00 2001 From: Zain Nadeem Date: Fri, 3 Jul 2026 14:02:14 +0500 Subject: [PATCH 04/13] Handle malformed image parser errors in View Bit Plane (#2612) --- src/core/operations/ViewBitPlane.mjs | 12 +++++++++--- tests/operations/tests/Image.mjs | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/core/operations/ViewBitPlane.mjs b/src/core/operations/ViewBitPlane.mjs index 3740c10d..920e5bce 100644 --- a/src/core/operations/ViewBitPlane.mjs +++ b/src/core/operations/ViewBitPlane.mjs @@ -52,9 +52,15 @@ class ViewBitPlane extends Operation { if (!isImage(input)) throw new OperationError("Please enter a valid image file."); - const [colour, bit] = args, - parsedImage = await Jimp.read(input), - width = parsedImage.bitmap.width, + const [colour, bit] = args; + let parsedImage; + try { + parsedImage = await Jimp.read(input); + } catch (err) { + throw new OperationError(`Error loading image. (${err})`); + } + + const width = parsedImage.bitmap.width, height = parsedImage.bitmap.height, colourIndex = COLOUR_OPTIONS.indexOf(colour), bitIndex = 7 - bit; diff --git a/tests/operations/tests/Image.mjs b/tests/operations/tests/Image.mjs index fe6cab10..7da6c65d 100644 --- a/tests/operations/tests/Image.mjs +++ b/tests/operations/tests/Image.mjs @@ -241,6 +241,21 @@ TestRegister.addTests([ } ] }, + { + name: "View Bit Plane: malformed PNG", + input: PNG_HEX.replace("49484452", "49424452"), + expectedOutput: "Error loading image. (Error: unrecognised content at end of stream)", + recipeConfig: [ + { + op: "From Hex", + args: ["None"] + }, + { + op: "View Bit Plane", + args: ["Red", 0] + } + ] + }, { name: "Randomize Colour Palette", "input": PNG_HEX, From 179eb9a379e64d2bbb7d4323e62a2fdca21e044a Mon Sep 17 00:00:00 2001 From: Kirill Date: Fri, 3 Jul 2026 13:06:55 +0300 Subject: [PATCH 05/13] Validate Wrap line width (#2606) Co-authored-by: GCHQDeveloper581 <63102987+GCHQDeveloper581@users.noreply.github.com> Co-authored-by: C85297 <95289555+C85297@users.noreply.github.com> --- src/core/operations/Wrap.mjs | 5 ++++ tests/operations/tests/Wrap.mjs | 44 +++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/core/operations/Wrap.mjs b/src/core/operations/Wrap.mjs index c6e57f88..004246ac 100644 --- a/src/core/operations/Wrap.mjs +++ b/src/core/operations/Wrap.mjs @@ -6,6 +6,8 @@ import Operation from "../Operation.mjs"; +const MAX_LINE_WIDTH = 65536; + /** * Wrap operation */ @@ -27,6 +29,9 @@ class Wrap extends Operation { "name": "Line Width", "type": "number", "value": 64, + "min": 1, + "max": MAX_LINE_WIDTH, + "integer": true, }, ]; } diff --git a/tests/operations/tests/Wrap.mjs b/tests/operations/tests/Wrap.mjs index 8d7c9a51..b7569ba8 100644 --- a/tests/operations/tests/Wrap.mjs +++ b/tests/operations/tests/Wrap.mjs @@ -40,5 +40,49 @@ TestRegister.addTests([ "args": [10] }, ], + }, + { + name: "Wrap rejects zero line width", + input: "hello", + expectedOutput: "Line Width must be greater than or equal to 1.", + recipeConfig: [ + { + "op": "Wrap", + "args": [0] + }, + ], + }, + { + name: "Wrap rejects negative line width", + input: "hello", + expectedOutput: "Line Width must be greater than or equal to 1.", + recipeConfig: [ + { + "op": "Wrap", + "args": [-1] + }, + ], + }, + { + name: "Wrap rejects non-integer line width", + input: "hello", + expectedOutput: "Line Width must be an integer.", + recipeConfig: [ + { + "op": "Wrap", + "args": [1.1] + }, + ], + }, + { + name: "Wrap rejects excessive line width", + input: "hello", + expectedOutput: "Line Width must be less than or equal to 65536.", + recipeConfig: [ + { + "op": "Wrap", + "args": [65537] + }, + ], } ]); From c51e21a242522d76b3d0c2de26cd101ece1849b2 Mon Sep 17 00:00:00 2001 From: alleria173 Date: Fri, 3 Jul 2026 11:23:06 +0100 Subject: [PATCH 06/13] fix/2444 TOTP input validation for correct otpauth uri generation (#2621) --- src/core/operations/GenerateTOTP.mjs | 16 ++++-- tests/operations/tests/OTP.mjs | 77 ++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/src/core/operations/GenerateTOTP.mjs b/src/core/operations/GenerateTOTP.mjs index 187f8418..b6ce8698 100644 --- a/src/core/operations/GenerateTOTP.mjs +++ b/src/core/operations/GenerateTOTP.mjs @@ -26,22 +26,30 @@ class GenerateTOTP extends Operation { { "name": "Name", "type": "string", - "value": "" + "value": "Account", + "allowEmpty": false }, { "name": "Code length", "type": "number", - "value": 6 + "value": 6, + "min": 6, + "max": 8, + "integer": true }, { "name": "Epoch offset (T0)", "type": "number", - "value": 0 + "value": 0, + "min": 0, + "integer": true }, { "name": "Interval (T1)", "type": "number", - "value": 30 + "value": 30, + "min": 1, + "integer": true } ]; } diff --git a/tests/operations/tests/OTP.mjs b/tests/operations/tests/OTP.mjs index 59ca9fec..9d67395e 100644 --- a/tests/operations/tests/OTP.mjs +++ b/tests/operations/tests/OTP.mjs @@ -86,4 +86,81 @@ TestRegister.addTests([ }, ], }, + { + name: "Generate TOTP", + input: "JBSWY3DPEHPK3PXP", + expectedMatch: /^URI: otpauth:\/\/totp\/Account\?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&period=30\n\nPassword: \d{6}$/, + recipeConfig: [ + { + op: "Generate TOTP", + args: ["Account", 6, 0, 30], // [Name, Code length, Epoch offset (T0), Interval (T1)] + }, + ], + }, + { + name: "Generate TOTP - empty name rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Name cannot be empty.", + recipeConfig: [ + { + op: "Generate TOTP", + args: ["", 6, 0, 30], + }, + ], + }, + { + name: "Generate TOTP - code length below minimum rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Code length must be greater than or equal to 6.", + recipeConfig: [ + { + op: "Generate TOTP", + args: ["Account", -6, 0, 30], + }, + ], + }, + { + name: "Generate TOTP - code length above maximum rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Code length must be less than or equal to 8.", + recipeConfig: [ + { + op: "Generate TOTP", + args: ["Account", 9, 0, 30], + }, + ], + }, + { + name: "Generate TOTP - non-integer code length rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Code length must be an integer.", + recipeConfig: [ + { + op: "Generate TOTP", + args: ["Account", 6.5, 0, 30], + }, + ], + }, + { + name: "Generate TOTP - negative interval rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Interval (T1) must be greater than or equal to 1.", + recipeConfig: [ + { + op: "Generate TOTP", + args: ["Account", 6, 0, -1], + }, + ], + }, + { + name: "Generate TOTP - negative epoch offset rejected", + input: "JBSWY3DPEHPK3PXP", + expectedOutput: "Epoch offset (T0) must be greater than or equal to 0.", + recipeConfig: [ + { + op: "Generate TOTP", + args: ["Account", 6, -1, 30], + }, + ], + }, ]); From 740d3503067794c5d8732160c94ea1112e69ee1d Mon Sep 17 00:00:00 2001 From: GCHQDeveloper581 <63102987+GCHQDeveloper581@users.noreply.github.com> Date: Fri, 3 Jul 2026 11:28:53 +0100 Subject: [PATCH 07/13] Add a workflow to automatically flag PRs without a signed CLA (#2627) --- .github/workflows/cla-label.yml | 87 +++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 .github/workflows/cla-label.yml diff --git a/.github/workflows/cla-label.yml b/.github/workflows/cla-label.yml new file mode 100644 index 00000000..5c514e9b --- /dev/null +++ b/.github/workflows/cla-label.yml @@ -0,0 +1,87 @@ +name: CLA Label Sync + +on: + issue_comment: + types: [created, edited] + pull_request_target: + types: [opened, synchronize, reopened] + +permissions: + pull-requests: write + issues: write + contents: read + +jobs: + sync-label: + # Only run for PRs (issue_comment fires for issues too) + if: >- + github.event_name == 'pull_request_target' || + (github.event.issue.pull_request != null) + runs-on: ubuntu-latest + steps: + - name: Sync "awaiting cla" label + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 #v9.0.0 + env: + AWAITING_LABEL: 'awaiting cla' + # Bot login that posts the CLA comment. Common values: + # 'github-actions[bot]', 'CLAassistant', 'cla-assistant[bot]' + CLA_BOT_LOGINS: 'CLAassistant' + # Regex (case-insensitive) that matches an UNSIGNED CLA comment + NOT_SIGNED_REGEX: 'cla-assistant.io/pull/badge/not_signed' + # Regex (case-insensitive) that matches a SIGNED CLA comment + SIGNED_REGEX: 'cla-assistant.io/pull/badge/signed' + with: + script: | + const awaitingLabel = process.env.AWAITING_LABEL; + const botLogins = process.env.CLA_BOT_LOGINS.split(',').map(s => s.trim().toLowerCase()); + const notSigned = new RegExp(process.env.NOT_SIGNED_REGEX, 'i'); + const signed = new RegExp(process.env.SIGNED_REGEX, 'i'); + + // Resolve PR number for either trigger + const prNumber = context.eventName === 'pull_request_target' + ? context.payload.pull_request.number + : context.payload.issue.number; + + const { owner, repo } = context.repo; + + // Pull the full comment history to find the latest CLA bot comment + const comments = await github.paginate(github.rest.issues.listComments, { + owner, repo, issue_number: prNumber, per_page: 100, + }); + + const claComments = comments.filter(c => + botLogins.includes((c.user?.login || '').toLowerCase()) && + (notSigned.test(c.body) || signed.test(c.body)) + ); + + if (claComments.length === 0) { + core.info('No CLA Assistant comment found yet; nothing to do.'); + return; + } + + const latest = claComments[claComments.length - 1]; + const isSigned = signed.test(latest.body) && !notSigned.test(latest.body); + + core.info(`Latest CLA comment (id ${latest.id}) => signed=${isSigned}`); + + // Current labels + const { data: issue } = await github.rest.issues.get({ + owner, repo, issue_number: prNumber, + }); + const hasLabel = issue.labels.some(l => + (typeof l === 'string' ? l : l.name) === awaitingLabel + ); + + if (isSigned && hasLabel) { + await github.rest.issues.removeLabel({ + owner, repo, issue_number: prNumber, name: awaitingLabel, + }).catch(e => core.warning(`removeLabel failed: ${e.message}`)); + core.info(`Removed "${awaitingLabel}".`); + } else if (!isSigned && !hasLabel) { + await github.rest.issues.addLabels({ + owner, repo, issue_number: prNumber, labels: [awaitingLabel], + }); + core.info(`Added "${awaitingLabel}".`); + } else { + core.info('Label already in the correct state.'); + } From eccaf723f5a5f4d33578daad05add389395daf4e Mon Sep 17 00:00:00 2001 From: loki1205 <87192195+loki1205@users.noreply.github.com> Date: Fri, 3 Jul 2026 16:09:33 +0530 Subject: [PATCH 08/13] Fix base32 unicode alphabet (#2380) --- src/core/operations/ToBase32.mjs | 24 +++++++++++++++++---- tests/node/tests/NodeDish.mjs | 36 +++++++++++++++++++++++++++++++ tests/node/tests/nodeApi.mjs | 32 +++++++++++++++++++++++++++ tests/operations/tests/Base32.mjs | 22 +++++++++++++++++++ 4 files changed, 110 insertions(+), 4 deletions(-) diff --git a/src/core/operations/ToBase32.mjs b/src/core/operations/ToBase32.mjs index 44eb8b48..b2ae0ef3 100644 --- a/src/core/operations/ToBase32.mjs +++ b/src/core/operations/ToBase32.mjs @@ -43,7 +43,14 @@ class ToBase32 extends Operation { if (!input) return ""; input = new Uint8Array(input); - const alphabet = args[0] ? Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="; + const alphabet = args[0] ? + Utils.expandAlphRange(args[0]).join("") : + "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="; + + // Unicode-safe alphabet handling + // Supports BMP + non-BMP characters (emoji, Mahjong tiles, etc.) + const alphabetChars = Array.from(alphabet); + let output = "", chr1, chr2, chr3, chr4, chr5, enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8, @@ -74,10 +81,19 @@ class ToBase32 extends Operation { enc8 = 32; } - output += alphabet.charAt(enc1) + alphabet.charAt(enc2) + alphabet.charAt(enc3) + - alphabet.charAt(enc4) + alphabet.charAt(enc5) + alphabet.charAt(enc6) + - alphabet.charAt(enc7) + alphabet.charAt(enc8); + // Preserve original charAt() behavior: + // out-of-range indexes return "" + output += + (alphabetChars[enc1] || "") + + (alphabetChars[enc2] || "") + + (alphabetChars[enc3] || "") + + (alphabetChars[enc4] || "") + + (alphabetChars[enc5] || "") + + (alphabetChars[enc6] || "") + + (alphabetChars[enc7] || "") + + (alphabetChars[enc8] || ""); } + return output; } diff --git a/tests/node/tests/NodeDish.mjs b/tests/node/tests/NodeDish.mjs index 3ec8b7e2..958e1338 100644 --- a/tests/node/tests/NodeDish.mjs +++ b/tests/node/tests/NodeDish.mjs @@ -65,6 +65,42 @@ TestRegister.addApiTests([ assert.strictEqual(result.toString(), "493e8136b759370a415ef2cf2f7a69690441ff86592aba082bc2e2e0"); }), + it("Composable Dish: toBase32 should support non-BMP Unicode alphabets", () => { + const alphabet = "🀇🀈🀉🀊🀋🀌🀍🀎🀏🀙🀚🀛🀜🀝🀞🀟🀠🀡🀐🀑🀒🀓🀔🀕🀖🀗🀘🀀🀁🀂🀃🀅"; + + const result = new Dish("hello") + .apply(toBase32, {alphabet}) + .toString(); + + // Should not contain replacement characters + assert.equal(result.includes("�"), false); + + // Should contain only symbols from the alphabet + for (const ch of Array.from(result)) { + assert.ok(Array.from(alphabet).includes(ch)); + } + + // "hello" => 8 Base32 symbols + assert.equal(Array.from(result).length, 8); + }), + + it("Composable Dish: toBase32 should omit padding for 32-character Unicode alphabets", () => { + const alphabet = "🀇🀈🀉🀊🀋🀌🀍🀎🀏🀙🀚🀛🀜🀝🀞🀟🀠🀡🀐🀑🀒🀓🀔🀕🀖🀗🀘🀀🀁🀂🀃🀅"; + + const result = new Dish("hell") + .apply(toBase32, {alphabet}) + .toString(); + + // Should not leak undefined from array indexing + assert.equal(result.includes("undefined"), false); + + // Should not contain replacement characters + assert.equal(result.includes("�"), false); + + // Unpadded Base32 output for 4-byte input should be 7 symbols + assert.equal(Array.from(result).length, 7); + }), + it("Dish translation: ArrayBuffer to ArrayBuffer", () => { const dish = new Dish(new ArrayBuffer(10), 4); dish.get("array buffer"); diff --git a/tests/node/tests/nodeApi.mjs b/tests/node/tests/nodeApi.mjs index 5f2476ee..b65b9abc 100644 --- a/tests/node/tests/nodeApi.mjs +++ b/tests/node/tests/nodeApi.mjs @@ -109,6 +109,38 @@ TestRegister.addApiTests([ assert.equal(3 + result, 35); }), + it("toBase32: should support non-BMP Unicode alphabets", () => { + const alphabet = "🀇🀈🀉🀊🀋🀌🀍🀎🀏🀙🀚🀛🀜🀝🀞🀟🀠🀡🀐🀑🀒🀓🀔🀕🀖🀗🀘🀀🀁🀂🀃🀅"; + + const result = chef.toBase32("hello", {alphabet}).toString(); + + // Should not contain replacement characters + assert.equal(result.includes("�"), false); + + // Should contain only symbols from the alphabet + for (const ch of Array.from(result)) { + assert.ok(Array.from(alphabet).includes(ch)); + } + + // "hello" => 8 Base32 symbols + assert.equal(Array.from(result).length, 8); + }), + + it("toBase32: should omit padding for 32-character Unicode alphabets", () => { + const alphabet = "🀇🀈🀉🀊🀋🀌🀍🀎🀏🀙🀚🀛🀜🀝🀞🀟🀠🀡🀐🀑🀒🀓🀔🀕🀖🀗🀘🀀🀁🀂🀃🀅"; + + const result = chef.toBase32("hell", {alphabet}).toString(); + + // Should not leak undefined from array indexing + assert.equal(result.includes("undefined"), false); + + // Should not contain replacement characters + assert.equal(result.includes("�"), false); + + // Unpadded Base32 output for 4-byte input should be 7 symbols + assert.equal(Array.from(result).length, 7); + }), + it("chef.help: should exist", () => { assert(chef.help); }), diff --git a/tests/operations/tests/Base32.mjs b/tests/operations/tests/Base32.mjs index 760cdf14..558d7df6 100644 --- a/tests/operations/tests/Base32.mjs +++ b/tests/operations/tests/Base32.mjs @@ -172,5 +172,27 @@ TestRegister.addTests([ }, ], }, + { + name: "To Base32: should support non-BMP Unicode alphabets", + input: "hello", + expectedOutput: "🀝🀈🀐🀔🀖🀀🀊🀟", + recipeConfig: [ + { + op: "To Base32", + args: ["🀇🀈🀉🀊🀋🀌🀍🀎🀏🀙🀚🀛🀜🀝🀞🀟🀠🀡🀐🀑🀒🀓🀔🀕🀖🀗🀘🀀🀁🀂🀃🀅"], + }, + ], + }, + { + name: "To Base32: should omit padding for 32-character Unicode alphabets", + input: "hell", + expectedOutput: "🀝🀈🀐🀔🀖🀀🀇", + recipeConfig: [ + { + op: "To Base32", + args: ["🀇🀈🀉🀊🀋🀌🀍🀎🀏🀙🀚🀛🀜🀝🀞🀟🀠🀡🀐🀑🀒🀓🀔🀕🀖🀗🀘🀀🀁🀂🀃🀅"], + }, + ], + }, ]); From 79de8f119932690cba98169d12dc59b579fee9a3 Mon Sep 17 00:00:00 2001 From: alleria173 Date: Fri, 3 Jul 2026 12:58:00 +0100 Subject: [PATCH 09/13] fix/2445 HOTP (and 2426 TOTP) type errors (#2620) --- src/core/operations/GenerateHOTP.mjs | 15 +++++++++++---- src/core/operations/GenerateTOTP.mjs | 15 ++++++++++++--- tests/operations/tests/OTP.mjs | 22 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/core/operations/GenerateHOTP.mjs b/src/core/operations/GenerateHOTP.mjs index c506dbd1..6b4c489d 100644 --- a/src/core/operations/GenerateHOTP.mjs +++ b/src/core/operations/GenerateHOTP.mjs @@ -5,6 +5,7 @@ */ import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; import * as OTPAuth from "otpauth"; /** @@ -19,7 +20,7 @@ class GenerateHOTP extends Operation { this.name = "Generate HOTP"; this.module = "Default"; - this.description = "The HMAC-based One-Time Password algorithm (HOTP) is an algorithm that computes a one-time password from a shared secret key and an incrementing counter. It has been adopted as Internet Engineering Task Force standard RFC 4226, is the cornerstone of Initiative For Open Authentication (OAUTH), and is used in a number of two-factor authentication systems.

Enter the secret as the input or leave it blank for a random secret to be generated."; + this.description = "The HMAC-based One-Time Password algorithm (HOTP) is an algorithm that computes a one-time password from a shared secret key and an incrementing counter. It has been adopted as Internet Engineering Task Force standard RFC 4226, is the cornerstone of Initiative For Open Authentication (OAUTH), and is used in a number of two-factor authentication systems.

Enter the secret as the input or leave it blank for a random secret to be generated. The secret must be a valid base32 string (characters A–Z and 2–7)."; this.infoURL = "https://wikipedia.org/wiki/HMAC-based_One-time_Password_algorithm"; this.inputType = "ArrayBuffer"; this.outputType = "string"; @@ -53,9 +54,15 @@ class GenerateHOTP extends Operation { */ run(input, args) { const secretStr = new TextDecoder("utf-8").decode(input).trim(); - const secret = secretStr ? - OTPAuth.Secret.fromBase32(secretStr.toUpperCase().replace(/\s+/g, "")) : - new OTPAuth.Secret(); + + let secret; + try { + secret = secretStr ? + OTPAuth.Secret.fromBase32(secretStr.toUpperCase().replace(/\s+/g, "")) : + new OTPAuth.Secret(); + } catch { + throw new OperationError("Invalid secret. The input must be a valid base32 string (characters A–Z and 2–7)."); + } const hotp = new OTPAuth.HOTP({ issuer: "", diff --git a/src/core/operations/GenerateTOTP.mjs b/src/core/operations/GenerateTOTP.mjs index b6ce8698..fd82385e 100644 --- a/src/core/operations/GenerateTOTP.mjs +++ b/src/core/operations/GenerateTOTP.mjs @@ -5,6 +5,7 @@ */ import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; import * as OTPAuth from "otpauth"; /** @@ -18,7 +19,7 @@ class GenerateTOTP extends Operation { super(); this.name = "Generate TOTP"; this.module = "Default"; - this.description = "The Time-based One-Time Password algorithm (TOTP) is an algorithm that computes a one-time password from a shared secret key and the current time. It has been adopted as Internet Engineering Task Force standard RFC 6238, is the cornerstone of Initiative For Open Authentication (OAUTH), and is used in a number of two-factor authentication systems. A TOTP is an HOTP where the counter is the current time.

Enter the secret as the input or leave it blank for a random secret to be generated. T0 and T1 are in seconds."; + this.description = "The Time-based One-Time Password algorithm (TOTP) is an algorithm that computes a one-time password from a shared secret key and the current time. It has been adopted as Internet Engineering Task Force standard RFC 6238, is the cornerstone of Initiative For Open Authentication (OAUTH), and is used in a number of two-factor authentication systems. A TOTP is an HOTP where the counter is the current time.

Enter the secret as the input or leave it blank for a random secret to be generated. The secret must be a valid base32 string (characters A–Z and 2–7). T0 and T1 are in seconds."; this.infoURL = "https://wikipedia.org/wiki/Time-based_One-time_Password_algorithm"; this.inputType = "ArrayBuffer"; this.outputType = "string"; @@ -59,7 +60,15 @@ class GenerateTOTP extends Operation { */ run(input, args) { const secretStr = new TextDecoder("utf-8").decode(input).trim(); - const secret = secretStr ? secretStr.toUpperCase().replace(/\s+/g, "") : ""; + + let secret; + try { + secret = secretStr ? + OTPAuth.Secret.fromBase32(secretStr.toUpperCase().replace(/\s+/g, "")) : + new OTPAuth.Secret(); + } catch { + throw new OperationError("Invalid secret. The input must be a valid base32 string (characters A–Z and 2–7)."); + } const totp = new OTPAuth.TOTP({ issuer: "", @@ -68,7 +77,7 @@ class GenerateTOTP extends Operation { digits: args[1], period: args[3], epoch: args[2] * 1000, // Convert seconds to milliseconds - secret: OTPAuth.Secret.fromBase32(secret) + secret }); const uri = totp.toString(); diff --git a/tests/operations/tests/OTP.mjs b/tests/operations/tests/OTP.mjs index 9d67395e..23130c90 100644 --- a/tests/operations/tests/OTP.mjs +++ b/tests/operations/tests/OTP.mjs @@ -163,4 +163,26 @@ TestRegister.addTests([ }, ], }, + { + name: "Generate HOTP - invalid base32 secret rejected", + input: "not,valid|base32;input", + expectedOutput: "Invalid secret. The input must be a valid base32 string (characters A–Z and 2–7).", + recipeConfig: [ + { + op: "Generate HOTP", + args: ["Account", 6, 0], + }, + ], + }, + { + name: "Generate TOTP - invalid base32 secret rejected", + input: "not,valid|base32;input", + expectedOutput: "Invalid secret. The input must be a valid base32 string (characters A–Z and 2–7).", + recipeConfig: [ + { + op: "Generate TOTP", + args: ["Account", 6, 0, 30], + }, + ], + }, ]); From 3ca7c792df1444a0363c56a85d55c24d234f8ec2 Mon Sep 17 00:00:00 2001 From: GCHQDeveloper581 <63102987+GCHQDeveloper581@users.noreply.github.com> Date: Fri, 3 Jul 2026 15:54:10 +0100 Subject: [PATCH 10/13] Feature: automatically expire PRs if CLA remains unsigned for an extended period (#2636) --- .github/workflows/cla-close-stale.yml | 62 +++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 .github/workflows/cla-close-stale.yml diff --git a/.github/workflows/cla-close-stale.yml b/.github/workflows/cla-close-stale.yml new file mode 100644 index 00000000..2bd2a78a --- /dev/null +++ b/.github/workflows/cla-close-stale.yml @@ -0,0 +1,62 @@ +name: Close Stale Unsigned CLA PRs + +on: + schedule: + # Runs daily at 01:30 UTC. + - cron: '30 1 * * *' + workflow_dispatch: {} + +permissions: + contents: read + pull-requests: write + issues: write + +# Configurable intervals (days). +# DAYS_BEFORE_WARNING = grace period before the warning comment. +# DAYS_BEFORE_CLOSURE = further period after the warning before closing. +env: + DAYS_BEFORE_WARNING: 7 + DAYS_BEFORE_CLOSURE: 21 + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - name: Close stale unsigned-CLA PRs + uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 #v10.3.0 + with: + # ---- Guards: only act on PRs carrying the CLA label ---- + only-labels: 'awaiting cla' + + # Never touch issues — PRs only. + days-before-issue-stale: -1 + days-before-issue-close: -1 + + # ---- Timing ---- + # DAYS_BEFORE_WARNING: days of inactivity before the warning comment. + days-before-pr-stale: ${{ env.DAYS_BEFORE_WARNING }} + # DAYS_BEFORE_CLOSURE: days after being marked stale before closing. + days-before-pr-close: ${{ env.DAYS_BEFORE_CLOSURE }} + + # ---- Warning comment (posted once when marked stale) ---- + stale-pr-message: > + As we are unable to accept contributions unless the CLA has + been signed, this PR will be automatically closed if the CLA + is not signed within ${{ env.DAYS_BEFORE_CLOSURE }} days. + + # ---- Close comment ---- + close-pr-message: > + This PR has been automatically closed as the CLA remains + unsigned. We will be happy to have it reopened if the CLA + is signed subsequently. + + # A dedicated marker label so we can track stale state without + # interfering with the "awaiting cla" label. + stale-pr-label: 'cla-stale' + + # If the PR is updated after being marked stale, remove the marker + # so the warning-then-close cycle restarts cleanly. + remove-pr-stale-when-updated: true + + # Process enough PRs per run for busy repos. + operations-per-run: 200 From a4edfdd770d8bd73817b4f5e5fadd744fb5db157 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 16:13:41 +0100 Subject: [PATCH 11/13] chore (deps): bump nginxinc/nginx-unprivileged from `458ecbe` to `fd3314e` in the docker-dependencies group (#2633) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 24eab9fc..564e8d66 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ RUN npm run build ######################################### # Package static build files into nginx # ######################################### -FROM nginxinc/nginx-unprivileged:stable-alpine@sha256:458ecbec226a23120713b35945bcdf0d6e4ea5bbec60c149ce1deca5d264071b AS cyberchef +FROM nginxinc/nginx-unprivileged:stable-alpine@sha256:fd3314e343bad2de4e1127ef58be122abbfa7e09572fa46ae62fcddb6b3f21c5 AS cyberchef LABEL maintainer="GCHQ " From eaf185242a8183d955529834a117e7b71ebc4e59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 16:26:10 +0100 Subject: [PATCH 12/13] chore (deps): bump webpack from 5.107.2 to 5.108.3 in the minor-updates group (#2635) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 157 ++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 75 insertions(+), 84 deletions(-) diff --git a/package-lock.json b/package-lock.json index e42ae6c4..54952358 100644 --- a/package-lock.json +++ b/package-lock.json @@ -157,7 +157,7 @@ "prompt": "^1.3.0", "sitemap": "^9.0.1", "terser": "^5.48.0", - "webpack": "^5.107.2", + "webpack": "^5.108.3", "webpack-bundle-analyzer": "^5.3.0", "webpack-dev-server": "^5.2.5", "webpack-node-externals": "^3.0.0", @@ -8841,9 +8841,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.22.0.tgz", - "integrity": "sha512-xYcDWrpELkFzz9SpZ3PlI6Eu6eD93Yf0WLDRxikGhWJ3MAir2SNZTIVCVZqZ/NUyx8AdMc2gT9C0gPiw18kG+A==", + "version": "5.24.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.1.tgz", + "integrity": "sha512-7DdUaTjmNwMcH2gLr1qycesKII3BK4RLy/mdAb7x10Lq7bR4aNKHt1BR1ZALSv0rPM/hF5wYF0PhGop/rJm8vw==", "dev": true, "license": "MIT", "dependencies": { @@ -10257,13 +10257,6 @@ "tslib": "2" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true, - "license": "BSD-2-Clause" - }, "node_modules/global-directory": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-5.0.0.tgz", @@ -13365,6 +13358,67 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minimizer-webpack-plugin": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, "node_modules/mocha": { "version": "10.8.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", @@ -17222,67 +17276,6 @@ "node": ">=10" } }, - "node_modules/terser-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@minify-html/node": { - "optional": true - }, - "@swc/core": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "@swc/html": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "cssnano": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "html-minifier-terser": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "postcss": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -18050,13 +18043,12 @@ "license": "Apache-2.0" }, "node_modules/watchpack": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", - "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", + "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", "dev": true, "license": "MIT", "dependencies": { - "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" }, "engines": { @@ -18094,9 +18086,9 @@ } }, "node_modules/webpack": { - "version": "5.107.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.107.2.tgz", - "integrity": "sha512-v7RhXaJbpMlV0D7hC7lb2EbnxkoeUqf9qhKr6lozx3Q48pmFrqqNRmZFUEGmi7pSwm6fCQ2H1IjvCkHqdpVdjQ==", + "version": "5.108.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.108.3.tgz", + "integrity": "sha512-hOpaCHmQVVY66IVTjofnH14IgSdmod2aquSGHGuYig/OIdWge01Hk2Wt988DZcwXumFUT4+FvJY5N+ikl8o/ww==", "dev": true, "license": "MIT", "dependencies": { @@ -18109,19 +18101,18 @@ "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.22.0", + "enhanced-resolve": "^5.22.2", "es-module-lexer": "^2.1.0", "eslint-scope": "5.1.1", "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "loader-runner": "^4.3.2", "mime-db": "^1.54.0", + "minimizer-webpack-plugin": "^5.6.1", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.5.0", - "watchpack": "^2.5.1", + "watchpack": "^2.5.2", "webpack-sources": "^3.5.0" }, "bin": { diff --git a/package.json b/package.json index ed678f33..d4c37428 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "prompt": "^1.3.0", "sitemap": "^9.0.1", "terser": "^5.48.0", - "webpack": "^5.107.2", + "webpack": "^5.108.3", "webpack-bundle-analyzer": "^5.3.0", "webpack-dev-server": "^5.2.5", "webpack-node-externals": "^3.0.0", From 4707ddb86104f9c965a3d6f4b5926a8b366b8d0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 17:22:33 +0100 Subject: [PATCH 13/13] chore (deps): bump the patch-updates group across 1 directory with 6 updates (#2638) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 54 +++++++++++++++++++++++++---------------------- package.json | 12 +++++------ 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index 54952358..7ae9b618 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "bootstrap-colorpicker": "^3.4.0", "bootstrap-material-design": "^4.1.3", "browserify-zlib": "^0.2.0", - "bson": "^7.3.0", + "bson": "^7.3.1", "buffer": "^6.0.3", "cbor": "10.0.12", "chi-squared": "^1.1.0", @@ -115,12 +115,12 @@ "@babel/preset-env": "^7.29.7", "@babel/runtime": "^7.29.7", "@codemirror/commands": "^6.10.4", - "@codemirror/language": "^6.12.3", + "@codemirror/language": "^6.12.4", "@codemirror/search": "^6.7.1", "@codemirror/state": "^6.5.4", - "@codemirror/view": "^6.43.2", - "@puppeteer/browsers": "3.0.5", - "autoprefixer": "^10.5.1", + "@codemirror/view": "^6.43.4", + "@puppeteer/browsers": "3.0.6", + "autoprefixer": "^10.5.2", "babel-loader": "^10.1.1", "base64-loader": "^1.0.0", "chromedriver": "^148.0.4", @@ -150,7 +150,7 @@ "mini-css-extract-plugin": "2.10.2", "modify-source-webpack-plugin": "^4.1.0", "nightwatch": "^3.16.0", - "postcss": "^8.5.15", + "postcss": "^8.5.16", "postcss-css-variables": "^0.19.0", "postcss-import": "^16.1.1", "postcss-loader": "^8.2.1", @@ -1861,9 +1861,9 @@ } }, "node_modules/@codemirror/language": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.3.tgz", - "integrity": "sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==", + "version": "6.12.4", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.4.tgz", + "integrity": "sha512-1q4PaT+o6PbgpkJt4Q8Fv5XJxTy4FUZ4MWETtyiDw3J0Pyr9E2vqcKL+k9wcvjNTIsauxvE7OfmWj3FRPHQ76A==", "dev": true, "license": "MIT", "dependencies": { @@ -1898,9 +1898,9 @@ } }, "node_modules/@codemirror/view": { - "version": "6.43.2", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.2.tgz", - "integrity": "sha512-8kU6WNRYBKV9Sw3cxNz+uSvUvx3tt+1qgupGFPubnbLFDHOgh5qQdIGmXcD7bkA/PROK6LDKVhKMpcY7H++Amg==", + "version": "6.43.4", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.4.tgz", + "integrity": "sha512-YImu23iyKfncJzT7sRy+rEqEhSc8RhOHqDxwy4WzXRKJwYm6iwf/9OJk5ctCAdZ6yi2ZqaGEvmf55fSVqMDrgg==", "dev": true, "license": "MIT", "dependencies": { @@ -4417,9 +4417,9 @@ "license": "MIT" }, "node_modules/@puppeteer/browsers": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.0.5.tgz", - "integrity": "sha512-xYXNuEQmHNIPWWcbL/skf2KF7seyp7c1xmKFRk3wmdFx7VwBsKVrtOLKs8ecaezsKPsWeF1YsgwIiElAscaryA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.0.6.tgz", + "integrity": "sha512-B/gKoqlFkzhvzsI6jo9K1cZz9o5ypviVv/xu8CwA4grZzyVwN+XfkT+tu8T1zrauuEXv6VhS2oGX+6NL95WcKA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4433,11 +4433,15 @@ "node": ">=22.12.0" }, "peerDependencies": { - "proxy-agent": ">=8.0.1" + "proxy-agent": ">=8.0.1", + "yauzl": "^2.10.0 || ^3.4.0" }, "peerDependenciesMeta": { "proxy-agent": { "optional": true + }, + "yauzl": { + "optional": true } } }, @@ -5615,9 +5619,9 @@ "license": "MIT" }, "node_modules/autoprefixer": { - "version": "10.5.1", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.1.tgz", - "integrity": "sha512-jwM2pcTuCWUoN70FEvf5XrXyDbUgRURK4FnU8v0jWZZYU/KkVvN9T33mu1sVLFY9JW3kTWzKheEpn6xYLRc/VA==", + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz", + "integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==", "dev": true, "funding": [ { @@ -6377,9 +6381,9 @@ } }, "node_modules/bson": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-7.3.0.tgz", - "integrity": "sha512-WmjjMEwFwZHmGnAb7wn90MhkiT+mTm4x/rLj7dvAPWfwnVWDXhLun2e+UM88MJoDGW624yzZglVX/zTBy9ZZMw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-7.3.1.tgz", + "integrity": "sha512-h/C0qe6857pQhcSJHLfsR1uYGj98Ge3wKAD3Ed9KqH3wcVh+BM4Jq4xISD7vs9OPuT07n+q3QQVjslJ286j6ag==", "license": "Apache-2.0", "engines": { "node": ">=20.19.0" @@ -14981,9 +14985,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", + "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index d4c37428..3e800214 100644 --- a/package.json +++ b/package.json @@ -45,12 +45,12 @@ "@babel/preset-env": "^7.29.7", "@babel/runtime": "^7.29.7", "@codemirror/commands": "^6.10.4", - "@codemirror/language": "^6.12.3", + "@codemirror/language": "^6.12.4", "@codemirror/search": "^6.7.1", "@codemirror/state": "^6.5.4", - "@codemirror/view": "^6.43.2", - "@puppeteer/browsers": "3.0.5", - "autoprefixer": "^10.5.1", + "@codemirror/view": "^6.43.4", + "@puppeteer/browsers": "3.0.6", + "autoprefixer": "^10.5.2", "babel-loader": "^10.1.1", "base64-loader": "^1.0.0", "chromedriver": "^148.0.4", @@ -80,7 +80,7 @@ "mini-css-extract-plugin": "2.10.2", "modify-source-webpack-plugin": "^4.1.0", "nightwatch": "^3.16.0", - "postcss": "^8.5.15", + "postcss": "^8.5.16", "postcss-css-variables": "^0.19.0", "postcss-import": "^16.1.1", "postcss-loader": "^8.2.1", @@ -111,7 +111,7 @@ "bootstrap-colorpicker": "^3.4.0", "bootstrap-material-design": "^4.1.3", "browserify-zlib": "^0.2.0", - "bson": "^7.3.0", + "bson": "^7.3.1", "buffer": "^6.0.3", "cbor": "10.0.12", "chi-squared": "^1.1.0",