libbase64 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,9 @@ on:
2
2
  push:
3
3
  branches:
4
4
  - master
5
+ # Manual run: publish the version currently on master (used when a release was cut
6
+ # but the publish step failed)
7
+ workflow_dispatch:
5
8
 
6
9
  permissions:
7
10
  contents: write
@@ -15,23 +18,22 @@ jobs:
15
18
  steps:
16
19
  - uses: google-github-actions/release-please-action@v3
17
20
  id: release
21
+ if: ${{ github.event_name == 'push' }}
18
22
  with:
19
23
  release-type: node
20
24
  package-name: ${{vars.NPM_MODULE_NAME}}
21
25
  pull-request-title-pattern: 'chore${scope}: release ${version} [skip-ci]'
22
- # The logic below handles the npm publication:
26
+ # The logic below handles the npm publication through npm trusted publishing
27
+ # (OIDC, no token secret): it runs when a new release is created, or on a
28
+ # manual dispatch.
23
29
  - uses: actions/checkout@v4
24
- # these if statements ensure that a publication only occurs when
25
- # a new release is created:
26
- if: ${{ steps.release.outputs.release_created }}
30
+ if: ${{ steps.release.outputs.release_created || github.event_name == 'workflow_dispatch' }}
27
31
  - uses: actions/setup-node@v4
28
32
  with:
29
- node-version: 20
33
+ node-version: 24
30
34
  registry-url: 'https://registry.npmjs.org'
31
- if: ${{ steps.release.outputs.release_created }}
35
+ if: ${{ steps.release.outputs.release_created || github.event_name == 'workflow_dispatch' }}
32
36
  - run: npm ci
33
- if: ${{ steps.release.outputs.release_created }}
37
+ if: ${{ steps.release.outputs.release_created || github.event_name == 'workflow_dispatch' }}
34
38
  - run: npm publish --provenance --access public
35
- env:
36
- NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
37
- if: ${{ steps.release.outputs.release_created }}
39
+ if: ${{ steps.release.outputs.release_created || github.event_name == 'workflow_dispatch' }}
package/.ncurc.js CHANGED
@@ -1,7 +1,13 @@
1
1
  module.exports = {
2
2
  upgrade: true,
3
3
  reject: [
4
+ // 12 is esm only ("type": "module"), and grunt-mocha-test require()s it as a
5
+ // constructor - "Mocha is not a constructor". Node 24 hides this through
6
+ // require(esm); CI on Node 22 does not. Lift it when the runner drops grunt.
7
+ 'mocha',
4
8
  // 5x is esm only
5
- 'chai'
9
+ 'chai',
10
+ // api changes in newer eslint
11
+ 'grunt-eslint'
6
12
  ]
7
13
  };
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.1](https://github.com/nodemailer/libbase64/compare/v1.3.0...v1.3.1) (2026-09-28)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **decoder:** decode every padded segment instead of stopping at the first padding ([d9ba154](https://github.com/nodemailer/libbase64/commit/d9ba154ba13e45338936a55acec417dfb6ae2e52))
9
+
3
10
  ## [1.3.0](https://github.com/nodemailer/libbase64/compare/v1.2.1...v1.3.0) (2024-02-23)
4
11
 
5
12
 
package/lib/libbase64.js CHANGED
@@ -26,6 +26,22 @@ function encode(buffer) {
26
26
  */
27
27
  function decode(str) {
28
28
  str = str || '';
29
+
30
+ // Buffer.from() stops decoding at the first padding char, so input made of several
31
+ // padded segments (eg. every line padded on its own) is decoded segment by segment
32
+ if (typeof str === 'string') {
33
+ let padPos = str.indexOf('=');
34
+ if (padPos >= 0 && /[a-zA-Z0-9+/\-_]/.test(str.substr(padPos))) {
35
+ let parts = [];
36
+ for (let segment of str.split(/[=]+/)) {
37
+ if (segment) {
38
+ parts.push(Buffer.from(segment, 'base64'));
39
+ }
40
+ }
41
+ return Buffer.concat(parts);
42
+ }
43
+ }
44
+
29
45
  return Buffer.from(str, 'base64');
30
46
  }
31
47
 
@@ -215,6 +231,15 @@ class Decoder extends Transform {
215
231
  b64 = b64.replace(/[^a-zA-Z0-9+/=]/g, '');
216
232
  }
217
233
 
234
+ // everything up to the last padding char ends in complete segments, quartets are
235
+ // only counted from there on as a padding run restarts the quartet alignment
236
+ let padded = '';
237
+ let lastPad = b64.lastIndexOf('=');
238
+ if (lastPad >= 0) {
239
+ padded = b64.substr(0, lastPad + 1);
240
+ b64 = b64.substr(lastPad + 1);
241
+ }
242
+
218
243
  if (b64.length < 4) {
219
244
  this._curLine = b64;
220
245
  b64 = '';
@@ -223,6 +248,8 @@ class Decoder extends Transform {
223
248
  b64 = b64.substr(0, b64.length - this._curLine.length);
224
249
  }
225
250
 
251
+ b64 = padded + b64;
252
+
226
253
  if (b64) {
227
254
  let buf = decode(b64);
228
255
  this.outputBytes += buf.length;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libbase64",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Encode and decode base64 encoded strings",
5
5
  "main": "lib/libbase64.js",
6
6
  "scripts": {
@@ -24,9 +24,9 @@
24
24
  "devDependencies": {
25
25
  "chai": "4.4.1",
26
26
  "eslint-config-nodemailer": "1.2.0",
27
- "eslint-config-prettier": "9.1.0",
28
- "grunt": "1.6.1",
29
- "grunt-cli": "1.4.3",
27
+ "eslint-config-prettier": "10.1.8",
28
+ "grunt": "1.6.3",
29
+ "grunt-cli": "1.5.0",
30
30
  "grunt-eslint": "24.3.0",
31
31
  "grunt-mocha-test": "0.13.3",
32
32
  "mocha": "10.3.0"