diff --git a/docs/notifications.md b/docs/notifications.md index 17588f79c..31aba6bb1 100644 --- a/docs/notifications.md +++ b/docs/notifications.md @@ -38,6 +38,32 @@ notify: content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}' ``` +### Publisher information + +You can access to the package publisher information in the `content` of a webhook using the `publisher` object. + +See below the `publisher` object type: + +``` +{ + name: string, + groups: string[], + real_groups: string[] +} +``` + +An example: + +``` +notify: + method: POST + headers: [{'Content-Type': 'application/json'}] + endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken + content: '{"color":"green","message":"New package published: * {{ name }}*. Publisher name: * {{ publisher.name }} *.","notify":true,"message_format":"text"}' +``` + +**Note:** it's not possible to get the publisher information if the `package.json` file already has the `publisher` property. + ## Configuration Property | Type | Required | Support | Default | Description @@ -47,4 +73,4 @@ packagePattern| string | No | all | | Only run this notification if the package packagePatternFlags| string | No | all | | Any flags to be used with the regular expression headers| array/object | Yes | all | | If this endpoint requires specific headers, set them here as an array of key: value objects. endpoint| string | Yes | all | | set the URL endpoint for this call -content| string | Yes | all | | any [handlebar](https://handlebarsjs.com/) expressions +content| string | Yes | all | | any [handlebar](https://handlebarsjs.com/) expressions \ No newline at end of file diff --git a/src/api/endpoint/api/publish.js b/src/api/endpoint/api/publish.js index 2fea32788..f4ebadb24 100644 --- a/src/api/endpoint/api/publish.js +++ b/src/api/endpoint/api/publish.js @@ -91,7 +91,7 @@ export default function(router: Router, auth: IAuth, storage: IStorageHandler, c if (err) { return next(err); } - notify(metadata, config); + notify(metadata, config, req.remote_user); res.status(201); return next({ok: ok_message, success: true}); }); diff --git a/src/lib/notify.js b/src/lib/notify.js index 6c834d4c9..695065b4f 100644 --- a/src/lib/notify.js +++ b/src/lib/notify.js @@ -3,7 +3,7 @@ const request = require('request'); const _ = require('lodash'); const logger = require('./logger'); -const handleNotify = function(metadata, notifyEntry) { +const handleNotify = function(metadata, notifyEntry, publisherInfo) { let regex; if (metadata.name && notifyEntry.packagePattern) { // FUTURE: comment out due https://github.com/verdaccio/verdaccio/pull/108#issuecomment-312421052 @@ -15,7 +15,12 @@ const handleNotify = function(metadata, notifyEntry) { } const template = Handlebars.compile(notifyEntry.content); - const content = template( metadata ); + + // don't override 'publisher' if package.json already has that + if (!metadata.publisher) { + metadata = {...metadata, publisher: publisherInfo}; + } + const content = template(metadata); const options = { body: content, @@ -28,7 +33,7 @@ const handleNotify = function(metadata, notifyEntry) { if (Object.is(item, item)) { for (const key in item) { if (item.hasOwnProperty(key)) { - header[key] = item[key]; + header[key] = item[key]; } } } @@ -40,20 +45,20 @@ const handleNotify = function(metadata, notifyEntry) { options.method = notifyEntry.method; - if ( notifyEntry.endpoint ) { + if (notifyEntry.endpoint) { options.url = notifyEntry.endpoint; } - return new Promise(( resolve, reject) => { + return new Promise((resolve, reject) => { request(options, function(err, response, body) { if (err || response.statusCode >= 400) { const errorMessage = _.isNil(err) ? response.statusMessage : err; - logger.logger.error({err: errorMessage}, ' notify error: @{err.message}' ); + logger.logger.error({err: errorMessage}, ' notify error: @{err.message}'); reject(errorMessage); } else { logger.logger.info({content: content}, 'A notification has been shipped: @{content}'); if (body) { - logger.logger.debug({body: body}, ' body: @{body}' ); + logger.logger.debug({body: body}, ' body: @{body}'); } resolve(_.isNil(body) === false ? body : null); } @@ -61,13 +66,13 @@ const handleNotify = function(metadata, notifyEntry) { }); }; -const notify = function(metadata, config) { +const notify = function(metadata, config, publisherInfo) { if (config.notify) { if (config.notify.content) { - return handleNotify(metadata, config.notify); + return handleNotify(metadata, config.notify, publisherInfo); } else { // multiple notifications endpoints PR #108 - return Promise.all(_.map(config.notify, (key) => handleNotify(metadata, key))); + return Promise.all(_.map(config.notify, (key) => handleNotify(metadata, key, publisherInfo))); } } }; diff --git a/test/functional/notifications/notify.js b/test/functional/notifications/notify.js index 43048eccc..53841c167 100644 --- a/test/functional/notifications/notify.js +++ b/test/functional/notifications/notify.js @@ -12,10 +12,14 @@ export default function(express) { 'Content-Type': HEADERS.JSON }], endpoint: "http://localhost:55550/api/notify", - content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}' + content: '{"color":"green","message":"New package published: * {{ name }}*. Publisher name: * {{ publisher.name }} *.","notify":true,"message_format":"text"}' } }; + const publisherInfo = { + name: "publisher-name-test" + }; + describe('notifications', () => { beforeAll(function () { @@ -33,10 +37,14 @@ export default function(express) { name: "pkg-test" }; - notify(metadata, config).then(function (body) { + notify(metadata, config, publisherInfo).then(function (body) { const jsonBody = JSON.parse(body); - assert.ok(`New package published: * ${metadata.name}*` === jsonBody.message, - 'Body notify message should be equal'); + assert.ok( + `New package published: * ${metadata.name}*. Publisher name: * ${ + publisherInfo.name + } *.` === jsonBody.message, + "Body notify message should be equal" + ); done(); }, function (err) { assert.fail(err); @@ -54,10 +62,14 @@ export default function(express) { 'Content-Type': HEADERS.JSON }; - notify(metadata, configMultipleHeader).then(function (body) { + notify(metadata, configMultipleHeader, publisherInfo).then(function (body) { const jsonBody = JSON.parse(body); - assert.ok(`New package published: * ${metadata.name}*` === jsonBody.message, - 'Body notify message should be equal'); + assert.ok( + `New package published: * ${metadata.name}*. Publisher name: * ${ + publisherInfo.name + } *.` === jsonBody.message, + "Body notify message should be equal" + ); done(); }, function (err) { assert.fail(err); @@ -85,11 +97,15 @@ export default function(express) { multipleNotificationsEndpoint.notify.push(notificationSettings); } - notify(metadata, multipleNotificationsEndpoint).then(function (body) { + notify(metadata, multipleNotificationsEndpoint, publisherInfo).then(function (body) { body.forEach(function(notification) { const jsonBody = JSON.parse(notification); - assert.ok(`New package published: * ${metadata.name}*` === jsonBody.message, - 'Body notify message should be equal'); + assert.ok( + `New package published: * ${metadata.name}*. Publisher name: * ${ + publisherInfo.name + } *.` === jsonBody.message, + "Body notify message should be equal" + ); }); done(); }, function (err) { @@ -105,7 +121,7 @@ export default function(express) { const configFail = _.cloneDeep(config); configFail.notify.endpoint = "http://localhost:55550/api/notify/bad"; - notify(metadata, configFail).then(function () { + notify(metadata, configFail, publisherInfo).then(function () { assert.equal(false, 'This service should fails with status code 400'); done(); }, function (err) { @@ -114,5 +130,31 @@ export default function(express) { }); }); + test("publisher property should not be overridden if it exists in metadata", done => { + const metadata = { + name: "pkg-test", + publisher: { + name: "existing-publisher-name" + } + }; + + notify(metadata, config, publisherInfo).then( + function(body) { + const jsonBody = JSON.parse(body); + assert.ok( + `New package published: * ${metadata.name}*. Publisher name: * ${ + metadata.publisher.name + } *.` === jsonBody.message, + "Body notify message should be equal" + ); + done(); + }, + function(err) { + assert.fail(err); + done(); + } + ); + }); + }); }