diff --git a/.gitignore b/.gitignore index 698dae8..70f2aa4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules config/default.json +config/open_poll.json diff --git a/README.md b/README.md index 8864de6..ed25615 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Open source poll for slack Welcome to the open source poll for slack. +This repository is hosted on [GitLab](https://gitlab.com/KazuAlex/openpollslack). [Github repository](https://github.com/KazuAlex/openpollslack) is only a mirror. +But feel free to open new issues on both. ## License @@ -33,6 +35,10 @@ Remember the four freedoms of the GPL : For both question and choices, feel free to use slack's emoji, `*bold*` `~strike~` `_italics_` and `` `code` `` +## Self hosted installation + +Wiki pages are available to help you with the [app configuration](https://gitlab.com/KazuAlex/openpollslack/-/wikis/Self-hosted-installation-(v2)) and the [web page configuration](https://gitlab.com/KazuAlex/openpollslack/-/wikis/Web-page). + ## Support me To support of thank me, you can contact me. I would be happy to provide you my PayPal address. diff --git a/assets/css/index.css b/assets/css/index.css index 14db90e..d85dd73 100644 --- a/assets/css/index.css +++ b/assets/css/index.css @@ -19,20 +19,32 @@ body { } #usage > div { - min-height: 100vh; + min-height: 700px; + height: 100vh; display: flex; align-items: center; justify-content: center; } #usage > div > div { - min-height: 100vh; + min-height: 700px; + height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; } +#usage .card-body > .command { + border-radius: 10px; + border: rgba(29,28,29,.5) 1px solid; + padding: 5px 10px 10px 10px; +} + +#usage .card-body > .image > img { + max-height: 500px; +} + .title { text-align: center; } @@ -72,3 +84,23 @@ body { #oauth-success.show, #oauth-error.show { display: block; } + +.navigation { + display: flex; + flex-direction: column; + width: auto; + + position: fixed; + right: 0; + top: calc(50vh - 60px); + + margin-right: 20px; + + user-select: none; +} + +.navigation > .up, +.navigation > .down { + font-size: 40px; + cursor: pointer; +} diff --git a/assets/poll-anonymous.png b/assets/poll-anonymous.png new file mode 100755 index 0000000..4056fb1 Binary files /dev/null and b/assets/poll-anonymous.png differ diff --git a/assets/poll-both.png b/assets/poll-both.png new file mode 100755 index 0000000..843052c Binary files /dev/null and b/assets/poll-both.png differ diff --git a/assets/poll-limited.png b/assets/poll-limited.png new file mode 100755 index 0000000..941e834 Binary files /dev/null and b/assets/poll-limited.png differ diff --git a/assets/poll-simple.png b/assets/poll-simple.png new file mode 100755 index 0000000..e83599b Binary files /dev/null and b/assets/poll-simple.png differ diff --git a/config/default.json.dist b/config/default.json.dist index 487a72a..9fee875 100644 --- a/config/default.json.dist +++ b/config/default.json.dist @@ -1,4 +1,11 @@ { + "port": 5000, + "command": "openpoll", + "help_link": "https://github.com/kazualex/openpollslack.git", "client_id": "", - "client_secret": "" + "client_secret": "", + "signing_secret": "", + "state_secret": "CHANGE ME", + "oauth_success": "https://openpoll.slack.alcor.space/?oauth=success", + "oauth_failure": "https://openpoll.slack.alcor.space/?oauth=error" } diff --git a/index.html b/index.html index c77037a..dab18a0 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + Open source poll for slack @@ -13,6 +13,14 @@ +

Open source poll for slack @@ -30,7 +38,9 @@

- Add to slack + + Add to Slack +
@@ -44,7 +54,12 @@

Simple poll

- /openpoll "What's you favourite color ?" "Red" "Green" "Blue" "Yellow" +
+ /poll "What's you favourite color ?" "Red" "Green" "Blue" "Yellow" +
+
+ Simple poll +
@@ -56,7 +71,12 @@

Anonymous poll

- /openpoll anonymous "What's you favourite color ?" "Red" "Green" "Blue" "Yellow" +
+ /poll anonymous "What's you favourite color ?" "Red" "Green" "Blue" "Yellow" +
+
+ Anonymous poll +
@@ -68,7 +88,12 @@

Limited choice poll

- /openpoll limit 2 "What's you favourite color ?" "Red" "Green" "Blue" "Yellow" +
+ /poll limit 2 "What's you favourite color ?" "Red" "Green" "Blue" "Yellow" +
+
+ Limited poll +
@@ -80,7 +105,12 @@

Anonymous limited choice poll

- /openpoll anonymous limit 2 "What's you favourite color ?" "Red" "Green" "Blue" "Yellow" +
+ /poll anonymous limit 2 "What's you favourite color ?" "Red" "Green" "Blue" "Yellow" +
+
+ Anonymous limited poll +
@@ -111,6 +141,7 @@

Need help ?

+ diff --git a/index.js b/index.js index 3c4fb02..ba8831b 100644 --- a/index.js +++ b/index.js @@ -1,124 +1,157 @@ -const express = require('express'); -const server = express(); -const bodyParser = require('body-parser') -const request = require('request'); -const compression = require('compression'); -const helmet = require('helmet'); +const { App, LogLevel } = require('@slack/bolt'); const config = require('config'); -server.use(bodyParser.json()); -server.use(bodyParser.urlencoded({ - extended: true -})); -server.use(compression()); -server.use(helmet()); -const hostname = '127.0.0.1'; -const port = 5000; +const { JsonDB } = require('node-json-db'); +const JsonDBConfig = require('node-json-db/dist/lib/JsonDBConfig').Config; + +const port = config.get('port'); +const signing_secret = config.get('signing_secret'); +const slackCommand = config.get('command'); +const helpLink = config.get('help_link'); + +const db = new JsonDB(new JsonDBConfig('config/open_poll', true, false, '/')); + +db.push('/token', {}, false); + +const app = new App({ + signingSecret: signing_secret, + clientId: config.get('client_id'), + clientSecret: config.get('client_secret'), + scopes: ['commands', 'chat:write.public', 'chat:write'], + stateSecret: config.get('state_secret'), + endpoints: { + events: '/slack/events', + commands: '/slack/commands', + actions: '/slack/actions', + }, + installerOptions: { + installPath: '/slack/install', + redirectUriPath: '/slack/oauth_redirect', + callbackOptions: { + success: (installation, installOptions, req, res) => { + res.redirect(config.get('oauth_success')); + }, + failure: (error, installOptions , req, res) => { + res.redirect(config.get('oauth_failure')); + }, + }, + }, + installationStore: { + storeInstallation: (installation) => { + db.push(`/token/${installation.team.id}`, installation, false); + db.reload(); + return installation.teamId; + }, + fetchInstallation: (InstallQuery) => { + try { + return db.getData(`/token/${InstallQuery.teamId}`); + } catch (e) { + throw new Error('No matching authorizations'); + } + }, + }, + logLevel: LogLevel.DEBUG, +}); -server.post('/', (req, res) => { - res.setHeader('Content-Type', 'plain/text'); - res.send(''); +app.command(`/${slackCommand}`, async ({ command, ack, say, context }) => { + await ack(); - const response_url = req.body ? req.body.response_url : null; + let body = (command && command.text) ? command.text.trim() : null; - if (!response_url) { - return; - } + const isHelp = body ? 'help' === body : false; - let question = null; - const options = []; - let body = req.body.text; - const user_id = req.body.user_id; - const cmd = req.body.command+' '+req.body.text; - - let isAnonymous = false; - let isLimited = false; - let limit = null; - let fetchLimit = false; - - if (body && body.trim() === 'help') { - const response = { - response_type: 'ephemeral', - blocks: [ - { - type: 'section', - text: { - type: 'mrkdwn', - text: '*Open source poll for slack*', - }, - }, - { - type: 'divider', + const channel = (command && command.channel_id) ? command.channel_id : null; + + const userId = (command && command.user_id) ? command.user_id : null; + + if (isHelp) { + const blocks = [ + { + type: 'section', + text: { + type: 'mrkdwn', + text: '*Open source poll for slack*', }, - { - type: 'section', - text: { - type: 'mrkdwn', - text: '*Simple poll*', - }, + }, + { + type: 'divider', + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: '*Simple poll*', }, - { - type: 'section', - text: { - type: 'mrkdwn', - text: "```\n/openpoll \"What's your favourite color ?\" \"Red\" \"Green\" \"Blue\" \"Yellow\"\n```", - }, + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: "```\n/"+slackCommand+" \"What's your favourite color ?\" \"Red\" \"Green\" \"Blue\" \"Yellow\"\n```", }, - { - type: 'section', - text: { - type: 'mrkdwn', - text: '*Anonymous poll*', - }, + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: '*Anonymous poll*', }, - { - type: 'section', - text: { - type: 'mrkdwn', - text: "```\n/openpoll anonymous \"What's your favourite color ?\" \"Red\" \"Green\" \"Blue\" \"Yellow\"\n```", - }, + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: "```\n/"+slackCommand+" anonymous \"What's your favourite color ?\" \"Red\" \"Green\" \"Blue\" \"Yellow\"\n```", }, - { - type: 'section', - text: { - type: 'mrkdwn', - text: '*Limited choice poll*', - }, + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: '*Limited choice poll*', }, - { - type: 'section', - text: { - type: 'mrkdwn', - text: "```\n/openpoll limit 2 \"What's your favourite color ?\" \"Red\" \"Green\" \"Blue\" \"Yellow\"\n```", - }, + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: "```\n/"+slackCommand+" limit 2 \"What's your favourite color ?\" \"Red\" \"Green\" \"Blue\" \"Yellow\"\n```", }, - { - type: 'section', - text: { - type: 'mrkdwn', - text: '*Anonymous limited choice poll*', - }, + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: '*Anonymous limited choice poll*', }, - { - type: 'section', - text: { - type: 'mrkdwn', - text: "```\n/openpoll anonymous limit 2 \"What's your favourite color ?\" \"Red\" \"Green\" \"Blue\" \"Yellow\"\n```", - }, + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: "```\n/"+slackCommand+" anonymous limit 2 \"What's your favourite color ?\" \"Red\" \"Green\" \"Blue\" \"Yellow\"\n```", }, - ], - }; - - request({ - uri: response_url, - body: JSON.stringify(response), - method: 'post', - header: { - 'Content-Type': 'application/json', }, + ]; + + await app.client.chat.postEphemeral({ + token: context.botToken, + channel: channel, + user: userId, + blocks: blocks, }); + return; - } else if (body) { + } else { + const cmd = `/${slackCommand} ${body}`; + let question = null; + const options = []; + + let isAnonymous = false; + let isLimited = false; + let limit = null; + let fetchLimit = false; + if (body.startsWith('anonymous')) { isAnonymous = true; body = body.substring(9).trim(); @@ -153,235 +186,620 @@ server.post('/', (req, res) => { } } - const blocks = []; + const blocks = createPollView(question, options, isAnonymous, isLimited, limit, userId, cmd); - if (question && options) { - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: question, - }, - }); + if (null === blocks) { + return; + } - let voteLimit = 0; + await app.client.chat.postMessage({ + token: context.botToken, + channel: channel, + blocks: blocks, + }); + } +}); - let elements = []; - if (isAnonymous || isLimited) { - if (isAnonymous) { - elements.push({ - type: 'mrkdwn', - text: ':shushing_face: Anonymous poll', - }); - } - if (isLimited) { - elements.push({ - type: 'mrkdwn', - text: ':warning: Limited to '+ limit + ' vote' +(limit > 1 ? 's': ''), - }); +const modalBlockInput = { + type: 'input', + element: { + type: 'plain_text_input', + placeholder: { + type: 'plain_text', + text: 'Write your choice', + }, + }, + label: { + type: 'plain_text', + text: ' ', + }, +}; + +(async () => { + await app.start(process.env.PORT || port); + + console.log('Bolt app is running!'); +})(); + +app.action('btn_add_choice', async ({ action, ack, body, client, context }) => { + await ack(); + + if ( + !body + || !body.view + || !body.view.blocks + || !body.view.hash + || !body.view.type + || !body.view.title + || !body.view.submit + || !body.view.close + || !body.view.id + || !body.view.private_metadata + ) { + console.log('error'); + return; + } + + let blocks = body.view.blocks; + const hash = body.view.hash; + + let beginBlocks = blocks.slice(0, blocks.length - 1); + let endBlocks = blocks.slice(-1); + + let tempModalBlockInput = JSON.parse(JSON.stringify(modalBlockInput)); + tempModalBlockInput.block_id = 'choice_'+(blocks.length-8); + + beginBlocks.push(tempModalBlockInput); + blocks = beginBlocks.concat(endBlocks); + + const view = { + type: body.view.type, + private_metadata: body.view.private_metadata, + callback_id: 'modal_poll_submit', + title: body.view.title, + submit: body.view.submit, + close: body.view.close, + blocks: blocks, + external_id: body.view.id, + }; + + const result = await client.views.update({ + token: context.botToken, + hash: hash, + view: view, + view_id: body.view.id, + }); +}); + +app.action('btn_vote', async ({ action, ack, body, context }) => { + await ack(); + + if ( + !body + || !action + || !body.user + || !body.user.id + || !body.message + || !body.message.blocks + || !body.message.ts + || !body.channel + || !body.channel.id + ) { + console.log('error'); + return; + } + + const user_id = body.user.id; + const message = body.message; + let blocks = message.blocks; + + const channel = body.channel.id; + + let value = JSON.parse(action.value); + button_id = 3 + (value.id * 2); + context_id = 3 + (value.id * 2) + 1; + let blockBtn = blocks[button_id]; + let block = blocks[context_id]; + let voters = value.voters ? value.voters : []; + let newVoters = ''; + + let removeVote = false; + if (voters.includes(user_id)) { + removeVote = true; + voters = voters.filter(voter_id => voter_id != user_id); + } else { + voters.push(user_id); + } + + if (value.limited && value.limit) { + let voteCount = 0; + for (let b of blocks) { + if (b.accessory) { + let val = JSON.parse(b.accessory.value); + if (val.voters && val.voters.includes(user_id)) { + ++voteCount; } } - elements.push({ - type: 'mrkdwn', - text: ':eyes: by <@'+user_id+'>' - }); - blocks.push({ - type: 'context', - elements: elements, - }); - blocks.push({ - type: 'divider', - }); + } + + if (removeVote) { + voteCount -= 1; + } - let button_value = { - anonymous: isAnonymous, - limited: isLimited, - limit: limit, - voters: [], - id: null, - }; - - for (let i in options) { - let option = options[i]; - btn_value = JSON.parse(JSON.stringify(button_value)); - btn_value.id = i; - let block = { - type: 'section', - text: { - type: 'mrkdwn', - text: option, + if (voteCount >= value.limit) { + return; + } + } + + if (voters.length === 0) { + newVoters = 'No votes'; + } else { + newVoters = ''; + for (let voter of voters) { + if (!value.anonymous) { + newVoters += '<@'+voter+'> '; + } + } + + newVoters += voters.length +' '; + if (voters.length === 1) { + newVoters += 'vote'; + } else { + newVoters += 'votes'; + } + } + + block.elements[0].text = newVoters; + value.voters = voters; + blockBtn.accessory.value = JSON.stringify(value); + blocks[context_id] = block; + + await app.client.chat.update({ + token: context.botToken, + channel: channel, + ts: message.ts, + blocks: blocks, + }); +}); + +app.shortcut('open_modal_new', async ({ shortcut, ack, context, client, lody }) => { + try { + await ack(); + + let tempModalBlockInput = JSON.parse(JSON.stringify(modalBlockInput)); + tempModalBlockInput.block_id = 'choice_0'; + + const privateMetadata = { + anonymous: false, + limited: false, + channel: null, + }; + + const result = await client.views.open({ + token: context.botToken, + trigger_id: shortcut.trigger_id, + view: { + type: 'modal', + callback_id: 'modal_poll_submit', + private_metadata: JSON.stringify(privateMetadata), + title: { + type: 'plain_text', + text: 'Create a poll', + }, + submit: { + type: 'plain_text', + text: 'Create', + }, + close: { + type: 'plain_text', + text: 'Cancel', + }, + blocks: [ + { + type: 'section', + text: { + type: 'mrkdwn', + text: 'Create a poll by filling the following form.', + }, }, - accessory: { - type: 'button', + { + type: 'divider', + }, + { + type: 'section', text: { - type: 'plain_text', - emoji: true, - text: 'Vote', + type: 'mrkdwn', + text: 'Select a channel to post poll', }, - value: JSON.stringify(btn_value), }, - }; - blocks.push(block); - block = { - type: 'context', - elements: [ - { + { + type: 'actions', + block_id: 'channel', + elements: [ + { + type: 'channels_select', + action_id: 'modal_poll_channel', + placeholder: { + type: 'plain_text', + text: 'Select a channel', + }, + }, + ], + }, + { + type: 'divider', + }, + { + type: 'section', + block_id: 'options', + text: { type: 'mrkdwn', - text: 'No votes', + text: "Choose your poll's options" + }, + accessory: { + type: 'checkboxes', + action_id: 'modal_poll_options', + options: [ + { + text: { + type: 'mrkdwn', + text: '*Anonymous*' + }, + description: { + type: 'mrkdwn', + text: '*This option makes your poll anonymous*' + }, + value: 'anonymous' + }, + { + text: { + type: 'mrkdwn', + text: '*Limited*' + }, + description: { + type: 'mrkdwn', + text: '*This option limit the number of choices by user*' + }, + value: 'limit' + } + ] } - ], - }; - blocks.push(block); - } - - blocks.push({ - type: 'divider', - }); - - blocks.push({ - type: 'context', - elements: [ + }, { - type: 'mrkdwn', - text: '', + type: 'divider', }, { - type: 'mrkdwn', - text: ':information_source: '+cmd, - } + type: 'input', + label: { + type: 'plain_text', + text: 'Choose your limit', + }, + element: { + type: 'plain_text_input', + placeholder: { + type: 'plain_text', + text: 'Type a number', + }, + }, + optional: true, + block_id: 'limit', + }, + { + type: 'divider', + }, + { + type: 'input', + label: { + type: 'plain_text', + text: 'Ask your question :', + }, + element: { + type: 'plain_text_input', + placeholder: { + type: 'plain_text', + text: 'Write your question', + }, + }, + block_id: 'question', + }, + { + type: 'divider', + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: '*Create your choice :*', + }, + }, + tempModalBlockInput, + { + type: 'actions', + elements: [ + { + type: 'button', + action_id: 'btn_add_choice', + text: { + type: 'plain_text', + text: '+ Add a choice', + emoji: true, + }, + }, + ], + }, ], - }); + } + }); + } catch (error) { + console.error(error); + } +}); - const response = { - response_type: 'in_channel', - blocks: blocks, - }; - - request({ - uri: response_url, - body: JSON.stringify(response), - method: 'post', - header: { - 'Content-Type': 'application/json', - }, - }); - } +app.action('modal_poll_channel', async ({ action, ack, body, client, context }) => { + await ack(); + + if ( + !action + && !action.selected_channel + ) { + return; } + + const privateMetadata = JSON.parse(body.view.private_metadata); + privateMetadata.channel = action.selected_channel; + + const view = { + type: body.view.type, + private_metadata: JSON.stringify(privateMetadata), + callback_id: 'modal_poll_submit', + title: body.view.title, + submit: body.view.submit, + close: body.view.close, + blocks: body.view.blocks, + external_id: body.view.id, + }; + + const result = await client.views.update({ + token: context.botToken, + hash: body.view.hash, + view: view, + view_id: body.view.id, + }); }); -server.post('/actions', (req, res) => { - res.setHeader('Content-Type', 'text/html'); - res.send(''); - - let response = ''; - if (req.body.payload) { - const payload = JSON.parse(req.body.payload); - const user_id = payload.user.id; - const message = payload.message; - - response = message; - let blocks = message.blocks; - const actions = payload.actions; - for (let action of actions) { - let value = JSON.parse(action.value); - button_id = 3 + (value.id * 2); - context_id = 3 + (value.id * 2) + 1; - let blockBtn = blocks[button_id]; - let block = blocks[context_id]; - let voters = value.voters ? value.voters : []; - let newVoters = ''; - - let removeVote = false; - if (voters.includes(user_id)) { - removeVote = true; - voters = voters.filter(voter_id => voter_id != user_id); - } else { - voters.push(user_id); - } +app.action('modal_poll_options', async ({ action, ack, body, client, context }) => { + await ack(); - if (value.limited && value.limit) { - let voteCount = 0; - for (let b of blocks) { - if (b.accessory) { - let val = JSON.parse(b.accessory.value); - if (val.voters && val.voters.includes(user_id)) { - ++voteCount; - } - } - } + if ( + !body + || !body.view + || !body.view.private_metadata + ) { + return; + } - if (removeVote) { - voteCount -= 1; - } + const privateMetadata = JSON.parse(body.view.private_metadata); + // let privateMetadata = { + // anonymous: false, + // limited: false, + // }; + + privateMetadata.anonymous = false; + privateMetadata.limited = false; + for (const option of action.selected_options) { + if ('anonymous' === option.value) { + privateMetadata.anonymous = true; + } else if ('limit' === option.value) { + privateMetadata.limited = true; + } + } - if (voteCount >= value.limit) { - return; - } - } + const view = { + type: body.view.type, + private_metadata: JSON.stringify(privateMetadata), + callback_id: 'modal_poll_submit', + title: body.view.title, + submit: body.view.submit, + close: body.view.close, + blocks: body.view.blocks, + external_id: body.view.id, + }; + + const result = await client.views.update({ + token: context.botToken, + hash: body.view.hash, + view: view, + view_id: body.view.id, + }); +}); - if (voters.length === 0) { - newVoters = 'No votes'; - } else { - newVoters = ''; - for (let voter of voters) { - if (!value.anonymous) { - newVoters += '<@'+voter+'> '; - } - } +app.view('modal_poll_submit', async ({ ack, body, view, context }) => { + await ack(); + + if ( + !view + || !body + || !view.blocks + || !view.state + || !view.private_metadata + || !body.user + || !body.user.id + ) { + return; + } - newVoters += voters.length +' '; - if (voters.length === 1) { - newVoters += 'vote'; - } else { - newVoters += 'votes'; - } - } + const privateMetadata = JSON.parse(view.private_metadata); + const userId = body.user.id; - block.elements[0].text = newVoters; - value.voters = voters; - blockBtn.accessory.value = JSON.stringify(value); - blocks[context_id] = block; + const state = view.state; + let question = null; + const options = []; + const isAnonymous = privateMetadata.anonymous; + const isLimited = privateMetadata.limited; + let limit = 1; + const channel = privateMetadata.channel; + + if (state.values) { + for (const optionName in state.values) { + const option = state.values[optionName][Object.keys(state.values[optionName])[0]]; + if ('question' === optionName) { + question = option.value; + } else if ('limit' === optionName) { + limit = parseInt(option.value, 10); + } else if (optionName.startsWith('choice_')) { + options.push(option.value); + } } - response.blocks = blocks; - - request({ - uri: payload.response_url, - body: JSON.stringify(response), - method: 'post', - header: { - 'Content-Type': 'application/json', - }, - }, (error, response) => { - }); } + + if ( + !question + || 0 === options.length + ) { + return; + } + + const cmd = createCmdFromInfos(question, options, isAnonymous, isLimited, limit); + + const blocks = createPollView(question, options, isAnonymous, isLimited, limit, userId, cmd); + + await app.client.chat.postMessage({ + token: context.botToken, + channel: channel, + blocks: blocks, + }); }); -server.get('/redirect', (req, res) => { - request({ - uri: 'https://slack.com/api/oauth.access', - form: { - client_id: config.get('client_id'), - client_secret: config.get('client_secret'), - code: req.query.code, - }, - method: 'post', - header: { - 'Content-Type': 'application/x-www-form-urlencoded', +function createCmdFromInfos(question, options, isAnonymous, isLimited, limit) { + let cmd = `/${slackCommand}`; + if (isAnonymous) { + cmd += ` anonymous` + } + if (isLimited) { + cmd += ` limit` + } + if (limit > 1) { + cmd += ` ${limit}` + } + + question = question.replace(/"/g, "\\\""); + cmd += ` "${question}"` + + for (let option of options) { + option = option.replace(/"/g, "\\\""); + cmd += ` "${option}"` + } + + return cmd; +} + +function createPollView(question, options, isAnonymous, isLimited, limit, userId, cmd) { + if ( + !question + || !options + || 0 === options.length + ) { + return null; + } + + const blocks = []; + + blocks.push({ + type: 'section', + text: { + type: 'mrkdwn', + text: question, }, - }, (error, response, body) => { - // do nothing }); - let uri = 'https://openpoll.slack.alcor.space'; - if (req.query.code) { - uri += '?oauth=success'; - } else { - uri += '?oauth=error'; + let voteLimit = 0; + + let elements = []; + if (isAnonymous || isLimited) { + if (isAnonymous) { + elements.push({ + type: 'mrkdwn', + text: ':shushing_face: Anonymous poll', + }); + } + if (isLimited) { + elements.push({ + type: 'mrkdwn', + text: ':warning: Limited to '+ limit + ' vote' +(limit > 1 ? 's': ''), + }); + } } - res.status(301).redirect(uri); -}); + elements.push({ + type: 'mrkdwn', + text: ':eyes: by <@'+userId+'>' + }); + blocks.push({ + type: 'context', + elements: elements, + }); + blocks.push({ + type: 'divider', + }); -server.listen(port, hostname, () => { - console.log('Hello there!'); -}); + let button_value = { + anonymous: isAnonymous, + limited: isLimited, + limit: limit, + voters: [], + id: null, + }; + + for (let i in options) { + let option = options[i]; + btn_value = JSON.parse(JSON.stringify(button_value)); + btn_value.id = i; + let block = { + type: 'section', + text: { + type: 'mrkdwn', + text: option, + }, + accessory: { + type: 'button', + action_id: 'btn_vote', + text: { + type: 'plain_text', + emoji: true, + text: 'Vote', + }, + value: JSON.stringify(btn_value), + }, + }; + blocks.push(block); + block = { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: 'No votes', + } + ], + }; + blocks.push(block); + } + + blocks.push({ + type: 'divider', + }); + + blocks.push({ + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: `<${helpLink}|Need help ?>`, + }, + { + type: 'mrkdwn', + text: ':information_source: '+cmd, + } + ], + }); + return blocks; +} diff --git a/package.json b/package.json index 914a3f7..cea2aa7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openpoll", - "version": "1.0.0", + "version": "2.0.0", "description": "Open source poll slack app", "main": "index.js", "scripts": { @@ -23,11 +23,13 @@ }, "homepage": "https://github.com/KazuAlex/openpollslack#readme", "dependencies": { + "@slack/bolt": "^2.1.1", "body-parser": "^1.19.0", "compression": "^1.7.4", "config": "^3.3.1", "express": "^4.17.1", "helmet": "^3.22.0", + "node-json-db": "^1.1.0", "request": "^2.88.2" } } diff --git a/privacy/index.html b/privacy/index.html index 7ad0b2b..38bee0c 100644 --- a/privacy/index.html +++ b/privacy/index.html @@ -22,6 +22,14 @@

What User Data We Collect

We do not collect any information.

+

Other Data We Collect

+ +

+ We only save informations provided by slack when you add this app to your slack workspace. + + This data is used to authenticate the app on your slack workspace. But no personnel data (like username or any information about your user) are collected. +

+

Our Cookie Policy

diff --git a/yarn.lock b/yarn.lock index bfec730..3521573 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,157 @@ # yarn lockfile v1 +"@slack/bolt@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@slack/bolt/-/bolt-2.1.1.tgz#310e14d989e35916aeae9d5a1bea1162df564b50" + integrity sha512-6Bpv1jiQx9XcbeYfGhldJghA2EzxnforvQ8nlDLLg276oLh2qIEJ2mx2GemOTjTv0bQsX1J9cFp480D8jhlk5g== + dependencies: + "@slack/logger" "^2.0.0" + "@slack/oauth" "^1.1.0" + "@slack/types" "^1.6.0" + "@slack/web-api" "^5.9.0" + "@types/express" "^4.16.1" + "@types/node" ">=10" + "@types/promise.allsettled" "^1.0.3" + axios "^0.19.0" + express "^4.16.4" + please-upgrade-node "^3.2.0" + promise.allsettled "^1.0.2" + raw-body "^2.3.3" + tsscmp "^1.0.6" + +"@slack/logger@>=1.0.0 <3.0.0", "@slack/logger@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@slack/logger/-/logger-2.0.0.tgz#6a4e1c755849bc0f66dac08a8be54ce790ec0e6b" + integrity sha512-OkIJpiU2fz6HOJujhlhfIGrc8hB4ibqtf7nnbJQDerG0BqwZCfmgtK5sWzZ0TkXVRBKD5MpLrTmCYyMxoMCgPw== + dependencies: + "@types/node" ">=8.9.0" + +"@slack/oauth@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@slack/oauth/-/oauth-1.1.0.tgz#68967f3ae92941132bad773e263976ebd6d9fad5" + integrity sha512-v4yawvn9DCmWO0HXXnWxjmwVikLkoZKjCU042o6UES5u0FroYX8ozs+xWbueO8lb7YYqSKPsIX6A6nlbR4pUyA== + dependencies: + "@slack/logger" "^2.0.0" + "@slack/web-api" "^5.7.0" + "@types/jsonwebtoken" "^8.3.7" + "@types/node" ">=6.0.0" + jsonwebtoken "^8.5.1" + lodash.isstring "^4.0.1" + +"@slack/types@^1.6.0", "@slack/types@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@slack/types/-/types-1.7.0.tgz#0a00b60bc6703c1413edd823dcb0f829d16457ed" + integrity sha512-aigLPmTO513JxeFyeII/74y+S5jU39tabDWPsZyMHJWCYqK3vCkRvV73NL+Ay+Tq5RC2NgSmkedk1wvQJ6oXLg== + +"@slack/web-api@^5.7.0", "@slack/web-api@^5.9.0": + version "5.10.0" + resolved "https://registry.yarnpkg.com/@slack/web-api/-/web-api-5.10.0.tgz#edc42c95aff4b7838be9c9fec1454aa5ef9990d6" + integrity sha512-t8c2lcSrdX8LIUOS1RvslbBBKvuNaTtbEcrWai4yDGkiNIxzhk+dHPcJzd7A4A0DkAgiEwXeezR7RCELuG8WgQ== + dependencies: + "@slack/logger" ">=1.0.0 <3.0.0" + "@slack/types" "^1.7.0" + "@types/is-stream" "^1.1.0" + "@types/node" ">=8.9.0" + "@types/p-queue" "^2.3.2" + axios "^0.19.0" + eventemitter3 "^3.1.0" + form-data "^2.5.0" + is-stream "^1.1.0" + p-queue "^2.4.2" + p-retry "^4.0.0" + +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.33" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" + integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== + dependencies: + "@types/node" "*" + +"@types/express-serve-static-core@*": + version "4.17.7" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.7.tgz#dfe61f870eb549dc6d7e12050901847c7d7e915b" + integrity sha512-EMgTj/DF9qpgLXyc+Btimg+XoH7A2liE8uKul8qSmMTHCeNYzydDKFdsJskDvw42UsesCnhO63dO0Grbj8J4Dw== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@^4.16.1": + version "4.17.6" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.6.tgz#6bce49e49570507b86ea1b07b806f04697fac45e" + integrity sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/is-stream@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@types/is-stream/-/is-stream-1.1.0.tgz#b84d7bb207a210f2af9bed431dc0fbe9c4143be1" + integrity sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg== + dependencies: + "@types/node" "*" + +"@types/jsonwebtoken@^8.3.7": + version "8.5.0" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#2531d5e300803aa63279b232c014acf780c981c5" + integrity sha512-9bVao7LvyorRGZCw0VmH/dr7Og+NdjYSsKAxB43OQoComFbBgsEpoR9JW6+qSq/ogwVBg8GI2MfAlk4SYI4OLg== + dependencies: + "@types/node" "*" + +"@types/mime@*": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.2.tgz#857a118d8634c84bba7ae14088e4508490cd5da5" + integrity sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q== + +"@types/node@*", "@types/node@>=10", "@types/node@>=6.0.0", "@types/node@>=8.9.0": + version "14.0.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.13.tgz#ee1128e881b874c371374c1f72201893616417c9" + integrity sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA== + +"@types/p-queue@^2.3.2": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@types/p-queue/-/p-queue-2.3.2.tgz#16bc5fece69ef85efaf2bce8b13f3ebe39c5a1c8" + integrity sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ== + +"@types/promise.allsettled@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/promise.allsettled/-/promise.allsettled-1.0.3.tgz#6f3166618226a570b98c8250fc78687a912e56d5" + integrity sha512-b/IFHHTkYkTqu41IH9UtpICwqrpKj2oNlb4KHPzFQDMiz+h1BgAeATeO0/XTph4+UkH9W2U0E4B4j64KWOovag== + +"@types/qs@*": + version "6.9.3" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.3.tgz#b755a0934564a200d3efdf88546ec93c369abd03" + integrity sha512-7s9EQWupR1fTc2pSMtXRQ9w9gLOcrJn+h7HOXw4evxyvVqMi4f+q7d2tnFe3ng3SNHjtK+0EzGMGFUQX4/AQRA== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/retry@^0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/serve-static@*": + version "1.13.4" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.4.tgz#6662a93583e5a6cabca1b23592eb91e12fa80e7c" + integrity sha512-jTDt0o/YbpNwZbQmE/+2e+lfjJEJJR0I3OFaKQKPWkASkCoW3i6fsUnqudSMcNAfbtmADGu8f4MV4q+GqULmug== + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -25,6 +176,16 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= +array.prototype.map@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.2.tgz#9a4159f416458a23e9483078de1106b2ef68f8ec" + integrity sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.4" + asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -52,6 +213,13 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== +axios@^0.19.0: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== + dependencies: + follow-redirects "1.5.10" + bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" @@ -80,6 +248,11 @@ bowser@2.9.0: resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.9.0.tgz#3bed854233b419b9a7422d9ee3e85504373821c9" integrity sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA== +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -185,6 +358,20 @@ debug@2.6.9: dependencies: ms "2.0.0" +debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -223,6 +410,13 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -233,6 +427,50 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5: + version "1.17.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" + integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.0" + is-regex "^1.1.0" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + +es-get-iterator@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8" + integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ== + dependencies: + es-abstract "^1.17.4" + has-symbols "^1.0.1" + is-arguments "^1.0.4" + is-map "^2.0.1" + is-set "^2.0.1" + is-string "^1.0.5" + isarray "^2.0.5" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -243,12 +481,17 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +eventemitter3@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" + integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== + expect-ct@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/expect-ct/-/expect-ct-0.2.0.tgz#3a54741b6ed34cc7a93305c605f63cd268a54a62" integrity sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g== -express@^4.17.1: +express@^4.16.4, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -300,9 +543,9 @@ extsprintf@^1.2.0: integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -327,11 +570,27 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +form-data@^2.5.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -356,6 +615,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" @@ -376,6 +640,18 @@ har-validator@~5.1.3: ajv "^6.5.5" har-schema "^2.0.0" +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + helmet-crossdomain@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz#5f1fe5a836d0325f1da0a78eaa5fd8429078894e" @@ -392,9 +668,9 @@ helmet-csp@2.10.0: dasherize "2.0.0" helmet@^3.22.0: - version "3.22.0" - resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.22.0.tgz#3a6f11d931799145f0aff15dbc563cff9e13131f" - integrity sha512-Xrqicn2nm1ZIUxP3YGuTBmbDL04neKsIT583Sjh0FkiwKDXYCMUqGqC88w3NUvVXtA75JyR2Jn6jw6ZEMOD+ZA== + version "3.23.0" + resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.23.0.tgz#b9377e96f8f9b8e42ff902238af28fa44b4b91bd" + integrity sha512-/AKPymGd+mJsFN43IkX+nf8J11V51bxLNYReQZmWrVx7M/FEOs2OEE6U1YIt8Y00rpOupbIeVWv5woEGja1Pug== dependencies: depd "2.0.0" dns-prefetch-control "0.2.0" @@ -440,7 +716,7 @@ http-errors@1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-errors@~1.7.2: +http-errors@1.7.3, http-errors@~1.7.2: version "1.7.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== @@ -487,16 +763,83 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + +is-callable@^1.1.4, is-callable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" + integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-map@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" + integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== + +is-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" + integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== + dependencies: + has-symbols "^1.0.1" + +is-set@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" + integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-string@^1.0.4, is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +iterate-iterator@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6" + integrity sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw== + +iterate-value@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" + integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== + dependencies: + es-get-iterator "^1.0.2" + iterate-iterator "^1.0.1" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -524,6 +867,22 @@ json5@^2.1.1: dependencies: minimist "^1.2.5" +jsonwebtoken@^8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -534,6 +893,58 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -571,6 +982,11 @@ minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +mkdirp@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -581,6 +997,11 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -591,11 +1012,38 @@ nocache@2.1.0: resolved "https://registry.yarnpkg.com/nocache/-/nocache-2.1.0.tgz#120c9ffec43b5729b1d5de88cd71aa75a0ba491f" integrity sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q== +node-json-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/node-json-db/-/node-json-db-1.1.0.tgz#b275703bf9467985aa2a08ae735a2b1ea02d1c35" + integrity sha512-HdgRbJrz5OV5+Vs4hLm/i8MTsbxqyvO9A2I/LNviAdrfbvOGt7UhT+DPIEUCaPQbV69fUd0zXB4MWlqGUMf0WA== + dependencies: + mkdirp "~1.0.4" + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -608,6 +1056,19 @@ on-headers@~1.0.2: resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== +p-queue@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-2.4.2.tgz#03609826682b743be9a22dba25051bd46724fc34" + integrity sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng== + +p-retry@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.2.0.tgz#ea9066c6b44f23cab4cd42f6147cdbbc6604da5d" + integrity sha512-jPH38/MRh263KKcq0wBNOGFJbm+U6784RilTmHjB/HM9kH9V8WlCpVUcdOmip9cjXOh6MxZ5yk1z2SjDUJfWmA== + dependencies: + "@types/retry" "^0.12.0" + retry "^0.12.0" + parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -623,6 +1084,24 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +please-upgrade-node@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" + integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== + dependencies: + semver-compare "^1.0.0" + +promise.allsettled@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.2.tgz#d66f78fbb600e83e863d893e98b3d4376a9c47c9" + integrity sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg== + dependencies: + array.prototype.map "^1.0.1" + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + iterate-value "^1.0.0" + proxy-addr@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" @@ -666,6 +1145,16 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@^2.3.3: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + referrer-policy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/referrer-policy/-/referrer-policy-1.2.0.tgz#b99cfb8b57090dc454895ef897a4cc35ef67a98e" @@ -697,6 +1186,11 @@ request@^2.88.2: tunnel-agent "^0.6.0" uuid "^3.3.2" +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + safe-buffer@5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -712,6 +1206,16 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.2: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -766,6 +1270,22 @@ sshpk@^1.7.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +string.prototype.trimend@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimstart@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + toidentifier@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" @@ -779,6 +1299,11 @@ tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +tsscmp@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" + integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"