emailengine-app 2.67.3 → 2.68.0
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.
- package/.github/workflows/test.yml +3 -0
- package/CHANGELOG.md +27 -0
- package/data/google-crawlers.json +1 -1
- package/lib/account.js +24 -1
- package/lib/api-routes/account-routes.js +12 -2
- package/lib/email-client/base-client.js +26 -20
- package/lib/email-client/gmail-client.js +14 -12
- package/lib/oauth/external-account-config.js +132 -0
- package/lib/oauth/external-account-signer.js +256 -0
- package/lib/oauth/gmail.js +113 -14
- package/lib/oauth/verify-app.js +397 -0
- package/lib/oauth2-apps.js +51 -6
- package/lib/routes-ui.js +153 -1
- package/lib/schemas.js +80 -2
- package/lib/settings.js +1 -0
- package/lib/tools.js +10 -10
- package/package.json +22 -22
- package/sbom.json +1 -1
- package/static/js/ace/ace.js +1 -1
- package/static/js/ace/ext-searchbox.js +1 -1
- package/static/js/ace/mode-handlebars.js +1 -1
- package/static/js/ace/mode-html.js +1 -1
- package/static/js/ace/mode-javascript.js +1 -1
- package/static/js/ace/mode-markdown.js +1 -1
- package/static/js/ace/worker-html.js +1 -1
- package/static/js/ace/worker-javascript.js +1 -1
- package/static/js/ace/worker-json.js +1 -1
- package/static/licenses.html +226 -66
- package/translations/messages.pot +13 -13
- package/views/config/oauth/app.hbs +224 -0
- package/views/config/oauth/edit.hbs +69 -0
- package/views/config/oauth/new.hbs +69 -0
- package/views/partials/oauth_form.hbs +99 -32
- package/workers/api.js +91 -2
package/workers/api.js
CHANGED
|
@@ -84,6 +84,7 @@ const pathlib = require('path');
|
|
|
84
84
|
const crypto = require('crypto');
|
|
85
85
|
const { Transform, finished } = require('stream');
|
|
86
86
|
const { oauth2Apps, OAUTH_PROVIDERS } = require('../lib/oauth2-apps');
|
|
87
|
+
const { verifyOAuth2App } = require('../lib/oauth/verify-app');
|
|
87
88
|
|
|
88
89
|
const handlebars = require('handlebars');
|
|
89
90
|
const AuthBearer = require('hapi-auth-bearer-token');
|
|
@@ -5016,7 +5017,7 @@ Include your token in requests using one of these methods:
|
|
|
5016
5017
|
let response = await oauth2Apps.list(request.query.page, request.query.pageSize);
|
|
5017
5018
|
|
|
5018
5019
|
for (let app of response.apps) {
|
|
5019
|
-
for (let secretKey of ['clientSecret', 'serviceKey', 'accessToken']) {
|
|
5020
|
+
for (let secretKey of ['clientSecret', 'serviceKey', 'accessToken', 'externalAccount']) {
|
|
5020
5021
|
if (app[secretKey]) {
|
|
5021
5022
|
app[secretKey] = '******';
|
|
5022
5023
|
}
|
|
@@ -5170,7 +5171,7 @@ Include your token in requests using one of these methods:
|
|
|
5170
5171
|
let app = await oauth2Apps.get(request.params.app);
|
|
5171
5172
|
|
|
5172
5173
|
// remove secrets
|
|
5173
|
-
for (let secretKey of ['clientSecret', 'serviceKey', 'accessToken']) {
|
|
5174
|
+
for (let secretKey of ['clientSecret', 'serviceKey', 'accessToken', 'externalAccount']) {
|
|
5174
5175
|
if (app[secretKey]) {
|
|
5175
5176
|
app[secretKey] = '******';
|
|
5176
5177
|
}
|
|
@@ -5576,6 +5577,94 @@ Include your token in requests using one of these methods:
|
|
|
5576
5577
|
}
|
|
5577
5578
|
});
|
|
5578
5579
|
|
|
5580
|
+
server.route({
|
|
5581
|
+
method: 'POST',
|
|
5582
|
+
path: '/v1/oauth2/{app}/verify',
|
|
5583
|
+
|
|
5584
|
+
async handler(request) {
|
|
5585
|
+
try {
|
|
5586
|
+
return await verifyOAuth2App(request.params.app, {
|
|
5587
|
+
account: request.payload.account,
|
|
5588
|
+
testConnection: request.payload.testConnection
|
|
5589
|
+
});
|
|
5590
|
+
} catch (err) {
|
|
5591
|
+
request.logger.error({ msg: 'API request failed', err });
|
|
5592
|
+
if (Boom.isBoom(err)) {
|
|
5593
|
+
throw err;
|
|
5594
|
+
}
|
|
5595
|
+
let error = Boom.boomify(err, { statusCode: err.statusCode || 500 });
|
|
5596
|
+
if (err.code) {
|
|
5597
|
+
error.output.payload.code = err.code;
|
|
5598
|
+
}
|
|
5599
|
+
throw error;
|
|
5600
|
+
}
|
|
5601
|
+
},
|
|
5602
|
+
options: {
|
|
5603
|
+
description: 'Verify OAuth2 application setup',
|
|
5604
|
+
notes: 'Runs the provider authentication chain step by step and reports which steps pass or fail, with hints for fixing failures. For service-account apps an optional mailbox address enables the delegation and live mailbox checks.',
|
|
5605
|
+
tags: ['api', 'OAuth2 Applications'],
|
|
5606
|
+
|
|
5607
|
+
plugins: {},
|
|
5608
|
+
|
|
5609
|
+
auth: {
|
|
5610
|
+
strategy: 'api-token',
|
|
5611
|
+
mode: 'required'
|
|
5612
|
+
},
|
|
5613
|
+
cors: CORS_CONFIG,
|
|
5614
|
+
|
|
5615
|
+
validate: {
|
|
5616
|
+
options: {
|
|
5617
|
+
stripUnknown: false,
|
|
5618
|
+
abortEarly: false,
|
|
5619
|
+
convert: true
|
|
5620
|
+
},
|
|
5621
|
+
failAction,
|
|
5622
|
+
|
|
5623
|
+
params: Joi.object({
|
|
5624
|
+
app: Joi.string().max(256).required().example('AAABhaBPHscAAAAH').description('OAuth2 application ID')
|
|
5625
|
+
}),
|
|
5626
|
+
|
|
5627
|
+
payload: Joi.object({
|
|
5628
|
+
account: Joi.string()
|
|
5629
|
+
.trim()
|
|
5630
|
+
.empty('')
|
|
5631
|
+
.max(256)
|
|
5632
|
+
.example('user@example.com')
|
|
5633
|
+
.description('Mailbox address used to verify domain-wide delegation and live mailbox access'),
|
|
5634
|
+
testConnection: Joi.boolean()
|
|
5635
|
+
.truthy('Y', 'true', '1', 'on')
|
|
5636
|
+
.falsy('N', 'false', 0, '')
|
|
5637
|
+
.default(true)
|
|
5638
|
+
.description('Perform the live IMAP/API connection step when an access token is obtained')
|
|
5639
|
+
}).label('VerifyOAuth2AppRequest')
|
|
5640
|
+
},
|
|
5641
|
+
|
|
5642
|
+
response: {
|
|
5643
|
+
schema: Joi.object({
|
|
5644
|
+
app: Joi.string().max(256).required().example('AAABhaBPHscAAAAH').description('OAuth2 application ID'),
|
|
5645
|
+
provider: Joi.string().example('gmailService').description('Provider type'),
|
|
5646
|
+
authMethod: Joi.string().allow(null).example('externalAccount').description('Authentication method for service-account apps'),
|
|
5647
|
+
account: Joi.string().allow(null).example('user@example.com').description('Mailbox used for the delegation/mailbox checks'),
|
|
5648
|
+
ok: Joi.boolean().example(true).description('True when no verification step failed'),
|
|
5649
|
+
steps: Joi.array()
|
|
5650
|
+
.items(
|
|
5651
|
+
Joi.object({
|
|
5652
|
+
id: Joi.string().example('signJwt').description('Step identifier'),
|
|
5653
|
+
label: Joi.string().example('Sign assertion (signJwt)').description('Human readable step name'),
|
|
5654
|
+
status: Joi.string().valid('ok', 'fail', 'skip').example('ok').description('Step outcome'),
|
|
5655
|
+
message: Joi.string().allow(null).example('Assertion signed via IAM signJwt').description('Outcome detail'),
|
|
5656
|
+
hint: Joi.string()
|
|
5657
|
+
.example('Grant roles/iam.serviceAccountTokenCreator to the workload principal')
|
|
5658
|
+
.description('How to fix a failed step')
|
|
5659
|
+
}).label('OAuth2VerifyStep')
|
|
5660
|
+
)
|
|
5661
|
+
.label('OAuth2VerifySteps')
|
|
5662
|
+
}).label('VerifyOAuth2AppResponse'),
|
|
5663
|
+
failAction: 'log'
|
|
5664
|
+
}
|
|
5665
|
+
}
|
|
5666
|
+
});
|
|
5667
|
+
|
|
5579
5668
|
server.route({
|
|
5580
5669
|
method: 'GET',
|
|
5581
5670
|
path: '/v1/gateways',
|