From cc9e7e284fc31e2bf81391f6e2eb90ae708b3b71 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Wed, 13 Feb 2019 10:36:32 +0000 Subject: [PATCH 01/27] Added JetBrains WebStorm config file to ignore list --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 667a66c..002d6d7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ yarn.lock config.json npm-debug.log *.sublime-* -.DS_Store \ No newline at end of file +.DS_Store +/.idea From 1176fbb90617a169a239ef776557fb45a87709d8 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Wed, 13 Feb 2019 11:00:02 +0000 Subject: [PATCH 02/27] Added Amazon Cognito oAuth using Passport --- config.tpl.json | 9 ++ package-lock.json | 236 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/auth.js | 26 +++++ 4 files changed, 272 insertions(+) diff --git a/config.tpl.json b/config.tpl.json index 4fe9785..0b49fb6 100644 --- a/config.tpl.json +++ b/config.tpl.json @@ -28,6 +28,15 @@ "mastodon": { "app_name": "your website name", "app_website": "https://blog.example.com/" + }, + "cognito": { + "userPoolId": "xxxxx", + "region": "Region ID (eg, ca-central-1)", + "clientId": "xxxxx", + "credentials": { + "accessKeyId": "xxxxx", + "secretAccessKey": "xxxxx" + } } }, "notify": { diff --git a/package-lock.json b/package-lock.json index da17c66..a354e0c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,6 +64,61 @@ "es6-promisify": "^5.0.0" } }, + "amazon-cognito-identity-js": { + "version": "1.31.0", + "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-1.31.0.tgz", + "integrity": "sha1-Hc0PJs6UBMGYo1Ro6LsAQQUDAh0=", + "dev": true, + "requires": { + "aws-sdk": "2.177.0", + "js-cookie": "^2.1.4" + }, + "dependencies": { + "aws-sdk": { + "version": "2.177.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.177.0.tgz", + "integrity": "sha1-1fvx+CurJQ5VFTaZsDC0T2h/YAs=", + "dev": true, + "requires": { + "buffer": "4.9.1", + "crypto-browserify": "1.0.9", + "events": "^1.1.1", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.1.0", + "xml2js": "0.4.17", + "xmlbuilder": "4.2.1" + } + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", + "dev": true + }, + "xml2js": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", + "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=", + "dev": true, + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "^4.1.0" + } + }, + "xmlbuilder": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", + "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=", + "dev": true, + "requires": { + "lodash": "^4.0.0" + } + } + } + }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -180,6 +235,43 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "aws-sdk": { + "version": "2.401.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.401.0.tgz", + "integrity": "sha512-mOI4gzKoP/g8Q0ToAaqTh7TijGG9PvGVVUkKmurXqBKy7GTPmy4JizfVkTrM+iBg7RAsx5H2lBxBFpdEFBa5fg==", + "dev": true, + "requires": { + "buffer": "4.9.1", + "events": "1.1.1", + "ieee754": "1.1.8", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "dependencies": { + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + } + } + }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -257,6 +349,12 @@ } } }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -461,6 +559,17 @@ } } }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -805,6 +914,12 @@ "which": "^1.2.9" } }, + "crypto-browserify": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-1.0.9.tgz", + "integrity": "sha1-zFRJaF37hesRyYKKzHy4erW7/MA=", + "dev": true + }, "crypto-random-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", @@ -1066,6 +1181,12 @@ "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", "dev": true }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, "execa": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", @@ -2256,6 +2377,12 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "dev": true + }, "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", @@ -2537,6 +2664,18 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "dev": true + }, + "js-cookie": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.0.tgz", + "integrity": "sha1-Gywnmm7s44ChIWi5JIUmWzWx7/s=", + "dev": true + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -2963,6 +3102,28 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" }, + "node-localstorage": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-1.3.1.tgz", + "integrity": "sha512-NMWCSWWc6JbHT5PyWlNT2i8r7PgGYXVntmKawY83k/M0UJScZ5jirb61TLnqKwd815DfBQu+lR3sRw08SPzIaQ==", + "dev": true, + "requires": { + "write-file-atomic": "^1.1.4" + }, + "dependencies": { + "write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + } + } + }, "node-pre-gyp": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz", @@ -3751,6 +3912,30 @@ "pause": "0.0.1" } }, + "passport-cognito": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/passport-cognito/-/passport-cognito-0.1.13.tgz", + "integrity": "sha512-KB/Uo81hh5GHe5no0bVFoBe1Kn3RyY/hp+bPjOLcM/SPqD+gAJ+QH1feI8hMjOwTXpjnUMzl2A7Rp1IHAYlwTg==", + "dev": true, + "requires": { + "amazon-cognito-identity-js": "1.31.0", + "aws-sdk": "^2.275.1", + "jsbn": "^1.1.0", + "moment": "^2.22.2", + "node-localstorage": "^1.3.1", + "passport-strategy": "^1.0.0", + "sjcl": "^1.0.7", + "util": "^0.11.0" + }, + "dependencies": { + "jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA=", + "dev": true + } + } + }, "passport-facebook": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/passport-facebook/-/passport-facebook-2.1.1.tgz", @@ -3958,6 +4143,12 @@ "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", "dev": true }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, "random-bytes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", @@ -4567,6 +4758,18 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "sjcl": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.8.tgz", + "integrity": "sha512-LzIjEQ0S0DpIgnxMEayM1rq9aGwGRG4OnZhCdjx7glTaJtf4zRfpg87ImfjSJjoW9vKpagd82McDOwbRT5kQKQ==", + "dev": true + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -5137,6 +5340,24 @@ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, "url-join": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.2.tgz", @@ -5163,6 +5384,15 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5173,6 +5403,12 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "dev": true + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index 973a430..af33152 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "devDependencies": { "http-server": "^0.10.0", "nodemon": "^1.18.6", + "passport-cognito": "^0.1.13", "rollup": "^0.55.4", "rollup-plugin-buble": "^0.16.0", "rollup-plugin-commonjs": "^8.3.0", diff --git a/src/auth.js b/src/auth.js index ad8eac3..b5bb2f9 100644 --- a/src/auth.js +++ b/src/auth.js @@ -6,6 +6,7 @@ const GitHubStrategy = require('passport-github2').Strategy; const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; const FacebookStrategy = require('passport-facebook').Strategy; const MastodonStrategy = require('passport-mastodon').Strategy; +const CognitoStrategy = require('passport-cognito').Strategy; const fetch = require('node-fetch'); const queries = require('./db/queries'); @@ -225,6 +226,31 @@ function init(app, db, domain) { } ); } + + // Amazon Cognito oAuth + if (authConfig.cognito) { + + providers.push({ id: 'cognito', name: 'Amazon Cognito' }); + passport.use(new CognitoStrategy({ + userPoolId: authConfig.cognito.userPoolId, + clientId: authConfig.cognito.clientId, + region: authConfig.cognito.region + }, (accessToken, refreshToken, profile, done) => { + done(null, profile); + })); + + app.get('/auth/cognito', + passport.authenticate('cognito') + ); + + app.get('/auth/cognito/callback', + passport.authenticate('cognito', { + failureRedirect: '/login' + }), (request, reply) => { + reply.redirect('/success') + } + ); + } } function getAuthorUrl(comment) { From 3a8f8aa0893ac430e28c50550c54ccee7b3bfd51 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Wed, 13 Feb 2019 11:06:08 +0000 Subject: [PATCH 03/27] Added server start-up routine suitable for Windows x64 environments --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 973a430..eb55b8f 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "build": "rollup -cw", "test-server": "http-server test -o 'http://localhost:8080/' -P 'http://localhost:3000/'", "server": "NODE_ENV=development nodemon index.js", + "server-windows": "set NODE_ENV=development&& nodemon index.js", "import": "node src/importer.js", "dev": "test/run" }, From cce1c723731e01412d76865cfe128a4797c07f3d Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Wed, 13 Feb 2019 11:13:35 +0000 Subject: [PATCH 04/27] Added contributor's note for Jerram Digital --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 973a430..1aef2c1 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,10 @@ { "name": "g-div", "web": "https://github.com/g-div" + }, + { + "name": "Jerram Digital", + "web": "https://jerram.co.uk/" } ], "devDependencies": { From bb815b548d364a54ecc14f0ded1329b3321ad2f2 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Wed, 13 Feb 2019 12:19:44 +0000 Subject: [PATCH 05/27] Added BASIC error checking to Cognito Passport, added example files --- config.json.example | 36 ++++++++++++++++++++++++++ config.tpl.json.example | 56 +++++++++++++++++++++++++++++++++++++++++ src/auth.js | 40 ++++++++++++++++------------- 3 files changed, 114 insertions(+), 18 deletions(-) create mode 100644 config.json.example create mode 100644 config.tpl.json.example diff --git a/config.json.example b/config.json.example new file mode 100644 index 0000000..d463164 --- /dev/null +++ b/config.json.example @@ -0,0 +1,36 @@ +{ + "schnack_host": "https://schnack.example.com", + "page_url": "https://blog.example.com/posts/%SLUG%", + "database": { + "comments": "comments.db", + "sessions": "sessions.db" + }, + "port": 3000, + "admins": [1], + "oauth": { + "secret": "1jz3n70ofkaf41njr2a5c3zsdxtzdbkqk", + "github": { + "client_id": "uttyq8d4phkuc688hhn6", + "client_secret": "1vul6ftftzqyzmrj17u10vjcwkcw3ai661yxzlw3" + }, + "cognito": { + "userPoolId": "us-west-1_n6l2wkypenflznehfi99", + "region": "us-west-1", + "clientId": "xf1bj8m9ilnges31ex9sckhgb", + "credentials": { + "accessKeyId": "P4V3QB2AQ6XVPM2T3KA2", + "secretAccessKey": "mc30fwqm4e836hh6b7mklo2pezjt0062z9hfwzk3" + } + } + }, + "notify": { + "webpush": { + "vapid_public_key": "M0e2BGI5kCGsAL0XUylg3dQxYHQKDlSOGZitTkgZJOe0L_vMvwJo7Iy8K5T7N5Q0OZZku8yGmNsS5MlrtMBDZRQ", + "vapid_private_key": "5U4aur3voOXd_QpOjGegCrxHiMqVHKxqAe5of9G4aH3" + }, + "slack": { + "webhook_url": "https://hooks.slack.com/services/N2TUTL8XL/2IXQYF1O0/NIbUXyoL7TFDo49XkiiTGYY4" + } + }, + "date_format": "DD MM YYYY - h:mm a" +} diff --git a/config.tpl.json.example b/config.tpl.json.example new file mode 100644 index 0000000..9e8520f --- /dev/null +++ b/config.tpl.json.example @@ -0,0 +1,56 @@ +{ + "schnack_host": "https://schnack.example.com", + "page_url": "https://blog.example.com/posts/%SLUG%", + "database": { + "comments": "comments.db", + "sessions": "sessions.db" + }, + "port": 3000, + "admins": [1], + "oauth": { + "secret": "xxxxx", + "twitter": { + "consumer_key": "xxxxx", + "consumer_secret": "xxxxx" + }, + "github": { + "client_id": "xxxxx", + "client_secret": "xxxxx" + }, + "google": { + "client_id": "xxxxx", + "client_secret": "xxxxx" + }, + "facebook": { + "client_id": "xxxxx", + "client_secret": "xxxxx" + }, + "mastodon": { + "app_name": "your website name", + "app_website": "https://blog.example.com/" + }, + "cognito": { + "userPoolId": "xxxxx", + "region": "xxxxx", + "clientId": "xxxxx", + "credentials": { + "accessKeyId": "xxxxx", + "secretAccessKey": "xxxxx" + } + } + }, + "notify": { + "pushover": { + "app_token": "xxxxx", + "user_key": "xxxxx" + }, + "webpush": { + "vapid_public_key": "xxxxx", + "vapid_private_key": "xxxxx" + }, + "slack": { + "webhook_url": "xxxxx" + } + }, + "date_format": "MMMM DD, YYYY - h:mm a" +} diff --git a/src/auth.js b/src/auth.js index b5bb2f9..d52e863 100644 --- a/src/auth.js +++ b/src/auth.js @@ -230,26 +230,30 @@ function init(app, db, domain) { // Amazon Cognito oAuth if (authConfig.cognito) { - providers.push({ id: 'cognito', name: 'Amazon Cognito' }); - passport.use(new CognitoStrategy({ - userPoolId: authConfig.cognito.userPoolId, - clientId: authConfig.cognito.clientId, - region: authConfig.cognito.region - }, (accessToken, refreshToken, profile, done) => { - done(null, profile); - })); + if (authConfig.cognito.userPoolId.length > 7) { + providers.push({ id: 'cognito', name: 'Amazon Cognito' }); + passport.use(new CognitoStrategy({ + userPoolId: authConfig.cognito.userPoolId, + clientId: authConfig.cognito.clientId, + region: authConfig.cognito.region + }, (accessToken, refreshToken, profile, done) => { + done(null, profile); + })); - app.get('/auth/cognito', - passport.authenticate('cognito') - ); + app.get('/auth/cognito', + passport.authenticate('cognito') + ); - app.get('/auth/cognito/callback', - passport.authenticate('cognito', { - failureRedirect: '/login' - }), (request, reply) => { - reply.redirect('/success') - } - ); + app.get('/auth/cognito/callback', + passport.authenticate('cognito', { + failureRedirect: '/login' + }), (request, reply) => { + reply.redirect('/success') + } + ); + } else { + console.error("Amazon Cognito's config doesn't look right", authConfig.cognito); + } } } From 279586bf8b6b91ef46987ed61f1b8eb1c9b21a85 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Wed, 13 Feb 2019 16:13:12 +0000 Subject: [PATCH 06/27] Removed unnecessary example files --- config.json.example | 36 -------------------------- config.tpl.json.example | 56 ----------------------------------------- 2 files changed, 92 deletions(-) delete mode 100644 config.json.example delete mode 100644 config.tpl.json.example diff --git a/config.json.example b/config.json.example deleted file mode 100644 index d463164..0000000 --- a/config.json.example +++ /dev/null @@ -1,36 +0,0 @@ -{ - "schnack_host": "https://schnack.example.com", - "page_url": "https://blog.example.com/posts/%SLUG%", - "database": { - "comments": "comments.db", - "sessions": "sessions.db" - }, - "port": 3000, - "admins": [1], - "oauth": { - "secret": "1jz3n70ofkaf41njr2a5c3zsdxtzdbkqk", - "github": { - "client_id": "uttyq8d4phkuc688hhn6", - "client_secret": "1vul6ftftzqyzmrj17u10vjcwkcw3ai661yxzlw3" - }, - "cognito": { - "userPoolId": "us-west-1_n6l2wkypenflznehfi99", - "region": "us-west-1", - "clientId": "xf1bj8m9ilnges31ex9sckhgb", - "credentials": { - "accessKeyId": "P4V3QB2AQ6XVPM2T3KA2", - "secretAccessKey": "mc30fwqm4e836hh6b7mklo2pezjt0062z9hfwzk3" - } - } - }, - "notify": { - "webpush": { - "vapid_public_key": "M0e2BGI5kCGsAL0XUylg3dQxYHQKDlSOGZitTkgZJOe0L_vMvwJo7Iy8K5T7N5Q0OZZku8yGmNsS5MlrtMBDZRQ", - "vapid_private_key": "5U4aur3voOXd_QpOjGegCrxHiMqVHKxqAe5of9G4aH3" - }, - "slack": { - "webhook_url": "https://hooks.slack.com/services/N2TUTL8XL/2IXQYF1O0/NIbUXyoL7TFDo49XkiiTGYY4" - } - }, - "date_format": "DD MM YYYY - h:mm a" -} diff --git a/config.tpl.json.example b/config.tpl.json.example deleted file mode 100644 index 9e8520f..0000000 --- a/config.tpl.json.example +++ /dev/null @@ -1,56 +0,0 @@ -{ - "schnack_host": "https://schnack.example.com", - "page_url": "https://blog.example.com/posts/%SLUG%", - "database": { - "comments": "comments.db", - "sessions": "sessions.db" - }, - "port": 3000, - "admins": [1], - "oauth": { - "secret": "xxxxx", - "twitter": { - "consumer_key": "xxxxx", - "consumer_secret": "xxxxx" - }, - "github": { - "client_id": "xxxxx", - "client_secret": "xxxxx" - }, - "google": { - "client_id": "xxxxx", - "client_secret": "xxxxx" - }, - "facebook": { - "client_id": "xxxxx", - "client_secret": "xxxxx" - }, - "mastodon": { - "app_name": "your website name", - "app_website": "https://blog.example.com/" - }, - "cognito": { - "userPoolId": "xxxxx", - "region": "xxxxx", - "clientId": "xxxxx", - "credentials": { - "accessKeyId": "xxxxx", - "secretAccessKey": "xxxxx" - } - } - }, - "notify": { - "pushover": { - "app_token": "xxxxx", - "user_key": "xxxxx" - }, - "webpush": { - "vapid_public_key": "xxxxx", - "vapid_private_key": "xxxxx" - }, - "slack": { - "webhook_url": "xxxxx" - } - }, - "date_format": "MMMM DD, YYYY - h:mm a" -} From d5163b9a6f28c92f11984d7aed1090a77c608a9c Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Thu, 14 Feb 2019 18:05:00 +0000 Subject: [PATCH 07/27] Added Jira REST API connector, added example connection strings, added documentation, created board lister --- README.md | 46 +++++++++++++++++++++++++++++++++++++++++++++- config.tpl.json | 7 +++++++ package-lock.json | 9 +++++++++ package.json | 6 ++++-- src/jira/boards.js | 18 ++++++++++++++++++ 5 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 src/jira/boards.js diff --git a/README.md b/README.md index 15a9e5e..2680a6a 100644 --- a/README.md +++ b/README.md @@ -88,10 +88,54 @@ You will find further information on the [schnack page](https://schnack.cool/). * slack * rss * sendmail +* [Jira](https://developer.atlassian.com/cloud/jira/platform/rest/v3/) + +#### Setting up Jira + +The implementation of the Jira notifier (using the `jira-connector` package) creates a new job in the board of your choice, whenever a new comment is submitted. This allows your team to assign a workflow to the moderation / approval process. + +**1: Generate an RSA Public / Private Key Pair** + +Run these commands in _Terminal_ or _Bash_, **individually**; following all on-screen propmpts: + +``` +openssl genrsa -out jira_privatekey.pem 1024 +``` +``` +openssl req -newkey rsa:1024 -x509 -key jira_privatekey.pem -out jira_publickey.cer -days 365 +``` +``` +openssl pkcs8 -topk8 -nocrypt -in jira_privatekey.pem -out jira_privatekey.pcks8 +``` +``` +openssl x509 -pubkey -noout -in jira_publickey.cer > jira_publickey.pem +``` + +**2: Copy the certificate** + +Copy the contents of the private key file, `_privatekey.pcks8`, to the `notify.jira.oauth.private_key` property, in the `confg.json` file, in the root folder of this application. An example can be found in `config.tpl.json`. + +**3: Add a host name** + +Add / copy / insert the your Jira host name to the `notify.jira.host` property, in the `confg.json` file, in the root folder of this application. An example can be found in `config.tpl.json`. + +**4: Setup the Application in Jira** + +1. Log into Jira using a privileged account, then visit [Atlassian Account API Token Manager](https://id.atlassian.com/manage/api-tokens) +1. Click _Create API Token_ and enter a label +1. When the [Your new API token](https://confluence.atlassian.com/cloud/files/938839638/938839639/1/1507010022324/Screen+Shot+2017-09-25+at+5.09.09+pm.png) modal is shown, click the _Copy to clipboard_ button +1. Using [your favourite Base64 Encoding tool](https://www.base64decode.org/), create the Base64 encoded string `my-email@example.com:my-copied-atlassian-token` +1. Copy the resulting string to the `notify.jira.basic_auth.base64` property + +**5: Assign a board to receive notifications** + +1. Collect a list of the boards available by running `npm run jira-boards` +2. Find the board you'd like to push notifications to, and note the `id` +3. Add the `id` to the `notify.jira.board_id` ### Who is behind Schnack? -Schnack is [yet another](https://github.com/gka/canvid/) happy collaboration between [Webkid](https://webkid.io/) and [Gregor Aisch](https://www.vis4.net). +Schnack is [yet another](https://github.com/gka/canvid/) happy collaboration between [Webkid](https://webkid.io/) and [Gregor Aisch](https://www.vis4.net), with a few minor additions from [Jerram Digital](https://jerram.co.uk/). ### Who is using Schnack? diff --git a/config.tpl.json b/config.tpl.json index 0b49fb6..ca0d6e0 100644 --- a/config.tpl.json +++ b/config.tpl.json @@ -50,6 +50,13 @@ }, "slack": { "webhook_url": "xxxxx" + }, + "jira": { + "host": "myhost.atlassian.net", + "board_id": "1", + "basic_auth": { + "base64": "xxxxx" + } } }, "date_format": "MMMM DD, YYYY - h:mm a" diff --git a/package-lock.json b/package-lock.json index a354e0c..ab73925 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2664,6 +2664,15 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "jira-connector": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/jira-connector/-/jira-connector-2.10.0.tgz", + "integrity": "sha512-nqRq2iEn0w/shTkM2jubQJfnTZxQvSMdmAkNZFB6eW3hn96MgKuHfQ8/CaGnZACrbqRaFTXhPe85GP+y0pemdA==", + "requires": { + "oauth": "^0.9.12", + "request": "^2.83.0" + } + }, "jmespath": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", diff --git a/package.json b/package.json index e872bfc..fa50820 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "cors": "^2.8.5", "express": "^4.16.4", "express-session": "^1.15.6", + "jira-connector": "^2.10.0", "lodash.countby": "^4.6", "marked": "^0.3.19", "moment": "^2.22.2", @@ -30,9 +31,10 @@ "start": "node index.js", "build": "rollup -cw", "test-server": "http-server test -o 'http://localhost:8080/' -P 'http://localhost:3000/'", - "server": "NODE_ENV=development nodemon index.js", + "server": "set NODE_ENV=development&& nodemon index.js", "import": "node src/importer.js", - "dev": "test/run" + "dev": "test/run", + "jira-boards": "node src/jira/boards.js" }, "description": "a simple node app for disqus-like drop-in commenting on static websites", "main": "index.js", diff --git a/src/jira/boards.js b/src/jira/boards.js new file mode 100644 index 0000000..cc7f815 --- /dev/null +++ b/src/jira/boards.js @@ -0,0 +1,18 @@ +const config = require("../config"); +const notifyConfig = config.get("notify"); +var JiraClient = require('jira-connector'); + +var jira = new JiraClient( { + host: notifyConfig.jira.host, + basic_auth: { + base64: notifyConfig.jira.basic_auth.base64 + } +}); + +jira.board.getAllBoards({}, function callback(no, data, response) { + if (data.values) { + console.log(data.values); + } else { + console.log(response); + } +}); \ No newline at end of file From 668da7d1dc8c1fa61b7e4380a4c9318922aa1417 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 10:28:29 +0000 Subject: [PATCH 08/27] Added Jira setup and notifications --- .gitignore | 1 + README.md | 40 ++++++++++------------------------------ config.tpl.json | 3 ++- package.json | 7 ++++--- src/jira/boards.js | 4 +++- src/jira/test.js | 33 +++++++++++++++++++++++++++++++++ src/push/index.js | 1 + src/push/jira.js | 43 +++++++++++++++++++++++++++++++++++++++++++ src/server.js | 8 ++++++-- 9 files changed, 103 insertions(+), 37 deletions(-) create mode 100644 src/jira/test.js create mode 100644 src/push/jira.js diff --git a/.gitignore b/.gitignore index 002d6d7..4168d8b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ npm-debug.log *.sublime-* .DS_Store /.idea +/wordpress-comments.xml diff --git a/README.md b/README.md index 2680a6a..9d2d9c0 100644 --- a/README.md +++ b/README.md @@ -92,34 +92,9 @@ You will find further information on the [schnack page](https://schnack.cool/). #### Setting up Jira -The implementation of the Jira notifier (using the `jira-connector` package) creates a new job in the board of your choice, whenever a new comment is submitted. This allows your team to assign a workflow to the moderation / approval process. +The Jira notifier adds a task to the backlog of your nominated project. This allows your team to assign a workflow to the moderation / approval process. -**1: Generate an RSA Public / Private Key Pair** - -Run these commands in _Terminal_ or _Bash_, **individually**; following all on-screen propmpts: - -``` -openssl genrsa -out jira_privatekey.pem 1024 -``` -``` -openssl req -newkey rsa:1024 -x509 -key jira_privatekey.pem -out jira_publickey.cer -days 365 -``` -``` -openssl pkcs8 -topk8 -nocrypt -in jira_privatekey.pem -out jira_privatekey.pcks8 -``` -``` -openssl x509 -pubkey -noout -in jira_publickey.cer > jira_publickey.pem -``` - -**2: Copy the certificate** - -Copy the contents of the private key file, `_privatekey.pcks8`, to the `notify.jira.oauth.private_key` property, in the `confg.json` file, in the root folder of this application. An example can be found in `config.tpl.json`. - -**3: Add a host name** - -Add / copy / insert the your Jira host name to the `notify.jira.host` property, in the `confg.json` file, in the root folder of this application. An example can be found in `config.tpl.json`. - -**4: Setup the Application in Jira** +**1: Setup the Application in Jira** 1. Log into Jira using a privileged account, then visit [Atlassian Account API Token Manager](https://id.atlassian.com/manage/api-tokens) 1. Click _Create API Token_ and enter a label @@ -127,11 +102,16 @@ Add / copy / insert the your Jira host name to the `notify.jira.host` property, 1. Using [your favourite Base64 Encoding tool](https://www.base64decode.org/), create the Base64 encoded string `my-email@example.com:my-copied-atlassian-token` 1. Copy the resulting string to the `notify.jira.basic_auth.base64` property -**5: Assign a board to receive notifications** +**2: Assign a board to receive notifications** 1. Collect a list of the boards available by running `npm run jira-boards` -2. Find the board you'd like to push notifications to, and note the `id` -3. Add the `id` to the `notify.jira.board_id` +2. Find the board you'd like to push notifications to, and note the `projectKey` +3. Add the `projectKey` to the `notify.jira.project_key` + +**3: Test** + +1. Send a test task to the board, by running `npm run jira-test` + ### Who is behind Schnack? diff --git a/config.tpl.json b/config.tpl.json index ca0d6e0..afba17b 100644 --- a/config.tpl.json +++ b/config.tpl.json @@ -53,7 +53,8 @@ }, "jira": { "host": "myhost.atlassian.net", - "board_id": "1", + "project_key": "xxxxx", + "issue_type": "Story", "basic_auth": { "base64": "xxxxx" } diff --git a/package.json b/package.json index fa50820..0d8c7af 100644 --- a/package.json +++ b/package.json @@ -30,11 +30,12 @@ "scripts": { "start": "node index.js", "build": "rollup -cw", - "test-server": "http-server test -o 'http://localhost:8080/' -P 'http://localhost:3000/'", - "server": "set NODE_ENV=development&& nodemon index.js", + "test-server": "http-server test", + "server": "NODE_ENV=development nodemon index.js", "import": "node src/importer.js", "dev": "test/run", - "jira-boards": "node src/jira/boards.js" + "jira-boards": "node src/jira/boards.js", + "jira-test": "node src/jira/test.js" }, "description": "a simple node app for disqus-like drop-in commenting on static websites", "main": "index.js", diff --git a/src/jira/boards.js b/src/jira/boards.js index cc7f815..cde335b 100644 --- a/src/jira/boards.js +++ b/src/jira/boards.js @@ -10,9 +10,11 @@ var jira = new JiraClient( { }); jira.board.getAllBoards({}, function callback(no, data, response) { - if (data.values) { + if ((data != null) && (data != undefined) && (typeof data !== "undefined")) { console.log(data.values); } else { console.log(response); + console.log("") + console.log("NOTICE: Could not retrieve a list of boards. Above is the response received from Jira."); } }); \ No newline at end of file diff --git a/src/jira/test.js b/src/jira/test.js new file mode 100644 index 0000000..d38cf69 --- /dev/null +++ b/src/jira/test.js @@ -0,0 +1,33 @@ +const config = require("../config"); +const notifyConfig = config.get("notify"); +var JiraClient = require('jira-connector'); + +var jira = new JiraClient( { + host: notifyConfig.jira.host, + basic_auth: { + base64: notifyConfig.jira.basic_auth.base64 + } +}); + +var issue = { + "fields": { + "project":{ + "key": notifyConfig.jira.project_key + }, + "summary": "Test from Schnack", + "description": "Congratulations, you have successfully configured Schnack to create a new task when a comment is posted.\n\nNice work :-)", + "issuetype": { + "name": notifyConfig.jira.issue_type + } + } +} +jira.issue.createIssue(issue, function callback(no, data, response) { + + if ((data != null) && (data != undefined) && (typeof data !== "undefined")) { + console.log("It worked! Please check the Jira Project's backlog for a new ticket"); + console.log(data); + } else { + console.log("NOTICE: Could not create new issue."); + console.log("Jira Errors:", response.body.errors); + } +}); \ No newline at end of file diff --git a/src/push/index.js b/src/push/index.js index 33e436e..a9d757b 100644 --- a/src/push/index.js +++ b/src/push/index.js @@ -4,6 +4,7 @@ const webpush = require('web-push'); const Pushover = require('pushover-notifications'); const queries = require('../db/queries'); const slack = require('./slack'); +const jira = require('./jira'); const sendmail = require('./sendmail'); const { send_file, diff --git a/src/push/jira.js b/src/push/jira.js new file mode 100644 index 0000000..f77953d --- /dev/null +++ b/src/push/jira.js @@ -0,0 +1,43 @@ +const config = require("../config"); +const notifyConfig = config.get("notify"); +const schnackEvents = require('../events'); + +if (notifyConfig.jira) { + + var JiraClient = require('jira-connector'); + var jira = new JiraClient({ + host: notifyConfig.jira.host, + basic_auth: { + base64: notifyConfig.jira.basic_auth.base64 + } + }); + + schnackEvents.on('new-comment', (event) => { + try { + const post_url = config.get('page_url').replace('%SLUG%', event.slug)+'#comment-'+event.id; + const comment = `\n\n----\n\n` + event.comment; + const description = `A [new comment|${post_url}] was posted by ${event.user.display_name || event.user.name} under *${event.slug}*:\n\n${comment}`; + + var issue = { + "fields": { + "project":{ + "key": notifyConfig.jira.project_key + }, + "summary": `Comment for Moderation (${event.user.display_name || event.user.name})`, + "description": description, + "issuetype": { + "name": notifyConfig.jira.issue_type + } + } + } + + jira.issue.createIssue(issue, function callback(no, data, response) { + if ((data == null) || (data == undefined) || (typeof data === "undefined")) { + console.log('Error sending Jira notification:', response.body.errors); + } + }); + } catch (error) { + console.error('Error sending Jira notification:', error); + } + }); +} diff --git a/src/server.js b/src/server.js index c8842c5..e2ee6e0 100644 --- a/src/server.js +++ b/src/server.js @@ -113,9 +113,13 @@ function run(db) { app.get('/success', (request, reply) => { const schnackDomain = getSchnackDomain(); + console.log(request); + console.log(reply); reply.send(``); }); From d0c0a00c8b9cf1f78bc5e5c96bf964446b9f87f4 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 10:44:02 +0000 Subject: [PATCH 09/27] Removed debugging code. Sorry :-( --- src/server.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/server.js b/src/server.js index e2ee6e0..a9638ae 100644 --- a/src/server.js +++ b/src/server.js @@ -113,13 +113,9 @@ function run(db) { app.get('/success', (request, reply) => { const schnackDomain = getSchnackDomain(); - console.log(request); - console.log(reply); reply.send(``); }); From c74a4dad948c58356b43fecbccfbc043b7ad383d Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 10:44:47 +0000 Subject: [PATCH 10/27] Removed unnecessary whitespace --- src/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server.js b/src/server.js index a9638ae..c8842c5 100644 --- a/src/server.js +++ b/src/server.js @@ -115,7 +115,7 @@ function run(db) { const schnackDomain = getSchnackDomain(); reply.send(``); }); From 97e577255d1f65179656a1191a6b6d4484e5e8a9 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 14:44:26 +0000 Subject: [PATCH 11/27] Improved efficiency of Jira test code --- src/jira/boards.js | 9 ++++----- src/jira/config.js | 6 ++++++ src/jira/test.js | 13 ++++++------- 3 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 src/jira/config.js diff --git a/src/jira/boards.js b/src/jira/boards.js index cde335b..e4e604c 100644 --- a/src/jira/boards.js +++ b/src/jira/boards.js @@ -1,15 +1,14 @@ -const config = require("../config"); -const notifyConfig = config.get("notify"); -var JiraClient = require('jira-connector'); +const { notifyConfig, JiraClient } = require('./config.js'); -var jira = new JiraClient( { +const jira = new JiraClient({ host: notifyConfig.jira.host, basic_auth: { base64: notifyConfig.jira.basic_auth.base64 } }); -jira.board.getAllBoards({}, function callback(no, data, response) { +jira.board.getAllBoards({}, function callback(empty, data, response) { + if ((data != null) && (data != undefined) && (typeof data !== "undefined")) { console.log(data.values); } else { diff --git a/src/jira/config.js b/src/jira/config.js new file mode 100644 index 0000000..4e49f1a --- /dev/null +++ b/src/jira/config.js @@ -0,0 +1,6 @@ +const config = require("../config"); +const notifyConfig = config.get("notify"); +const JiraClient = require('jira-connector'); + +exports.notifyConfig = notifyConfig; +exports.JiraClient = JiraClient; \ No newline at end of file diff --git a/src/jira/test.js b/src/jira/test.js index d38cf69..4511026 100644 --- a/src/jira/test.js +++ b/src/jira/test.js @@ -1,15 +1,13 @@ -const config = require("../config"); -const notifyConfig = config.get("notify"); -var JiraClient = require('jira-connector'); +const { notifyConfig, JiraClient } = require('./config.js'); -var jira = new JiraClient( { +const jira = new JiraClient({ host: notifyConfig.jira.host, basic_auth: { base64: notifyConfig.jira.basic_auth.base64 } }); -var issue = { +const issue = { "fields": { "project":{ "key": notifyConfig.jira.project_key @@ -20,8 +18,9 @@ var issue = { "name": notifyConfig.jira.issue_type } } -} -jira.issue.createIssue(issue, function callback(no, data, response) { +}; + +jira.issue.createIssue(issue, function callback(empty, data, response) { if ((data != null) && (data != undefined) && (typeof data !== "undefined")) { console.log("It worked! Please check the Jira Project's backlog for a new ticket"); From d9f8e12bc6a3b4f035226e30a5d5d6c096ddb5cf Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 14:55:04 +0000 Subject: [PATCH 12/27] Updated jira push to use jira config, instead of re-difining all constants --- src/push/jira.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/push/jira.js b/src/push/jira.js index f77953d..ae58cbe 100644 --- a/src/push/jira.js +++ b/src/push/jira.js @@ -1,11 +1,10 @@ +const { notifyConfig, JiraClient } = require('../jira/config.js'); const config = require("../config"); -const notifyConfig = config.get("notify"); const schnackEvents = require('../events'); if (notifyConfig.jira) { - var JiraClient = require('jira-connector'); - var jira = new JiraClient({ + const jira = new JiraClient({ host: notifyConfig.jira.host, basic_auth: { base64: notifyConfig.jira.basic_auth.base64 From c2904c1102397c0b64f4f8803ee11788e2f82335 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 14:57:00 +0000 Subject: [PATCH 13/27] Updated declarations, to be more consistant --- src/push/jira.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/push/jira.js b/src/push/jira.js index ae58cbe..733f335 100644 --- a/src/push/jira.js +++ b/src/push/jira.js @@ -17,7 +17,7 @@ if (notifyConfig.jira) { const comment = `\n\n----\n\n` + event.comment; const description = `A [new comment|${post_url}] was posted by ${event.user.display_name || event.user.name} under *${event.slug}*:\n\n${comment}`; - var issue = { + const issue = { "fields": { "project":{ "key": notifyConfig.jira.project_key From c3c041a7f354c70cc3cd91cb8adfece59f127225 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 15:28:37 +0000 Subject: [PATCH 14/27] Added error checking for Jira notifier --- src/jira/boards.js | 31 ++++++++++++--------------- src/jira/config.js | 11 +++++++++- src/jira/test.js | 53 ++++++++++++++++++++++------------------------ src/push/jira.js | 12 +++-------- 4 files changed, 52 insertions(+), 55 deletions(-) diff --git a/src/jira/boards.js b/src/jira/boards.js index e4e604c..33e2eec 100644 --- a/src/jira/boards.js +++ b/src/jira/boards.js @@ -1,19 +1,16 @@ -const { notifyConfig, JiraClient } = require('./config.js'); +const { notifyConfig, jira } = require('./config.js'); -const jira = new JiraClient({ - host: notifyConfig.jira.host, - basic_auth: { - base64: notifyConfig.jira.basic_auth.base64 - } -}); +if (notifyConfig.jira) { + jira.board.getAllBoards({}, function callback(empty, data, response) { -jira.board.getAllBoards({}, function callback(empty, data, response) { - - if ((data != null) && (data != undefined) && (typeof data !== "undefined")) { - console.log(data.values); - } else { - console.log(response); - console.log("") - console.log("NOTICE: Could not retrieve a list of boards. Above is the response received from Jira."); - } -}); \ No newline at end of file + if ((data != null) && (data != undefined) && (typeof data !== "undefined")) { + console.log(data.values); + } else { + console.log(response); + console.log("") + console.log("NOTICE: Could not retrieve a list of boards. Above is the response received from Jira."); + } + }); +} else { + console.log("NOTICE: Jira does not appear to be configured. Please check the README for instructions on how to setup Jira Notifications."); +} \ No newline at end of file diff --git a/src/jira/config.js b/src/jira/config.js index 4e49f1a..0347bb5 100644 --- a/src/jira/config.js +++ b/src/jira/config.js @@ -2,5 +2,14 @@ const config = require("../config"); const notifyConfig = config.get("notify"); const JiraClient = require('jira-connector'); +if (notifyConfig.jira) { + const JiraInit = new JiraClient({ + host: notifyConfig.jira.host, + basic_auth: { + base64: notifyConfig.jira.basic_auth.base64 + } + }); + exports.jira = JiraInit; +} + exports.notifyConfig = notifyConfig; -exports.JiraClient = JiraClient; \ No newline at end of file diff --git a/src/jira/test.js b/src/jira/test.js index 4511026..9088d0c 100644 --- a/src/jira/test.js +++ b/src/jira/test.js @@ -1,32 +1,29 @@ -const { notifyConfig, JiraClient } = require('./config.js'); +const { notifyConfig, jira } = require('./config.js'); -const jira = new JiraClient({ - host: notifyConfig.jira.host, - basic_auth: { - base64: notifyConfig.jira.basic_auth.base64 - } -}); - -const issue = { - "fields": { - "project":{ - "key": notifyConfig.jira.project_key - }, - "summary": "Test from Schnack", - "description": "Congratulations, you have successfully configured Schnack to create a new task when a comment is posted.\n\nNice work :-)", - "issuetype": { - "name": notifyConfig.jira.issue_type +if (notifyConfig.jira) { + const issue = { + "fields": { + "project":{ + "key": notifyConfig.jira.project_key + }, + "summary": "Test from Schnack", + "description": "Congratulations, you have successfully configured Schnack to create a new task when a comment is posted.\n\nNice work :-)", + "issuetype": { + "name": notifyConfig.jira.issue_type + } } - } -}; + }; -jira.issue.createIssue(issue, function callback(empty, data, response) { + jira.issue.createIssue(issue, function callback(empty, data, response) { - if ((data != null) && (data != undefined) && (typeof data !== "undefined")) { - console.log("It worked! Please check the Jira Project's backlog for a new ticket"); - console.log(data); - } else { - console.log("NOTICE: Could not create new issue."); - console.log("Jira Errors:", response.body.errors); - } -}); \ No newline at end of file + if ((data != null) && (data != undefined) && (typeof data !== "undefined")) { + console.log("It worked! Please check the Jira Project's backlog for a new ticket"); + console.log(data); + } else { + console.log("NOTICE: Could not create new issue."); + console.log("Jira Errors:", response.body.errors); + } + }); +} else { + console.log("NOTICE: Jira does not appear to be configured. Please check the README for instructions on how to setup Jira Notifications."); +} diff --git a/src/push/jira.js b/src/push/jira.js index 733f335..bd320a7 100644 --- a/src/push/jira.js +++ b/src/push/jira.js @@ -1,15 +1,9 @@ -const { notifyConfig, JiraClient } = require('../jira/config.js'); -const config = require("../config"); -const schnackEvents = require('../events'); +const { notifyConfig, jira } = require('../jira/config.js'); if (notifyConfig.jira) { - const jira = new JiraClient({ - host: notifyConfig.jira.host, - basic_auth: { - base64: notifyConfig.jira.basic_auth.base64 - } - }); + const config = require("../config"); + const schnackEvents = require('../events'); schnackEvents.on('new-comment', (event) => { try { From a6887376c44e0e049bcfc14c213a8551ba6614cc Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 16:16:52 +0000 Subject: [PATCH 15/27] Cleaning up Jira code --- src/jira/boards.js | 4 ++-- src/jira/config.js | 6 ++++-- src/jira/test.js | 4 ++-- src/push/jira.js | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/jira/boards.js b/src/jira/boards.js index 33e2eec..b0dbca8 100644 --- a/src/jira/boards.js +++ b/src/jira/boards.js @@ -1,6 +1,6 @@ -const { notifyConfig, jira } = require('./config.js'); +const { jira } = require('./config.js'); -if (notifyConfig.jira) { +if (jira) { jira.board.getAllBoards({}, function callback(empty, data, response) { if ((data != null) && (data != undefined) && (typeof data !== "undefined")) { diff --git a/src/jira/config.js b/src/jira/config.js index 0347bb5..79c8b92 100644 --- a/src/jira/config.js +++ b/src/jira/config.js @@ -2,14 +2,16 @@ const config = require("../config"); const notifyConfig = config.get("notify"); const JiraClient = require('jira-connector'); +let JiraInit; + if (notifyConfig.jira) { - const JiraInit = new JiraClient({ + JiraInit = new JiraClient({ host: notifyConfig.jira.host, basic_auth: { base64: notifyConfig.jira.basic_auth.base64 } }); - exports.jira = JiraInit; } exports.notifyConfig = notifyConfig; +exports.jira = JiraInit; diff --git a/src/jira/test.js b/src/jira/test.js index 9088d0c..600f4a5 100644 --- a/src/jira/test.js +++ b/src/jira/test.js @@ -1,6 +1,6 @@ -const { notifyConfig, jira } = require('./config.js'); +const { jira } = require('./config.js'); -if (notifyConfig.jira) { +if (jira) { const issue = { "fields": { "project":{ diff --git a/src/push/jira.js b/src/push/jira.js index bd320a7..0d8fa30 100644 --- a/src/push/jira.js +++ b/src/push/jira.js @@ -1,6 +1,6 @@ const { notifyConfig, jira } = require('../jira/config.js'); -if (notifyConfig.jira) { +if (jira) { const config = require("../config"); const schnackEvents = require('../events'); From 1ce2e79dc196567aef367b31054b43e0fb3662f5 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 16:18:00 +0000 Subject: [PATCH 16/27] Cleaning up Jira code --- src/jira/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jira/test.js b/src/jira/test.js index 600f4a5..aa412ec 100644 --- a/src/jira/test.js +++ b/src/jira/test.js @@ -1,4 +1,4 @@ -const { jira } = require('./config.js'); +const { notifyConfig, jira } = require('./config.js'); if (jira) { const issue = { From 02ead81b99661bdfcc01eba1fe624a760e72f371 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 16:27:07 +0000 Subject: [PATCH 17/27] Updated README to reflect *actual* product being supported (Jira Cloud, not Jira) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d2d9c0..b5635a6 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ You will find further information on the [schnack page](https://schnack.cool/). * slack * rss * sendmail -* [Jira](https://developer.atlassian.com/cloud/jira/platform/rest/v3/) +* [Jira Cloud](https://developer.atlassian.com/cloud/jira/platform/rest/v3/) #### Setting up Jira From ec64c05d79dcf2d34071ab68070e324d5410e600 Mon Sep 17 00:00:00 2001 From: Dan Menzies Date: Tue, 19 Feb 2019 16:59:02 +0000 Subject: [PATCH 18/27] Added cross-env, so x64 Windows Dev Machines can launch the server without errors --- package.json | 18 +++++++++--------- test/index.html | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index aa333d8..19bba81 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "express-session": "^1.15.6", "lodash.countby": "^4.6", "marked": "^0.3.19", - "moment": "^2.22.2", + "moment": "^2.24.0", "nconf": "^0.10.0", "node-fetch": "^2.3.0", "passport": "^0.4.0", @@ -21,17 +21,16 @@ "pushover-notifications": "^0.2.4", "request": "^2.88.0", "rss": "^1.2.2", - "sqlite": "^3.0.0", - "sqlite3": "^4.0.4", + "sqlite": "^3.0.2", + "sqlite3": "^4.0.6", "unfetch": "^3.1.2", "web-push": "^3.3.3" }, "scripts": { "start": "node index.js", "build": "rollup -cw", - "test-server": "http-server test -o 'http://localhost:8080/' -P 'http://localhost:3000/'", - "server": "NODE_ENV=development nodemon index.js", - "server-windows": "set NODE_ENV=development&& nodemon index.js", + "test-server": "http-server test", + "server": "cross-env NODE_ENV=development nodemon index.js", "import": "node src/importer.js", "dev": "test/run" }, @@ -59,14 +58,15 @@ } ], "devDependencies": { + "cross-env": "^5.2.0", "http-server": "^0.10.0", - "nodemon": "^1.18.6", + "nodemon": "^1.18.10", "passport-cognito": "^0.1.13", "rollup": "^0.55.4", "rollup-plugin-buble": "^0.16.0", - "rollup-plugin-commonjs": "^8.3.0", + "rollup-plugin-commonjs": "^8.4.1", "rollup-plugin-jst": "^1.2.0", - "rollup-plugin-node-resolve": "^3.0.2", + "rollup-plugin-node-resolve": "^3.4.0", "rollup-plugin-string": "^2.0.2", "rollup-plugin-template": "^1.0.10", "rollup-plugin-uglify": "^2.0.1", diff --git a/test/index.html b/test/index.html index 88aa0c9..bd52c80 100644 --- a/test/index.html +++ b/test/index.html @@ -10,8 +10,8 @@