Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data/google-crawlers.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"creationTime": "2026-02-18T15:45:53.000000",
"creationTime": "2026-02-25T17:56:15.000000",
"prefixes": [
{
"ipv6Prefix": "2001:4860:4801:2008::/64"
Expand Down
12 changes: 11 additions & 1 deletion lib/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,14 @@ function formatTokenError(provider, tokenRequest) {
return parts.join(': ');
}

function resolveOAuthErrorStatus(responseError, err) {
if (typeof responseError.code === 'number' && responseError.code >= 400) {
return responseError.code;
}
const fallback = (err && err.statusCode) || (err && err.oauthRequest && err.oauthRequest.status);
return typeof fallback === 'number' && fallback >= 400 ? fallback : 500;
}

module.exports = {
/**
* Helper function to set specific bit in a buffer
Expand Down Expand Up @@ -1963,7 +1971,9 @@ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEV3QUiYsp13nD9suD1/ZkEXnuMoSg

normalizeHashKeys,

formatTokenError
formatTokenError,

resolveOAuthErrorStatus
};

function msgpackDecode(buf) {
Expand Down
249 changes: 129 additions & 120 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@
"homepage": "https://emailengine.app/",
"dependencies": {
"@bugsnag/js": "8.8.1",
"@bull-board/api": "6.19.0",
"@bull-board/hapi": "6.19.0",
"@bull-board/api": "6.20.3",
"@bull-board/hapi": "6.20.3",
"@elastic/elasticsearch": "8.15.3",
"@hapi/accept": "6.0.3",
"@hapi/bell": "13.1.0",
"@hapi/boom": "10.0.1",
"@hapi/cookie": "12.0.1",
"@hapi/crumb": "9.0.1",
"@hapi/hapi": "21.4.5",
"@hapi/hapi": "21.4.6",
"@hapi/inert": "7.1.0",
"@hapi/vision": "7.0.3",
"@phc/pbkdf2": "1.1.14",
Expand All @@ -68,7 +68,7 @@
"@zone-eu/wild-config": "1.7.3",
"ace-builds": "1.43.6",
"base32.js": "0.1.0",
"bullmq": "5.69.3",
"bullmq": "5.70.1",
"compare-versions": "6.1.1",
"dotenv": "17.3.1",
"encoding-japanese": "2.2.0",
Expand All @@ -83,7 +83,7 @@
"ical.js": "1.5.0",
"iconv-lite": "0.7.2",
"imapflow": "1.2.10",
"ioredfour": "1.3.0-ioredis-07",
"ioredfour": "1.4.0",
"ioredis": "5.9.3",
"ipaddr.js": "2.3.0",
"joi": "17.13.3",
Expand Down Expand Up @@ -118,7 +118,7 @@
"@eslint/js": "10.0.1",
"chai": "4.3.10",
"eerawlog": "1.5.1",
"eslint": "10.0.0",
"eslint": "10.0.2",
"grunt": "1.6.1",
"grunt-cli": "1.5.0",
"grunt-shell-spawn": "0.5.0",
Expand Down
2 changes: 1 addition & 1 deletion sbom.json

Large diffs are not rendered by default.

58 changes: 29 additions & 29 deletions static/licenses.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!doctype html><html><head><meta charset="utf-8"><title>EmailEngine Licenses</title><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous"></head><body>
<div class="container-fluid">
<h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following software packages:</p>
<h1>EmailEngine v2.63.0</h1><p>EmailEngine includes code from the following software packages:</p>
<table class="table table-sm">
<tr><thead class="thead-dark"><th>Package</th><th>Version</th><th>License</th><th>Publisher</th><th>Publisher's Email</th><th>Package URL</th></tr>
<tbody>
Expand Down Expand Up @@ -146,7 +146,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@bull-board/api">@bull-board/api</a></td>
<td>6.19.0</td>
<td>6.20.3</td>
<td>MIT</td>
<td>felixmosh</td>
<td></td>
Expand All @@ -156,7 +156,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@bull-board/hapi">@bull-board/hapi</a></td>
<td>6.19.0</td>
<td>6.20.3</td>
<td>MIT</td>
<td>felixmosh</td>
<td></td>
Expand All @@ -166,7 +166,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@bull-board/ui">@bull-board/ui</a></td>
<td>6.19.0</td>
<td>6.20.3</td>
<td>MIT</td>
<td>felixmosh</td>
<td></td>
Expand Down Expand Up @@ -216,7 +216,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@csstools/css-syntax-patches-for-csstree">@csstools/css-syntax-patches-for-csstree</a></td>
<td>1.0.27</td>
<td>1.0.28</td>
<td>MIT-0</td>
<td></td>
<td></td>
Expand Down Expand Up @@ -276,7 +276,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@eslint/config-array">@eslint/config-array</a></td>
<td>0.23.1</td>
<td>0.23.2</td>
<td>Apache-2.0</td>
<td>Nicholas C. Zakas</td>
<td></td>
Expand Down Expand Up @@ -316,7 +316,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@eslint/object-schema">@eslint/object-schema</a></td>
<td>3.0.1</td>
<td>3.0.2</td>
<td>Apache-2.0</td>
<td>Nicholas C. Zakas</td>
<td></td>
Expand Down Expand Up @@ -506,7 +506,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@hapi/hapi">@hapi/hapi</a></td>
<td>21.4.5</td>
<td>21.4.6</td>
<td>BSD-3-Clause</td>
<td></td>
<td></td>
Expand Down Expand Up @@ -1266,7 +1266,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/acorn">acorn</a></td>
<td>8.15.0</td>
<td>8.16.0</td>
<td>MIT</td>
<td></td>
<td></td>
Expand All @@ -1286,7 +1286,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/ajv">ajv</a></td>
<td>6.12.6</td>
<td>6.14.0</td>
<td>MIT</td>
<td>Evgeny Poberezkin</td>
<td></td>
Expand Down Expand Up @@ -1466,7 +1466,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/balanced-match">balanced-match</a></td>
<td>4.0.3</td>
<td>4.0.4</td>
<td>MIT</td>
<td></td>
<td></td>
Expand Down Expand Up @@ -1576,7 +1576,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/brace-expansion">brace-expansion</a></td>
<td>5.0.2</td>
<td>5.0.3</td>
<td>MIT</td>
<td></td>
<td></td>
Expand Down Expand Up @@ -1606,7 +1606,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/bullmq">bullmq</a></td>
<td>5.69.3</td>
<td>5.70.1</td>
<td>MIT</td>
<td>Taskforce.sh Inc.</td>
<td></td>
Expand Down Expand Up @@ -2485,7 +2485,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/eslint-scope">eslint-scope</a></td>
<td>9.1.0</td>
<td>9.1.1</td>
<td>BSD-2-Clause</td>
<td></td>
<td></td>
Expand All @@ -2505,7 +2505,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/eslint-visitor-keys">eslint-visitor-keys</a></td>
<td>5.0.0</td>
<td>5.0.1</td>
<td>Apache-2.0</td>
<td>Toru Nagashima</td>
<td></td>
Expand All @@ -2515,7 +2515,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/eslint">eslint</a></td>
<td>10.0.0</td>
<td>10.0.2</td>
<td>MIT</td>
<td>Nicholas C. Zakas</td>
<td>nicholas+npm@nczconsulting.com</td>
Expand All @@ -2535,7 +2535,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/espree">espree</a></td>
<td>11.1.0</td>
<td>11.1.1</td>
<td>BSD-2-Clause</td>
<td>Nicholas C. Zakas</td>
<td>nicholas+npm@nczconsulting.com</td>
Expand Down Expand Up @@ -2745,7 +2745,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/filelist">filelist</a></td>
<td>1.0.4</td>
<td>1.0.6</td>
<td>Apache-2.0</td>
<td>Matthew Eernisse</td>
<td>mde@fleegix.org</td>
Expand Down Expand Up @@ -3534,18 +3534,18 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</td
</tr>
<tr>
<td><a href="https://npmjs.com/package/ioredis">ioredis</a></td>
<td>5.3.2</td>
<td><a href="https://npmjs.com/package/ioredfour">ioredfour</a></td>
<td>1.4.0</td>
<td>MIT</td>
<td>Zihua Li</td>
<td>i@zihua.li</td>
<td>Mixmax</td>
<td>hello@mixmax.com</td>
<td>
<a href="https://github.com/luin/ioredis">github.com/luin/ioredis</a>
<a href="https://github.com/nodemailer/ioredfour">github.com/nodemailer/ioredfour</a>
</td
</tr>
<tr>
<td><a href="https://npmjs.com/package/ioredis">ioredis</a></td>
<td>5.9.2</td>
<td>5.3.2</td>
<td>MIT</td>
<td>Zihua Li</td>
<td>i@zihua.li</td>
Expand Down Expand Up @@ -4285,7 +4285,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/minimatch">minimatch</a></td>
<td>10.2.1</td>
<td>10.2.4</td>
<td>BlueOak-1.0.0</td>
<td>Isaac Z. Schlueter</td>
<td>i@izs.me</td>
Expand All @@ -4305,7 +4305,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/minimatch">minimatch</a></td>
<td>3.1.2</td>
<td>3.1.5</td>
<td>ISC</td>
<td>Isaac Z. Schlueter</td>
<td>i@izs.me</td>
Expand All @@ -4315,7 +4315,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/minimatch">minimatch</a></td>
<td>5.1.6</td>
<td>5.1.9</td>
<td>ISC</td>
<td>Isaac Z. Schlueter</td>
<td>i@izs.me</td>
Expand Down Expand Up @@ -5685,7 +5685,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/spdx-license-ids">spdx-license-ids</a></td>
<td>3.0.22</td>
<td>3.0.23</td>
<td>CC0-1.0</td>
<td>Shinnosuke Watanabe</td>
<td></td>
Expand Down Expand Up @@ -5915,7 +5915,7 @@ <h1>EmailEngine v2.62.2</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/swagger-ui-dist">swagger-ui-dist</a></td>
<td>5.31.1</td>
<td>5.31.2</td>
<td>Apache-2.0</td>
<td></td>
<td></td>
Expand Down
79 changes: 79 additions & 0 deletions test/oauth-error-status-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
'use strict';

const test = require('node:test');
const assert = require('node:assert').strict;

const { resolveOAuthErrorStatus } = require('../lib/tools');

test('resolveOAuthErrorStatus tests', async t => {
t.after(() => {
// Force exit after tests to prevent hanging on Redis connections from loaded modules
setTimeout(() => process.exit(), 1000).unref();
});

await t.test('returns numeric error code when it is a valid HTTP status', async () => {
assert.strictEqual(resolveOAuthErrorStatus({ code: 400 }, {}), 400);
assert.strictEqual(resolveOAuthErrorStatus({ code: 403 }, {}), 403);
assert.strictEqual(resolveOAuthErrorStatus({ code: 404 }, {}), 404);
assert.strictEqual(resolveOAuthErrorStatus({ code: 429 }, {}), 429);
assert.strictEqual(resolveOAuthErrorStatus({ code: 500 }, {}), 500);
assert.strictEqual(resolveOAuthErrorStatus({ code: 503 }, {}), 503);
});

await t.test('falls back to err.statusCode when error code is a string', async () => {
let err = { statusCode: 429 };
assert.strictEqual(resolveOAuthErrorStatus({ code: 'TooManyPendingRequests' }, err), 429);
assert.strictEqual(resolveOAuthErrorStatus({ code: 'TooManyRequests' }, err), 429);

err = { statusCode: 400 };
assert.strictEqual(resolveOAuthErrorStatus({ code: 'BadRequest' }, err), 400);
});

await t.test('falls back to err.oauthRequest.status when err.statusCode is missing', async () => {
let err = { oauthRequest: { status: 429 } };
assert.strictEqual(resolveOAuthErrorStatus({ code: 'TooManyPendingRequests' }, err), 429);

err = { oauthRequest: { status: 503 } };
assert.strictEqual(resolveOAuthErrorStatus({ code: 'ServiceUnavailable' }, err), 503);
});

await t.test('returns 500 when no fallback status is available', async () => {
assert.strictEqual(resolveOAuthErrorStatus({ code: 'UnknownError' }, {}), 500);
assert.strictEqual(resolveOAuthErrorStatus({ code: 'TooManyPendingRequests' }, {}), 500);
});

await t.test('rejects numeric codes below 400', async () => {
let err = { statusCode: 429 };
assert.strictEqual(resolveOAuthErrorStatus({ code: 200 }, err), 429);
assert.strictEqual(resolveOAuthErrorStatus({ code: 301 }, err), 429);
assert.strictEqual(resolveOAuthErrorStatus({ code: 0 }, err), 429);
});

await t.test('handles undefined and null error codes', async () => {
let err = { statusCode: 502 };
assert.strictEqual(resolveOAuthErrorStatus({ code: undefined }, err), 502);
assert.strictEqual(resolveOAuthErrorStatus({ code: null }, err), 502);
assert.strictEqual(resolveOAuthErrorStatus({}, err), 502);
});

await t.test('returns 500 when err.statusCode is a string', async () => {
assert.strictEqual(resolveOAuthErrorStatus({ code: 'TooManyRequests' }, { statusCode: '429' }), 500);
assert.strictEqual(resolveOAuthErrorStatus({ code: 'BadRequest' }, { statusCode: 'error' }), 500);
});

await t.test('returns 500 when err.statusCode is below 400', async () => {
assert.strictEqual(resolveOAuthErrorStatus({ code: 'SomeError' }, { statusCode: 200 }), 500);
assert.strictEqual(resolveOAuthErrorStatus({ code: 'SomeError' }, { statusCode: 302 }), 500);
assert.strictEqual(resolveOAuthErrorStatus({ code: 'SomeError' }, { statusCode: 0 }), 500);
});

await t.test('returns 500 when err.oauthRequest.status is a string', async () => {
assert.strictEqual(resolveOAuthErrorStatus({ code: 'TooManyRequests' }, { oauthRequest: { status: '429' } }), 500);
});

await t.test('handles missing err parameter', async () => {
assert.strictEqual(resolveOAuthErrorStatus({ code: 403 }, null), 403);
assert.strictEqual(resolveOAuthErrorStatus({ code: 'BadRequest' }, null), 500);
assert.strictEqual(resolveOAuthErrorStatus({ code: 'BadRequest' }, undefined), 500);
});
});
Loading
Loading