From 0bc150fc7cf0f2c67b8805e12664029b5e921ed1 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 15 Mar 2021 21:26:50 +0000 Subject: [PATCH 001/135] v0.8.10 --- lerna.json | 2 +- packages/builder/package.json | 6 +++--- packages/client/package.json | 6 +++--- packages/server/package.json | 8 ++++---- packages/standard-components/package.json | 2 +- packages/string-templates/package.json | 2 +- packages/worker/package.json | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lerna.json b/lerna.json index f63871e1c3..3a3a6597b6 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "0.8.9", + "version": "0.8.10", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/builder/package.json b/packages/builder/package.json index 32389a985b..9e5f7a6a27 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "0.8.9", + "version": "0.8.10", "license": "AGPL-3.0", "private": true, "scripts": { @@ -64,9 +64,9 @@ }, "dependencies": { "@budibase/bbui": "^1.58.13", - "@budibase/client": "^0.8.9", + "@budibase/client": "^0.8.10", "@budibase/colorpicker": "1.1.2", - "@budibase/string-templates": "^0.8.9", + "@budibase/string-templates": "^0.8.10", "@budibase/svelte-ag-grid": "^1.0.4", "@sentry/browser": "5.19.1", "@svelteschool/svelte-forms": "0.7.0", diff --git a/packages/client/package.json b/packages/client/package.json index 192bacfbc4..bb7325ff45 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "0.8.9", + "version": "0.8.10", "license": "MPL-2.0", "main": "dist/budibase-client.js", "module": "dist/budibase-client.js", @@ -9,13 +9,13 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/string-templates": "^0.8.9", + "@budibase/string-templates": "^0.8.10", "regexparam": "^1.3.0", "shortid": "^2.2.15", "svelte-spa-router": "^3.0.5" }, "devDependencies": { - "@budibase/standard-components": "^0.8.9", + "@budibase/standard-components": "^0.8.10", "@rollup/plugin-commonjs": "^16.0.0", "@rollup/plugin-node-resolve": "^10.0.0", "fs-extra": "^8.1.0", diff --git a/packages/server/package.json b/packages/server/package.json index 0a53aa8f55..db3370b676 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "0.8.9", + "version": "0.8.10", "description": "Budibase Web Server", "main": "src/electron.js", "repository": { @@ -71,8 +71,8 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/client": "^0.8.9", - "@budibase/string-templates": "^0.8.9", + "@budibase/client": "^0.8.10", + "@budibase/string-templates": "^0.8.10", "@elastic/elasticsearch": "7.10.0", "@koa/router": "8.0.0", "@sendgrid/mail": "7.1.1", @@ -126,7 +126,7 @@ "zlib": "1.0.5" }, "devDependencies": { - "@budibase/standard-components": "^0.8.9", + "@budibase/standard-components": "^0.8.10", "@jest/test-sequencer": "^24.8.0", "cross-env": "^7.0.3", "electron": "10.1.3", diff --git a/packages/standard-components/package.json b/packages/standard-components/package.json index 3e937cff44..f3243a5776 100644 --- a/packages/standard-components/package.json +++ b/packages/standard-components/package.json @@ -35,7 +35,7 @@ "keywords": [ "svelte" ], - "version": "0.8.9", + "version": "0.8.10", "license": "MIT", "gitHead": "1b95326b20d1352d36305910259228b96a683dc7", "dependencies": { diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 6e0b573656..48f0f8d1a8 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "0.8.9", + "version": "0.8.10", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.js", "module": "src/index.js", diff --git a/packages/worker/package.json b/packages/worker/package.json index 1670fd729e..e0b7301a2b 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/deployment", "email": "hi@budibase.com", - "version": "0.8.9", + "version": "0.8.10", "description": "Budibase Deployment Server", "main": "src/index.js", "repository": { From 222aae3543239902de1112be3785bff95fe5909b Mon Sep 17 00:00:00 2001 From: Maurits Lourens Date: Thu, 18 Mar 2021 09:08:39 +0100 Subject: [PATCH 002/135] 1292 - add help menu items related to budibase instead of electron --- packages/server/src/electron.js | 113 +++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 2 deletions(-) diff --git a/packages/server/src/electron.js b/packages/server/src/electron.js index 290c13e6a0..f2770e1d49 100644 --- a/packages/server/src/electron.js +++ b/packages/server/src/electron.js @@ -1,4 +1,4 @@ -const { app, BrowserWindow, shell, dialog } = require("electron") +const { app, BrowserWindow, shell, dialog, Menu } = require("electron") const { join } = require("./utilities/centralPath") const isDev = require("electron-is-dev") const { autoUpdater } = require("electron-updater") @@ -8,7 +8,7 @@ const initialiseBudibase = require("./utilities/initialiseBudibase") const { budibaseAppsDir } = require("./utilities/budibaseDir") const { openNewGitHubIssue, debugInfo } = require("electron-util") const eventEmitter = require("./events") - +const isMac = process.platform === 'darwin'; const budibaseDir = budibaseAppsDir() const envFile = join(budibaseDir, ".env") @@ -87,6 +87,115 @@ async function startApp() { // dock icon is clicked and there are no other windows open. if (win === null) createWindow() }) + + const template = [ + // { role: 'appMenu' } + ...(isMac ? [{ + label: app.name, + submenu: [ + { role: 'about' }, + { type: 'separator' }, + { role: 'services' }, + { type: 'separator' }, + { role: 'hide' }, + { role: 'hideothers' }, + { role: 'unhide' }, + { type: 'separator' }, + { role: 'quit' } + ] + }] : []), + // { role: 'fileMenu' } + { + label: 'File', + submenu: [ + isMac ? { role: 'close' } : { role: 'quit' } + ] + }, + // { role: 'editMenu' } + { + label: 'Edit', + submenu: [ + { role: 'undo' }, + { role: 'redo' }, + { type: 'separator' }, + { role: 'cut' }, + { role: 'copy' }, + { role: 'paste' }, + ...(isMac ? [ + { role: 'pasteAndMatchStyle' }, + { role: 'delete' }, + { role: 'selectAll' }, + { type: 'separator' }, + { + label: 'Speech', + submenu: [ + { role: 'startSpeaking' }, + { role: 'stopSpeaking' } + ] + } + ] : [ + { role: 'delete' }, + { type: 'separator' }, + { role: 'selectAll' } + ]) + ] + }, + // { role: 'viewMenu' } + { + label: 'View', + submenu: [ + { role: 'reload' }, + { role: 'forceReload' }, + { role: 'toggleDevTools' }, + { type: 'separator' }, + { role: 'resetZoom' }, + { role: 'zoomIn' }, + { role: 'zoomOut' }, + { type: 'separator' }, + { role: 'togglefullscreen' } + ] + }, + // { role: 'windowMenu' } + { + label: 'Window', + submenu: [ + { role: 'minimize' }, + { role: 'zoom' }, + ...(isMac ? [ + { type: 'separator' }, + { role: 'front' }, + { type: 'separator' }, + { role: 'window' } + ] : [ + { role: 'close' } + ]) + ] + }, + { + role: 'help', + submenu: [ + { + label: 'Learn More', + click: () => shell.openExternal('https://www.budibase.com/') + }, + { + label: 'Documentation', + click: () => shell.openExternal('https://docs.budibase.com/') + }, + { + label: 'Search issues', + click: () => shell.openExternal('https://github.com/Budibase/budibase/issues') + }, + { + label: 'Community discussions', + click: () => shell.openExternal('https://github.com/Budibase/budibase/discussions') + }, + ] + } + ] + + const menu = Menu.buildFromTemplate(template) + Menu.setApplicationMenu(menu) } autoUpdater.on("update-downloaded", (event, releaseNotes, releaseName) => { From 51a5aea4cefc750ab815ba070f4b493293e179dc Mon Sep 17 00:00:00 2001 From: Maurits Lourens Date: Tue, 23 Mar 2021 20:32:22 +0100 Subject: [PATCH 003/135] fix build by running yarn format --- .../PropertyControls/ColorPicker.svelte | 34 ++-- packages/server/src/electron.js | 155 +++++++++--------- 2 files changed, 97 insertions(+), 92 deletions(-) diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ColorPicker.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ColorPicker.svelte index 6235e744f8..c777f79666 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ColorPicker.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/ColorPicker.svelte @@ -1,38 +1,42 @@ diff --git a/packages/server/src/electron.js b/packages/server/src/electron.js index f2770e1d49..9f10384b10 100644 --- a/packages/server/src/electron.js +++ b/packages/server/src/electron.js @@ -8,7 +8,7 @@ const initialiseBudibase = require("./utilities/initialiseBudibase") const { budibaseAppsDir } = require("./utilities/budibaseDir") const { openNewGitHubIssue, debugInfo } = require("electron-util") const eventEmitter = require("./events") -const isMac = process.platform === 'darwin'; +const isMac = process.platform === "darwin" const budibaseDir = budibaseAppsDir() const envFile = join(budibaseDir, ".env") @@ -90,108 +90,109 @@ async function startApp() { const template = [ // { role: 'appMenu' } - ...(isMac ? [{ - label: app.name, - submenu: [ - { role: 'about' }, - { type: 'separator' }, - { role: 'services' }, - { type: 'separator' }, - { role: 'hide' }, - { role: 'hideothers' }, - { role: 'unhide' }, - { type: 'separator' }, - { role: 'quit' } - ] - }] : []), + ...(isMac + ? [ + { + label: app.name, + submenu: [ + { role: "about" }, + { type: "separator" }, + { role: "services" }, + { type: "separator" }, + { role: "hide" }, + { role: "hideothers" }, + { role: "unhide" }, + { type: "separator" }, + { role: "quit" }, + ], + }, + ] + : []), // { role: 'fileMenu' } { - label: 'File', - submenu: [ - isMac ? { role: 'close' } : { role: 'quit' } - ] + label: "File", + submenu: [isMac ? { role: "close" } : { role: "quit" }], }, // { role: 'editMenu' } { - label: 'Edit', + label: "Edit", submenu: [ - { role: 'undo' }, - { role: 'redo' }, - { type: 'separator' }, - { role: 'cut' }, - { role: 'copy' }, - { role: 'paste' }, - ...(isMac ? [ - { role: 'pasteAndMatchStyle' }, - { role: 'delete' }, - { role: 'selectAll' }, - { type: 'separator' }, - { - label: 'Speech', - submenu: [ - { role: 'startSpeaking' }, - { role: 'stopSpeaking' } + { role: "undo" }, + { role: "redo" }, + { type: "separator" }, + { role: "cut" }, + { role: "copy" }, + { role: "paste" }, + ...(isMac + ? [ + { role: "pasteAndMatchStyle" }, + { role: "delete" }, + { role: "selectAll" }, + { type: "separator" }, + { + label: "Speech", + submenu: [{ role: "startSpeaking" }, { role: "stopSpeaking" }], + }, ] - } - ] : [ - { role: 'delete' }, - { type: 'separator' }, - { role: 'selectAll' } - ]) - ] + : [{ role: "delete" }, { type: "separator" }, { role: "selectAll" }]), + ], }, // { role: 'viewMenu' } { - label: 'View', + label: "View", submenu: [ - { role: 'reload' }, - { role: 'forceReload' }, - { role: 'toggleDevTools' }, - { type: 'separator' }, - { role: 'resetZoom' }, - { role: 'zoomIn' }, - { role: 'zoomOut' }, - { type: 'separator' }, - { role: 'togglefullscreen' } - ] + { role: "reload" }, + { role: "forceReload" }, + { role: "toggleDevTools" }, + { type: "separator" }, + { role: "resetZoom" }, + { role: "zoomIn" }, + { role: "zoomOut" }, + { type: "separator" }, + { role: "togglefullscreen" }, + ], }, // { role: 'windowMenu' } { - label: 'Window', + label: "Window", submenu: [ - { role: 'minimize' }, - { role: 'zoom' }, - ...(isMac ? [ - { type: 'separator' }, - { role: 'front' }, - { type: 'separator' }, - { role: 'window' } - ] : [ - { role: 'close' } - ]) - ] + { role: "minimize" }, + { role: "zoom" }, + ...(isMac + ? [ + { type: "separator" }, + { role: "front" }, + { type: "separator" }, + { role: "window" }, + ] + : [{ role: "close" }]), + ], }, { - role: 'help', + role: "help", submenu: [ { - label: 'Learn More', - click: () => shell.openExternal('https://www.budibase.com/') + label: "Learn More", + click: () => shell.openExternal("https://www.budibase.com/"), }, { - label: 'Documentation', - click: () => shell.openExternal('https://docs.budibase.com/') + label: "Documentation", + click: () => shell.openExternal("https://docs.budibase.com/"), }, { - label: 'Search issues', - click: () => shell.openExternal('https://github.com/Budibase/budibase/issues') + label: "Search issues", + click: () => + shell.openExternal("https://github.com/Budibase/budibase/issues"), }, { - label: 'Community discussions', - click: () => shell.openExternal('https://github.com/Budibase/budibase/discussions') + label: "Community discussions", + click: () => + shell.openExternal( + "https://github.com/Budibase/budibase/discussions" + ), }, - ] - } + ], + }, ] const menu = Menu.buildFromTemplate(template) From 69eacab7e19132e4de5c1701e9c51453ee28b7ad Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Wed, 24 Mar 2021 15:30:15 +0000 Subject: [PATCH 004/135] Update release.yml --- .github/workflows/release.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 14c0cc06a3..c8a4fb180d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,6 +1,13 @@ name: Budibase Release on: + workflow_dispatch: + inputs: + name: + description: 'Version' + required: false + default: '0.8' + # Trigger the workflow on push with tags, # but only for the master branch push: From c74205e4c80ac4161d9852ec31c01d34808d7453 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Wed, 24 Mar 2021 18:48:26 +0000 Subject: [PATCH 005/135] v0.8.11 --- lerna.json | 2 +- packages/builder/package.json | 6 +++--- packages/client/package.json | 6 +++--- packages/server/package.json | 8 ++++---- packages/standard-components/package.json | 2 +- packages/string-templates/package.json | 2 +- packages/worker/package.json | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lerna.json b/lerna.json index 3a3a6597b6..2291c7a7a5 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "0.8.10", + "version": "0.8.11", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/builder/package.json b/packages/builder/package.json index 9e5f7a6a27..9dd00acfc9 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "0.8.10", + "version": "0.8.11", "license": "AGPL-3.0", "private": true, "scripts": { @@ -64,9 +64,9 @@ }, "dependencies": { "@budibase/bbui": "^1.58.13", - "@budibase/client": "^0.8.10", + "@budibase/client": "^0.8.11", "@budibase/colorpicker": "1.1.2", - "@budibase/string-templates": "^0.8.10", + "@budibase/string-templates": "^0.8.11", "@budibase/svelte-ag-grid": "^1.0.4", "@sentry/browser": "5.19.1", "@svelteschool/svelte-forms": "0.7.0", diff --git a/packages/client/package.json b/packages/client/package.json index bb7325ff45..f090cbf7f7 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "0.8.10", + "version": "0.8.11", "license": "MPL-2.0", "main": "dist/budibase-client.js", "module": "dist/budibase-client.js", @@ -9,13 +9,13 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/string-templates": "^0.8.10", + "@budibase/string-templates": "^0.8.11", "regexparam": "^1.3.0", "shortid": "^2.2.15", "svelte-spa-router": "^3.0.5" }, "devDependencies": { - "@budibase/standard-components": "^0.8.10", + "@budibase/standard-components": "^0.8.11", "@rollup/plugin-commonjs": "^16.0.0", "@rollup/plugin-node-resolve": "^10.0.0", "fs-extra": "^8.1.0", diff --git a/packages/server/package.json b/packages/server/package.json index db3370b676..b65247d03e 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "0.8.10", + "version": "0.8.11", "description": "Budibase Web Server", "main": "src/electron.js", "repository": { @@ -71,8 +71,8 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/client": "^0.8.10", - "@budibase/string-templates": "^0.8.10", + "@budibase/client": "^0.8.11", + "@budibase/string-templates": "^0.8.11", "@elastic/elasticsearch": "7.10.0", "@koa/router": "8.0.0", "@sendgrid/mail": "7.1.1", @@ -126,7 +126,7 @@ "zlib": "1.0.5" }, "devDependencies": { - "@budibase/standard-components": "^0.8.10", + "@budibase/standard-components": "^0.8.11", "@jest/test-sequencer": "^24.8.0", "cross-env": "^7.0.3", "electron": "10.1.3", diff --git a/packages/standard-components/package.json b/packages/standard-components/package.json index f3243a5776..cd20d7fffc 100644 --- a/packages/standard-components/package.json +++ b/packages/standard-components/package.json @@ -35,7 +35,7 @@ "keywords": [ "svelte" ], - "version": "0.8.10", + "version": "0.8.11", "license": "MIT", "gitHead": "1b95326b20d1352d36305910259228b96a683dc7", "dependencies": { diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 48f0f8d1a8..67f4d3c5dd 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "0.8.10", + "version": "0.8.11", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.js", "module": "src/index.js", diff --git a/packages/worker/package.json b/packages/worker/package.json index e0b7301a2b..1667e27a59 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/deployment", "email": "hi@budibase.com", - "version": "0.8.10", + "version": "0.8.11", "description": "Budibase Deployment Server", "main": "src/index.js", "repository": { From 00d6696b081f3794add41e84b78054f82db74884 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 25 Mar 2021 10:27:48 +0000 Subject: [PATCH 006/135] Update release.yml --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c8a4fb180d..1f2cb80d1d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,8 +59,8 @@ jobs: mac_certs: ${{ secrets.mac_certs }} mac_certs_password: ${{ secrets.mac_certs_password }} - # windows_certs: ${{ secrets.windows_certs }} - # windows_certs_password: ${{ secrets.windows_certs_password }} + windows_certs: ${{ secrets.windows_certs }} + windows_certs_password: ${{ secrets.windows_certs_password }} # release the app after building release: ${{ startsWith(github.ref, 'refs/tags/v') }} From 637d115534e0ea9aac61a668af5421695e801aa6 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 25 Mar 2021 10:40:08 +0000 Subject: [PATCH 007/135] v0.8.12 --- lerna.json | 2 +- packages/builder/package.json | 6 +++--- packages/client/package.json | 6 +++--- packages/server/package.json | 8 ++++---- packages/standard-components/package.json | 2 +- packages/string-templates/package.json | 2 +- packages/worker/package.json | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lerna.json b/lerna.json index 2291c7a7a5..5d71dc2023 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "0.8.11", + "version": "0.8.12", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/builder/package.json b/packages/builder/package.json index 9dd00acfc9..3db29b0603 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "0.8.11", + "version": "0.8.12", "license": "AGPL-3.0", "private": true, "scripts": { @@ -64,9 +64,9 @@ }, "dependencies": { "@budibase/bbui": "^1.58.13", - "@budibase/client": "^0.8.11", + "@budibase/client": "^0.8.12", "@budibase/colorpicker": "1.1.2", - "@budibase/string-templates": "^0.8.11", + "@budibase/string-templates": "^0.8.12", "@budibase/svelte-ag-grid": "^1.0.4", "@sentry/browser": "5.19.1", "@svelteschool/svelte-forms": "0.7.0", diff --git a/packages/client/package.json b/packages/client/package.json index f090cbf7f7..af80ac21f5 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "0.8.11", + "version": "0.8.12", "license": "MPL-2.0", "main": "dist/budibase-client.js", "module": "dist/budibase-client.js", @@ -9,13 +9,13 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/string-templates": "^0.8.11", + "@budibase/string-templates": "^0.8.12", "regexparam": "^1.3.0", "shortid": "^2.2.15", "svelte-spa-router": "^3.0.5" }, "devDependencies": { - "@budibase/standard-components": "^0.8.11", + "@budibase/standard-components": "^0.8.12", "@rollup/plugin-commonjs": "^16.0.0", "@rollup/plugin-node-resolve": "^10.0.0", "fs-extra": "^8.1.0", diff --git a/packages/server/package.json b/packages/server/package.json index b65247d03e..c6a0519118 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "0.8.11", + "version": "0.8.12", "description": "Budibase Web Server", "main": "src/electron.js", "repository": { @@ -71,8 +71,8 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/client": "^0.8.11", - "@budibase/string-templates": "^0.8.11", + "@budibase/client": "^0.8.12", + "@budibase/string-templates": "^0.8.12", "@elastic/elasticsearch": "7.10.0", "@koa/router": "8.0.0", "@sendgrid/mail": "7.1.1", @@ -126,7 +126,7 @@ "zlib": "1.0.5" }, "devDependencies": { - "@budibase/standard-components": "^0.8.11", + "@budibase/standard-components": "^0.8.12", "@jest/test-sequencer": "^24.8.0", "cross-env": "^7.0.3", "electron": "10.1.3", diff --git a/packages/standard-components/package.json b/packages/standard-components/package.json index cd20d7fffc..451db3320c 100644 --- a/packages/standard-components/package.json +++ b/packages/standard-components/package.json @@ -35,7 +35,7 @@ "keywords": [ "svelte" ], - "version": "0.8.11", + "version": "0.8.12", "license": "MIT", "gitHead": "1b95326b20d1352d36305910259228b96a683dc7", "dependencies": { diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 67f4d3c5dd..c5ee74f2d1 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "0.8.11", + "version": "0.8.12", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.js", "module": "src/index.js", diff --git a/packages/worker/package.json b/packages/worker/package.json index 1667e27a59..adc219a228 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/deployment", "email": "hi@budibase.com", - "version": "0.8.11", + "version": "0.8.12", "description": "Budibase Deployment Server", "main": "src/index.js", "repository": { From 3f21a6ba6fd52b3828dee5975f319304fb475d09 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 29 Mar 2021 15:00:40 +0100 Subject: [PATCH 008/135] Starting worker instance as part of the stack, some changes to how environment handled for worker. --- hosting/docker-compose.yaml | 2 +- packages/worker/package.json | 10 +- packages/worker/scripts/dev/manage.js | 42 ++ packages/worker/src/api/controllers/deploy.js | 2 +- packages/worker/src/environment.js | 18 +- packages/worker/src/index.js | 2 +- packages/worker/yarn.lock | 647 +++++++++++++++++- 7 files changed, 710 insertions(+), 13 deletions(-) create mode 100644 packages/worker/scripts/dev/manage.js diff --git a/hosting/docker-compose.yaml b/hosting/docker-compose.yaml index 8de5e9fcdd..7b5a7612a9 100644 --- a/hosting/docker-compose.yaml +++ b/hosting/docker-compose.yaml @@ -37,7 +37,7 @@ services: PORT: 4003 MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY} MINIO_SECRET_KEY: ${MINIO_SECRET_KEY} - RAW_MINIO_URL: http://minio-service:9000 + MINIO_URL: http://minio-service:9000 COUCH_DB_USERNAME: ${COUCH_DB_USER} COUCH_DB_PASSWORD: ${COUCH_DB_PASSWORD} COUCH_DB_URL: http://${COUCH_DB_USER}:${COUCH_DB_PASSWORD}@couchdb-service:5984 diff --git a/packages/worker/package.json b/packages/worker/package.json index 7d88654a88..43deb14a50 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,5 +1,5 @@ { - "name": "@budibase/deployment", + "name": "@budibase/worker", "email": "hi@budibase.com", "version": "0.8.9", "description": "Budibase Deployment Server", @@ -12,13 +12,16 @@ "budibase" ], "scripts": { - "run:docker": "node src/index.js" + "run:docker": "node src/index.js", + "dev:stack:init": "node ./scripts/dev/manage.js init", + "dev:builder": "npm run dev:stack:init && nodemon src/index.js" }, "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { "@koa/router": "^8.0.0", "aws-sdk": "^2.811.0", + "dotenv": "^8.2.0", "got": "^11.8.1", "joi": "^17.2.1", "koa": "^2.7.0", @@ -33,5 +36,8 @@ "pouchdb": "^7.2.2", "pouchdb-all-dbs": "^1.0.2", "server-destroy": "^1.0.1" + }, + "devDependencies": { + "nodemon": "^2.0.7" } } diff --git a/packages/worker/scripts/dev/manage.js b/packages/worker/scripts/dev/manage.js new file mode 100644 index 0000000000..b7e92f6d15 --- /dev/null +++ b/packages/worker/scripts/dev/manage.js @@ -0,0 +1,42 @@ +#!/usr/bin/env node +const path = require("path") +const fs = require("fs") + +async function init() { + const envFilePath = path.join(process.cwd(), ".env") + if (fs.existsSync(envFilePath)) { + return + } + const envFileJson = { + SELF_HOSTED: 1, + PORT: 4002, + MINIO_ACCESS_KEY: "budibase", + MINIO_SECRET_KEY: "budibase", + COUCH_DB_USER: "budibase", + COUCH_DB_PASSWORD: "budibase", + MINIO_URL: "http://localhost:10000/", + COUCH_DB_URL: "http://budibase:budibase@localhost:10000/db/", + } + let envFile = "" + Object.keys(envFileJson).forEach(key => { + envFile += `${key}=${envFileJson[key]}\n` + }) + fs.writeFileSync(envFilePath, envFile) +} + +// if more than init required use this to determine the command type +//const managementCommand = process.argv.slice(2)[0] + +// for now only one command +let command = init + +command() + .then(() => { + console.log("Done! 🎉") + }) + .catch(err => { + console.error( + "Something went wrong while managing budibase dev worker:", + err.message + ) + }) diff --git a/packages/worker/src/api/controllers/deploy.js b/packages/worker/src/api/controllers/deploy.js index 207be71c90..cbaf842083 100644 --- a/packages/worker/src/api/controllers/deploy.js +++ b/packages/worker/src/api/controllers/deploy.js @@ -43,7 +43,7 @@ async function getMinioSession() { // make sure the bucket exists const objClient = new AWS.S3({ - endpoint: env.RAW_MINIO_URL, + endpoint: env.MINIO_URL, region: REGION, s3ForcePathStyle: true, // needed with minio? params: { diff --git a/packages/worker/src/environment.js b/packages/worker/src/environment.js index 0cd7860869..b857dc6098 100644 --- a/packages/worker/src/environment.js +++ b/packages/worker/src/environment.js @@ -1,16 +1,28 @@ +function isDev() { + return process.env.NODE_ENV !== "production" +} + +let LOADED = false +if (!LOADED && isDev()) { + require("dotenv").config() + LOADED = true +} + module.exports = { SELF_HOSTED: process.env.SELF_HOSTED, PORT: process.env.PORT, MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY, MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY, - RAW_MINIO_URL: process.env.RAW_MINIO_URL, - MINIO_PORT: process.env.MINIO_PORT, + MINIO_URL: process.env.MINIO_URL, + COUCH_DB_URL: process.env.COUCH_DB_URL, + LOG_LEVEL: process.env.LOG_LEVEL, + /* TODO: to remove - once deployment removed */ SELF_HOST_KEY: process.env.SELF_HOST_KEY, COUCH_DB_USERNAME: process.env.COUCH_DB_USERNAME, COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD, - COUCH_DB_URL: process.env.COUCH_DB_URL, _set(key, value) { process.env[key] = value module.exports[key] = value }, + isDev, } diff --git a/packages/worker/src/index.js b/packages/worker/src/index.js index 2cc78cce2d..2426b39411 100644 --- a/packages/worker/src/index.js +++ b/packages/worker/src/index.js @@ -32,7 +32,7 @@ destroyable(server) server.on("close", () => console.log("Server Closed")) -module.exports = server.listen(env.PORT || 4002, async () => { +module.exports = server.listen(parseInt(env.PORT || 4002), async () => { console.log(`Worker running on ${JSON.stringify(server.address())}`) }) diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index d88e560173..70bea3b7ea 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -48,11 +48,23 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + "@sindresorhus/is@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4" integrity sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ== +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + "@szmarczak/http-timer@^4.0.5": version "4.0.5" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" @@ -107,6 +119,11 @@ dependencies: "@types/node" "*" +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + abort-controller@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -159,6 +176,23 @@ amdefine@>=0.0.4: resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= +ansi-align@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" + integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== + dependencies: + string-width "^3.0.0" + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -178,6 +212,14 @@ any-promise@^1.1.0: resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + args@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/args/-/args-5.0.1.tgz#4bf298df90a4799a09521362c579278cc2fdd761" @@ -243,6 +285,25 @@ base64-js@^1.0.2, base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +boxen@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" + integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^5.3.1" + chalk "^3.0.0" + cli-boxes "^2.2.0" + string-width "^4.1.0" + term-size "^2.1.0" + type-fest "^0.8.1" + widest-line "^3.1.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -251,6 +312,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + buffer-from@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -291,6 +359,19 @@ cacheable-lookup@^5.0.3: resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + cacheable-request@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" @@ -309,6 +390,11 @@ camelcase@5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + chalk@2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -318,6 +404,14 @@ chalk@2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -326,6 +420,31 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chokidar@^3.2.2: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cli-boxes@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + clone-buffer@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" @@ -409,6 +528,18 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +configstore@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== + dependencies: + dot-prop "^5.2.0" + graceful-fs "^4.1.2" + make-dir "^3.0.0" + unique-string "^2.0.0" + write-file-atomic "^3.0.0" + xdg-basedir "^4.0.0" + content-disposition@~0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" @@ -441,12 +572,24 @@ crc@^3.4.4: dependencies: buffer "^5.1.0" +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + dateformat@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -debug@^3.1.0: +debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.1.0, debug@^3.2.6: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -467,6 +610,13 @@ debug@~3.1.0: dependencies: ms "2.0.0" +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -479,6 +629,16 @@ deep-equal@~1.0.1: resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + defer-to-connect@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" @@ -525,16 +685,43 @@ detective@^4.3.1: acorn "^5.2.1" defined "^1.0.0" +dot-prop@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== + dependencies: + is-obj "^2.0.0" + +dotenv@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + double-ended-queue@2.1.0-0: version "2.1.0-0" resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw= +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + encodeurl@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -589,6 +776,11 @@ es3ify@^0.2.2: jstransform "~11.0.0" through "~2.3.4" +escape-goat@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" + integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== + escape-html@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -673,6 +865,13 @@ fetch-cookie@0.10.1: dependencies: tough-cookie "^2.3.3 || ^3.0.1 || ^4.0.0" +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + flatstr@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" @@ -693,6 +892,18 @@ fresh@~0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -700,6 +911,13 @@ get-stream@^5.1.0: dependencies: pump "^3.0.0" +glob-parent@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + glob@^5.0.15: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" @@ -711,6 +929,13 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d" + integrity sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ== + dependencies: + ini "1.3.7" + got@^11.8.1: version "11.8.1" resolved "https://registry.yarnpkg.com/got/-/got-11.8.1.tgz#df04adfaf2e782babb3daabc79139feec2f7e85d" @@ -728,6 +953,23 @@ got@^11.8.1: p-cancelable "^2.0.0" responselike "^2.0.0" +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + graceful-fs@^4.1.2: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" @@ -743,6 +985,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-yarn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" + integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== + http-assert@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878" @@ -813,6 +1060,11 @@ ieee754@^1.1.13, ieee754@^1.1.4: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= + immediate@3.3.0, immediate@^3.2.3: version "3.3.0" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" @@ -823,6 +1075,16 @@ immediate@~3.0.5: resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + inflation@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f" @@ -846,6 +1108,16 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +ini@1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" + integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + inline-process-browser@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/inline-process-browser/-/inline-process-browser-1.0.0.tgz#46a61b153dd3c9b1624b1a00626edb4f7f414f22" @@ -854,16 +1126,80 @@ inline-process-browser@^1.0.0: falafel "^1.0.1" through2 "^0.6.5" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + is-class-hotfix@~0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/is-class-hotfix/-/is-class-hotfix-0.0.6.tgz#a527d31fb23279281dde5f385c77b5de70a72435" integrity sha512-0n+pzCC6ICtVr/WXnN2f03TK/3BfXY7me4cjCAqT8TYXEl0+JBRoqBo94JJHXcyDSLUeWbNX8Fvy5g5RJdAstQ== +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + is-generator-function@^1.0.7: version "1.0.8" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.8.tgz#dfb5c2b120e02b0a8d9d2c6806cd5621aa922f7b" integrity sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ== +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" + integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== + dependencies: + global-dirs "^2.0.1" + is-path-inside "^3.0.1" + +is-npm@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" + integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-path-inside@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-type-of@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/is-type-of/-/is-type-of-1.2.1.tgz#e263ec3857aceb4f28c47130ec78db09a920f8c5" @@ -873,6 +1209,16 @@ is-type-of@^1.0.0: is-class-hotfix "~0.0.6" isstream "~0.1.2" +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= + +is-yarn-global@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" + integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -909,6 +1255,11 @@ joycon@^2.2.5: resolved "https://registry.yarnpkg.com/joycon/-/joycon-2.2.5.tgz#8d4cf4cbb2544d7b7583c216fcdfec19f6be1615" integrity sha512-YqvUxoOcVPnCp0VU1/56f+iKSdvIRJYPznH22BdXV3xMk75SFXhWeJkZ8C9XxUWt1b5x2X1SxuFygW1U0FmkEQ== +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -941,6 +1292,13 @@ keygrip@~1.1.0: dependencies: tsscmp "1.0.6" +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + keyv@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" @@ -1056,6 +1414,13 @@ koa@^2.7.0: type-is "^1.6.16" vary "^1.1.2" +latest-version@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== + dependencies: + package-json "^6.3.0" + level-codec@9.0.2, level-codec@^9.0.0: version "9.0.2" resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" @@ -1160,6 +1525,11 @@ lie@3.0.4: inline-process-browser "^1.0.0" unreachable-branch-transform "^0.3.0" +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + lowercase-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" @@ -1170,6 +1540,13 @@ ltgt@2.2.1, ltgt@^2.1.2: resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -1197,7 +1574,7 @@ mime-types@^2.1.18, mime-types@~2.1.24: dependencies: mime-db "1.44.0" -mimic-response@^1.0.0: +mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== @@ -1207,14 +1584,14 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -"minimatch@2 || 3": +"minimatch@2 || 3", minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimist@^1.2.5: +minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -1271,6 +1648,34 @@ node-gyp-build@~4.1.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb" integrity sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ== +nodemon@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.7.tgz#6f030a0a0ebe3ea1ba2a38f71bf9bab4841ced32" + integrity sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA== + dependencies: + chokidar "^3.2.2" + debug "^3.2.6" + ignore-by-default "^1.0.1" + minimatch "^3.0.4" + pstree.remy "^1.1.7" + semver "^5.7.1" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.3" + update-notifier "^4.1.0" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + normalize-url@^4.1.0: version "4.5.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" @@ -1305,11 +1710,26 @@ only@~0.0.2: resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + p-cancelable@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== +package-json@^6.3.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== + dependencies: + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" + parseurl@^1.3.2: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -1327,6 +1747,11 @@ path-to-regexp@1.x: dependencies: isarray "0.0.1" +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + pino-http@^5.0.1: version "5.3.0" resolved "https://registry.yarnpkg.com/pino-http/-/pino-http-5.3.0.tgz#8ad9c296a60220b8d7067800a63c8716a622c661" @@ -1414,6 +1839,11 @@ pouchdb@^7.2.2: uuid "8.1.0" vuvuzela "1.0.3" +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + private@^0.1.6, private@~0.1.5: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -1429,6 +1859,11 @@ psl@^1.1.33: resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== +pstree.remy@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -1452,6 +1887,13 @@ punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +pupa@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== + dependencies: + escape-goat "^2.0.0" + q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -1487,6 +1929,16 @@ raw-body@^2.2.0: iconv-lite "0.4.24" unpipe "1.0.0" +rc@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + readable-stream@1.1.14: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -1521,6 +1973,13 @@ readable-stream@~0.0.2: resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-0.0.4.tgz#f32d76e3fb863344a548d79923007173665b3b8d" integrity sha1-8y124/uGM0SlSNeZIwBxc2ZbO40= +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + recast@^0.10.1: version "0.10.43" resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.43.tgz#b95d50f6d60761a5f6252e15d80678168491ce7f" @@ -1541,6 +2000,20 @@ recast@^0.11.17: private "~0.1.5" source-map "~0.5.0" +registry-auth-token@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== + dependencies: + rc "^1.2.8" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" + resolve-alpn@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c" @@ -1554,6 +2027,13 @@ resolve-path@^1.4.0: http-errors "~1.6.2" path-is-absolute "1.0.1" +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + responselike@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" @@ -1586,6 +2066,23 @@ sax@>=0.6.0: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +semver-diff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" + integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== + dependencies: + semver "^6.3.0" + +semver@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + server-destroy@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/server-destroy/-/server-destroy-1.0.1.tgz#f13bf928e42b9c3e79383e61cc3998b5d14e6cdd" @@ -1606,6 +2103,11 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + sonic-boom@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.3.0.tgz#5c77c846ce6c395dddf2eb8e8e65f9cc576f2e76" @@ -1655,6 +2157,24 @@ statuses@^2.0.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.0.tgz#aa7b107e018eb33e08e8aee2e7337e762dda1028" integrity sha512-w9jNUUQdpuVoYqXxnyOakhckBbOxRaoYqJscyIBYCS5ixyCnO7nQn7zBZvP9zf5QOPZcz2DLUpE3KsNPbJBOFA== +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.0.0, string-width@^4.1.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -1667,12 +2187,31 @@ string_decoder@~0.10.x: resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= +strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@^5.3.0: +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -1686,6 +2225,11 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +term-size@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" + integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== + through2@3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4" @@ -1712,11 +2256,30 @@ tiny-queue@^0.2.0: resolved "https://registry.yarnpkg.com/tiny-queue/-/tiny-queue-0.2.1.tgz#25a67f2c6e253b2ca941977b5ef7442ef97a6046" integrity sha1-JaZ/LG4lOyypQZd7XvdELvl6YEY= +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + toidentifier@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + "tough-cookie@^2.3.3 || ^3.0.1 || ^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -1731,6 +2294,11 @@ tsscmp@1.0.6: resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + type-is@^1.6.14, type-is@^1.6.16: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -1739,6 +2307,27 @@ type-is@^1.6.14, type-is@^1.6.16: media-typer "0.3.0" mime-types "~2.1.24" +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +undefsafe@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" + integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== + dependencies: + debug "^2.2.0" + +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -1758,11 +2347,37 @@ unreachable-branch-transform@^0.3.0: recast "^0.10.1" through2 "^0.6.2" +update-notifier@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" + integrity sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A== + dependencies: + boxen "^4.2.0" + chalk "^3.0.0" + configstore "^5.0.1" + has-yarn "^2.1.0" + import-lazy "^2.1.0" + is-ci "^2.0.0" + is-installed-globally "^0.3.1" + is-npm "^4.0.0" + is-yarn-global "^0.3.0" + latest-version "^5.0.0" + pupa "^2.0.1" + semver-diff "^3.1.1" + xdg-basedir "^4.0.0" + urijs@^1.19.2: version "1.19.2" resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.2.tgz#f9be09f00c4c5134b7cb3cf475c1dd394526265a" integrity sha512-s/UIq9ap4JPZ7H1EB5ULo/aOUbWqfDi7FKzMC2Nz+0Si8GiT1rIEaprt8hy3Vy2Ex2aJPpOQv4P4DuOZ+K1c6w== +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + url@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" @@ -1801,11 +2416,28 @@ vuvuzela@1.0.3: resolved "https://registry.yarnpkg.com/vuvuzela/-/vuvuzela-1.0.3.tgz#3be145e58271c73ca55279dd851f12a682114b0b" integrity sha1-O+FF5YJxxzylUnndhR8SpoIRSws= +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + write-stream@~0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/write-stream/-/write-stream-0.4.3.tgz#83cc8c0347d0af6057a93862b4e3ae01de5c81c1" @@ -1813,6 +2445,11 @@ write-stream@~0.4.3: dependencies: readable-stream "~0.0.2" +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + xml2js@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" From 76f330fc3624816312ef9c02a19fbbed444ff8ef Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 29 Mar 2021 15:06:00 +0100 Subject: [PATCH 009/135] Replacing deprecated symbols. --- packages/server/src/api/index.js | 4 ++-- packages/worker/src/api/index.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/server/src/api/index.js b/packages/server/src/api/index.js index aeceb65039..ef8deb36cc 100644 --- a/packages/server/src/api/index.js +++ b/packages/server/src/api/index.js @@ -13,10 +13,10 @@ router compress({ threshold: 2048, gzip: { - flush: zlib.Z_SYNC_FLUSH, + flush: zlib.constants.Z_SYNC_FLUSH, }, deflate: { - flush: zlib.Z_SYNC_FLUSH, + flush: zlib.constants.Z_SYNC_FLUSH, }, br: false, }) diff --git a/packages/worker/src/api/index.js b/packages/worker/src/api/index.js index 8b77669c95..0568d79a68 100644 --- a/packages/worker/src/api/index.js +++ b/packages/worker/src/api/index.js @@ -10,10 +10,10 @@ router compress({ threshold: 2048, gzip: { - flush: zlib.Z_SYNC_FLUSH, + flush: zlib.constants.Z_SYNC_FLUSH, }, deflate: { - flush: zlib.Z_SYNC_FLUSH, + flush: zlib.constants.Z_SYNC_FLUSH, }, br: false, }) From 942312836991554775a1c9843dbd35c54a4c4ab2 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 29 Mar 2021 17:31:41 +0100 Subject: [PATCH 010/135] Updating worker package with the various parts of server that needed moved over. --- packages/worker/package.json | 3 +- .../worker/src/api/controllers/admin/index.js | 79 ++++++++++++++++ .../worker/src/api/controllers/admin/utils.js | 13 +++ packages/worker/src/api/controllers/deploy.js | 92 ------------------- packages/worker/src/api/routes/admin/index.js | 12 +++ packages/worker/src/api/routes/deploy.js | 9 -- packages/worker/src/api/routes/index.js | 4 +- packages/worker/src/constants/index.js | 4 + packages/worker/src/db/utils.js | 32 +++++++ packages/worker/src/environment.js | 2 + packages/worker/src/middleware/authorized.js | 7 ++ packages/worker/yarn.lock | 7 +- 12 files changed, 159 insertions(+), 105 deletions(-) create mode 100644 packages/worker/src/api/controllers/admin/index.js create mode 100644 packages/worker/src/api/controllers/admin/utils.js delete mode 100644 packages/worker/src/api/controllers/deploy.js create mode 100644 packages/worker/src/api/routes/admin/index.js delete mode 100644 packages/worker/src/api/routes/deploy.js create mode 100644 packages/worker/src/constants/index.js create mode 100644 packages/worker/src/db/utils.js create mode 100644 packages/worker/src/middleware/authorized.js diff --git a/packages/worker/package.json b/packages/worker/package.json index 43deb14a50..73b417c580 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -21,6 +21,7 @@ "dependencies": { "@koa/router": "^8.0.0", "aws-sdk": "^2.811.0", + "bcryptjs": "^2.4.3", "dotenv": "^8.2.0", "got": "^11.8.1", "joi": "^17.2.1", @@ -33,7 +34,7 @@ "koa-static": "^5.0.0", "node-fetch": "^2.6.1", "pino-pretty": "^4.0.0", - "pouchdb": "^7.2.2", + "pouchdb": "^7.2.1", "pouchdb-all-dbs": "^1.0.2", "server-destroy": "^1.0.1" }, diff --git a/packages/worker/src/api/controllers/admin/index.js b/packages/worker/src/api/controllers/admin/index.js new file mode 100644 index 0000000000..f94cf39fc4 --- /dev/null +++ b/packages/worker/src/api/controllers/admin/index.js @@ -0,0 +1,79 @@ +const CouchDB = require("../../../db") +const { StaticDatabases, generateUserID, getUserParams } = require("../../../db/utils") +const { hash } = require("./utils") +const { UserStatus } = require("../../../constants") + +const USER_DB = StaticDatabases.USER.name + +exports.userSave = async ctx => { + const db = new CouchDB(USER_DB) + const { email, password, _id } = ctx.request.body + const hashedPassword = password ? await hash(password) : null + let user = { + ...ctx.request.body, + _id: generateUserID(email), + password: hashedPassword, + }, dbUser + // in-case user existed already + if (_id) { + dbUser = await db.get(_id) + } + // add the active status to a user if its not provided + if (user.status == null) { + user.status = UserStatus.ACTIVE + } + try { + const response = await db.post({ + password: hashedPassword || dbUser.password, + ...user, + }) + ctx.body = { + _id: response.id, + _rev: response.rev, + email, + } + } catch (err) { + if (err.status === 409) { + ctx.throw(400, "User exists already") + } else { + ctx.throw(err.status, err) + } + } +} + +exports.userDelete = async ctx => { + const db = new CouchDB(USER_DB) + await db.destroy(generateUserID(ctx.params.email)) + ctx.body = { + message: `User ${ctx.params.email} deleted.`, + } +} + +// called internally by app server user fetch +exports.userFetch = async ctx => { + const db = new CouchDB(USER_DB) + const users = ( + await db.allDocs( + getUserParams(null, { + include_docs: true, + }) + ) + ).rows.map(row => row.doc) + // user hashed password shouldn't ever be returned + for (let user of users) { + if (user) { + delete user.password + } + } + ctx.body = users +} + +// called internally by app server user find +exports.userFind = async ctx => { + const db = new CouchDB(USER_DB) + const user = await db.get(generateUserID(ctx.params.email)) + if (user) { + delete user.password + } + ctx.body = user +} diff --git a/packages/worker/src/api/controllers/admin/utils.js b/packages/worker/src/api/controllers/admin/utils.js new file mode 100644 index 0000000000..4af0a52c46 --- /dev/null +++ b/packages/worker/src/api/controllers/admin/utils.js @@ -0,0 +1,13 @@ +const bcrypt = require("bcryptjs") +const env = require("../environment") + +const SALT_ROUNDS = env.SALT_ROUNDS || 10 + +exports.hash = async data => { + const salt = await bcrypt.genSalt(SALT_ROUNDS) + return bcrypt.hash(data, salt) +} + +exports.compare = async (data, encrypted) => { + return bcrypt.compare(data, encrypted) +} \ No newline at end of file diff --git a/packages/worker/src/api/controllers/deploy.js b/packages/worker/src/api/controllers/deploy.js deleted file mode 100644 index cbaf842083..0000000000 --- a/packages/worker/src/api/controllers/deploy.js +++ /dev/null @@ -1,92 +0,0 @@ -const env = require("../../environment") -const got = require("got") -const AWS = require("aws-sdk") - -const APP_BUCKET = "app-assets" -// this doesn't matter in self host -const REGION = "eu-west-1" -const PUBLIC_READ_POLICY = { - Version: "2012-10-17", - Statement: [ - { - Effect: "Allow", - Principal: { - AWS: ["*"], - }, - Action: "s3:GetObject", - Resource: [`arn:aws:s3:::${APP_BUCKET}/*`], - }, - ], -} - -async function getCouchSession() { - // fetch session token for the api user - const session = await got.post(`${env.COUCH_DB_URL}/_session`, { - responseType: "json", - credentials: "include", - json: { - username: env.COUCH_DB_USERNAME, - password: env.COUCH_DB_PASSWORD, - }, - }) - - const cookie = session.headers["set-cookie"][0] - // Get the session cookie value only - return cookie.split(";")[0] -} - -async function getMinioSession() { - AWS.config.update({ - accessKeyId: env.MINIO_ACCESS_KEY, - secretAccessKey: env.MINIO_SECRET_KEY, - }) - - // make sure the bucket exists - const objClient = new AWS.S3({ - endpoint: env.MINIO_URL, - region: REGION, - s3ForcePathStyle: true, // needed with minio? - params: { - Bucket: APP_BUCKET, - }, - }) - // make sure the bucket exists - try { - await objClient - .headBucket({ - Bucket: APP_BUCKET, - }) - .promise() - } catch (err) { - // bucket doesn't exist create it - if (err.statusCode === 404) { - await objClient - .createBucket({ - Bucket: APP_BUCKET, - }) - .promise() - } else { - throw err - } - } - // always make sure policy is correct - await objClient - .putBucketPolicy({ - Bucket: APP_BUCKET, - Policy: JSON.stringify(PUBLIC_READ_POLICY), - }) - .promise() - // Ideally want to send back some pre-signed URLs for files that are to be uploaded - return { - accessKeyId: env.MINIO_ACCESS_KEY, - secretAccessKey: env.MINIO_SECRET_KEY, - } -} - -exports.deploy = async ctx => { - ctx.body = { - couchDbSession: await getCouchSession(), - bucket: APP_BUCKET, - objectStoreSession: await getMinioSession(), - } -} diff --git a/packages/worker/src/api/routes/admin/index.js b/packages/worker/src/api/routes/admin/index.js new file mode 100644 index 0000000000..9d85927900 --- /dev/null +++ b/packages/worker/src/api/routes/admin/index.js @@ -0,0 +1,12 @@ +const Router = require("@koa/router") +const controller = require("../../controllers/admin") +const authorized = require("../../../middleware/authorized") + +const router = Router() + +router.post("/api/admin/users", authorized, controller.userSave) + .delete("/api/admin/users/:email", authorized, controller.userDelete) + .get("/api/admin/users", authorized, controller.userFetch) + .get("/api/admin/users/:email", authorized, controller.userFind) + +module.exports = router diff --git a/packages/worker/src/api/routes/deploy.js b/packages/worker/src/api/routes/deploy.js deleted file mode 100644 index 97c5439752..0000000000 --- a/packages/worker/src/api/routes/deploy.js +++ /dev/null @@ -1,9 +0,0 @@ -const Router = require("@koa/router") -const controller = require("../controllers/deploy") -const checkKey = require("../../middleware/check-key") - -const router = Router() - -router.post("/api/deploy", checkKey, controller.deploy) - -module.exports = router diff --git a/packages/worker/src/api/routes/index.js b/packages/worker/src/api/routes/index.js index 7ad619c2b7..076710b21b 100644 --- a/packages/worker/src/api/routes/index.js +++ b/packages/worker/src/api/routes/index.js @@ -1,4 +1,4 @@ -const deployRoutes = require("./deploy") +const adminRoutes = require("./admin") const appRoutes = require("./app") -exports.routes = [deployRoutes, appRoutes] +exports.routes = [adminRoutes, appRoutes] diff --git a/packages/worker/src/constants/index.js b/packages/worker/src/constants/index.js new file mode 100644 index 0000000000..77a6aedca0 --- /dev/null +++ b/packages/worker/src/constants/index.js @@ -0,0 +1,4 @@ +exports.UserStatus = { + ACTIVE: "active", + INACTIVE: "inactive", +} diff --git a/packages/worker/src/db/utils.js b/packages/worker/src/db/utils.js new file mode 100644 index 0000000000..aa274eff3b --- /dev/null +++ b/packages/worker/src/db/utils.js @@ -0,0 +1,32 @@ +exports.StaticDatabases = { + USER: { + name: "user-db", + } +} + +const DocumentTypes = { + USER: "us" +} + +const UNICODE_MAX = "\ufff0" +const SEPARATOR = "_" + +/** + * Generates a new user ID based on the passed in email. + * @param {string} email The email which the ID is going to be built up of. + * @returns {string} The new user ID which the user doc can be stored under. + */ +exports.generateUserID = email => { + return `${DocumentTypes.USER}${SEPARATOR}${email}` +} + +/** + * Gets parameters for retrieving users, this is a utility function for the getDocParams function. + */ +exports.getUserParams = (email = "", otherProps = {}) => { + return { + ...otherProps, + startkey: `${DocumentTypes.USER}${SEPARATOR}${email}`, + endkey: `${DocumentTypes.USER}${SEPARATOR}${email}${UNICODE_MAX}`, + } +} \ No newline at end of file diff --git a/packages/worker/src/environment.js b/packages/worker/src/environment.js index b857dc6098..bf399fade5 100644 --- a/packages/worker/src/environment.js +++ b/packages/worker/src/environment.js @@ -16,6 +16,8 @@ module.exports = { MINIO_URL: process.env.MINIO_URL, COUCH_DB_URL: process.env.COUCH_DB_URL, LOG_LEVEL: process.env.LOG_LEVEL, + JWT_SECRET: process.env.JWT_SECRET, + SALT_ROUNDS: process.env.SALT_ROUNDS, /* TODO: to remove - once deployment removed */ SELF_HOST_KEY: process.env.SELF_HOST_KEY, COUCH_DB_USERNAME: process.env.COUCH_DB_USERNAME, diff --git a/packages/worker/src/middleware/authorized.js b/packages/worker/src/middleware/authorized.js new file mode 100644 index 0000000000..86a5ab27db --- /dev/null +++ b/packages/worker/src/middleware/authorized.js @@ -0,0 +1,7 @@ +/** + * Check the user token, used when creating admin resources, like for example + * a global user record. + */ +module.exports = async (ctx, next) => { + next() +} diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index 70bea3b7ea..d969c67ceb 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -285,6 +285,11 @@ base64-js@^1.0.2, base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +bcryptjs@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -1813,7 +1818,7 @@ pouchdb-promise@5.4.3: dependencies: lie "3.0.4" -pouchdb@^7.2.2: +pouchdb@^7.2.1: version "7.2.2" resolved "https://registry.yarnpkg.com/pouchdb/-/pouchdb-7.2.2.tgz#fcae82862db527e4cf7576ed8549d1384961f364" integrity sha512-5gf5nw5XH/2H/DJj8b0YkvG9fhA/4Jt6kL0Y8QjtztVjb1y4J19Rg4rG+fUbXu96gsUrlyIvZ3XfM0b4mogGmw== From ae8dd1ec786f959d8f8b6784f8801a7590017c1c Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 29 Mar 2021 17:32:05 +0100 Subject: [PATCH 011/135] Removing use of the , replacing to ctx.appId to make it clear appId not part of the auth. --- packages/server/src/api/controllers/auth.js | 2 +- .../server/src/api/controllers/automation.js | 40 ++++++++++++------- .../server/src/api/controllers/datasource.js | 8 ++-- .../src/api/controllers/deploy/index.js | 6 +-- packages/server/src/api/controllers/layout.js | 4 +- packages/server/src/api/controllers/query.js | 12 +++--- packages/server/src/api/controllers/role.js | 8 ++-- packages/server/src/api/controllers/row.js | 20 +++++----- packages/server/src/api/controllers/screen.js | 6 +-- .../src/api/controllers/search/index.js | 2 +- .../src/api/controllers/static/index.js | 6 +-- .../server/src/api/controllers/table/index.js | 8 ++-- .../server/src/api/controllers/table/utils.js | 7 ++-- packages/server/src/api/controllers/user.js | 13 +++--- .../server/src/api/controllers/view/index.js | 8 ++-- .../server/src/api/controllers/webhook.js | 8 ++-- .../server/src/api/routes/tests/misc.spec.js | 10 +++-- .../server/src/middleware/authenticated.js | 4 +- packages/server/src/middleware/usageQuota.js | 2 +- packages/server/src/utilities/bcrypt.js | 2 + 20 files changed, 96 insertions(+), 80 deletions(-) diff --git a/packages/server/src/api/controllers/auth.js b/packages/server/src/api/controllers/auth.js index fc486bcb50..fab46bd05e 100644 --- a/packages/server/src/api/controllers/auth.js +++ b/packages/server/src/api/controllers/auth.js @@ -48,7 +48,7 @@ exports.authenticate = async ctx => { // if in prod add the user api key, unless self hosted /* istanbul ignore next */ if (env.isProd() && !env.SELF_HOSTED) { - const { apiKey } = await getAPIKey(ctx.user.appId) + const { apiKey } = await getAPIKey(ctx.appId) payload.apiKey = apiKey } diff --git a/packages/server/src/api/controllers/automation.js b/packages/server/src/api/controllers/automation.js index df17371f92..d3ed836bc9 100644 --- a/packages/server/src/api/controllers/automation.js +++ b/packages/server/src/api/controllers/automation.js @@ -34,13 +34,14 @@ function cleanAutomationInputs(automation) { /** * This function handles checking if any webhooks need to be created or deleted for automations. + * @param {string} appId The ID of the app in which we are checking for webhooks * @param {object} user The user object, including all auth info * @param {object|undefined} oldAuto The old automation object if updating/deleting * @param {object|undefined} newAuto The new automation object if creating/updating * @returns {Promise} After this is complete the new automation object may have been updated and should be * written to DB (this does not write to DB as it would be wasteful to repeat). */ -async function checkForWebhooks({ user, oldAuto, newAuto }) { +async function checkForWebhooks({ appId, user, oldAuto, newAuto }) { const oldTrigger = oldAuto ? oldAuto.definition.trigger : null const newTrigger = newAuto ? newAuto.definition.trigger : null function isWebhookTrigger(auto) { @@ -56,7 +57,7 @@ async function checkForWebhooks({ user, oldAuto, newAuto }) { !isWebhookTrigger(newAuto) && oldTrigger.webhookId ) { - let db = new CouchDB(user.appId) + let db = new CouchDB(appId) // need to get the webhook to get the rev const webhook = await db.get(oldTrigger.webhookId) const ctx = { @@ -86,17 +87,17 @@ async function checkForWebhooks({ user, oldAuto, newAuto }) { const id = ctx.body.webhook._id newTrigger.webhookId = id newTrigger.inputs = { - schemaUrl: `api/webhooks/schema/${user.appId}/${id}`, - triggerUrl: `api/webhooks/trigger/${user.appId}/${id}`, + schemaUrl: `api/webhooks/schema/${appId}/${id}`, + triggerUrl: `api/webhooks/trigger/${appId}/${id}`, } } return newAuto } exports.create = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) let automation = ctx.request.body - automation.appId = ctx.user.appId + automation.appId = ctx.appId // call through to update if already exists if (automation._id && automation._rev) { @@ -107,7 +108,11 @@ exports.create = async function(ctx) { automation.type = "automation" automation = cleanAutomationInputs(automation) - automation = await checkForWebhooks({ user: ctx.user, newAuto: automation }) + automation = await checkForWebhooks({ + appId: ctx.appId, + user: ctx.user, + newAuto: automation, + }) const response = await db.put(automation) automation._rev = response.rev @@ -122,12 +127,13 @@ exports.create = async function(ctx) { } exports.update = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) let automation = ctx.request.body - automation.appId = ctx.user.appId + automation.appId = ctx.appId const oldAutomation = await db.get(automation._id) automation = cleanAutomationInputs(automation) automation = await checkForWebhooks({ + appId: ctx.appId, user: ctx.user, oldAuto: oldAutomation, newAuto: automation, @@ -147,7 +153,7 @@ exports.update = async function(ctx) { } exports.fetch = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const response = await db.allDocs( getAutomationParams(null, { include_docs: true, @@ -157,14 +163,18 @@ exports.fetch = async function(ctx) { } exports.find = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) ctx.body = await db.get(ctx.params.id) } exports.destroy = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const oldAutomation = await db.get(ctx.params.id) - await checkForWebhooks({ user: ctx.user, oldAuto: oldAutomation }) + await checkForWebhooks({ + appId: ctx.appId, + user: ctx.user, + oldAuto: oldAutomation, + }) ctx.body = await db.remove(ctx.params.id, ctx.params.rev) } @@ -195,11 +205,11 @@ module.exports.getDefinitionList = async function(ctx) { *********************/ exports.trigger = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) let automation = await db.get(ctx.params.id) await triggers.externalTrigger(automation, { ...ctx.request.body, - appId: ctx.user.appId, + appId: ctx.appId, }) ctx.status = 200 ctx.body = { diff --git a/packages/server/src/api/controllers/datasource.js b/packages/server/src/api/controllers/datasource.js index 678c56a14c..b5a207dbbe 100644 --- a/packages/server/src/api/controllers/datasource.js +++ b/packages/server/src/api/controllers/datasource.js @@ -6,7 +6,7 @@ const { } = require("../../db/utils") exports.fetch = async function(ctx) { - const database = new CouchDB(ctx.user.appId) + const database = new CouchDB(ctx.appId) ctx.body = ( await database.allDocs( getDatasourceParams(null, { @@ -17,7 +17,7 @@ exports.fetch = async function(ctx) { } exports.save = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const datasource = { _id: generateDatasourceID(), @@ -34,7 +34,7 @@ exports.save = async function(ctx) { } exports.destroy = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) // Delete all queries for the datasource const rows = await db.allDocs(getQueryParams(ctx.params.datasourceId, null)) @@ -48,6 +48,6 @@ exports.destroy = async function(ctx) { } exports.find = async function(ctx) { - const database = new CouchDB(ctx.user.appId) + const database = new CouchDB(ctx.appId) ctx.body = await database.get(ctx.params.datasourceId) } diff --git a/packages/server/src/api/controllers/deploy/index.js b/packages/server/src/api/controllers/deploy/index.js index 026ce5c85b..490fb3c72e 100644 --- a/packages/server/src/api/controllers/deploy/index.js +++ b/packages/server/src/api/controllers/deploy/index.js @@ -93,7 +93,7 @@ async function deployApp(deployment) { exports.fetchDeployments = async function(ctx) { try { - const db = new PouchDB(ctx.user.appId) + const db = new PouchDB(ctx.appId) const deploymentDoc = await db.get("_local/deployments") const { updated, deployments } = await checkAllDeployments( deploymentDoc, @@ -110,7 +110,7 @@ exports.fetchDeployments = async function(ctx) { exports.deploymentProgress = async function(ctx) { try { - const db = new PouchDB(ctx.user.appId) + const db = new PouchDB(ctx.appId) const deploymentDoc = await db.get("_local/deployments") ctx.body = deploymentDoc[ctx.params.deploymentId] } catch (err) { @@ -128,7 +128,7 @@ exports.deployApp = async function(ctx) { hostingInfo.type === HostingTypes.CLOUD ? require("./awsDeploy") : require("./selfDeploy") - let deployment = new Deployment(ctx.user.appId) + let deployment = new Deployment(ctx.appId) deployment.setStatus(DeploymentStatus.PENDING) deployment = await storeLocalDeploymentHistory(deployment) diff --git a/packages/server/src/api/controllers/layout.js b/packages/server/src/api/controllers/layout.js index f270e95bec..86c324d178 100644 --- a/packages/server/src/api/controllers/layout.js +++ b/packages/server/src/api/controllers/layout.js @@ -3,7 +3,7 @@ const CouchDB = require("../../db") const { generateLayoutID, getScreenParams } = require("../../db/utils") exports.save = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) let layout = ctx.request.body if (!layout.props) { @@ -22,7 +22,7 @@ exports.save = async function(ctx) { } exports.destroy = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const layoutId = ctx.params.layoutId, layoutRev = ctx.params.layoutRev diff --git a/packages/server/src/api/controllers/query.js b/packages/server/src/api/controllers/query.js index b9b7c85427..ddf88e925f 100644 --- a/packages/server/src/api/controllers/query.js +++ b/packages/server/src/api/controllers/query.js @@ -28,7 +28,7 @@ function formatResponse(resp) { } exports.fetch = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const body = await db.allDocs( getQueryParams(null, { @@ -39,7 +39,7 @@ exports.fetch = async function(ctx) { } exports.save = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const query = ctx.request.body if (!query._id) { @@ -90,7 +90,7 @@ async function enrichQueryFields(fields, parameters) { } exports.find = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const query = enrichQueries(await db.get(ctx.params.queryId)) // remove properties that could be dangerous in real app if (env.isProd()) { @@ -102,7 +102,7 @@ exports.find = async function(ctx) { } exports.preview = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const datasource = await db.get(ctx.request.body.datasourceId) @@ -130,7 +130,7 @@ exports.preview = async function(ctx) { } exports.execute = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const query = await db.get(ctx.params.queryId) const datasource = await db.get(query.datasourceId) @@ -153,7 +153,7 @@ exports.execute = async function(ctx) { } exports.destroy = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) await db.remove(ctx.params.queryId, ctx.params.revId) ctx.message = `Query deleted.` ctx.status = 200 diff --git a/packages/server/src/api/controllers/role.js b/packages/server/src/api/controllers/role.js index 2c29d1030e..11f81c1219 100644 --- a/packages/server/src/api/controllers/role.js +++ b/packages/server/src/api/controllers/role.js @@ -51,7 +51,7 @@ async function updateRolesOnUserTable(db, roleId, updateOption) { } exports.fetch = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const body = await db.allDocs( getRoleParams(null, { include_docs: true, @@ -79,11 +79,11 @@ exports.fetch = async function(ctx) { } exports.find = async function(ctx) { - ctx.body = await getRole(ctx.user.appId, ctx.params.roleId) + ctx.body = await getRole(ctx.appId, ctx.params.roleId) } exports.save = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) let { _id, name, inherits, permissionId } = ctx.request.body if (!_id) { _id = generateRoleID() @@ -104,7 +104,7 @@ exports.save = async function(ctx) { } exports.destroy = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const roleId = ctx.params.roleId if (isBuiltin(roleId)) { ctx.throw(400, "Cannot delete builtin role.") diff --git a/packages/server/src/api/controllers/row.js b/packages/server/src/api/controllers/row.js index 7540cc1894..fe293e9318 100644 --- a/packages/server/src/api/controllers/row.js +++ b/packages/server/src/api/controllers/row.js @@ -60,7 +60,7 @@ async function findRow(db, appId, tableId, rowId) { } exports.patch = async function(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) let dbRow = await db.get(ctx.params.rowId) let dbTable = await db.get(dbRow.tableId) @@ -121,7 +121,7 @@ exports.patch = async function(ctx) { } exports.save = async function(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) let inputs = ctx.request.body inputs.tableId = ctx.params.tableId @@ -197,7 +197,7 @@ exports.save = async function(ctx) { } exports.fetchView = async function(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const viewName = ctx.params.viewName // if this is a table view being looked for just transfer to that @@ -256,7 +256,7 @@ exports.fetchView = async function(ctx) { } exports.search = async function(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) const { query, @@ -303,7 +303,7 @@ exports.search = async function(ctx) { } exports.fetchTableRows = async function(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) // special case for users, fetch through the user controller @@ -324,7 +324,7 @@ exports.fetchTableRows = async function(ctx) { } exports.find = async function(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) try { const table = await db.get(ctx.params.tableId) @@ -336,7 +336,7 @@ exports.find = async function(ctx) { } exports.destroy = async function(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) const row = await db.get(ctx.params.rowId) if (row.tableId !== ctx.params.tableId) { @@ -358,7 +358,7 @@ exports.destroy = async function(ctx) { exports.validate = async function(ctx) { const errors = await validate({ - appId: ctx.user.appId, + appId: ctx.appId, tableId: ctx.params.tableId, row: ctx.request.body, }) @@ -388,7 +388,7 @@ async function validate({ appId, tableId, row, table }) { } exports.fetchEnrichedRow = async function(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) const tableId = ctx.params.tableId const rowId = ctx.params.rowId @@ -433,7 +433,7 @@ exports.fetchEnrichedRow = async function(ctx) { } async function bulkDelete(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const { rows } = ctx.request.body const db = new CouchDB(appId) diff --git a/packages/server/src/api/controllers/screen.js b/packages/server/src/api/controllers/screen.js index 8f9baa8172..6095d00c95 100644 --- a/packages/server/src/api/controllers/screen.js +++ b/packages/server/src/api/controllers/screen.js @@ -3,7 +3,7 @@ const { getScreenParams, generateScreenID } = require("../../db/utils") const { AccessController } = require("../../utilities/security/roles") exports.fetch = async ctx => { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) const screens = ( @@ -21,7 +21,7 @@ exports.fetch = async ctx => { } exports.save = async ctx => { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) let screen = ctx.request.body @@ -39,7 +39,7 @@ exports.save = async ctx => { } exports.destroy = async ctx => { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) await db.remove(ctx.params.screenId, ctx.params.screenRev) ctx.body = { message: "Screen deleted successfully", diff --git a/packages/server/src/api/controllers/search/index.js b/packages/server/src/api/controllers/search/index.js index 1810f07198..be431b62a7 100644 --- a/packages/server/src/api/controllers/search/index.js +++ b/packages/server/src/api/controllers/search/index.js @@ -2,7 +2,7 @@ const { QueryBuilder, buildSearchUrl, search } = require("./utils") exports.rowSearch = async ctx => { // this can't be done through pouch, have to reach for trusty node-fetch - const appId = ctx.user.appId + const appId = ctx.appId const bookmark = ctx.params.bookmark let url if (ctx.params.query) { diff --git a/packages/server/src/api/controllers/static/index.js b/packages/server/src/api/controllers/static/index.js index 7caf6d0f7f..afb1d908ae 100644 --- a/packages/server/src/api/controllers/static/index.js +++ b/packages/server/src/api/controllers/static/index.js @@ -84,7 +84,7 @@ exports.uploadFile = async function(ctx) { return prepareUpload({ file, - s3Key: `assets/${ctx.user.appId}/attachments/${processedFileName}`, + s3Key: `assets/${ctx.appId}/attachments/${processedFileName}`, bucket: "prod-budi-app-assets", }) }) @@ -120,7 +120,7 @@ exports.serveApp = async function(ctx) { exports.serveAttachment = async function(ctx) { await returnObjectStoreFile( ctx, - join(ctx.user.appId, "attachments", ctx.file) + join(ctx.appId, "attachments", ctx.file) ) } @@ -128,7 +128,7 @@ exports.serveAppAsset = async function(ctx) { if (env.isDev() || env.isTest()) { return send(ctx, ctx.file, { root: budibaseTempDir() }) } - await returnObjectStoreFile(ctx, join(ctx.user.appId, "public", ctx.file)) + await returnObjectStoreFile(ctx, join(ctx.appId, "public", ctx.file)) } exports.serveComponentLibrary = async function(ctx) { diff --git a/packages/server/src/api/controllers/table/index.js b/packages/server/src/api/controllers/table/index.js index 4cb1d16146..995ba8f72c 100644 --- a/packages/server/src/api/controllers/table/index.js +++ b/packages/server/src/api/controllers/table/index.js @@ -10,7 +10,7 @@ const { FieldTypes } = require("../../../constants") const { TableSaveFunctions } = require("./utils") exports.fetch = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const body = await db.allDocs( getTableParams(null, { include_docs: true, @@ -20,12 +20,12 @@ exports.fetch = async function(ctx) { } exports.find = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) ctx.body = await db.get(ctx.params.id) } exports.save = async function(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) const { dataImport, ...rest } = ctx.request.body let tableToSave = { @@ -127,7 +127,7 @@ exports.save = async function(ctx) { } exports.destroy = async function(ctx) { - const appId = ctx.user.appId + const appId = ctx.appId const db = new CouchDB(appId) const tableToDelete = await db.get(ctx.params.tableId) diff --git a/packages/server/src/api/controllers/table/utils.js b/packages/server/src/api/controllers/table/utils.js index 66b3651ccf..0302ca18a3 100644 --- a/packages/server/src/api/controllers/table/utils.js +++ b/packages/server/src/api/controllers/table/utils.js @@ -57,8 +57,8 @@ exports.makeSureTableUpToDate = (table, tableToSave) => { return tableToSave } -exports.handleDataImport = async (user, table, dataImport) => { - const db = new CouchDB(user.appId) +exports.handleDataImport = async (appId, user, table, dataImport) => { + const db = new CouchDB(appId) if (dataImport && dataImport.csvString) { // Populate the table with rows imported from CSV in a bulk update const data = await csvParser.transform(dataImport) @@ -152,7 +152,7 @@ class TableSaveFunctions { this.db = db this.ctx = ctx if (this.ctx && this.ctx.user) { - this.appId = this.ctx.user.appId + this.appId = this.ctx.appId } this.oldTable = oldTable this.dataImport = dataImport @@ -184,6 +184,7 @@ class TableSaveFunctions { async after(table) { table = await exports.handleSearchIndexes(this.appId, table) table = await exports.handleDataImport( + this.appId, this.ctx.user, table, this.dataImport diff --git a/packages/server/src/api/controllers/user.js b/packages/server/src/api/controllers/user.js index 3dd28284be..d9a4af9719 100644 --- a/packages/server/src/api/controllers/user.js +++ b/packages/server/src/api/controllers/user.js @@ -5,7 +5,7 @@ const { getRole } = require("../../utilities/security/roles") const { UserStatus } = require("../../constants") exports.fetch = async function(ctx) { - const database = new CouchDB(ctx.user.appId) + const database = new CouchDB(ctx.appId) const users = ( await database.allDocs( getUserParams(null, { @@ -20,15 +20,16 @@ exports.fetch = async function(ctx) { ctx.body = users } +// TODO: need to replace this with something that purely manages metadata exports.create = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const { email, password, roleId } = ctx.request.body if (!email || !password) { ctx.throw(400, "email and Password Required.") } - const role = await getRole(ctx.user.appId, roleId) + const role = await getRole(ctx.appId, roleId) if (!role) ctx.throw(400, "Invalid Role") @@ -67,7 +68,7 @@ exports.create = async function(ctx) { } exports.update = async function(ctx) { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const user = ctx.request.body let dbUser if (user.email && !user._id) { @@ -94,7 +95,7 @@ exports.update = async function(ctx) { } exports.destroy = async function(ctx) { - const database = new CouchDB(ctx.user.appId) + const database = new CouchDB(ctx.appId) await database.destroy(generateUserID(ctx.params.email)) ctx.body = { message: `User ${ctx.params.email} deleted.`, @@ -103,7 +104,7 @@ exports.destroy = async function(ctx) { } exports.find = async function(ctx) { - const database = new CouchDB(ctx.user.appId) + const database = new CouchDB(ctx.appId) let lookup = ctx.params.email ? generateUserID(ctx.params.email) : ctx.params.userId diff --git a/packages/server/src/api/controllers/view/index.js b/packages/server/src/api/controllers/view/index.js index 0f6f008a1b..3d0f236fce 100644 --- a/packages/server/src/api/controllers/view/index.js +++ b/packages/server/src/api/controllers/view/index.js @@ -7,7 +7,7 @@ const { ViewNames } = require("../../../db/utils") const controller = { fetch: async ctx => { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const designDoc = await db.get("_design/database") const response = [] @@ -25,7 +25,7 @@ const controller = { ctx.body = response }, save: async ctx => { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const { originalName, ...viewToSave } = ctx.request.body const designDoc = await db.get("_design/database") const view = viewTemplate(viewToSave) @@ -66,7 +66,7 @@ const controller = { } }, destroy: async ctx => { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const designDoc = await db.get("_design/database") const viewName = decodeURI(ctx.params.viewName) const view = designDoc.views[viewName] @@ -81,7 +81,7 @@ const controller = { ctx.body = view }, exportView: async ctx => { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const designDoc = await db.get("_design/database") const viewName = decodeURI(ctx.query.view) diff --git a/packages/server/src/api/controllers/webhook.js b/packages/server/src/api/controllers/webhook.js index 5b76f86190..c810f85004 100644 --- a/packages/server/src/api/controllers/webhook.js +++ b/packages/server/src/api/controllers/webhook.js @@ -22,7 +22,7 @@ exports.WebhookType = { } exports.fetch = async ctx => { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const response = await db.allDocs( getWebhookParams(null, { include_docs: true, @@ -32,9 +32,9 @@ exports.fetch = async ctx => { } exports.save = async ctx => { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) const webhook = ctx.request.body - webhook.appId = ctx.user.appId + webhook.appId = ctx.appId // check that the webhook exists if (webhook._id) { @@ -51,7 +51,7 @@ exports.save = async ctx => { } exports.destroy = async ctx => { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) ctx.body = await db.remove(ctx.params.id, ctx.params.rev) } diff --git a/packages/server/src/api/routes/tests/misc.spec.js b/packages/server/src/api/routes/tests/misc.spec.js index 2957e42d90..f9608c0d49 100644 --- a/packages/server/src/api/routes/tests/misc.spec.js +++ b/packages/server/src/api/routes/tests/misc.spec.js @@ -41,10 +41,12 @@ describe("run misc tests", () => { const dataImport = { csvString: "a,b,c,d\n1,2,3,4" } - await tableUtils.handleDataImport({ - appId: config.getAppId(), - userId: "test", - }, table, dataImport) + await tableUtils.handleDataImport( + config.getAppId(), + { userId: "test" }, + table, + dataImport + ) const rows = await config.getRows() expect(rows[0].a).toEqual("1") expect(rows[0].b).toEqual("2") diff --git a/packages/server/src/middleware/authenticated.js b/packages/server/src/middleware/authenticated.js index 32ed3f63d0..d27b88ae96 100644 --- a/packages/server/src/middleware/authenticated.js +++ b/packages/server/src/middleware/authenticated.js @@ -41,7 +41,6 @@ module.exports = async (ctx, next) => { ctx.auth.authenticated = false ctx.appId = appId ctx.user = { - appId, role: builtinRoles.PUBLIC, } await next() @@ -55,9 +54,10 @@ module.exports = async (ctx, next) => { ctx.auth.apiKey = jwtPayload.apiKey ctx.user = { ...jwtPayload, - appId: appId, role: await getRole(appId, jwtPayload.roleId), } + // appId no longer carried in user, make sure + delete ctx.user.appId } catch (err) { console.log(err) if (authType === AuthTypes.BUILDER) { diff --git a/packages/server/src/middleware/usageQuota.js b/packages/server/src/middleware/usageQuota.js index 1bc829fbcf..a37f089a65 100644 --- a/packages/server/src/middleware/usageQuota.js +++ b/packages/server/src/middleware/usageQuota.js @@ -27,7 +27,7 @@ function getProperty(url) { } module.exports = async (ctx, next) => { - const db = new CouchDB(ctx.user.appId) + const db = new CouchDB(ctx.appId) let usage = METHOD_MAP[ctx.req.method] const property = getProperty(ctx.req.url) if (usage == null || property == null) { diff --git a/packages/server/src/utilities/bcrypt.js b/packages/server/src/utilities/bcrypt.js index 58a37c06a9..6c52d2c2c7 100644 --- a/packages/server/src/utilities/bcrypt.js +++ b/packages/server/src/utilities/bcrypt.js @@ -1,3 +1,5 @@ +// TODO: REMOVE + const bcrypt = require("bcryptjs") const env = require("../environment") From 3b82bd7f7acd89d42ac7e406e421f35289e032f3 Mon Sep 17 00:00:00 2001 From: Theo Melo <9499829+theomelo@users.noreply.github.com> Date: Thu, 1 Apr 2021 11:43:47 -0700 Subject: [PATCH 012/135] fix(README): Broken troubeshooting link --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 04bb71fb50..d60cb52f5a 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ GitHub release (latest by date) - Discord + Discord Follow @budibase @@ -58,9 +58,9 @@ ## ✨ Features -When other platforms chose the closed source route, we decided to go open source. When other platforms chose cloud builders, we decided a local builder offered the better developer experience. We like to do things differently at Budibase. +When other platforms chose the closed source route, we decided to go open source. When other platforms chose cloud builders, we decided a local builder offered the better developer experience. We like to do things differently at Budibase. -- **Build and ship real software.** Unlike other platforms, with Budibase you build and ship single page applications. Budibase applications have performance baked in and can be designed responsively, providing your users with a great experience. +- **Build and ship real software.** Unlike other platforms, with Budibase you build and ship single page applications. Budibase applications have performance baked in and can be designed responsively, providing your users with a great experience. - **Open source and extensable.** Budibase is open-source. The builder is licensed AGPL v3, the server is GPL v3, and the client is MPL. This should fill you with confidence that Budibase will always be around. You can also code against Budibase or fork it and make changes as you please, providing a developer-friendly experience. @@ -83,7 +83,7 @@ When other platforms chose the closed source route, we decided to go open source - [x] Public Beta: Anyone can [sign-up and use Budibase](https://portal.budi.live/signup). - [ ] Official Launch -Watch "releases" of this repo to get notified of major updates, and give the star button a click whilst you're there. +Watch "releases" of this repo to get notified of major updates, and give the star button a click whilst you're there.

@@ -93,7 +93,7 @@ Watch "releases" of this repo to get notified of major updates, and give the sta [![Stargazers over time](https://starchart.cc/Budibase/budibase.svg)](https://starchart.cc/Budibase/budibase) -If you are having issues between updates of the builder, please use the guide [here](https://github.com/Budibase/budibase/blob/master/CONTRIBUTING.md#troubleshooting) to clear down your environment. +If you are having issues between updates of the builder, please use the guide [here](https://github.com/Budibase/budibase/blob/next/.github/CONTRIBUTING.md#troubleshooting) to clear down your environment. ## 🏁 Getting Started with Budibase @@ -131,14 +131,14 @@ Checkout our [Public Roadmap](https://github.com/Budibase/budibase/projects/10). ## ❗ Code of Conduct -Budibase is dedicated to providing a welcoming, diverse, and harrassment-free experience for everyone. We expect everyone in the Budibase community to abide by our [**Code of Conduct**](https://github.com/Budibase/budibase/blob/master/.github/CODE_OF_CONDUCT.md). Please read it. +Budibase is dedicated to providing a welcoming, diverse, and harrassment-free experience for everyone. We expect everyone in the Budibase community to abide by our [**Code of Conduct**](https://github.com/Budibase/budibase/blob/master/.github/CODE_OF_CONDUCT.md). Please read it. ## 🙌 Contributing to Budibase From opening a bug report to creating a pull request: every contribution is appreciated and welcomed. If you're planning to implement a new feature or change the API please create an issue first. This way we can ensure your work is not in vain. ### Not Sure Where to Start? -A good place to start contributing, is the [First time issues project](https://github.com/Budibase/budibase/projects/22). +A good place to start contributing, is the [First time issues project](https://github.com/Budibase/budibase/projects/22). ### How the repository is organized Budibase is a monorepo managed by lerna. Lerna manages the building and publishing of the budibase packages. At a high level, here are the packages that make up Budibase. From 1d5c04d865ee66bf01100b11ec4815248cfea38f Mon Sep 17 00:00:00 2001 From: Theo Melo <9499829+theomelo@users.noreply.github.com> Date: Thu, 1 Apr 2021 11:52:23 -0700 Subject: [PATCH 013/135] fix(README) Update places referencing old default branch name --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d60cb52f5a..d3db6144b6 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ Checkout our [Public Roadmap](https://github.com/Budibase/budibase/projects/10). ## ❗ Code of Conduct -Budibase is dedicated to providing a welcoming, diverse, and harrassment-free experience for everyone. We expect everyone in the Budibase community to abide by our [**Code of Conduct**](https://github.com/Budibase/budibase/blob/master/.github/CODE_OF_CONDUCT.md). Please read it. +Budibase is dedicated to providing a welcoming, diverse, and harrassment-free experience for everyone. We expect everyone in the Budibase community to abide by our [**Code of Conduct**](https://github.com/Budibase/budibase/blob/next/.github/CODE_OF_CONDUCT.md). Please read it. ## 🙌 Contributing to Budibase @@ -143,13 +143,13 @@ A good place to start contributing, is the [First time issues project](https://g ### How the repository is organized Budibase is a monorepo managed by lerna. Lerna manages the building and publishing of the budibase packages. At a high level, here are the packages that make up Budibase. -- [packages/builder](https://github.com/Budibase/budibase/tree/master/packages/builder) - contains code for the budibase builder client side svelte application. +- [packages/builder](https://github.com/Budibase/budibase/tree/next/packages/builder) - contains code for the budibase builder client side svelte application. -- [packages/client](https://github.com/Budibase/budibase/tree/master/packages/client) - A module that runs in the browser responsible for reading JSON definition and creating living, breathing web apps from it. +- [packages/client](https://github.com/Budibase/budibase/tree/next/packages/client) - A module that runs in the browser responsible for reading JSON definition and creating living, breathing web apps from it. -- [packages/server](https://github.com/Budibase/budibase/tree/master/packages/server) - The budibase server. This Koa app is responsible for serving the JS for the builder and budibase apps, as well as providing the API for interaction with the database and file system. +- [packages/server](https://github.com/Budibase/budibase/tree/next/packages/server) - The budibase server. This Koa app is responsible for serving the JS for the builder and budibase apps, as well as providing the API for interaction with the database and file system. -For more information, see [CONTRIBUTING.md](https://github.com/Budibase/budibase/blob/master/.github/CONTRIBUTING.md) +For more information, see [CONTRIBUTING.md](https://github.com/Budibase/budibase/blob/next/.github/CONTRIBUTING.md) ## 📝 License From 3f1c18e7dd854b19008a135f990a3da872a997c0 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 1 Apr 2021 20:34:43 +0100 Subject: [PATCH 014/135] basic couchDB authentication using passport --- packages/worker/package.json | 4 + .../worker/src/api/controllers/admin/auth.js | 14 ++ .../worker/src/api/controllers/admin/index.js | 17 +- packages/worker/src/api/routes/admin/auth.js | 8 + packages/worker/src/api/routes/admin/index.js | 5 +- packages/worker/src/db/utils.js | 6 +- packages/worker/src/index.js | 6 + packages/worker/src/middleware/auth/google.js | 13 ++ packages/worker/src/middleware/auth/index.js | 20 ++ packages/worker/src/middleware/auth/jwt.js | 38 ++++ packages/worker/src/middleware/auth/local.js | 58 ++++++ .../src/{api/controllers/admin => }/utils.js | 4 +- packages/worker/yarn.lock | 186 +++++++++++++++++- 13 files changed, 365 insertions(+), 14 deletions(-) create mode 100644 packages/worker/src/api/controllers/admin/auth.js create mode 100644 packages/worker/src/api/routes/admin/auth.js create mode 100644 packages/worker/src/middleware/auth/google.js create mode 100644 packages/worker/src/middleware/auth/index.js create mode 100644 packages/worker/src/middleware/auth/jwt.js create mode 100644 packages/worker/src/middleware/auth/local.js rename packages/worker/src/{api/controllers/admin => }/utils.js (87%) diff --git a/packages/worker/package.json b/packages/worker/package.json index 73b417c580..8f9e301399 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -28,11 +28,15 @@ "koa": "^2.7.0", "koa-body": "^4.2.0", "koa-compress": "^4.0.1", + "koa-passport": "^4.1.4", "koa-pino-logger": "^3.0.0", "koa-send": "^5.0.0", "koa-session": "^5.12.0", "koa-static": "^5.0.0", "node-fetch": "^2.6.1", + "passport-google-oauth": "^2.0.0", + "passport-jwt": "^4.0.0", + "passport-local": "^1.0.0", "pino-pretty": "^4.0.0", "pouchdb": "^7.2.1", "pouchdb-all-dbs": "^1.0.2", diff --git a/packages/worker/src/api/controllers/admin/auth.js b/packages/worker/src/api/controllers/admin/auth.js new file mode 100644 index 0000000000..f6b25091ac --- /dev/null +++ b/packages/worker/src/api/controllers/admin/auth.js @@ -0,0 +1,14 @@ +const jwt = require("jsonwebtoken") +const CouchDB = require("../../../db") +const passport = require("koa-passport") + +exports.authenticate = async (ctx, next) => { + return passport.authenticate("local", (err, user, info, status) => { + ctx.body = { + err, + user, + info, + status, + } + })(ctx, next) +} diff --git a/packages/worker/src/api/controllers/admin/index.js b/packages/worker/src/api/controllers/admin/index.js index f94cf39fc4..b6531174bd 100644 --- a/packages/worker/src/api/controllers/admin/index.js +++ b/packages/worker/src/api/controllers/admin/index.js @@ -1,6 +1,10 @@ const CouchDB = require("../../../db") -const { StaticDatabases, generateUserID, getUserParams } = require("../../../db/utils") -const { hash } = require("./utils") +const { + StaticDatabases, + generateUserID, + getUserParams, +} = require("../../../db/utils") +const { hash } = require("../../../utils") const { UserStatus } = require("../../../constants") const USER_DB = StaticDatabases.USER.name @@ -10,10 +14,11 @@ exports.userSave = async ctx => { const { email, password, _id } = ctx.request.body const hashedPassword = password ? await hash(password) : null let user = { - ...ctx.request.body, - _id: generateUserID(email), - password: hashedPassword, - }, dbUser + ...ctx.request.body, + _id: generateUserID(email), + password: hashedPassword, + }, + dbUser // in-case user existed already if (_id) { dbUser = await db.get(_id) diff --git a/packages/worker/src/api/routes/admin/auth.js b/packages/worker/src/api/routes/admin/auth.js new file mode 100644 index 0000000000..ca41e9e19e --- /dev/null +++ b/packages/worker/src/api/routes/admin/auth.js @@ -0,0 +1,8 @@ +// const Router = require("@koa/router") +// const controller = require("../controllers/auth") + +// const router = Router() + +// router.post("/api/authenticate", controller.authenticate) + +// module.exports = router diff --git a/packages/worker/src/api/routes/admin/index.js b/packages/worker/src/api/routes/admin/index.js index 9d85927900..cf3a5c021a 100644 --- a/packages/worker/src/api/routes/admin/index.js +++ b/packages/worker/src/api/routes/admin/index.js @@ -1,10 +1,13 @@ const Router = require("@koa/router") const controller = require("../../controllers/admin") +const authController = require("../../controllers/admin/auth") const authorized = require("../../../middleware/authorized") const router = Router() -router.post("/api/admin/users", authorized, controller.userSave) +router + .post("/api/admin/users", authorized, controller.userSave) + .post("/api/admin/authenticate", authController.authenticate) .delete("/api/admin/users/:email", authorized, controller.userDelete) .get("/api/admin/users", authorized, controller.userFetch) .get("/api/admin/users/:email", authorized, controller.userFind) diff --git a/packages/worker/src/db/utils.js b/packages/worker/src/db/utils.js index aa274eff3b..cda7708825 100644 --- a/packages/worker/src/db/utils.js +++ b/packages/worker/src/db/utils.js @@ -1,11 +1,11 @@ exports.StaticDatabases = { USER: { name: "user-db", - } + }, } const DocumentTypes = { - USER: "us" + USER: "us", } const UNICODE_MAX = "\ufff0" @@ -29,4 +29,4 @@ exports.getUserParams = (email = "", otherProps = {}) => { startkey: `${DocumentTypes.USER}${SEPARATOR}${email}`, endkey: `${DocumentTypes.USER}${SEPARATOR}${email}${UNICODE_MAX}`, } -} \ No newline at end of file +} diff --git a/packages/worker/src/index.js b/packages/worker/src/index.js index 2426b39411..199bb1d31b 100644 --- a/packages/worker/src/index.js +++ b/packages/worker/src/index.js @@ -1,6 +1,7 @@ const Koa = require("koa") const destroyable = require("server-destroy") const koaBody = require("koa-body") +const passport = require("koa-passport") const logger = require("koa-pino-logger") const http = require("http") const api = require("./api") @@ -24,6 +25,11 @@ app.use( }) ) +// authentication +require("./middleware/auth") +app.use(passport.initialize()) +app.use(passport.session()) + // api routes app.use(api.routes()) diff --git a/packages/worker/src/middleware/auth/google.js b/packages/worker/src/middleware/auth/google.js new file mode 100644 index 0000000000..fd33bc89a3 --- /dev/null +++ b/packages/worker/src/middleware/auth/google.js @@ -0,0 +1,13 @@ +// const GoogleStrategy = require("passport-google-auth").Strategy + +exports.options = { + clientId: "your-client-id", + clientSecret: "your-secret", + callbackURL: + "http://localhost:" + (process.env.PORT || 3000) + "/auth/google/callback", +} + +exports.authenticate = async function(token, tokenSecret, profile, done) { + // retrieve user ... + // fetchUser().then(user => done(null, user)) +} diff --git a/packages/worker/src/middleware/auth/index.js b/packages/worker/src/middleware/auth/index.js new file mode 100644 index 0000000000..3eac2badbf --- /dev/null +++ b/packages/worker/src/middleware/auth/index.js @@ -0,0 +1,20 @@ +const passport = require("koa-passport") +const LocalStrategy = require("passport-local").Strategy +const JwtStrategy = require("passport-jwt").Strategy +const GoogleStrategy = require("passport-google-oauth").Strategy +const jwt = require("./jwt") +const local = require("./local") +const google = require("./google") + +// Strategies +passport.use(new LocalStrategy(local.options, local.authenticate)) +passport.use(new JwtStrategy(jwt.options, jwt.authenticate)) +// passport.use(new GoogleStrategy(google.options, google.authenticate)) + +// exports.middleware = async (ctx, next) => { +// if (ctx.isAuthenticated()) { +// return next() +// } else { +// ctx.throw(403, "Not Authenticated") +// } +// } diff --git a/packages/worker/src/middleware/auth/jwt.js b/packages/worker/src/middleware/auth/jwt.js new file mode 100644 index 0000000000..8313d5abca --- /dev/null +++ b/packages/worker/src/middleware/auth/jwt.js @@ -0,0 +1,38 @@ +const jwt = require("passport-jwt") +const env = require("../../environment") +const { getCookieName } = require("../../../../server/src/utilities") + +const ExtractJWT = jwt.ExtractJwt + +exports.options = { + jwtFromRequest: function(ctx) { + return ctx.cookies.get("budibase") + }, + // TODO: fix + secretOrKey: env.JWT_SECRET || "funky", +} + +exports.authenticate = async function(jwt, done) { + console.log(jwt) + done({ name: "joe" }) + // const appId = ctx.appId + // if (!appId) ctx.throw(400, "No appId") + + // const { email, password } = ctx.request.body + + // if (!email) ctx.throw(400, "Email Required.") + // if (!password) ctx.throw(400, "Password Required.") + + // // Check the user exists in the instance DB by email + // const db = new CouchDB(appId) + // const app = await db.get(appId) + + // let dbUser + // try { + // dbUser = await db.get(generateUserID(email)) + // } catch (_) { + // // do not want to throw a 404 - as this could be + // // used to determine valid emails + // ctx.throw(401, INVALID_ERR) + // } +} diff --git a/packages/worker/src/middleware/auth/local.js b/packages/worker/src/middleware/auth/local.js new file mode 100644 index 0000000000..413ab1c8fb --- /dev/null +++ b/packages/worker/src/middleware/auth/local.js @@ -0,0 +1,58 @@ +const jwt = require("jsonwebtoken") +const { UserStatus } = require("../../constants") +const CouchDB = require("../../db") +const { StaticDatabases, generateUserID } = require("../../db/utils") +const { compare } = require("../../utils") +const env = require("../../environment") + +const INVALID_ERR = "Invalid Credentials" + +exports.options = {} + +/** + * Passport Local Authentication Middleware. + * @param {*} username - username to login with + * @param {*} password - plain text password to log in with + * @param {*} done - callback from passport to return user information and errors + * @returns The authenticated user, or errors if they occur + */ +exports.authenticate = async function(username, password, done) { + if (!username) return done(null, false, "Email Required.") + if (!password) return done(null, false, "Password Required.") + + // Check the user exists in the instance DB by email + const db = new CouchDB(StaticDatabases.USER.name) + + let dbUser + try { + dbUser = await db.get(generateUserID(username)) + } catch { + console.error("User not found") + return done(null, false, { message: "User not found" }) + } + + // check that the user is currently inactive, if this is the case throw invalid + if (dbUser.status === UserStatus.INACTIVE) { + return done(null, false, { message: INVALID_ERR }) + } + + // authenticate + if (await compare(password, dbUser.password)) { + const payload = { + userId: dbUser._id, + } + + const token = jwt.sign(payload, env.JWT_SECRET, { + expiresIn: "1 day", + }) + + // TODO: remove and use cookie + dbUser.token = token + // setCookie(ctx, token, appId) + + delete dbUser.password + return done(null, dbUser) + } else { + done(new Error(INVALID_ERR), false) + } +} diff --git a/packages/worker/src/api/controllers/admin/utils.js b/packages/worker/src/utils.js similarity index 87% rename from packages/worker/src/api/controllers/admin/utils.js rename to packages/worker/src/utils.js index 4af0a52c46..0711ae67bf 100644 --- a/packages/worker/src/api/controllers/admin/utils.js +++ b/packages/worker/src/utils.js @@ -1,5 +1,5 @@ const bcrypt = require("bcryptjs") -const env = require("../environment") +const env = require("./environment") const SALT_ROUNDS = env.SALT_ROUNDS || 10 @@ -10,4 +10,4 @@ exports.hash = async data => { exports.compare = async (data, encrypted) => { return bcrypt.compare(data, encrypted) -} \ No newline at end of file +} diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index d969c67ceb..df8965f515 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -285,6 +285,11 @@ base64-js@^1.0.2, base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +base64url@3.x.x: + version "3.0.1" + resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" + integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== + bcryptjs@^2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" @@ -324,6 +329,11 @@ braces@~3.0.2: dependencies: fill-range "^7.0.1" +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= + buffer-from@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -712,6 +722,13 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= +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" @@ -1270,6 +1287,22 @@ json-buffer@3.0.1: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== +jsonwebtoken@^8.2.0: + 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" + jstransform@~11.0.0: version "11.0.3" resolved "https://registry.yarnpkg.com/jstransform/-/jstransform-11.0.3.tgz#09a78993e0ae4d4ef4487f6155a91f6190cb4223" @@ -1290,6 +1323,23 @@ jstransform@~3.0.0: esprima-fb "~3001.1.0-dev-harmony-fb" source-map "0.1.31" +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" + keygrip@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" @@ -1356,6 +1406,13 @@ koa-is-json@^1.0.0: resolved "https://registry.yarnpkg.com/koa-is-json/-/koa-is-json-1.0.0.tgz#273c07edcdcb8df6a2c1ab7d59ee76491451ec14" integrity sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ= +koa-passport@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/koa-passport/-/koa-passport-4.1.4.tgz#5f1665c1c2a37ace79af9f970b770885ca30ccfa" + integrity sha512-dJBCkl4X+zdYxbI2V2OtoGy0PUenpvp2ZLLWObc8UJhsId0iQpTFT8RVcuA0709AL2txGwRHnSPoT1bYNGa6Kg== + dependencies: + passport "^0.4.0" + koa-pino-logger@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/koa-pino-logger/-/koa-pino-logger-3.0.0.tgz#27600b4f3639e8767dfc6b66493109c5457f53ba" @@ -1530,6 +1587,41 @@ lie@3.0.4: inline-process-browser "^1.0.0" unreachable-branch-transform "^0.3.0" +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= + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -1686,6 +1778,11 @@ normalize-url@^4.1.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== +oauth@0.9.x: + version "0.9.15" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" + integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE= + object-assign@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa" @@ -1740,6 +1837,76 @@ parseurl@^1.3.2: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +passport-google-oauth1@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-google-oauth1/-/passport-google-oauth1-1.0.0.tgz#af74a803df51ec646f66a44d82282be6f108e0cc" + integrity sha1-r3SoA99R7GRvZqRNgigr5vEI4Mw= + dependencies: + passport-oauth1 "1.x.x" + +passport-google-oauth20@2.x.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz#0d241b2d21ebd3dc7f2b60669ec4d587e3a674ef" + integrity sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ== + dependencies: + passport-oauth2 "1.x.x" + +passport-google-oauth@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/passport-google-oauth/-/passport-google-oauth-2.0.0.tgz#f6eb4bc96dd6c16ec0ecfdf4e05ec48ca54d4dae" + integrity sha512-JKxZpBx6wBQXX1/a1s7VmdBgwOugohH+IxCy84aPTZNq/iIPX6u7Mqov1zY7MKRz3niFPol0KJz8zPLBoHKtYA== + dependencies: + passport-google-oauth1 "1.x.x" + passport-google-oauth20 "2.x.x" + +passport-jwt@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" + integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== + dependencies: + jsonwebtoken "^8.2.0" + passport-strategy "^1.0.0" + +passport-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-local/-/passport-local-1.0.0.tgz#1fe63268c92e75606626437e3b906662c15ba6ee" + integrity sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4= + dependencies: + passport-strategy "1.x.x" + +passport-oauth1@1.x.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/passport-oauth1/-/passport-oauth1-1.1.0.tgz#a7de988a211f9cf4687377130ea74df32730c918" + integrity sha1-p96YiiEfnPRoc3cTDqdN8ycwyRg= + dependencies: + oauth "0.9.x" + passport-strategy "1.x.x" + utils-merge "1.x.x" + +passport-oauth2@1.x.x: + version "1.5.0" + resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.5.0.tgz#64babbb54ac46a4dcab35e7f266ed5294e3c4108" + integrity sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ== + dependencies: + base64url "3.x.x" + oauth "0.9.x" + passport-strategy "1.x.x" + uid2 "0.0.x" + utils-merge "1.x.x" + +passport-strategy@1.x.x, passport-strategy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= + +passport@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" + integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg== + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + path-is-absolute@1.0.1, path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -1752,6 +1919,11 @@ path-to-regexp@1.x: dependencies: isarray "0.0.1" +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= + picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -2051,7 +2223,7 @@ safe-buffer@5.1.2: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -2078,7 +2250,7 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -semver@^5.7.1: +semver@^5.6.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -2319,6 +2491,11 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +uid2@0.0.x: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I= + undefsafe@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" @@ -2396,6 +2573,11 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +utils-merge@1.x.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + uuid@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" From a4b1f2390ead8ad2361cfc65a2ce60f4d57f1429 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 6 Apr 2021 18:08:07 +0100 Subject: [PATCH 015/135] Formatting. --- packages/server/src/api/controllers/static/index.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/server/src/api/controllers/static/index.js b/packages/server/src/api/controllers/static/index.js index afb1d908ae..e05327d9f1 100644 --- a/packages/server/src/api/controllers/static/index.js +++ b/packages/server/src/api/controllers/static/index.js @@ -118,10 +118,7 @@ exports.serveApp = async function(ctx) { } exports.serveAttachment = async function(ctx) { - await returnObjectStoreFile( - ctx, - join(ctx.appId, "attachments", ctx.file) - ) + await returnObjectStoreFile(ctx, join(ctx.appId, "attachments", ctx.file)) } exports.serveAppAsset = async function(ctx) { From cf073a1e55e869e94f852070f652566136a099bb Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Wed, 7 Apr 2021 11:33:16 +0100 Subject: [PATCH 016/135] groundwork for budibase auth lib --- packages/auth/.gitignore | 117 ++ packages/auth/README.md | 1 + packages/auth/package.json | 18 + packages/auth/src/constants.js | 9 + packages/auth/src/db/index.js | 11 + packages/auth/src/db/utils.js | 32 + packages/auth/src/hashing.js | 12 + packages/auth/src/index.js | 31 + packages/auth/src/middleware/authenticated.js | 73 ++ packages/auth/src/middleware/google.js | 13 + packages/auth/src/middleware/index.js | 9 + packages/auth/src/middleware/jwt.js | 19 + .../auth => auth/src/middleware}/local.js | 22 +- packages/auth/yarn.lock | 950 ++++++++++++++ packages/server/package.json | 1 - packages/server/yarn.lock | 1116 +---------------- packages/worker/package.json | 1 + .../worker/src/api/controllers/admin/auth.js | 10 +- packages/worker/src/api/routes/admin/auth.js | 8 - packages/worker/src/api/routes/admin/index.js | 11 +- packages/worker/src/index.js | 3 +- packages/worker/src/middleware/auth/google.js | 13 - packages/worker/src/middleware/auth/index.js | 20 - packages/worker/src/middleware/auth/jwt.js | 38 - packages/worker/src/middleware/authorized.js | 2 +- 25 files changed, 1330 insertions(+), 1210 deletions(-) create mode 100644 packages/auth/.gitignore create mode 100644 packages/auth/README.md create mode 100644 packages/auth/package.json create mode 100644 packages/auth/src/constants.js create mode 100644 packages/auth/src/db/index.js create mode 100644 packages/auth/src/db/utils.js create mode 100644 packages/auth/src/hashing.js create mode 100644 packages/auth/src/index.js create mode 100644 packages/auth/src/middleware/authenticated.js create mode 100644 packages/auth/src/middleware/google.js create mode 100644 packages/auth/src/middleware/index.js create mode 100644 packages/auth/src/middleware/jwt.js rename packages/{worker/src/middleware/auth => auth/src/middleware}/local.js (74%) create mode 100644 packages/auth/yarn.lock delete mode 100644 packages/worker/src/api/routes/admin/auth.js delete mode 100644 packages/worker/src/middleware/auth/google.js delete mode 100644 packages/worker/src/middleware/auth/index.js delete mode 100644 packages/worker/src/middleware/auth/jwt.js diff --git a/packages/auth/.gitignore b/packages/auth/.gitignore new file mode 100644 index 0000000000..2528ad91a4 --- /dev/null +++ b/packages/auth/.gitignore @@ -0,0 +1,117 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + diff --git a/packages/auth/README.md b/packages/auth/README.md new file mode 100644 index 0000000000..bbe704026a --- /dev/null +++ b/packages/auth/README.md @@ -0,0 +1 @@ +# Budibase Authentication Library \ No newline at end of file diff --git a/packages/auth/package.json b/packages/auth/package.json new file mode 100644 index 0000000000..ff59eeb7ba --- /dev/null +++ b/packages/auth/package.json @@ -0,0 +1,18 @@ +{ + "name": "@budibase/auth", + "version": "0.0.1", + "description": "Authentication middlewares for budibase builder and apps", + "main": "src/index.js", + "author": "Budibase", + "license": "AGPL-3.0", + "dependencies": { + "bcryptjs": "^2.4.3", + "jsonwebtoken": "^8.5.1", + "koa-passport": "^4.1.4", + "passport-google-auth": "^1.0.2", + "passport-google-oauth": "^2.0.0", + "passport-jwt": "^4.0.0", + "passport-local": "^1.0.0", + "pouchdb": "^7.2.2" + } +} diff --git a/packages/auth/src/constants.js b/packages/auth/src/constants.js new file mode 100644 index 0000000000..b6946a543b --- /dev/null +++ b/packages/auth/src/constants.js @@ -0,0 +1,9 @@ +exports.UserStatus = { + ACTIVE: "active", + INACTIVE: "inactive", +} + +exports.Cookies = { + CurrentApp: "budibase:currentapp", + Auth: "budibase:auth", +} diff --git a/packages/auth/src/db/index.js b/packages/auth/src/db/index.js new file mode 100644 index 0000000000..4db890f01e --- /dev/null +++ b/packages/auth/src/db/index.js @@ -0,0 +1,11 @@ +const PouchDB = require("pouchdb") + +// level option is purely for testing (development) +const COUCH_DB_URL = + process.env.COUCH_DB_URL || "http://budibase:budibase@localhost:10000/db/" + +const Pouch = PouchDB.defaults({ + prefix: COUCH_DB_URL, +}) + +module.exports = Pouch diff --git a/packages/auth/src/db/utils.js b/packages/auth/src/db/utils.js new file mode 100644 index 0000000000..cda7708825 --- /dev/null +++ b/packages/auth/src/db/utils.js @@ -0,0 +1,32 @@ +exports.StaticDatabases = { + USER: { + name: "user-db", + }, +} + +const DocumentTypes = { + USER: "us", +} + +const UNICODE_MAX = "\ufff0" +const SEPARATOR = "_" + +/** + * Generates a new user ID based on the passed in email. + * @param {string} email The email which the ID is going to be built up of. + * @returns {string} The new user ID which the user doc can be stored under. + */ +exports.generateUserID = email => { + return `${DocumentTypes.USER}${SEPARATOR}${email}` +} + +/** + * Gets parameters for retrieving users, this is a utility function for the getDocParams function. + */ +exports.getUserParams = (email = "", otherProps = {}) => { + return { + ...otherProps, + startkey: `${DocumentTypes.USER}${SEPARATOR}${email}`, + endkey: `${DocumentTypes.USER}${SEPARATOR}${email}${UNICODE_MAX}`, + } +} diff --git a/packages/auth/src/hashing.js b/packages/auth/src/hashing.js new file mode 100644 index 0000000000..8c81e39d95 --- /dev/null +++ b/packages/auth/src/hashing.js @@ -0,0 +1,12 @@ +const bcrypt = require("bcryptjs") + +const SALT_ROUNDS = process.env.SALT_ROUNDS || 10 + +exports.hash = async data => { + const salt = await bcrypt.genSalt(SALT_ROUNDS) + return bcrypt.hash(data, salt) +} + +exports.compare = async (data, encrypted) => { + return bcrypt.compare(data, encrypted) +} diff --git a/packages/auth/src/index.js b/packages/auth/src/index.js new file mode 100644 index 0000000000..778d4fb32e --- /dev/null +++ b/packages/auth/src/index.js @@ -0,0 +1,31 @@ +const passport = require("koa-passport") +const LocalStrategy = require("passport-local").Strategy +const JwtStrategy = require("passport-jwt").Strategy +// const GoogleStrategy = require("passport-google-oauth").Strategy +const CouchDB = require("./db") +const { StaticDatabases } = require("./db/utils") +const { jwt, local, google } = require("./middleware") +const hashing = require("./hashing") + +// Strategies +passport.use(new LocalStrategy(local.options, local.authenticate)) +passport.use(new JwtStrategy(jwt.options, jwt.authenticate)) +// passport.use(new GoogleStrategy(google.options, google.authenticate)) + +passport.serializeUser((user, done) => done(null, user)) + +passport.deserializeUser(async (user, done) => { + const db = new CouchDB(StaticDatabases.USER.name) + + try { + const user = await db.get(user._id) + return done(null, user) + } catch (err) { + console.error("User not found", err) + return done(null, false, { message: "User not found" }) + } +}) + +// exports.hashing = hashing + +module.exports = passport diff --git a/packages/auth/src/middleware/authenticated.js b/packages/auth/src/middleware/authenticated.js new file mode 100644 index 0000000000..f7ff086b67 --- /dev/null +++ b/packages/auth/src/middleware/authenticated.js @@ -0,0 +1,73 @@ +const jwt = require("jsonwebtoken") +const STATUS_CODES = require("../utilities/statusCodes") +const { getRole, getBuiltinRoles } = require("../utilities/security/roles") +const { AuthTypes, Cookies } = require("../constants") +const { + getAppId, + getCookieName, + clearCookie, + setCookie, + isClient, +} = require("../utilities") + +module.exports = async (ctx, next) => { + // if (ctx.path === "/_builder") { + // await next() + // return + // } + + // do everything we can to make sure the appId is held correctly + // we hold it in state as a + let appId = getAppId(ctx) + const cookieAppId = ctx.cookies.get(Cookies.CurrentApp) + // const builtinRoles = getBuiltinRoles() + if (appId && cookieAppId !== appId) { + setCookie(ctx, appId, "currentapp") + } else if (cookieAppId) { + appId = cookieAppId + } + let token, authType + // if (!isClient(ctx)) { + // token = ctx.cookies.get(getCookieName()) + // authType = AuthTypes.BUILDER + // } + + if (!token && appId) { + token = ctx.cookies.get(getCookieName(appId)) + // authType = AuthTypes.APP + } + + // if (!token) { + // ctx.auth.authenticated = false + // ctx.appId = appId + // ctx.user = { + // role: builtinRoles.PUBLIC, + // } + // await next() + // return + // } + + try { + // ctx.auth.authenticated = authType + const jwtPayload = jwt.verify(token, ctx.config.jwtSecret) + ctx.appId = appId + // ctx.auth.apiKey = jwtPayload.apiKey + ctx.user = { + ...jwtPayload, + role: await getRole(appId, jwtPayload.roleId), + } + // appId no longer carried in user, make sure + delete ctx.user.appId + } catch (err) { + console.log(err) + // if (authType === AuthTypes.BUILDER) { + // clearCookie(ctx) + // ctx.status = 200 + // return + // } else { + ctx.throw(err.status || STATUS_CODES.FORBIDDEN, err.text) + // } + } + + await next() +} diff --git a/packages/auth/src/middleware/google.js b/packages/auth/src/middleware/google.js new file mode 100644 index 0000000000..008d4a6816 --- /dev/null +++ b/packages/auth/src/middleware/google.js @@ -0,0 +1,13 @@ +const CouchDB = require("../db") + +exports.options = { + clientId: process.env.GOOGLE_CLIENT_ID, + clientSecret: process.env.GOOGLE_CLIENT_SECRET, + callbackURL: process.env.GOOGLE_AUTH_CALLBACK_URL, + // "http://localhost:" + (process.env.PORT || 3000) + "/auth/google/callback", +} + +exports.authenticate = async function(token, tokenSecret, profile, done) { + // retrieve user ... + // fetchUser().then(user => done(null, user)) +} diff --git a/packages/auth/src/middleware/index.js b/packages/auth/src/middleware/index.js new file mode 100644 index 0000000000..a9d07516ed --- /dev/null +++ b/packages/auth/src/middleware/index.js @@ -0,0 +1,9 @@ +const jwt = require("./jwt") +const local = require("./local") +const google = require("./google") + +module.exports = { + google, + jwt, + local, +} diff --git a/packages/auth/src/middleware/jwt.js b/packages/auth/src/middleware/jwt.js new file mode 100644 index 0000000000..5d36f0b91e --- /dev/null +++ b/packages/auth/src/middleware/jwt.js @@ -0,0 +1,19 @@ +// const jwt = require("passport-jwt") +const { Cookies } = require("../constants") + +// const ExtractJWT = jwt.ExtractJwt + +exports.options = { + jwtFromRequest: function(ctx) { + return ctx.cookies.get(Cookies.Auth) + }, + secretOrKey: process.env.JWT_SECRET, +} + +exports.authenticate = async function(jwt, done) { + try { + return done(null, jwt) + } catch (err) { + return done(new Error("JWT invalid."), false) + } +} diff --git a/packages/worker/src/middleware/auth/local.js b/packages/auth/src/middleware/local.js similarity index 74% rename from packages/worker/src/middleware/auth/local.js rename to packages/auth/src/middleware/local.js index 413ab1c8fb..85a68af87c 100644 --- a/packages/worker/src/middleware/auth/local.js +++ b/packages/auth/src/middleware/local.js @@ -1,9 +1,8 @@ const jwt = require("jsonwebtoken") -const { UserStatus } = require("../../constants") -const CouchDB = require("../../db") -const { StaticDatabases, generateUserID } = require("../../db/utils") -const { compare } = require("../../utils") -const env = require("../../environment") +const { UserStatus } = require("../constants") +const CouchDB = require("../db") +const { StaticDatabases, generateUserID } = require("../db/utils") +const { compare } = require("../hashing") const INVALID_ERR = "Invalid Credentials" @@ -26,8 +25,8 @@ exports.authenticate = async function(username, password, done) { let dbUser try { dbUser = await db.get(generateUserID(username)) - } catch { - console.error("User not found") + } catch (err) { + console.error("User not found", err) return done(null, false, { message: "User not found" }) } @@ -39,18 +38,17 @@ exports.authenticate = async function(username, password, done) { // authenticate if (await compare(password, dbUser.password)) { const payload = { - userId: dbUser._id, + _id: dbUser._id, } - const token = jwt.sign(payload, env.JWT_SECRET, { + const token = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "1 day", }) - // TODO: remove and use cookie dbUser.token = token - // setCookie(ctx, token, appId) - + // Remove users password in payload delete dbUser.password + return done(null, dbUser) } else { done(new Error(INVALID_ERR), false) diff --git a/packages/auth/yarn.lock b/packages/auth/yarn.lock new file mode 100644 index 0000000000..cde01d2106 --- /dev/null +++ b/packages/auth/yarn.lock @@ -0,0 +1,950 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +abort-controller@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +abstract-leveldown@^6.2.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a" + integrity sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ== + dependencies: + buffer "^5.5.0" + immediate "^3.2.3" + level-concat-iterator "~2.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +abstract-leveldown@~6.2.1, abstract-leveldown@~6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb" + integrity sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ== + dependencies: + buffer "^5.5.0" + immediate "^3.2.3" + level-concat-iterator "~2.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +argsarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/argsarray/-/argsarray-0.0.1.tgz#6e7207b4ecdb39b0af88303fa5ae22bda8df61cb" + integrity sha1-bnIHtOzbObCviDA/pa4ivajfYcs= + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +async@~2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" + integrity sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw= + dependencies: + lodash "^4.14.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base64url@3.x.x: + version "3.0.1" + resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" + integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +bcryptjs@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= + +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= + +buffer-from@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer@^5.5.0, buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +clone-buffer@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +deferred-leveldown@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" + integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw== + dependencies: + abstract-leveldown "~6.2.1" + inherits "^2.0.3" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +double-ended-queue@2.1.0-0: + version "2.1.0-0" + resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" + integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw= + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + 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" + +encoding-down@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" + integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw== + dependencies: + abstract-leveldown "^6.2.1" + inherits "^2.0.3" + level-codec "^9.0.0" + level-errors "^2.0.0" + +end-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/end-stream/-/end-stream-0.1.0.tgz#32003f3f438a2b0143168137f8fa6e9866c81ed5" + integrity sha1-MgA/P0OKKwFDFoE3+PpumGbIHtU= + dependencies: + write-stream "~0.4.3" + +errno@~0.1.1: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + 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" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fetch-cookie@0.10.1: + version "0.10.1" + resolved "https://registry.yarnpkg.com/fetch-cookie/-/fetch-cookie-0.10.1.tgz#5ea88f3d36950543c87997c27ae2aeafb4b5c4d4" + integrity sha512-beB+VEd4cNeVG1PY+ee74+PkuCQnik78pgLi5Ah/7qdUfov8IctU0vLUbBT8/10Ma5GMBeI4wtxhGrEfKNYs2g== + dependencies: + tough-cookie "^2.3.3 || ^3.0.1 || ^4.0.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.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +google-auth-library@~0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-0.10.0.tgz#6e15babee85fd1dd14d8d128a295b6838d52136e" + integrity sha1-bhW6vuhf0d0U2NEoopW2g41SE24= + dependencies: + gtoken "^1.2.1" + jws "^3.1.4" + lodash.noop "^3.0.1" + request "^2.74.0" + +google-p12-pem@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-0.1.2.tgz#33c46ab021aa734fa0332b3960a9a3ffcb2f3177" + integrity sha1-M8RqsCGqc0+gMys5YKmj/8svMXc= + dependencies: + node-forge "^0.7.1" + +googleapis@^16.0.0: + version "16.1.0" + resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-16.1.0.tgz#0f19f2d70572d918881a0f626e3b1a2fa8629576" + integrity sha1-Dxny1wVy2RiIGg9ibjsaL6hilXY= + dependencies: + async "~2.1.4" + google-auth-library "~0.10.0" + string-template "~1.0.0" + +gtoken@^1.2.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-1.2.3.tgz#5509571b8afd4322e124cf66cf68115284c476d8" + integrity sha512-wQAJflfoqSgMWrSBk9Fg86q+sd6s7y6uJhIvvIPz++RElGlMtEqsdAR2oWwZ/WTEtp7P9xFbJRrT976oRgzJ/w== + dependencies: + google-p12-pem "^0.1.0" + jws "^3.0.0" + mime "^1.4.1" + request "^2.72.0" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +immediate@3.3.0, immediate@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" + integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== + +inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +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@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +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= + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +jsonwebtoken@^8.2.0, 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" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + 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.0.0, jws@^3.1.4, 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" + +koa-passport@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/koa-passport/-/koa-passport-4.1.4.tgz#5f1665c1c2a37ace79af9f970b770885ca30ccfa" + integrity sha512-dJBCkl4X+zdYxbI2V2OtoGy0PUenpvp2ZLLWObc8UJhsId0iQpTFT8RVcuA0709AL2txGwRHnSPoT1bYNGa6Kg== + dependencies: + passport "^0.4.0" + +level-codec@9.0.2, level-codec@^9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" + integrity sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ== + dependencies: + buffer "^5.6.0" + +level-concat-iterator@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263" + integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw== + +level-errors@^2.0.0, level-errors@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" + integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw== + dependencies: + errno "~0.1.1" + +level-iterator-stream@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz#7ceba69b713b0d7e22fcc0d1f128ccdc8a24f79c" + integrity sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q== + dependencies: + inherits "^2.0.4" + readable-stream "^3.4.0" + xtend "^4.0.2" + +level-js@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/level-js/-/level-js-5.0.2.tgz#5e280b8f93abd9ef3a305b13faf0b5397c969b55" + integrity sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg== + dependencies: + abstract-leveldown "~6.2.3" + buffer "^5.5.0" + inherits "^2.0.3" + ltgt "^2.1.2" + +level-packager@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939" + integrity sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ== + dependencies: + encoding-down "^6.3.0" + levelup "^4.3.2" + +level-supports@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" + integrity sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg== + dependencies: + xtend "^4.0.2" + +level-write-stream@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/level-write-stream/-/level-write-stream-1.0.0.tgz#3f7fbb679a55137c0feb303dee766e12ee13c1dc" + integrity sha1-P3+7Z5pVE3wP6zA97nZuEu4Twdw= + dependencies: + end-stream "~0.1.0" + +level@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/level/-/level-6.0.1.tgz#dc34c5edb81846a6de5079eac15706334b0d7cd6" + integrity sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw== + dependencies: + level-js "^5.0.0" + level-packager "^5.1.0" + leveldown "^5.4.0" + +leveldown@5.6.0, leveldown@^5.4.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-5.6.0.tgz#16ba937bb2991c6094e13ac5a6898ee66d3eee98" + integrity sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ== + dependencies: + abstract-leveldown "~6.2.1" + napi-macros "~2.0.0" + node-gyp-build "~4.1.0" + +levelup@4.4.0, levelup@^4.3.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6" + integrity sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ== + dependencies: + deferred-leveldown "~5.3.0" + level-errors "~2.0.0" + level-iterator-stream "~4.0.0" + level-supports "~1.0.0" + xtend "~4.0.0" + +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.noop@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-3.0.1.tgz#38188f4d650a3a474258439b96ec45b32617133c" + integrity sha1-OBiPTWUKOkdCWEObluxFsyYXEzw= + +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= + +lodash@^4.14.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +ltgt@2.2.1, ltgt@^2.1.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" + integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= + +mime-db@1.47.0: + version "1.47.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" + integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.30" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" + integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== + dependencies: + mime-db "1.47.0" + +mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +napi-macros@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" + integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== + +node-fetch@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== + +node-forge@^0.7.1: + version "0.7.6" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac" + integrity sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw== + +node-gyp-build@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb" + integrity sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ== + +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== + +oauth@0.9.x: + version "0.9.15" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" + integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE= + +passport-google-auth@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/passport-google-auth/-/passport-google-auth-1.0.2.tgz#8b300b5aa442ef433de1d832ed3112877d0b2938" + integrity sha1-izALWqRC70M94dgy7TESh30LKTg= + dependencies: + googleapis "^16.0.0" + passport-strategy "1.x" + +passport-google-oauth1@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-google-oauth1/-/passport-google-oauth1-1.0.0.tgz#af74a803df51ec646f66a44d82282be6f108e0cc" + integrity sha1-r3SoA99R7GRvZqRNgigr5vEI4Mw= + dependencies: + passport-oauth1 "1.x.x" + +passport-google-oauth20@2.x.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz#0d241b2d21ebd3dc7f2b60669ec4d587e3a674ef" + integrity sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ== + dependencies: + passport-oauth2 "1.x.x" + +passport-google-oauth@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/passport-google-oauth/-/passport-google-oauth-2.0.0.tgz#f6eb4bc96dd6c16ec0ecfdf4e05ec48ca54d4dae" + integrity sha512-JKxZpBx6wBQXX1/a1s7VmdBgwOugohH+IxCy84aPTZNq/iIPX6u7Mqov1zY7MKRz3niFPol0KJz8zPLBoHKtYA== + dependencies: + passport-google-oauth1 "1.x.x" + passport-google-oauth20 "2.x.x" + +passport-jwt@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" + integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== + dependencies: + jsonwebtoken "^8.2.0" + passport-strategy "^1.0.0" + +passport-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-local/-/passport-local-1.0.0.tgz#1fe63268c92e75606626437e3b906662c15ba6ee" + integrity sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4= + dependencies: + passport-strategy "1.x.x" + +passport-oauth1@1.x.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/passport-oauth1/-/passport-oauth1-1.1.0.tgz#a7de988a211f9cf4687377130ea74df32730c918" + integrity sha1-p96YiiEfnPRoc3cTDqdN8ycwyRg= + dependencies: + oauth "0.9.x" + passport-strategy "1.x.x" + utils-merge "1.x.x" + +passport-oauth2@1.x.x: + version "1.5.0" + resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.5.0.tgz#64babbb54ac46a4dcab35e7f266ed5294e3c4108" + integrity sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ== + dependencies: + base64url "3.x.x" + oauth "0.9.x" + passport-strategy "1.x.x" + uid2 "0.0.x" + utils-merge "1.x.x" + +passport-strategy@1.x, passport-strategy@1.x.x, passport-strategy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= + +passport@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" + integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg== + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pouchdb@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/pouchdb/-/pouchdb-7.2.2.tgz#fcae82862db527e4cf7576ed8549d1384961f364" + integrity sha512-5gf5nw5XH/2H/DJj8b0YkvG9fhA/4Jt6kL0Y8QjtztVjb1y4J19Rg4rG+fUbXu96gsUrlyIvZ3XfM0b4mogGmw== + dependencies: + abort-controller "3.0.0" + argsarray "0.0.1" + buffer-from "1.1.1" + clone-buffer "1.0.0" + double-ended-queue "2.1.0-0" + fetch-cookie "0.10.1" + immediate "3.3.0" + inherits "2.0.4" + level "6.0.1" + level-codec "9.0.2" + level-write-stream "1.0.0" + leveldown "5.6.0" + levelup "4.4.0" + ltgt "2.2.1" + node-fetch "2.6.0" + readable-stream "1.1.14" + spark-md5 "3.0.1" + through2 "3.0.2" + uuid "8.1.0" + vuvuzela "1.0.3" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +psl@^1.1.28, psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +readable-stream@1.1.14: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +"readable-stream@2 || 3", readable-stream@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@~0.0.2: + version "0.0.4" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-0.0.4.tgz#f32d76e3fb863344a548d79923007173665b3b8d" + integrity sha1-8y124/uGM0SlSNeZIwBxc2ZbO40= + +request@^2.72.0, request@^2.74.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +spark-md5@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.1.tgz#83a0e255734f2ab4e5c466e5a2cfc9ba2aa2124d" + integrity sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig== + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +string-template@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96" + integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y= + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +through2@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4" + integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== + dependencies: + inherits "^2.0.4" + readable-stream "2 || 3" + +"tough-cookie@^2.3.3 || ^3.0.1 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +uid2@0.0.x: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I= + +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +utils-merge@1.x.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d" + integrity sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vuvuzela@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/vuvuzela/-/vuvuzela-1.0.3.tgz#3be145e58271c73ca55279dd851f12a682114b0b" + integrity sha1-O+FF5YJxxzylUnndhR8SpoIRSws= + +write-stream@~0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/write-stream/-/write-stream-0.4.3.tgz#83cc8c0347d0af6057a93862b4e3ae01de5c81c1" + integrity sha1-g8yMA0fQr2BXqThitOOuAd5cgcE= + dependencies: + readable-stream "~0.0.2" + +xtend@^4.0.2, xtend@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== diff --git a/packages/server/package.json b/packages/server/package.json index 36cd215423..cdaa94b7cf 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -43,7 +43,6 @@ "electron": "electron src/electron.js", "build:electron": "electron-builder --dir", "publish:electron": "electron-builder -mwl --publish always", - "postinstall": "electron-builder install-app-deps", "lint": "eslint --fix src/", "initialise": "node scripts/initialise.js" }, diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index 599b64ca60..919dccf1a1 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -7,11 +7,6 @@ resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-5.0.3.tgz#bc5b5532ecafd923a61f2fb097e3b108c0106a3f" integrity sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA== -"@adobe/spectrum-css-workflow-icons@^1.1.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@adobe/spectrum-css-workflow-icons/-/spectrum-css-workflow-icons-1.2.0.tgz#cda8bbe873ba9317160458858ae979e5393e5550" - integrity sha512-STSQQHvoBM0kf1JrNL3KEt88RklIctaGyGOzwUTnhtTkT1jHLaF4FgxrPDCvr1AT8VOq1nGplKUCeyZ9vdUUmA== - "@azure/ms-rest-azure-env@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-env/-/ms-rest-azure-env-1.1.2.tgz#8505873afd4a1227ec040894a64fdd736b4a101f" @@ -254,110 +249,6 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" -"@budibase/bbui@^1.58.13": - version "1.58.13" - resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.58.13.tgz#59df9c73def2d81c75dcbd2266c52c19db88dbd7" - integrity sha512-Zk6CKXdBfKsTVzA1Xs5++shdSSZLfphVpZuKVbjfzkgtuhyH7ruucexuSHEpFsxjW5rEKgKIBoRFzCK5vPvN0w== - dependencies: - markdown-it "^12.0.2" - quill "^1.3.7" - sirv-cli "^0.4.6" - svelte-flatpickr "^2.4.0" - svelte-portal "^1.0.0" - turndown "^7.0.0" - -"@budibase/client@^0.8.9": - version "0.8.10" - resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.8.10.tgz#18cd929dddfd2fa65c15e23871a26bccaa03049f" - integrity sha512-C/25rBAspQDk7Lp8w9icEcytgMAm8+7l+A4Lp7egpDJvrH+5jq2kVNuRRi3emAddCSTBmM0amIoS+PHUGvAa9Q== - dependencies: - "@budibase/string-templates" "^0.8.10" - regexparam "^1.3.0" - shortid "^2.2.15" - svelte-spa-router "^3.0.5" - -"@budibase/handlebars-helpers@^0.11.3": - version "0.11.3" - resolved "https://registry.yarnpkg.com/@budibase/handlebars-helpers/-/handlebars-helpers-0.11.3.tgz#b6e5c91b83e8906e7d7ff10ddde277a3d561016e" - integrity sha512-MS1ptZEYq8o9J3tNLM7cZ2RGSSJIer4GiMIUHtbBI3sC9UKqZebao1JYNfmZKpNjntuqhZKgjqc5GfnVIEjsYQ== - dependencies: - arr-flatten "^1.1.0" - array-sort "^0.1.4" - define-property "^1.0.0" - extend-shallow "^3.0.2" - "falsey" "^0.3.2" - for-in "^1.0.2" - for-own "^1.0.0" - get-object "^0.2.0" - get-value "^2.0.6" - handlebars "^4.0.11" - handlebars-utils "^1.0.6" - has-value "^1.0.0" - helper-date "^1.0.1" - helper-markdown "^1.0.0" - helper-md "^0.2.2" - html-tag "^2.0.0" - is-even "^1.0.0" - is-glob "^4.0.0" - is-number "^4.0.0" - kind-of "^6.0.0" - logging-helpers "^1.0.0" - micromatch "^3.1.4" - relative "^3.0.2" - striptags "^3.1.0" - to-gfm-code-block "^0.1.1" - year "^0.2.1" - -"@budibase/standard-components@^0.8.9": - version "0.8.10" - resolved "https://registry.yarnpkg.com/@budibase/standard-components/-/standard-components-0.8.10.tgz#ffde4e3bfe5afe14c242d7066328066500333b62" - integrity sha512-zXE9SbMFxrZ8tpYmTaBQEPwT+3xJ8p4QtDkSRfnEcxbWojNghh5ikn0897FpgnP7q9x+63tDQ0UCiUcNoiOk7w== - dependencies: - "@adobe/spectrum-css-workflow-icons" "^1.1.0" - "@budibase/bbui" "^1.58.13" - "@budibase/svelte-ag-grid" "^1.0.4" - "@spectrum-css/actionbutton" "^1.0.0-beta.1" - "@spectrum-css/button" "^3.0.0-beta.6" - "@spectrum-css/checkbox" "^3.0.0-beta.6" - "@spectrum-css/fieldlabel" "^3.0.0-beta.7" - "@spectrum-css/icon" "^3.0.0-beta.2" - "@spectrum-css/inputgroup" "^3.0.0-beta.7" - "@spectrum-css/menu" "^3.0.0-beta.5" - "@spectrum-css/page" "^3.0.0-beta.0" - "@spectrum-css/picker" "^1.0.0-beta.3" - "@spectrum-css/popover" "^3.0.0-beta.6" - "@spectrum-css/stepper" "^3.0.0-beta.7" - "@spectrum-css/textfield" "^3.0.0-beta.6" - "@spectrum-css/vars" "^3.0.0-beta.2" - apexcharts "^3.22.1" - flatpickr "^4.6.6" - loadicons "^1.0.0" - lodash.debounce "^4.0.8" - markdown-it "^12.0.2" - quill "^1.3.7" - remixicon "^2.5.0" - svelte-apexcharts "^1.0.2" - svelte-flatpickr "^3.1.0" - turndown "^7.0.0" - -"@budibase/string-templates@^0.8.10", "@budibase/string-templates@^0.8.9": - version "0.8.10" - resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-0.8.10.tgz#57b1cfb44d4bdac0ab3ef9a4912a6185e972711b" - integrity sha512-YUtbbAvLcxpeEiCs36cF5bkEDgpLaklvpuG/pcUIOxAPr1feqcN1KyFbuoSPihZOWXjXLgsujQerQ5xn8MUrhg== - dependencies: - "@budibase/handlebars-helpers" "^0.11.3" - dayjs "^1.10.4" - handlebars "^4.7.6" - handlebars-utils "^1.0.6" - lodash "^4.17.20" - -"@budibase/svelte-ag-grid@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@budibase/svelte-ag-grid/-/svelte-ag-grid-1.0.4.tgz#41cceec4bde2c4aea8b9da8f610fe36055c7709f" - integrity sha512-JZm6qujxnZpqw7Twbegr6se4sHhyWzN0Cibrk5bVBH32hBgzD6dd33fxwrjHKkWFxjys9wRT+cqYgYVlSt9E3w== - dependencies: - ag-grid-community "^24.0.0" - "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -885,11 +776,6 @@ path-to-regexp "^1.1.1" urijs "^1.19.0" -"@polka/url@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@polka/url/-/url-0.5.0.tgz#b21510597fd601e5d7c95008b76bf0d254ebfd31" - integrity sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw== - "@sendgrid/client@^7.1.1": version "7.4.2" resolved "https://registry.yarnpkg.com/@sendgrid/client/-/client-7.4.2.tgz#204a9fbb5dc05a721a5d8cd8930f57f9f8e612b1" @@ -1002,73 +888,6 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== -"@spectrum-css/actionbutton@^1.0.0-beta.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/actionbutton/-/actionbutton-1.0.1.tgz#9c75da37ea6915919fb574c74bd60dacc03b6577" - integrity sha512-AUqtyNabHF451Aj9i3xz82TxS5Z6k1dttA68/1hMeU9kbPCSS4P6Viw3vaRGs9CSspuR8xnnhDgrq+F+zMy2Hw== - -"@spectrum-css/button@^3.0.0-beta.6": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/button/-/button-3.0.1.tgz#6db8c3e851baecd0f1c2d88fef37d49d01c6e643" - integrity sha512-YXrBtjIYisk4Vaxnp0RiE4gdElQX04P2mc4Pi2GlQ27dJKlHmufYcF+kAqGdtiyK5yjdN/vKRcC8y13aA4rusA== - -"@spectrum-css/checkbox@^3.0.0-beta.6": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/checkbox/-/checkbox-3.0.1.tgz#6f36377d8bd556989ddd1dec2506dc295c5fcda8" - integrity sha512-fI0q2Cp6yU4ORyE6JWUSMYNgEtGf6AjYViZ2Weg3UPTYBQuWdQd8J0ZTcH38pDMyARFPRdiXgQ3KnyX5Hk5huw== - -"@spectrum-css/fieldlabel@^3.0.0-beta.7": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/fieldlabel/-/fieldlabel-3.0.1.tgz#39f7c0f25cc2ff402afeff005341b0832f7c588c" - integrity sha512-LMfwrwIq8wEEvxFLobdLvXRwKrp8o9Fty4iJ9aYl2Rj1uXkfRd8qLz9HGZjLEE1OuJgoTBgamYABl7EvoA5PLw== - -"@spectrum-css/icon@^3.0.0-beta.2": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/icon/-/icon-3.0.1.tgz#e300a6fc353c85c6b5d6e7a364408a940c31b177" - integrity sha512-cGFtIrcQ/7tthdkHK1npuEFiCdYVHLqwmLxghUYQw8Tb8KgJaw3OBO1tpjgsUizexNgu26BjVRIbGxNWuBXIHQ== - -"@spectrum-css/inputgroup@^3.0.0-beta.7": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/inputgroup/-/inputgroup-3.0.1.tgz#8c5b257b57b3b2cf04e99355709365fa0d6838cc" - integrity sha512-asBRa1jTlld6plkcq4ySO+xl+OJlCMSOLoAFdSSIJowcSlCV0yDy7oeOhf5YQv9mMHFWTKlWUSoAKDZTguIPxA== - -"@spectrum-css/menu@^3.0.0-beta.5": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/menu/-/menu-3.0.1.tgz#2a376f991acc24e12ec892bb6b9db2650fc41fbe" - integrity sha512-Qjg0+1O0eC89sb/bRFq2AGnQ8XqhVy23TUXHyffNM8qdcMssnlny3QmhzjURCZKvx/Y5UytCpzhedPQqSpQwZg== - -"@spectrum-css/page@^3.0.0-beta.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/page/-/page-3.0.1.tgz#5e1c3dd5b1a1ee591f9d636b75f03665f542d846" - integrity sha512-LAlKF8km5BlsGPpZ2SNtwKOQIHn1lz0X93aczGZVZceOg73O4gyeoT5cx4vi1z+KtBRY5VMDWx3XgGtUwwjqwA== - dependencies: - "@spectrum-css/vars" "^3.0.1" - -"@spectrum-css/picker@^1.0.0-beta.3": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/picker/-/picker-1.0.1.tgz#98991198576d26bd14160824e7b6f3c278ff930b" - integrity sha512-Rv4/UBOdNW1gs7WVBCJnPD5VFly8MqP++psDX6kcugUIcfJy0GC3acvElotmKRlCDk8Qxks2W2A0jKeSgphTmA== - -"@spectrum-css/popover@^3.0.0-beta.6": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/popover/-/popover-3.0.1.tgz#5863c1efc53f98f9aba2de9186666780041303fc" - integrity sha512-LmOSj/yCwQQ9iGmCYnHiJsJR/HfPiGqI1Jl7pkKxBOCxYBMS/5+ans9vfCN2Qnd0eK7WSbfPg72S6mjye7db2Q== - -"@spectrum-css/stepper@^3.0.0-beta.7": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/stepper/-/stepper-3.0.1.tgz#7f270f53505e7dbe082591e8ea1c4c8f397e045a" - integrity sha512-IvZlGFJ8QPr9tUz5xvVN4hASaTRDPdKu9IIp25q/x0ecgSrKAM55e3EBWEYWy1H1JI3h+zlPnNRuK0VLhDbCYA== - -"@spectrum-css/textfield@^3.0.0-beta.6": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/textfield/-/textfield-3.0.1.tgz#e875b8e37817378ad08fc4af7d53026df38911e5" - integrity sha512-MUV5q87CVxbkNdSNoxGrFbgyKc51ft/WWf3aVEoPdPw5yBnXqFe1w1YmAit5zYDOOhhs58sCLAlUcCMlOpkgrA== - -"@spectrum-css/vars@^3.0.0-beta.2", "@spectrum-css/vars@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-3.0.1.tgz#561fd69098f896a647242dd8d6108af603bfa31e" - integrity sha512-l4oRcCOqInChYXZN6OQhpe3isk6l4OE6Ys8cgdlsiKp53suNoQxyyd9p/eGRbCjZgH3xQ8nK0t4DHa7QYC0S6w== - "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -1353,11 +1172,6 @@ adal-node@^0.1.28: xmldom ">= 0.1.x" xpath.js "~1.1.0" -ag-grid-community@^24.0.0: - version "24.1.0" - resolved "https://registry.yarnpkg.com/ag-grid-community/-/ag-grid-community-24.1.0.tgz#1e3cab51211822e08d56f03a491b7c0deaa398e6" - integrity sha512-pWnWphuDcejZ8ahf6C734EpCx3XQ6dHEZWMWTlCdHNT0mZBLJ4YKCGACX+ttAEtSX2MGM3G13JncvuratUlYag== - agent-base@6: version "6.0.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.1.tgz#808007e4e5867decb0ab6ab2f928fbdb5a596db4" @@ -1403,130 +1217,6 @@ ansi-align@^3.0.0: dependencies: string-width "^3.0.0" -ansi-bgblack@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-bgblack/-/ansi-bgblack-0.1.1.tgz#a68ba5007887701b6aafbe3fa0dadfdfa8ee3ca2" - integrity sha1-poulAHiHcBtqr74/oNrf36juPKI= - dependencies: - ansi-wrap "0.1.0" - -ansi-bgblue@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-bgblue/-/ansi-bgblue-0.1.1.tgz#67bdc04edc9b9b5278969da196dea3d75c8c3613" - integrity sha1-Z73ATtybm1J4lp2hlt6j11yMNhM= - dependencies: - ansi-wrap "0.1.0" - -ansi-bgcyan@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-bgcyan/-/ansi-bgcyan-0.1.1.tgz#58489425600bde9f5507068dd969ebfdb50fe768" - integrity sha1-WEiUJWAL3p9VBwaN2Wnr/bUP52g= - dependencies: - ansi-wrap "0.1.0" - -ansi-bggreen@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-bggreen/-/ansi-bggreen-0.1.1.tgz#4e3191248529943f4321e96bf131d1c13816af49" - integrity sha1-TjGRJIUplD9DIelr8THRwTgWr0k= - dependencies: - ansi-wrap "0.1.0" - -ansi-bgmagenta@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-bgmagenta/-/ansi-bgmagenta-0.1.1.tgz#9b28432c076eaa999418672a3efbe19391c2c7a1" - integrity sha1-myhDLAduqpmUGGcqPvvhk5HCx6E= - dependencies: - ansi-wrap "0.1.0" - -ansi-bgred@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-bgred/-/ansi-bgred-0.1.1.tgz#a76f92838382ba43290a6c1778424f984d6f1041" - integrity sha1-p2+Sg4OCukMpCmwXeEJPmE1vEEE= - dependencies: - ansi-wrap "0.1.0" - -ansi-bgwhite@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-bgwhite/-/ansi-bgwhite-0.1.1.tgz#6504651377a58a6ececd0331994e480258e11ba8" - integrity sha1-ZQRlE3elim7OzQMxmU5IAljhG6g= - dependencies: - ansi-wrap "0.1.0" - -ansi-bgyellow@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-bgyellow/-/ansi-bgyellow-0.1.1.tgz#c3fe2eb08cd476648029e6874d15a0b38f61d44f" - integrity sha1-w/4usIzUdmSAKeaHTRWgs49h1E8= - dependencies: - ansi-wrap "0.1.0" - -ansi-black@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-black/-/ansi-black-0.1.1.tgz#f6185e889360b2545a1ec50c0bf063fc43032453" - integrity sha1-9hheiJNgslRaHsUMC/Bj/EMDJFM= - dependencies: - ansi-wrap "0.1.0" - -ansi-blue@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-blue/-/ansi-blue-0.1.1.tgz#15b804990e92fc9ca8c5476ce8f699777c21edbf" - integrity sha1-FbgEmQ6S/JyoxUds6PaZd3wh7b8= - dependencies: - ansi-wrap "0.1.0" - -ansi-bold@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-bold/-/ansi-bold-0.1.1.tgz#3e63950af5acc2ae2e670e6f67deb115d1a5f505" - integrity sha1-PmOVCvWswq4uZw5vZ96xFdGl9QU= - dependencies: - ansi-wrap "0.1.0" - -ansi-colors@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-0.2.0.tgz#72c31de2a0d9a2ccd0cac30cc9823eeb2f6434b5" - integrity sha1-csMd4qDZoszQysMMyYI+6y9kNLU= - dependencies: - ansi-bgblack "^0.1.1" - ansi-bgblue "^0.1.1" - ansi-bgcyan "^0.1.1" - ansi-bggreen "^0.1.1" - ansi-bgmagenta "^0.1.1" - ansi-bgred "^0.1.1" - ansi-bgwhite "^0.1.1" - ansi-bgyellow "^0.1.1" - ansi-black "^0.1.1" - ansi-blue "^0.1.1" - ansi-bold "^0.1.1" - ansi-cyan "^0.1.1" - ansi-dim "^0.1.1" - ansi-gray "^0.1.1" - ansi-green "^0.1.1" - ansi-grey "^0.1.1" - ansi-hidden "^0.1.1" - ansi-inverse "^0.1.1" - ansi-italic "^0.1.1" - ansi-magenta "^0.1.1" - ansi-red "^0.1.1" - ansi-reset "^0.1.1" - ansi-strikethrough "^0.1.1" - ansi-underline "^0.1.1" - ansi-white "^0.1.1" - ansi-yellow "^0.1.1" - lazy-cache "^2.0.1" - -ansi-cyan@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" - integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= - dependencies: - ansi-wrap "0.1.0" - -ansi-dim@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-dim/-/ansi-dim-0.1.1.tgz#40de4c603aa8086d8e7a86b8ff998d5c36eefd6c" - integrity sha1-QN5MYDqoCG2Oeoa4/5mNXDbu/Ww= - dependencies: - ansi-wrap "0.1.0" - ansi-escapes@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" @@ -1539,62 +1229,6 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.11.0" -ansi-gray@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" - integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= - dependencies: - ansi-wrap "0.1.0" - -ansi-green@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-green/-/ansi-green-0.1.1.tgz#8a5d9a979e458d57c40e33580b37390b8e10d0f7" - integrity sha1-il2al55FjVfEDjNYCzc5C44Q0Pc= - dependencies: - ansi-wrap "0.1.0" - -ansi-grey@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-grey/-/ansi-grey-0.1.1.tgz#59d98b6ac2ba19f8a51798e9853fba78339a33c1" - integrity sha1-WdmLasK6GfilF5jphT+6eDOaM8E= - dependencies: - ansi-wrap "0.1.0" - -ansi-hidden@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-hidden/-/ansi-hidden-0.1.1.tgz#ed6a4c498d2bb7cbb289dbf2a8d1dcc8567fae0f" - integrity sha1-7WpMSY0rt8uyidvyqNHcyFZ/rg8= - dependencies: - ansi-wrap "0.1.0" - -ansi-inverse@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-inverse/-/ansi-inverse-0.1.1.tgz#b6af45826fe826bfb528a6c79885794355ccd269" - integrity sha1-tq9Fgm/oJr+1KKbHmIV5Q1XM0mk= - dependencies: - ansi-wrap "0.1.0" - -ansi-italic@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-italic/-/ansi-italic-0.1.1.tgz#104743463f625c142a036739cf85eda688986f23" - integrity sha1-EEdDRj9iXBQqA2c5z4XtpoiYbyM= - dependencies: - ansi-wrap "0.1.0" - -ansi-magenta@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-magenta/-/ansi-magenta-0.1.1.tgz#063b5ba16fb3f23e1cfda2b07c0a89de11e430ae" - integrity sha1-BjtboW+z8j4c/aKwfAqJ3hHkMK4= - dependencies: - ansi-wrap "0.1.0" - -ansi-red@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" - integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= - dependencies: - ansi-wrap "0.1.0" - ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -1615,20 +1249,6 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== -ansi-reset@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-reset/-/ansi-reset-0.1.1.tgz#e7e71292c3c7ddcd4d62ef4a6c7c05980911c3b7" - integrity sha1-5+cSksPH3c1NYu9KbHwFmAkRw7c= - dependencies: - ansi-wrap "0.1.0" - -ansi-strikethrough@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-strikethrough/-/ansi-strikethrough-0.1.1.tgz#d84877140b2cff07d1c93ebce69904f68885e568" - integrity sha1-2Eh3FAss/wfRyT685pkE9oiF5Wg= - dependencies: - ansi-wrap "0.1.0" - ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1643,32 +1263,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-underline@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-underline/-/ansi-underline-0.1.1.tgz#dfc920f4c97b5977ea162df8ffb988308aaa71a4" - integrity sha1-38kg9Ml7WXfqFi34/7mIMIqqcaQ= - dependencies: - ansi-wrap "0.1.0" - -ansi-white@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-white/-/ansi-white-0.1.1.tgz#9c77b7c193c5ee992e6011d36ec4c921b4578944" - integrity sha1-nHe3wZPF7pkuYBHTbsTJIbRXiUQ= - dependencies: - ansi-wrap "0.1.0" - -ansi-wrap@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" - integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= - -ansi-yellow@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-yellow/-/ansi-yellow-0.1.1.tgz#cb9356f2f46c732f0e3199e6102955a77da83c1d" - integrity sha1-y5NW8vRscy8OMZnmEClVp32oPB0= - dependencies: - ansi-wrap "0.1.0" - any-base@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" @@ -1695,18 +1289,6 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -apexcharts@^3.19.2, apexcharts@^3.22.1: - version "3.26.0" - resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.26.0.tgz#a78abc108b2e1b3086a738f0ec7c98e292f4a14b" - integrity sha512-zdYHs3k3tgmCn1BpYLj7rhGEndBYF33Pq1+g0ora37xAr+3act5CJrpdXM2jx2boVUyXgavoSp6sa8WpK7RkSA== - dependencies: - svg.draggable.js "^2.2.2" - svg.easing.js "^2.0.0" - svg.filter.js "^2.0.2" - svg.pathmorphing.js "^0.1.3" - svg.resize.js "^1.4.3" - svg.select.js "^3.0.1" - app-builder-bin@3.5.10: version "3.5.10" resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.10.tgz#4a7f9999fccc0c435b6284ae1366bc76a17c4a7d" @@ -1758,18 +1340,13 @@ archive-type@^4.0.0: dependencies: file-type "^4.2.0" -argparse@^1.0.10, argparse@^1.0.7: +argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - args@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/args/-/args-5.0.1.tgz#4bf298df90a4799a09521362c579278cc2fdd761" @@ -1805,15 +1382,6 @@ array-equal@^1.0.0: resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= -array-sort@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-0.1.4.tgz#662855eaeb671b4188df4451b2f24a0753992b23" - integrity sha512-BNcM+RXxndPxiZ2rd76k6nyQLRZr2/B/sdi8pQ+Joafr5AH279L40dfokSUTp8O+AaqYjXWhblBWa2st2nc4fQ== - dependencies: - default-compare "^1.0.0" - get-value "^2.0.6" - kind-of "^5.0.2" - array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -1891,13 +1459,6 @@ atomic-sleep@^1.0.0: resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== -autolinker@~0.28.0: - version "0.28.1" - resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-0.28.1.tgz#0652b491881879f0775dace0cdca3233942a4e47" - integrity sha1-BlK0kYgYefB3XazgzcoyM5QqTkc= - dependencies: - gulp-header "^1.7.1" - aws-sdk@^2.767.0: version "2.771.0" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.771.0.tgz#ff4beb0a04d6ab1ae962c85dfb42e3e9bfe2b93b" @@ -2493,11 +2054,6 @@ clone-response@1.0.2, clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" -clone@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= - co-body@^5.1.1: version "5.2.0" resolved "https://registry.yarnpkg.com/co-body/-/co-body-5.2.0.tgz#5a0a658c46029131e0e3a306f67647302f71c124" @@ -2562,11 +2118,6 @@ commander@^2.5.0, commander@^2.8.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - commoner@^0.10.1: version "0.10.8" resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.8.tgz#34fc3672cd24393e8bb47e70caa0293811f4f2c5" @@ -2609,13 +2160,6 @@ concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" -concat-with-sourcemaps@*: - version "1.1.0" - resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz#d4ea93f05ae25790951b99e7b3b09e3908a4082e" - integrity sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg== - dependencies: - source-map "^0.6.1" - config-chain@^1.1.11: version "1.1.12" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" @@ -2636,11 +2180,6 @@ configstore@^5.0.1: write-file-atomic "^3.0.0" xdg-basedir "^4.0.0" -console-clear@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/console-clear/-/console-clear-1.1.1.tgz#995e20cbfbf14dd792b672cde387bd128d674bf7" - integrity sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ== - content-disposition@^0.5.2, content-disposition@~0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" @@ -2719,15 +2258,6 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" @@ -2775,23 +2305,11 @@ date-utils@*: resolved "https://registry.yarnpkg.com/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64" integrity sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q= -date.js@^0.3.1: - version "0.3.3" - resolved "https://registry.yarnpkg.com/date.js/-/date.js-0.3.3.tgz#ef1e92332f507a638795dbb985e951882e50bbda" - integrity sha512-HgigOS3h3k6HnW011nAb43c5xx5rBXk8P2v/WIT9Zv4koIaVXiH2BURguI78VVp+5Qc076T7OR378JViCnZtBw== - dependencies: - debug "~3.1.0" - dateformat@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -dayjs@^1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.4.tgz#8e544a9b8683f61783f570980a8a80eaf54ab1e2" - integrity sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw== - debug@4, debug@^4.0.1: version "4.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" @@ -2897,18 +2415,6 @@ decompress@^4.2.1: pify "^2.3.0" strip-dirs "^2.0.0" -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - deep-equal@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" @@ -2929,13 +2435,6 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== -default-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" - integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== - dependencies: - kind-of "^5.0.2" - default-shell@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/default-shell/-/default-shell-1.0.1.tgz#752304bddc6174f49eb29cb988feea0b8813c8bc" @@ -3085,11 +2584,6 @@ domexception@^1.0.1: dependencies: webidl-conversions "^4.0.2" -domino@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/domino/-/domino-2.1.6.tgz#fe4ace4310526e5e7b9d12c7de01b7f485a57ffe" - integrity sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ== - dot-prop@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -3306,24 +2800,6 @@ ensure-error@^2.0.0: resolved "https://registry.yarnpkg.com/ensure-error/-/ensure-error-2.1.0.tgz#f11fbe383c0cf4a54850ac77acceb7bc06e0f99d" integrity sha512-+BMSJHw9gxiJAAp2ZR1E0TNcL09dD3lOvkl7WVm4+Y6xnes/pMetP/TzCHiDduh8ihNDjbGfuYxl7l4PA1xZ8A== -ent@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" - integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= - -entities@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" - integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== - -env-cmd@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/env-cmd/-/env-cmd-10.1.0.tgz#c7f5d3b550c9519f137fdac4dd8fb6866a8c8c4b" - integrity sha512-mMdWTT9XKN7yNth/6N6g2GuKuJTsKMDHlQFUDacb/heQRRWOTIZ42t1rMHnQu4jYxU1ajdTeJM+9eEETlqToMA== - dependencies: - commander "^4.0.0" - cross-spawn "^7.0.0" - env-paths@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" @@ -3348,11 +2824,6 @@ error-inject@^1.0.0: resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= -error-symbol@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/error-symbol/-/error-symbol-0.1.0.tgz#0a4dae37d600d15a29ba453d8ef920f1844333f6" - integrity sha1-Ck2uN9YA0VopukU9jvkg8YRDM/Y= - es-abstract@^1.18.0-next.2: version "1.18.0-next.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.3.tgz#56bc8b5cc36b2cca25a13be07f3c02c2343db6b7" @@ -3595,11 +3066,6 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba" - integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo= - events@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -3701,7 +3167,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@^3.0.0, extend@^3.0.2, extend@~3.0.2: +extend@^3.0.0, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -3759,23 +3225,11 @@ falafel@^1.0.1: isarray "0.0.1" object-keys "^1.0.6" -"falsey@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/falsey/-/falsey-0.3.2.tgz#b21c90c5c34660fc192bf909575db95b6880d597" - integrity sha512-lxEuefF5MBIVDmE6XeqCdM4BWk1+vYmGZtkbKZ/VFcg6uBBw6fXNEbWmxCjDdQlFc9hy450nkiWwM3VAW6G1qg== - dependencies: - kind-of "^5.0.2" - fast-deep-equal@^3.1.1: 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-diff@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154" - integrity sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig== - fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -3955,11 +3409,6 @@ flat-cache@^2.0.1: rimraf "2.6.3" write "1.0.3" -flatpickr@^4.5.2, flatpickr@^4.6.6: - version "4.6.9" - resolved "https://registry.yarnpkg.com/flatpickr/-/flatpickr-4.6.9.tgz#9a13383e8a6814bda5d232eae3fcdccb97dc1499" - integrity sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw== - flatstr@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" @@ -3989,18 +3438,11 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -for-in@^1.0.1, for-in@^1.0.2: +for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -for-own@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" - integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= - dependencies: - for-in "^1.0.1" - foreach@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" @@ -4059,11 +3501,6 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-exists-sync@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" - integrity sha1-mC1ok6+RjnLQjeyehnP/K1qNat0= - fs-extra@8.1.0, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -4140,19 +3577,6 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" -get-object@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/get-object/-/get-object-0.2.0.tgz#d92ff7d5190c64530cda0543dac63a3d47fe8c0c" - integrity sha1-2S/31RkMZFMM2gVD2sY6PUf+jAw= - dependencies: - is-number "^2.0.2" - isobject "^0.2.0" - -get-port@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" - integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= - get-stream@3.0.0, get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -4350,35 +3774,6 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -gulp-header@^1.7.1: - version "1.8.12" - resolved "https://registry.yarnpkg.com/gulp-header/-/gulp-header-1.8.12.tgz#ad306be0066599127281c4f8786660e705080a84" - integrity sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ== - dependencies: - concat-with-sourcemaps "*" - lodash.template "^4.4.0" - through2 "^2.0.0" - -handlebars-utils@^1.0.2, handlebars-utils@^1.0.4, handlebars-utils@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/handlebars-utils/-/handlebars-utils-1.0.6.tgz#cb9db43362479054782d86ffe10f47abc76357f9" - integrity sha512-d5mmoQXdeEqSKMtQQZ9WkiUcO1E3tPbWxluCK9hVgIDPzQa9WsKo3Lbe/sGflTe7TomHEeZaOgwIkyIr1kfzkw== - dependencies: - kind-of "^6.0.0" - typeof-article "^0.1.1" - -handlebars@^4.0.11, handlebars@^4.7.6: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.0" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -4467,39 +3862,6 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -helper-date@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/helper-date/-/helper-date-1.0.1.tgz#12fedea3ad8e44a7ca4c4efb0ff4104a5120cffb" - integrity sha512-wU3VOwwTJvGr/w5rZr3cprPHO+hIhlblTJHD6aFBrKLuNbf4lAmkawd2iK3c6NbJEvY7HAmDpqjOFSI5/+Ey2w== - dependencies: - date.js "^0.3.1" - handlebars-utils "^1.0.4" - moment "^2.18.1" - -helper-markdown@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/helper-markdown/-/helper-markdown-1.0.0.tgz#ee7e9fc554675007d37eb90f7853b13ce74f3e10" - integrity sha512-AnDqMS4ejkQK0MXze7pA9TM3pu01ZY+XXsES6gEE0RmCGk5/NIfvTn0NmItfyDOjRAzyo9z6X7YHbHX4PzIvOA== - dependencies: - handlebars-utils "^1.0.2" - highlight.js "^9.12.0" - remarkable "^1.7.1" - -helper-md@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/helper-md/-/helper-md-0.2.2.tgz#c1f59d7e55bbae23362fd8a0e971607aec69d41f" - integrity sha1-wfWdflW7riM2L9ig6XFgeuxp1B8= - dependencies: - ent "^2.2.0" - extend-shallow "^2.0.1" - fs-exists-sync "^0.1.0" - remarkable "^1.6.2" - -highlight.js@^9.12.0: - version "9.18.5" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825" - integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA== - hosted-git-info@^2.1.4: version "2.8.8" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" @@ -4529,14 +3891,6 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-tag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/html-tag/-/html-tag-2.0.0.tgz#36c3bc8d816fd30b570d5764a497a641640c2fed" - integrity sha512-XxzooSo6oBoxBEUazgjdXj7VwTn/iSTSZzTYKzYY6I916tkaYzypHxy+pbVU1h+0UQ9JlVf5XkNQyxOAiiQO1g== - dependencies: - is-self-closing "^1.0.1" - kind-of "^6.0.0" - http-assert@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878" @@ -4694,11 +4048,6 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -info-symbol@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/info-symbol/-/info-symbol-0.1.0.tgz#27841d72867ddb4242cd612d79c10633881c6a78" - integrity sha1-J4QdcoZ920JCzWEtecEGM4gcang= - inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" @@ -4775,13 +4124,6 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-arguments@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" - integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== - dependencies: - call-bind "^1.0.0" - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -4877,13 +4219,6 @@ is-docker@^2.0.0: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw== -is-even@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-even/-/is-even-1.0.0.tgz#76b5055fbad8d294a86b6a949015e1c97b717c06" - integrity sha1-drUFX7rY0pSoa2qUkBXhyXtxfAY= - dependencies: - is-odd "^0.1.2" - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -4961,13 +4296,6 @@ is-number-object@^1.0.4: resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== -is-number@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= - dependencies: - kind-of "^3.0.2" - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -4975,11 +4303,6 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -4995,13 +4318,6 @@ is-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= -is-odd@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-0.1.2.tgz#bc573b5ce371ef2aad6e6f49799b72bef13978a7" - integrity sha1-vFc7XONx7yqtbm9JeZtyvvE5eKc= - dependencies: - is-number "^3.0.0" - is-path-inside@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" @@ -5019,7 +4335,7 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.4, is-regex@^1.1.2: +is-regex@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== @@ -5032,13 +4348,6 @@ is-retry-allowed@^1.1.0: resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== -is-self-closing@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-self-closing/-/is-self-closing-1.0.1.tgz#5f406b527c7b12610176320338af0fa3896416e4" - integrity sha512-E+60FomW7Blv5GXTlYee2KDrnG6srxF7Xt1SjrhWUGUEsTFIqY/nq2y3DaftCsgUMdh89V07IVfhY9KIJhLezg== - dependencies: - self-closing-tags "^1.0.1" - is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -5117,11 +4426,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -isobject@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-0.2.0.tgz#a3432192f39b910b5f02cc989487836ec70aa85e" - integrity sha1-o0MhkvObkQtfAsyYlIeDbscKqF4= - isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" @@ -5798,7 +5102,7 @@ keyv@^3.0.0: dependencies: json-buffer "3.0.0" -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.1.0, kind-of@^3.2.0: +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= @@ -5812,7 +5116,7 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" -kind-of@^5.0.0, kind-of@^5.0.2: +kind-of@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== @@ -5822,7 +5126,7 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -kleur@^3.0.0, kleur@^3.0.3: +kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== @@ -5953,13 +5257,6 @@ latest-version@^5.0.0: dependencies: package-json "^6.3.0" -lazy-cache@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" - integrity sha1-uRkKT5EzVGlIQIWfio9whNiCImQ= - dependencies: - set-getter "^0.1.0" - lazy-val@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.4.tgz#882636a7245c2cfe6e0a4e3ba6c5d68a137e5c65" @@ -6131,13 +5428,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -linkify-it@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.2.tgz#f55eeb8bc1d3ae754049e124ab3bb56d97797fb8" - integrity sha512-gDBO4aHNZS6coiZCKVhSNh43F9ioIL4JwRjLZPkoLIY4yZFwg264Y5lu2x6rb1Js42Gh6Yqm2f6L2AJcnkzinQ== - dependencies: - uc.micro "^1.0.1" - load-bmfont@^1.3.1, load-bmfont@^1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.1.tgz#c0f5f4711a1e2ccff725a7b6078087ccfcddd3e9" @@ -6162,16 +5452,6 @@ load-json-file@^4.0.0: pify "^3.0.0" strip-bom "^3.0.0" -loadicons@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/loadicons/-/loadicons-1.0.0.tgz#79fd9b08ef2933988c94068cbd246ef3f21cbd04" - integrity sha512-KSywiudfuOK5sTdhNMM8hwRpMxZ5TbQlU4ZijMxUFwRW7jpxUmb9YJoLIzDn7+xuxeLzCZWBmLJS2JDjDWCpsw== - -local-access@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/local-access/-/local-access-1.1.0.tgz#e007c76ba2ca83d5877ba1a125fc8dfe23ba4798" - integrity sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw== - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -6187,11 +5467,6 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= - lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -6262,21 +5537,6 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash.template@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" - integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" - integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.without@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" @@ -6297,40 +5557,11 @@ lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.3: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== -lodash@^4.17.19, lodash@^4.17.20: +lodash@^4.17.19: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-ok@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/log-ok/-/log-ok-0.1.1.tgz#bea3dd36acd0b8a7240d78736b5b97c65444a334" - integrity sha1-vqPdNqzQuKckDXhza1uXxlREozQ= - dependencies: - ansi-green "^0.1.1" - success-symbol "^0.1.0" - -log-utils@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/log-utils/-/log-utils-0.2.1.tgz#a4c217a0dd9a50515d9b920206091ab3d4e031cf" - integrity sha1-pMIXoN2aUFFdm5ICBgkas9TgMc8= - dependencies: - ansi-colors "^0.2.0" - error-symbol "^0.1.0" - info-symbol "^0.1.0" - log-ok "^0.1.1" - success-symbol "^0.1.0" - time-stamp "^1.0.1" - warning-symbol "^0.1.0" - -logging-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/logging-helpers/-/logging-helpers-1.0.0.tgz#b5a37b32ad53eb0137c58c7898a47b175ddb7c36" - integrity sha512-qyIh2goLt1sOgQQrrIWuwkRjUx4NUcEqEGAcYqD8VOnOC6ItwkrVE8/tA4smGpjzyp4Svhc6RodDp9IO5ghpyA== - dependencies: - isobject "^3.0.0" - log-utils "^0.2.1" - loose-envify@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -6426,17 +5657,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -markdown-it@^12.0.2: - version "12.0.4" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.0.4.tgz#eec8247d296327eac3ba9746bdeec9cfcc751e33" - integrity sha512-34RwOXZT8kyuOJy25oJNJoulO8L0bTHYWXcdZBYZqFnjIy3NgjeoM3FmPXIOFQ26/lSHYMr8oc62B6adxXcb3Q== - dependencies: - argparse "^2.0.1" - entities "~2.1.0" - linkify-it "^3.0.1" - mdurl "^1.0.1" - uc.micro "^1.0.5" - matcher@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca" @@ -6444,11 +5664,6 @@ matcher@^3.0.0: dependencies: escape-string-regexp "^4.0.0" -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -6558,11 +5773,6 @@ mime@^1.3.4, mime@^1.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.3.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" - integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== - mime@^2.4.6: version "2.4.6" resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" @@ -6617,11 +5827,6 @@ mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.4: dependencies: minimist "^1.2.5" -moment@^2.18.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" - integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== - mongodb@3.6.3: version "3.6.3" resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.6.3.tgz#eddaed0cc3598474d7a15f0f2a5b04848489fd05" @@ -6640,11 +5845,6 @@ mri@1.1.4: resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" integrity sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w== -mri@^1.1.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.6.tgz#49952e1044db21dbf90f6cd92bc9c9a777d415a6" - integrity sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ== - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -6706,11 +5906,6 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== -nanoid@^2.1.0: - version "2.1.11" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280" - integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA== - nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -6758,11 +5953,6 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -neo-async@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - new-github-issue-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/new-github-issue-url/-/new-github-issue-url-0.2.1.tgz#e17be1f665a92de465926603e44b9f8685630c1d" @@ -6927,14 +6117,6 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== -object-is@^1.0.1: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - object-keys@^1.0.12, object-keys@^1.0.6, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -7145,11 +6327,6 @@ pako@^1.0.5: resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== -parchment@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/parchment/-/parchment-1.1.4.tgz#aeded7ab938fe921d4c34bc339ce1168bc2ffde5" - integrity sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg== - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -7233,11 +6410,6 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -7823,27 +6995,6 @@ quick-format-unescaped@^4.0.1: resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.1.tgz#437a5ea1a0b61deb7605f8ab6a8fd3858dbeb701" integrity sha512-RyYpQ6Q5/drsJyOhrWHYMWTedvjTIat+FTwv0K4yoUxzvekw2aRHMQJLlnvt8UantkZg2++bEzD9EdxXqkWf4A== -quill-delta@^3.6.2: - version "3.6.3" - resolved "https://registry.yarnpkg.com/quill-delta/-/quill-delta-3.6.3.tgz#b19fd2b89412301c60e1ff213d8d860eac0f1032" - integrity sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg== - dependencies: - deep-equal "^1.0.1" - extend "^3.0.2" - fast-diff "1.1.2" - -quill@^1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/quill/-/quill-1.3.7.tgz#da5b2f3a2c470e932340cdbf3668c9f21f9286e8" - integrity sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g== - dependencies: - clone "^2.1.1" - deep-equal "^1.0.1" - eventemitter3 "^2.0.3" - extend "^3.0.2" - parchment "^1.1.4" - quill-delta "^3.6.2" - raw-body@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" @@ -8020,19 +7171,6 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -regexparam@1.3.0, regexparam@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f" - integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g== - regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" @@ -8052,26 +7190,6 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" -relative@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/relative/-/relative-3.0.2.tgz#0dcd8ec54a5d35a3c15e104503d65375b5a5367f" - integrity sha1-Dc2OxUpdNaPBXhBFA9ZTdbWlNn8= - dependencies: - isobject "^2.0.0" - -remarkable@^1.6.2, remarkable@^1.7.1: - version "1.7.4" - resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.4.tgz#19073cb960398c87a7d6546eaa5e50d2022fcd00" - integrity sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg== - dependencies: - argparse "^1.0.10" - autolinker "~0.28.0" - -remixicon@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/remixicon/-/remixicon-2.5.0.tgz#b5e245894a1550aa23793f95daceadbf96ad1a41" - integrity sha512-q54ra2QutYDZpuSnFjmeagmEiN9IMo56/zz5dDNitzKD23oFRw77cWo4TsrAdmdkPiEn8mxlrTqxnkujDbEGww== - remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -8258,13 +7376,6 @@ rxjs@^6.6.0: dependencies: tslib "^1.9.0" -sade@^1.4.0: - version "1.7.4" - resolved "https://registry.yarnpkg.com/sade/-/sade-1.7.4.tgz#ea681e0c65d248d2095c90578c03ca0bb1b54691" - integrity sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA== - dependencies: - mri "^1.1.0" - safe-buffer@*, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -8343,11 +7454,6 @@ seek-bzip@^1.0.5: dependencies: commander "^2.8.1" -self-closing-tags@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/self-closing-tags/-/self-closing-tags-1.0.1.tgz#6c5fa497994bb826b484216916371accee490a5d" - integrity sha512-7t6hNbYMxM+VHXTgJmxwgZgLGktuXtVVD5AivWzNTdJBM4DBjnDKDzkf2SrNjihaArpeJYNjxkELBu1evI4lQA== - semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" @@ -8399,13 +7505,6 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -set-getter@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376" - integrity sha1-12nBgsnVpR9AkUXy+6guXoboA3Y= - dependencies: - to-object-path "^0.3.0" - set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -8438,23 +7537,11 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - shell-env@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/shell-env/-/shell-env-0.3.0.tgz#2250339022989165bda4eb7bf383afeaaa92dc34" @@ -8476,39 +7563,11 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== -shortid@^2.2.15: - version "2.2.16" - resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.16.tgz#b742b8f0cb96406fd391c76bfc18a67a57fe5608" - integrity sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g== - dependencies: - nanoid "^2.1.0" - signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== -sirv-cli@^0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/sirv-cli/-/sirv-cli-0.4.6.tgz#c28ab20deb3b34637f5a60863dc350f055abca04" - integrity sha512-/Vj85/kBvPL+n9ibgX6FicLE8VjidC1BhlX67PYPBfbBAphzR6i0k0HtU5c2arejfU3uzq8l3SYPCwl1x7z6Ww== - dependencies: - console-clear "^1.1.0" - get-port "^3.2.0" - kleur "^3.0.0" - local-access "^1.0.1" - sade "^1.4.0" - sirv "^0.4.6" - tinydate "^1.0.0" - -sirv@^0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-0.4.6.tgz#185e44eb93d24009dd183b7494285c5180b81f22" - integrity sha512-rYpOXlNbpHiY4nVXxuDf4mXPvKz1reZGap/LkWp9TvcZ84qD/nPBjjH/6GZsgIjVMbOslnY8YYULAyP8jMn1GQ== - dependencies: - "@polka/url" "^0.5.0" - mime "^2.3.1" - sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -8899,11 +7958,6 @@ strip-outer@^1.0.0: dependencies: escape-string-regexp "^1.0.2" -striptags@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.1.1.tgz#c8c3e7fdd6fb4bb3a32a3b752e5b5e3e38093ebd" - integrity sha1-yMPn/db7S7OjKjt1LltePjgJPr0= - sublevel-pouchdb@7.2.2: version "7.2.2" resolved "https://registry.yarnpkg.com/sublevel-pouchdb/-/sublevel-pouchdb-7.2.2.tgz#49e46cd37883bf7ff5006d7c5b9bcc7bcc1f422f" @@ -8914,11 +7968,6 @@ sublevel-pouchdb@7.2.2: ltgt "2.2.1" readable-stream "1.1.14" -success-symbol@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/success-symbol/-/success-symbol-0.1.0.tgz#24022e486f3bf1cdca094283b769c472d3b72897" - integrity sha1-JAIuSG878c3KCUKDt2nEctO3KJc= - sumchecker@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42" @@ -8971,99 +8020,11 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -svelte-apexcharts@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/svelte-apexcharts/-/svelte-apexcharts-1.0.2.tgz#4e000f8b8f7c901c05658c845457dfc8314d54c1" - integrity sha512-6qlx4rE+XsonZ0FZudfwqOQ34Pq+3wpxgAD75zgEmGoYhYBJcwmikTuTf3o8ZBsZue9U/pAwhNy3ed1Bkq1gmA== - dependencies: - apexcharts "^3.19.2" - -svelte-flatpickr@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/svelte-flatpickr/-/svelte-flatpickr-2.4.0.tgz#190871fc3305956c8c8fd3601cd036b8ac71ef49" - integrity sha512-UUC5Te+b0qi4POg7VDwfGh0m5W3Hf64OwkfOTj6FEe/dYZN4cBzpQ82EuuQl0CTbbBAsMkcjJcixV1d2V6EHCQ== - dependencies: - flatpickr "^4.5.2" - -svelte-flatpickr@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/svelte-flatpickr/-/svelte-flatpickr-3.1.0.tgz#ad83588430dbd55196a1a258b8ba27e7f9c1ee37" - integrity sha512-zKyV+ukeVuJ8CW0Ing3T19VSekc4bPkou/5Riutt1yATrLvSsanNqcgqi7Q5IePvIoOF9GJ5OtHvn1qK9Wx9BQ== - dependencies: - flatpickr "^4.5.2" - -svelte-portal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/svelte-portal/-/svelte-portal-1.0.0.tgz#36a47c5578b1a4d9b4dc60fa32a904640ec4cdd3" - integrity sha512-nHf+DS/jZ6jjnZSleBMSaZua9JlG5rZv9lOGKgJuaZStfevtjIlUJrkLc3vbV8QdBvPPVmvcjTlazAzfKu0v3Q== - -svelte-spa-router@^3.0.5: - version "3.1.0" - resolved "https://registry.yarnpkg.com/svelte-spa-router/-/svelte-spa-router-3.1.0.tgz#a929f0def7e12c41f32bc356f91685aeadcd75bf" - integrity sha512-jlM/xwjn57mylr+pzHYCOOy+IPQauT46gOucNGTBu6jHcFXu3F+oaojN4PXC1LYizRGxFB6QA0qnYbZnRfX7Sg== - dependencies: - regexparam "1.3.0" - svelte@3.30.0: version "3.30.0" resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.30.0.tgz#cbde341e96bf34f4ac73c8f14f8a014e03bfb7d6" integrity sha512-z+hdIACb9TROGvJBQWcItMtlr4s0DBUgJss6qWrtFkOoIInkG+iAMo/FJZQFyDBQZc+dul2+TzYSi/tpTT5/Ag== -svg.draggable.js@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz#c514a2f1405efb6f0263e7958f5b68fce50603ba" - integrity sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw== - dependencies: - svg.js "^2.0.1" - -svg.easing.js@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/svg.easing.js/-/svg.easing.js-2.0.0.tgz#8aa9946b0a8e27857a5c40a10eba4091e5691f12" - integrity sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI= - dependencies: - svg.js ">=2.3.x" - -svg.filter.js@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/svg.filter.js/-/svg.filter.js-2.0.2.tgz#91008e151389dd9230779fcbe6e2c9a362d1c203" - integrity sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM= - dependencies: - svg.js "^2.2.5" - -svg.js@>=2.3.x, svg.js@^2.0.1, svg.js@^2.2.5, svg.js@^2.4.0, svg.js@^2.6.5: - version "2.7.1" - resolved "https://registry.yarnpkg.com/svg.js/-/svg.js-2.7.1.tgz#eb977ed4737001eab859949b4a398ee1bb79948d" - integrity sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA== - -svg.pathmorphing.js@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz#c25718a1cc7c36e852ecabc380e758ac09bb2b65" - integrity sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww== - dependencies: - svg.js "^2.4.0" - -svg.resize.js@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/svg.resize.js/-/svg.resize.js-1.4.3.tgz#885abd248e0cd205b36b973c4b578b9a36f23332" - integrity sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw== - dependencies: - svg.js "^2.6.5" - svg.select.js "^2.1.2" - -svg.select.js@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-2.1.2.tgz#e41ce13b1acff43a7441f9f8be87a2319c87be73" - integrity sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ== - dependencies: - svg.js "^2.2.5" - -svg.select.js@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/svg.select.js/-/svg.select.js-3.0.1.tgz#a4198e359f3825739226415f82176a90ea5cc917" - integrity sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw== - dependencies: - svg.js "^2.6.5" - symbol-tree@^3.2.2: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -9218,11 +8179,6 @@ through@^2.3.6, through@^2.3.8, through@~2.3.4: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -time-stamp@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" - integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= - timed-out@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -9243,11 +8199,6 @@ tinycolor2@^1.4.1: resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA== -tinydate@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/tinydate/-/tinydate-1.3.0.tgz#e6ca8e5a22b51bb4ea1c3a2a4fd1352dbd4c57fb" - integrity sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w== - tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -9270,11 +8221,6 @@ to-fast-properties@^2.0.0: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= -to-gfm-code-block@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/to-gfm-code-block/-/to-gfm-code-block-0.1.1.tgz#25d045a5fae553189e9637b590900da732d8aa82" - integrity sha1-JdBFpfrlUxielje1kJANpzLYqoI= - to-json-schema@0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/to-json-schema/-/to-json-schema-0.2.5.tgz#ef3c3f11ad64460dcfbdbafd0fd525d69d62a98f" @@ -9391,13 +8337,6 @@ tunnel@0.0.6, tunnel@^0.0.6: resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== -turndown@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/turndown/-/turndown-7.0.0.tgz#19b2a6a2d1d700387a1e07665414e4af4fec5225" - integrity sha512-G1FfxfR0mUNMeGjszLYl3kxtopC4O9DRRiMlMDDVHvU1jaBkGFg4qxIyjIk2aiKLHyDyZvZyu4qBO2guuYBy3Q== - dependencies: - domino "^2.1.6" - tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -9450,23 +8389,6 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typeof-article@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/typeof-article/-/typeof-article-0.1.1.tgz#9f07e733c3fbb646ffa9e61c08debacd460e06af" - integrity sha1-nwfnM8P7tkb/qeYcCN66zUYOBq8= - dependencies: - kind-of "^3.1.0" - -uc.micro@^1.0.1, uc.micro@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" - integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== - -uglify-js@^3.1.4: - version "3.13.2" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.2.tgz#fe10319861bccc8682bfe2e8151fbdd8aa921c44" - integrity sha512-SbMu4D2Vo95LMC/MetNaso1194M1htEA+JrqE9Hk+G2DhI+itfS9TRu9ZKeCahLDNa/J3n4MqUJ/fOHMzQpRWw== - unbox-primitive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.0.tgz#eeacbc4affa28e9b3d36b5eaeccc50b3251b1d3f" @@ -9711,11 +8633,6 @@ walker@^1.0.7, walker@~1.0.5: dependencies: makeerror "1.0.x" -warning-symbol@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/warning-symbol/-/warning-symbol-0.1.0.tgz#bb31dd11b7a0f9d67ab2ed95f457b65825bbad21" - integrity sha1-uzHdEbeg+dZ6su2V9Fe2WCW7rSE= - webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -9774,13 +8691,6 @@ which@^1.2.9, which@^1.3.0: dependencies: isexe "^2.0.0" -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - widest-line@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" @@ -9793,11 +8703,6 @@ word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - worker-farm@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" @@ -10036,11 +8941,6 @@ yauzl@^2.10.0, yauzl@^2.4.2: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" -year@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/year/-/year-0.2.1.tgz#4083ae520a318b23ec86037f3000cb892bdf9bb0" - integrity sha1-QIOuUgoxiyPshgN/MADLiSvfm7A= - ylru@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" diff --git a/packages/worker/package.json b/packages/worker/package.json index 8f9e301399..5ab414dab1 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -19,6 +19,7 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { + "@budibase/auth": "0.0.1", "@koa/router": "^8.0.0", "aws-sdk": "^2.811.0", "bcryptjs": "^2.4.3", diff --git a/packages/worker/src/api/controllers/admin/auth.js b/packages/worker/src/api/controllers/admin/auth.js index f6b25091ac..07b08c7d1f 100644 --- a/packages/worker/src/api/controllers/admin/auth.js +++ b/packages/worker/src/api/controllers/admin/auth.js @@ -1,9 +1,15 @@ const jwt = require("jsonwebtoken") const CouchDB = require("../../../db") -const passport = require("koa-passport") +const passport = require("@budibase/auth") exports.authenticate = async (ctx, next) => { - return passport.authenticate("local", (err, user, info, status) => { + return passport.authenticate("local", async (err, user, info, status) => { + // TODO: better + if (err) { + ctx.throw(err) + } + + // await ctx.login(user) ctx.body = { err, user, diff --git a/packages/worker/src/api/routes/admin/auth.js b/packages/worker/src/api/routes/admin/auth.js deleted file mode 100644 index ca41e9e19e..0000000000 --- a/packages/worker/src/api/routes/admin/auth.js +++ /dev/null @@ -1,8 +0,0 @@ -// const Router = require("@koa/router") -// const controller = require("../controllers/auth") - -// const router = Router() - -// router.post("/api/authenticate", controller.authenticate) - -// module.exports = router diff --git a/packages/worker/src/api/routes/admin/index.js b/packages/worker/src/api/routes/admin/index.js index cf3a5c021a..5a6aaf77e6 100644 --- a/packages/worker/src/api/routes/admin/index.js +++ b/packages/worker/src/api/routes/admin/index.js @@ -1,15 +1,16 @@ const Router = require("@koa/router") +const passport = require("@budibase/auth") const controller = require("../../controllers/admin") const authController = require("../../controllers/admin/auth") -const authorized = require("../../../middleware/authorized") +const authenticated = require("../../../middleware/authenticated") const router = Router() router - .post("/api/admin/users", authorized, controller.userSave) + .post("/api/admin/users", authenticated, controller.userSave) .post("/api/admin/authenticate", authController.authenticate) - .delete("/api/admin/users/:email", authorized, controller.userDelete) - .get("/api/admin/users", authorized, controller.userFetch) - .get("/api/admin/users/:email", authorized, controller.userFind) + .delete("/api/admin/users/:email", authenticated, controller.userDelete) + .get("/api/admin/users", passport.authenticate("jwt"), controller.userFetch) + .get("/api/admin/users/:email", authenticated, controller.userFind) module.exports = router diff --git a/packages/worker/src/index.js b/packages/worker/src/index.js index 199bb1d31b..aad8bf54f7 100644 --- a/packages/worker/src/index.js +++ b/packages/worker/src/index.js @@ -1,7 +1,7 @@ const Koa = require("koa") const destroyable = require("server-destroy") const koaBody = require("koa-body") -const passport = require("koa-passport") +const passport = require("@budibase/auth") const logger = require("koa-pino-logger") const http = require("http") const api = require("./api") @@ -26,7 +26,6 @@ app.use( ) // authentication -require("./middleware/auth") app.use(passport.initialize()) app.use(passport.session()) diff --git a/packages/worker/src/middleware/auth/google.js b/packages/worker/src/middleware/auth/google.js deleted file mode 100644 index fd33bc89a3..0000000000 --- a/packages/worker/src/middleware/auth/google.js +++ /dev/null @@ -1,13 +0,0 @@ -// const GoogleStrategy = require("passport-google-auth").Strategy - -exports.options = { - clientId: "your-client-id", - clientSecret: "your-secret", - callbackURL: - "http://localhost:" + (process.env.PORT || 3000) + "/auth/google/callback", -} - -exports.authenticate = async function(token, tokenSecret, profile, done) { - // retrieve user ... - // fetchUser().then(user => done(null, user)) -} diff --git a/packages/worker/src/middleware/auth/index.js b/packages/worker/src/middleware/auth/index.js deleted file mode 100644 index 3eac2badbf..0000000000 --- a/packages/worker/src/middleware/auth/index.js +++ /dev/null @@ -1,20 +0,0 @@ -const passport = require("koa-passport") -const LocalStrategy = require("passport-local").Strategy -const JwtStrategy = require("passport-jwt").Strategy -const GoogleStrategy = require("passport-google-oauth").Strategy -const jwt = require("./jwt") -const local = require("./local") -const google = require("./google") - -// Strategies -passport.use(new LocalStrategy(local.options, local.authenticate)) -passport.use(new JwtStrategy(jwt.options, jwt.authenticate)) -// passport.use(new GoogleStrategy(google.options, google.authenticate)) - -// exports.middleware = async (ctx, next) => { -// if (ctx.isAuthenticated()) { -// return next() -// } else { -// ctx.throw(403, "Not Authenticated") -// } -// } diff --git a/packages/worker/src/middleware/auth/jwt.js b/packages/worker/src/middleware/auth/jwt.js deleted file mode 100644 index 8313d5abca..0000000000 --- a/packages/worker/src/middleware/auth/jwt.js +++ /dev/null @@ -1,38 +0,0 @@ -const jwt = require("passport-jwt") -const env = require("../../environment") -const { getCookieName } = require("../../../../server/src/utilities") - -const ExtractJWT = jwt.ExtractJwt - -exports.options = { - jwtFromRequest: function(ctx) { - return ctx.cookies.get("budibase") - }, - // TODO: fix - secretOrKey: env.JWT_SECRET || "funky", -} - -exports.authenticate = async function(jwt, done) { - console.log(jwt) - done({ name: "joe" }) - // const appId = ctx.appId - // if (!appId) ctx.throw(400, "No appId") - - // const { email, password } = ctx.request.body - - // if (!email) ctx.throw(400, "Email Required.") - // if (!password) ctx.throw(400, "Password Required.") - - // // Check the user exists in the instance DB by email - // const db = new CouchDB(appId) - // const app = await db.get(appId) - - // let dbUser - // try { - // dbUser = await db.get(generateUserID(email)) - // } catch (_) { - // // do not want to throw a 404 - as this could be - // // used to determine valid emails - // ctx.throw(401, INVALID_ERR) - // } -} diff --git a/packages/worker/src/middleware/authorized.js b/packages/worker/src/middleware/authorized.js index 86a5ab27db..716f55fbd5 100644 --- a/packages/worker/src/middleware/authorized.js +++ b/packages/worker/src/middleware/authorized.js @@ -3,5 +3,5 @@ * a global user record. */ module.exports = async (ctx, next) => { - next() + return next() } From f135aa9db439aa3a94d9ac236777aab9ca17d4c9 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Wed, 7 Apr 2021 15:15:05 +0100 Subject: [PATCH 017/135] JWT auth on admin endpoints --- packages/auth/src/index.js | 3 +-- packages/auth/src/middleware/authenticated.js | 2 +- packages/auth/src/middleware/index.js | 6 ++--- .../src/middleware/{ => passport}/google.js | 2 +- .../auth/src/middleware/{ => passport}/jwt.js | 5 +--- .../src/middleware/{ => passport}/local.js | 8 +++--- .../worker/src/api/controllers/admin/auth.js | 25 ++++++++++--------- packages/worker/src/api/routes/admin/index.js | 15 ++++++++--- 8 files changed, 35 insertions(+), 31 deletions(-) rename packages/auth/src/middleware/{ => passport}/google.js (91%) rename packages/auth/src/middleware/{ => passport}/jwt.js (71%) rename packages/auth/src/middleware/{ => passport}/local.js (88%) diff --git a/packages/auth/src/index.js b/packages/auth/src/index.js index 778d4fb32e..3088008086 100644 --- a/packages/auth/src/index.js +++ b/packages/auth/src/index.js @@ -5,7 +5,6 @@ const JwtStrategy = require("passport-jwt").Strategy const CouchDB = require("./db") const { StaticDatabases } = require("./db/utils") const { jwt, local, google } = require("./middleware") -const hashing = require("./hashing") // Strategies passport.use(new LocalStrategy(local.options, local.authenticate)) @@ -26,6 +25,6 @@ passport.deserializeUser(async (user, done) => { } }) -// exports.hashing = hashing +// exports.Cookies = Cookies module.exports = passport diff --git a/packages/auth/src/middleware/authenticated.js b/packages/auth/src/middleware/authenticated.js index f7ff086b67..7797649b18 100644 --- a/packages/auth/src/middleware/authenticated.js +++ b/packages/auth/src/middleware/authenticated.js @@ -22,7 +22,7 @@ module.exports = async (ctx, next) => { const cookieAppId = ctx.cookies.get(Cookies.CurrentApp) // const builtinRoles = getBuiltinRoles() if (appId && cookieAppId !== appId) { - setCookie(ctx, appId, "currentapp") + setCookie(ctx, appId, Cookies.CurrentApp) } else if (cookieAppId) { appId = cookieAppId } diff --git a/packages/auth/src/middleware/index.js b/packages/auth/src/middleware/index.js index a9d07516ed..9d822e5937 100644 --- a/packages/auth/src/middleware/index.js +++ b/packages/auth/src/middleware/index.js @@ -1,6 +1,6 @@ -const jwt = require("./jwt") -const local = require("./local") -const google = require("./google") +const jwt = require("./passport/jwt") +const local = require("./passport/local") +const google = require("./passport/google") module.exports = { google, diff --git a/packages/auth/src/middleware/google.js b/packages/auth/src/middleware/passport/google.js similarity index 91% rename from packages/auth/src/middleware/google.js rename to packages/auth/src/middleware/passport/google.js index 008d4a6816..1ee6583b59 100644 --- a/packages/auth/src/middleware/google.js +++ b/packages/auth/src/middleware/passport/google.js @@ -1,4 +1,4 @@ -const CouchDB = require("../db") +// const CouchDB = require("../db") exports.options = { clientId: process.env.GOOGLE_CLIENT_ID, diff --git a/packages/auth/src/middleware/jwt.js b/packages/auth/src/middleware/passport/jwt.js similarity index 71% rename from packages/auth/src/middleware/jwt.js rename to packages/auth/src/middleware/passport/jwt.js index 5d36f0b91e..a619ab994b 100644 --- a/packages/auth/src/middleware/jwt.js +++ b/packages/auth/src/middleware/passport/jwt.js @@ -1,7 +1,4 @@ -// const jwt = require("passport-jwt") -const { Cookies } = require("../constants") - -// const ExtractJWT = jwt.ExtractJwt +const { Cookies } = require("../../constants") exports.options = { jwtFromRequest: function(ctx) { diff --git a/packages/auth/src/middleware/local.js b/packages/auth/src/middleware/passport/local.js similarity index 88% rename from packages/auth/src/middleware/local.js rename to packages/auth/src/middleware/passport/local.js index 85a68af87c..379ec58dbb 100644 --- a/packages/auth/src/middleware/local.js +++ b/packages/auth/src/middleware/passport/local.js @@ -1,8 +1,8 @@ const jwt = require("jsonwebtoken") -const { UserStatus } = require("../constants") -const CouchDB = require("../db") -const { StaticDatabases, generateUserID } = require("../db/utils") -const { compare } = require("../hashing") +const { UserStatus } = require("../../constants") +const CouchDB = require("../../db") +const { StaticDatabases, generateUserID } = require("../../db/utils") +const { compare } = require("../../hashing") const INVALID_ERR = "Invalid Credentials" diff --git a/packages/worker/src/api/controllers/admin/auth.js b/packages/worker/src/api/controllers/admin/auth.js index 07b08c7d1f..2c41c1f47d 100644 --- a/packages/worker/src/api/controllers/admin/auth.js +++ b/packages/worker/src/api/controllers/admin/auth.js @@ -1,20 +1,21 @@ -const jwt = require("jsonwebtoken") -const CouchDB = require("../../../db") const passport = require("@budibase/auth") exports.authenticate = async (ctx, next) => { - return passport.authenticate("local", async (err, user, info, status) => { - // TODO: better + return passport.authenticate("local", async (err, user) => { if (err) { - ctx.throw(err) + return ctx.throw(err) } - // await ctx.login(user) - ctx.body = { - err, - user, - info, - status, - } + const expires = new Date() + expires.setDate(expires.getDate() + 1) + + ctx.cookies.set("budibase:auth", user.token, { + expires, + path: "/", + httpOnly: false, + overwrite: true, + }) + + ctx.body = { success: true } })(ctx, next) } diff --git a/packages/worker/src/api/routes/admin/index.js b/packages/worker/src/api/routes/admin/index.js index 5a6aaf77e6..c87e395a22 100644 --- a/packages/worker/src/api/routes/admin/index.js +++ b/packages/worker/src/api/routes/admin/index.js @@ -2,15 +2,22 @@ const Router = require("@koa/router") const passport = require("@budibase/auth") const controller = require("../../controllers/admin") const authController = require("../../controllers/admin/auth") -const authenticated = require("../../../middleware/authenticated") const router = Router() router - .post("/api/admin/users", authenticated, controller.userSave) + .post("/api/admin/users", passport.authenticate("jwt"), controller.userSave) .post("/api/admin/authenticate", authController.authenticate) - .delete("/api/admin/users/:email", authenticated, controller.userDelete) + .delete( + "/api/admin/users/:email", + passport.authenticate("jwt"), + controller.userDelete + ) .get("/api/admin/users", passport.authenticate("jwt"), controller.userFetch) - .get("/api/admin/users/:email", authenticated, controller.userFind) + .get( + "/api/admin/users/:email", + passport.authenticate("jwt"), + controller.userFind + ) module.exports = router From 5ac3d455c15ae93ca0f2d06f050703dc6130a01e Mon Sep 17 00:00:00 2001 From: Theo Melo <9499829+theomelo@users.noreply.github.com> Date: Wed, 7 Apr 2021 15:27:06 -0700 Subject: [PATCH 018/135] fix(README): References to HEAD --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d3db6144b6..5ecf9d3ecb 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Code of conduct - +

@@ -93,7 +93,7 @@ Watch "releases" of this repo to get notified of major updates, and give the sta [![Stargazers over time](https://starchart.cc/Budibase/budibase.svg)](https://starchart.cc/Budibase/budibase) -If you are having issues between updates of the builder, please use the guide [here](https://github.com/Budibase/budibase/blob/next/.github/CONTRIBUTING.md#troubleshooting) to clear down your environment. +If you are having issues between updates of the builder, please use the guide [here](https://github.com/Budibase/budibase/blob/HEAD/.github/CONTRIBUTING.md#troubleshooting) to clear down your environment. ## 🏁 Getting Started with Budibase @@ -131,7 +131,7 @@ Checkout our [Public Roadmap](https://github.com/Budibase/budibase/projects/10). ## ❗ Code of Conduct -Budibase is dedicated to providing a welcoming, diverse, and harrassment-free experience for everyone. We expect everyone in the Budibase community to abide by our [**Code of Conduct**](https://github.com/Budibase/budibase/blob/next/.github/CODE_OF_CONDUCT.md). Please read it. +Budibase is dedicated to providing a welcoming, diverse, and harrassment-free experience for everyone. We expect everyone in the Budibase community to abide by our [**Code of Conduct**](https://github.com/Budibase/budibase/blob/HEAD/.github/CODE_OF_CONDUCT.md). Please read it. ## 🙌 Contributing to Budibase @@ -143,13 +143,13 @@ A good place to start contributing, is the [First time issues project](https://g ### How the repository is organized Budibase is a monorepo managed by lerna. Lerna manages the building and publishing of the budibase packages. At a high level, here are the packages that make up Budibase. -- [packages/builder](https://github.com/Budibase/budibase/tree/next/packages/builder) - contains code for the budibase builder client side svelte application. +- [packages/builder](https://github.com/Budibase/budibase/tree/HEAD/packages/builder) - contains code for the budibase builder client side svelte application. -- [packages/client](https://github.com/Budibase/budibase/tree/next/packages/client) - A module that runs in the browser responsible for reading JSON definition and creating living, breathing web apps from it. +- [packages/client](https://github.com/Budibase/budibase/tree/HEAD/packages/client) - A module that runs in the browser responsible for reading JSON definition and creating living, breathing web apps from it. -- [packages/server](https://github.com/Budibase/budibase/tree/next/packages/server) - The budibase server. This Koa app is responsible for serving the JS for the builder and budibase apps, as well as providing the API for interaction with the database and file system. +- [packages/server](https://github.com/Budibase/budibase/tree/HEAD/packages/server) - The budibase server. This Koa app is responsible for serving the JS for the builder and budibase apps, as well as providing the API for interaction with the database and file system. -For more information, see [CONTRIBUTING.md](https://github.com/Budibase/budibase/blob/next/.github/CONTRIBUTING.md) +For more information, see [CONTRIBUTING.md](https://github.com/Budibase/budibase/blob/HEAD/.github/CONTRIBUTING.md) ## 📝 License From c7f4070ff5462e8995f7ebb3a50978f883960919 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 8 Apr 2021 11:20:37 +0100 Subject: [PATCH 019/135] encapsulate more auth functionality into shared module and use in worker --- packages/auth/src/db/utils.js | 2 + packages/auth/src/index.js | 15 +++- packages/auth/src/middleware/authenticated.js | 73 ----------------- packages/auth/src/utils.js | 79 ++++++++++++++++++ .../src/api/controllers/search/index.js | 2 +- .../worker/src/api/controllers/admin/auth.js | 2 +- packages/worker/src/api/routes/admin/index.js | 17 ++-- packages/worker/src/db/utils.js | 3 + packages/worker/src/index.js | 2 +- .../worker/src/middleware/authenticated.js | 44 ++++++++++ packages/worker/src/utils.js | 81 +++++++++++++++++-- 11 files changed, 222 insertions(+), 98 deletions(-) delete mode 100644 packages/auth/src/middleware/authenticated.js create mode 100644 packages/auth/src/utils.js create mode 100644 packages/worker/src/middleware/authenticated.js diff --git a/packages/auth/src/db/utils.js b/packages/auth/src/db/utils.js index cda7708825..17d09ceaeb 100644 --- a/packages/auth/src/db/utils.js +++ b/packages/auth/src/db/utils.js @@ -8,6 +8,8 @@ const DocumentTypes = { USER: "us", } +exports.DocumentTypes = DocumentTypes + const UNICODE_MAX = "\ufff0" const SEPARATOR = "_" diff --git a/packages/auth/src/index.js b/packages/auth/src/index.js index 3088008086..84e3fe6595 100644 --- a/packages/auth/src/index.js +++ b/packages/auth/src/index.js @@ -5,6 +5,9 @@ const JwtStrategy = require("passport-jwt").Strategy const CouchDB = require("./db") const { StaticDatabases } = require("./db/utils") const { jwt, local, google } = require("./middleware") +const { Cookies, UserStatus } = require("./constants") +const { hash, compare } = require("./hashing") +const { getAppId, setCookie } = require("./utils") // Strategies passport.use(new LocalStrategy(local.options, local.authenticate)) @@ -25,6 +28,12 @@ passport.deserializeUser(async (user, done) => { } }) -// exports.Cookies = Cookies - -module.exports = passport +module.exports = { + passport, + Cookies, + UserStatus, + hash, + compare, + getAppId, + setCookie, +} diff --git a/packages/auth/src/middleware/authenticated.js b/packages/auth/src/middleware/authenticated.js deleted file mode 100644 index 7797649b18..0000000000 --- a/packages/auth/src/middleware/authenticated.js +++ /dev/null @@ -1,73 +0,0 @@ -const jwt = require("jsonwebtoken") -const STATUS_CODES = require("../utilities/statusCodes") -const { getRole, getBuiltinRoles } = require("../utilities/security/roles") -const { AuthTypes, Cookies } = require("../constants") -const { - getAppId, - getCookieName, - clearCookie, - setCookie, - isClient, -} = require("../utilities") - -module.exports = async (ctx, next) => { - // if (ctx.path === "/_builder") { - // await next() - // return - // } - - // do everything we can to make sure the appId is held correctly - // we hold it in state as a - let appId = getAppId(ctx) - const cookieAppId = ctx.cookies.get(Cookies.CurrentApp) - // const builtinRoles = getBuiltinRoles() - if (appId && cookieAppId !== appId) { - setCookie(ctx, appId, Cookies.CurrentApp) - } else if (cookieAppId) { - appId = cookieAppId - } - let token, authType - // if (!isClient(ctx)) { - // token = ctx.cookies.get(getCookieName()) - // authType = AuthTypes.BUILDER - // } - - if (!token && appId) { - token = ctx.cookies.get(getCookieName(appId)) - // authType = AuthTypes.APP - } - - // if (!token) { - // ctx.auth.authenticated = false - // ctx.appId = appId - // ctx.user = { - // role: builtinRoles.PUBLIC, - // } - // await next() - // return - // } - - try { - // ctx.auth.authenticated = authType - const jwtPayload = jwt.verify(token, ctx.config.jwtSecret) - ctx.appId = appId - // ctx.auth.apiKey = jwtPayload.apiKey - ctx.user = { - ...jwtPayload, - role: await getRole(appId, jwtPayload.roleId), - } - // appId no longer carried in user, make sure - delete ctx.user.appId - } catch (err) { - console.log(err) - // if (authType === AuthTypes.BUILDER) { - // clearCookie(ctx) - // ctx.status = 200 - // return - // } else { - ctx.throw(err.status || STATUS_CODES.FORBIDDEN, err.text) - // } - } - - await next() -} diff --git a/packages/auth/src/utils.js b/packages/auth/src/utils.js new file mode 100644 index 0000000000..7eb39a3005 --- /dev/null +++ b/packages/auth/src/utils.js @@ -0,0 +1,79 @@ +const { DocumentTypes, SEPARATOR } = require("./db/utils") + +const APP_PREFIX = DocumentTypes.APP + SEPARATOR + +function confirmAppId(possibleAppId) { + return possibleAppId && possibleAppId.startsWith(APP_PREFIX) + ? possibleAppId + : undefined +} + +/** + * Given a request tries to find the appId, which can be located in various places + * @param {object} ctx The main request body to look through. + * @returns {string|undefined} If an appId was found it will be returned. + */ +exports.getAppId = ctx => { + const options = [ctx.headers["x-budibase-app-id"], ctx.params.appId] + if (ctx.subdomains) { + options.push(ctx.subdomains[1]) + } + let appId + for (let option of options) { + appId = confirmAppId(option) + if (appId) { + break + } + } + + // look in body if can't find it in subdomain + if (!appId && ctx.request.body && ctx.request.body.appId) { + appId = confirmAppId(ctx.request.body.appId) + } + let appPath = + ctx.request.headers.referrer || + ctx.path.split("/").filter(subPath => subPath.startsWith(APP_PREFIX)) + if (!appId && appPath.length !== 0) { + appId = confirmAppId(appPath[0]) + } + return appId +} + +/** + * Store a cookie for the request, has a hardcoded expiry. + * @param {object} ctx The request which is to be manipulated. + * @param {string} name The name of the cookie to set. + * @param {string|object} value The value of cookie which will be set. + */ +exports.setCookie = (ctx, value, name = "builder") => { + const expires = new Date() + expires.setDate(expires.getDate() + 1) + + if (!value) { + ctx.cookies.set(name) + } else { + ctx.cookies.set(name, value, { + expires, + path: "/", + httpOnly: false, + overwrite: true, + }) + } +} + +/** + * Utility function, simply calls setCookie with an empty string for value + */ +exports.clearCookie = (ctx, name) => { + exports.setCookie(ctx, "", name) +} + +/** + * Checks if the API call being made (based on the provided ctx object) is from the client. If + * the call is not from a client app then it is from the builder. + * @param {object} ctx The koa context object to be tested. + * @return {boolean} returns true if the call is from the client lib (a built app rather than the builder). + */ +exports.isClient = ctx => { + return ctx.headers["x-budibase-type"] === "client" +} diff --git a/packages/server/src/api/controllers/search/index.js b/packages/server/src/api/controllers/search/index.js index d3c588d079..234c7eb258 100644 --- a/packages/server/src/api/controllers/search/index.js +++ b/packages/server/src/api/controllers/search/index.js @@ -1,7 +1,7 @@ const { QueryBuilder, buildSearchUrl, search } = require("./utils") exports.rowSearch = async ctx => { - const appId = ctx.user.appId + const appId = ctx.appId const { tableId } = ctx.params const { bookmark, query, raw } = ctx.request.body let url diff --git a/packages/worker/src/api/controllers/admin/auth.js b/packages/worker/src/api/controllers/admin/auth.js index 2c41c1f47d..62128efedf 100644 --- a/packages/worker/src/api/controllers/admin/auth.js +++ b/packages/worker/src/api/controllers/admin/auth.js @@ -1,4 +1,4 @@ -const passport = require("@budibase/auth") +const { passport } = require("@budibase/auth") exports.authenticate = async (ctx, next) => { return passport.authenticate("local", async (err, user) => { diff --git a/packages/worker/src/api/routes/admin/index.js b/packages/worker/src/api/routes/admin/index.js index c87e395a22..1c64110d2a 100644 --- a/packages/worker/src/api/routes/admin/index.js +++ b/packages/worker/src/api/routes/admin/index.js @@ -2,22 +2,15 @@ const Router = require("@koa/router") const passport = require("@budibase/auth") const controller = require("../../controllers/admin") const authController = require("../../controllers/admin/auth") +const authenticated = require("../../../middleware/authenticated") const router = Router() router - .post("/api/admin/users", passport.authenticate("jwt"), controller.userSave) + .post("/api/admin/users", authenticated, controller.userSave) .post("/api/admin/authenticate", authController.authenticate) - .delete( - "/api/admin/users/:email", - passport.authenticate("jwt"), - controller.userDelete - ) - .get("/api/admin/users", passport.authenticate("jwt"), controller.userFetch) - .get( - "/api/admin/users/:email", - passport.authenticate("jwt"), - controller.userFind - ) + .delete("/api/admin/users/:email", authenticated, controller.userDelete) + .get("/api/admin/users", authenticated, controller.userFetch) + .get("/api/admin/users/:email", authenticated, controller.userFind) module.exports = router diff --git a/packages/worker/src/db/utils.js b/packages/worker/src/db/utils.js index cda7708825..b250b895bb 100644 --- a/packages/worker/src/db/utils.js +++ b/packages/worker/src/db/utils.js @@ -6,8 +6,11 @@ exports.StaticDatabases = { const DocumentTypes = { USER: "us", + APP: "app", } +exports.DocumentTypes = DocumentTypes + const UNICODE_MAX = "\ufff0" const SEPARATOR = "_" diff --git a/packages/worker/src/index.js b/packages/worker/src/index.js index aad8bf54f7..2e031b9f64 100644 --- a/packages/worker/src/index.js +++ b/packages/worker/src/index.js @@ -1,7 +1,7 @@ const Koa = require("koa") const destroyable = require("server-destroy") const koaBody = require("koa-body") -const passport = require("@budibase/auth") +const { passport } = require("@budibase/auth") const logger = require("koa-pino-logger") const http = require("http") const api = require("./api") diff --git a/packages/worker/src/middleware/authenticated.js b/packages/worker/src/middleware/authenticated.js new file mode 100644 index 0000000000..8701da7316 --- /dev/null +++ b/packages/worker/src/middleware/authenticated.js @@ -0,0 +1,44 @@ +const { passport, getAppId, setCookie, Cookies } = require("@budibase/auth") + +module.exports = async (ctx, next) => { + // do everything we can to make sure the appId is held correctly + let appId = getAppId(ctx) + const cookieAppId = ctx.cookies.get(Cookies.CurrentApp) + // const builtinRoles = getBuiltinRoles() + if (appId && cookieAppId !== appId) { + setCookie(ctx, appId, Cookies.CurrentApp) + } else if (cookieAppId) { + appId = cookieAppId + } + + let token + if (appId) { + token = ctx.cookies.get(Cookies.Auth) + } + + if (!token) { + ctx.auth = { + authenticated: true, + } + ctx.appId = appId + // ctx.user = { + // // TODO: introduce roles again + // // role: builtinRoles.PUBLIC, + // } + return await next() + } + + return passport.authenticate("jwt", async (err, user) => { + if (err) { + return ctx.throw(err) + } + + try { + ctx.user = user + await next() + } catch (err) { + console.log(err) + ctx.throw(err.status || 403, err.text) + } + })(ctx, next) +} diff --git a/packages/worker/src/utils.js b/packages/worker/src/utils.js index 0711ae67bf..260a64cda5 100644 --- a/packages/worker/src/utils.js +++ b/packages/worker/src/utils.js @@ -1,13 +1,80 @@ -const bcrypt = require("bcryptjs") const env = require("./environment") +const { DocumentTypes, SEPARATOR } = require("./db/utils") -const SALT_ROUNDS = env.SALT_ROUNDS || 10 +const APP_PREFIX = DocumentTypes.APP + SEPARATOR -exports.hash = async data => { - const salt = await bcrypt.genSalt(SALT_ROUNDS) - return bcrypt.hash(data, salt) +function confirmAppId(possibleAppId) { + return possibleAppId && possibleAppId.startsWith(APP_PREFIX) + ? possibleAppId + : undefined } -exports.compare = async (data, encrypted) => { - return bcrypt.compare(data, encrypted) +/** + * Given a request tries to find the appId, which can be located in various places + * @param {object} ctx The main request body to look through. + * @returns {string|undefined} If an appId was found it will be returned. + */ +exports.getAppId = ctx => { + const options = [ctx.headers["x-budibase-app-id"], ctx.params.appId] + if (ctx.subdomains) { + options.push(ctx.subdomains[1]) + } + let appId + for (let option of options) { + appId = confirmAppId(option) + if (appId) { + break + } + } + + // look in body if can't find it in subdomain + if (!appId && ctx.request.body && ctx.request.body.appId) { + appId = confirmAppId(ctx.request.body.appId) + } + let appPath = + ctx.request.headers.referrer || + ctx.path.split("/").filter(subPath => subPath.startsWith(APP_PREFIX)) + if (!appId && appPath.length !== 0) { + appId = confirmAppId(appPath[0]) + } + return appId +} + +/** + * Store a cookie for the request, has a hardcoded expiry. + * @param {object} ctx The request which is to be manipulated. + * @param {string} name The name of the cookie to set. + * @param {string|object} value The value of cookie which will be set. + */ +exports.setCookie = (ctx, value, name = "builder") => { + const expires = new Date() + expires.setDate(expires.getDate() + 1) + + if (!value) { + ctx.cookies.set(name) + } else { + ctx.cookies.set(name, value, { + expires, + path: "/", + httpOnly: false, + overwrite: true, + }) + } +} + +/** + * Utility function, simply calls setCookie with an empty string for value + */ +exports.clearCookie = (ctx, name) => { + exports.setCookie(ctx, "", name) +} + +/** + * Checks if the API call being made (based on the provided ctx object) is from the client. If + * the call is not from a client app then it is from the builder. + * @param {object} ctx The koa context object to be tested. + * @return {boolean} returns true if the call is from the client lib (a built app rather than the builder). + */ +exports.isClient = ctx => { + return ctx.headers["x-budibase-type"] === "client" } From 6aa7a38442ddf2796edcdcea75a3756a5f473ac7 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 8 Apr 2021 11:21:52 +0100 Subject: [PATCH 020/135] flip auth boolean --- hosting/generated-envoy.dev.yaml | 125 ++++++++++++++++++ .../worker/src/middleware/authenticated.js | 2 +- 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 hosting/generated-envoy.dev.yaml diff --git a/hosting/generated-envoy.dev.yaml b/hosting/generated-envoy.dev.yaml new file mode 100644 index 0000000000..72cad34104 --- /dev/null +++ b/hosting/generated-envoy.dev.yaml @@ -0,0 +1,125 @@ +static_resources: + listeners: + - name: main_listener + address: + socket_address: { address: 0.0.0.0, port_value: 10000 } + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: ingress + codec_type: auto + route_config: + name: local_route + virtual_hosts: + - name: local_services + domains: ["*"] + routes: + - match: { prefix: "/db/" } + route: + cluster: couchdb-service + prefix_rewrite: "/" + + - match: { prefix: "/cache/" } + route: + cluster: redis-service + prefix_rewrite: "/" + + - match: { prefix: "/api/" } + route: + cluster: server-dev + + - match: { prefix: "/app_" } + route: + cluster: server-dev + + - match: { prefix: "/builder/" } + route: + cluster: builder-dev + + - match: { prefix: "/builder" } + route: + cluster: builder-dev + prefix_rewrite: "/builder/" + + # minio is on the default route because this works + # best, minio + AWS SDK doesn't handle path proxy + - match: { prefix: "/" } + route: + cluster: minio-service + + http_filters: + - name: envoy.filters.http.router + + clusters: + - name: minio-service + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: minio-service + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: minio-service + port_value: 9000 + + - name: couchdb-service + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: couchdb-service + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: couchdb-service + port_value: 5984 + + - name: redis-service + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: redis-service + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: redis-service + port_value: 6379 + + - name: server-dev + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: server-dev + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: host.docker.internal + port_value: 4001 + + - name: builder-dev + connect_timeout: 15s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: builder-dev + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: host.docker.internal + port_value: 3000 + diff --git a/packages/worker/src/middleware/authenticated.js b/packages/worker/src/middleware/authenticated.js index 8701da7316..dd7e1d974d 100644 --- a/packages/worker/src/middleware/authenticated.js +++ b/packages/worker/src/middleware/authenticated.js @@ -18,7 +18,7 @@ module.exports = async (ctx, next) => { if (!token) { ctx.auth = { - authenticated: true, + authenticated: false, } ctx.appId = appId // ctx.user = { From fb2fda4055f85b3dc71713ca8c8752fa7f7fcc61 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 8 Apr 2021 11:26:08 +0100 Subject: [PATCH 021/135] encapsulate db ID generation functions --- packages/auth/src/index.js | 4 + .../worker/src/api/controllers/admin/index.js | 6 +- packages/worker/src/utils.js | 80 ------------------- 3 files changed, 7 insertions(+), 83 deletions(-) delete mode 100644 packages/worker/src/utils.js diff --git a/packages/auth/src/index.js b/packages/auth/src/index.js index 84e3fe6595..51431e4241 100644 --- a/packages/auth/src/index.js +++ b/packages/auth/src/index.js @@ -8,6 +8,7 @@ const { jwt, local, google } = require("./middleware") const { Cookies, UserStatus } = require("./constants") const { hash, compare } = require("./hashing") const { getAppId, setCookie } = require("./utils") +const { generateUserID, getUserParams } = require("./db/utils") // Strategies passport.use(new LocalStrategy(local.options, local.authenticate)) @@ -32,6 +33,9 @@ module.exports = { passport, Cookies, UserStatus, + StaticDatabases, + generateUserID, + getUserParams, hash, compare, getAppId, diff --git a/packages/worker/src/api/controllers/admin/index.js b/packages/worker/src/api/controllers/admin/index.js index b6531174bd..515feb8420 100644 --- a/packages/worker/src/api/controllers/admin/index.js +++ b/packages/worker/src/api/controllers/admin/index.js @@ -1,10 +1,10 @@ const CouchDB = require("../../../db") const { - StaticDatabases, + hash, generateUserID, getUserParams, -} = require("../../../db/utils") -const { hash } = require("../../../utils") + StaticDatabases, +} = require("@budibase/auth") const { UserStatus } = require("../../../constants") const USER_DB = StaticDatabases.USER.name diff --git a/packages/worker/src/utils.js b/packages/worker/src/utils.js deleted file mode 100644 index 260a64cda5..0000000000 --- a/packages/worker/src/utils.js +++ /dev/null @@ -1,80 +0,0 @@ -const env = require("./environment") -const { DocumentTypes, SEPARATOR } = require("./db/utils") - -const APP_PREFIX = DocumentTypes.APP + SEPARATOR - -function confirmAppId(possibleAppId) { - return possibleAppId && possibleAppId.startsWith(APP_PREFIX) - ? possibleAppId - : undefined -} - -/** - * Given a request tries to find the appId, which can be located in various places - * @param {object} ctx The main request body to look through. - * @returns {string|undefined} If an appId was found it will be returned. - */ -exports.getAppId = ctx => { - const options = [ctx.headers["x-budibase-app-id"], ctx.params.appId] - if (ctx.subdomains) { - options.push(ctx.subdomains[1]) - } - let appId - for (let option of options) { - appId = confirmAppId(option) - if (appId) { - break - } - } - - // look in body if can't find it in subdomain - if (!appId && ctx.request.body && ctx.request.body.appId) { - appId = confirmAppId(ctx.request.body.appId) - } - let appPath = - ctx.request.headers.referrer || - ctx.path.split("/").filter(subPath => subPath.startsWith(APP_PREFIX)) - if (!appId && appPath.length !== 0) { - appId = confirmAppId(appPath[0]) - } - return appId -} - -/** - * Store a cookie for the request, has a hardcoded expiry. - * @param {object} ctx The request which is to be manipulated. - * @param {string} name The name of the cookie to set. - * @param {string|object} value The value of cookie which will be set. - */ -exports.setCookie = (ctx, value, name = "builder") => { - const expires = new Date() - expires.setDate(expires.getDate() + 1) - - if (!value) { - ctx.cookies.set(name) - } else { - ctx.cookies.set(name, value, { - expires, - path: "/", - httpOnly: false, - overwrite: true, - }) - } -} - -/** - * Utility function, simply calls setCookie with an empty string for value - */ -exports.clearCookie = (ctx, name) => { - exports.setCookie(ctx, "", name) -} - -/** - * Checks if the API call being made (based on the provided ctx object) is from the client. If - * the call is not from a client app then it is from the builder. - * @param {object} ctx The koa context object to be tested. - * @return {boolean} returns true if the call is from the client lib (a built app rather than the builder). - */ -exports.isClient = ctx => { - return ctx.headers["x-budibase-type"] === "client" -} From 4abe6192dc56bf7bb2f30d56a61afdbabae0e04c Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 8 Apr 2021 11:53:40 +0100 Subject: [PATCH 022/135] further simplification of jwt auth --- .../worker/src/middleware/authenticated.js | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/packages/worker/src/middleware/authenticated.js b/packages/worker/src/middleware/authenticated.js index dd7e1d974d..751e10ee9a 100644 --- a/packages/worker/src/middleware/authenticated.js +++ b/packages/worker/src/middleware/authenticated.js @@ -11,29 +11,15 @@ module.exports = async (ctx, next) => { appId = cookieAppId } - let token - if (appId) { - token = ctx.cookies.get(Cookies.Auth) - } - - if (!token) { - ctx.auth = { - authenticated: false, - } - ctx.appId = appId - // ctx.user = { - // // TODO: introduce roles again - // // role: builtinRoles.PUBLIC, - // } - return await next() - } - return passport.authenticate("jwt", async (err, user) => { if (err) { - return ctx.throw(err) + return ctx.throw(err.status || 403, err) } try { + ctx.appId = appId + ctx.isAuthenticated = true + // TODO: introduce roles again ctx.user = user await next() } catch (err) { From 2077073986bab894df20ca2c02b1238fec485efd Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 8 Apr 2021 11:57:23 +0100 Subject: [PATCH 023/135] move auth controller into it's own dir --- packages/worker/src/api/controllers/{admin => }/auth.js | 0 packages/worker/src/api/routes/admin/index.js | 3 --- packages/worker/src/api/routes/auth.js | 8 ++++++++ packages/worker/src/api/routes/index.js | 3 ++- 4 files changed, 10 insertions(+), 4 deletions(-) rename packages/worker/src/api/controllers/{admin => }/auth.js (100%) create mode 100644 packages/worker/src/api/routes/auth.js diff --git a/packages/worker/src/api/controllers/admin/auth.js b/packages/worker/src/api/controllers/auth.js similarity index 100% rename from packages/worker/src/api/controllers/admin/auth.js rename to packages/worker/src/api/controllers/auth.js diff --git a/packages/worker/src/api/routes/admin/index.js b/packages/worker/src/api/routes/admin/index.js index 1c64110d2a..2c56f67f3f 100644 --- a/packages/worker/src/api/routes/admin/index.js +++ b/packages/worker/src/api/routes/admin/index.js @@ -1,14 +1,11 @@ const Router = require("@koa/router") -const passport = require("@budibase/auth") const controller = require("../../controllers/admin") -const authController = require("../../controllers/admin/auth") const authenticated = require("../../../middleware/authenticated") const router = Router() router .post("/api/admin/users", authenticated, controller.userSave) - .post("/api/admin/authenticate", authController.authenticate) .delete("/api/admin/users/:email", authenticated, controller.userDelete) .get("/api/admin/users", authenticated, controller.userFetch) .get("/api/admin/users/:email", authenticated, controller.userFind) diff --git a/packages/worker/src/api/routes/auth.js b/packages/worker/src/api/routes/auth.js new file mode 100644 index 0000000000..d40071b774 --- /dev/null +++ b/packages/worker/src/api/routes/auth.js @@ -0,0 +1,8 @@ +const Router = require("@koa/router") +const authController = require("../controllers/auth") + +const router = Router() + +router.post("/api/auth/authenticate", authController.authenticate) + +module.exports = router diff --git a/packages/worker/src/api/routes/index.js b/packages/worker/src/api/routes/index.js index 076710b21b..c6bacc81e5 100644 --- a/packages/worker/src/api/routes/index.js +++ b/packages/worker/src/api/routes/index.js @@ -1,4 +1,5 @@ const adminRoutes = require("./admin") +const authRoutes = require("./auth") const appRoutes = require("./app") -exports.routes = [adminRoutes, appRoutes] +exports.routes = [adminRoutes, authRoutes, appRoutes] From 8cde219db9106a41a6d6fb020b49a33870bec3ee Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 8 Apr 2021 16:58:33 +0100 Subject: [PATCH 024/135] First pass of global user configuration through existing user API with role mappings. --- hosting/envoy.dev.yaml.hbs | 18 ++ hosting/envoy.yaml | 5 + packages/auth/src/db/utils.js | 4 + packages/auth/src/index.js | 3 +- packages/server/package.json | 1 + packages/server/src/api/controllers/auth.js | 2 +- packages/server/src/api/controllers/row.js | 8 +- packages/server/src/api/controllers/user.js | 170 ++++++++++-------- packages/server/src/api/routes/user.js | 20 +-- .../src/automations/steps/createUser.js | 2 +- packages/server/src/constants/index.js | 8 +- packages/server/src/db/utils.js | 6 +- .../src/tests/utilities/TestConfiguration.js | 6 +- packages/worker/package.json | 2 +- packages/worker/src/api/routes/admin/index.js | 19 +- .../worker/src/middleware/joi-validator.js | 28 +++ packages/worker/yarn.lock | 8 +- 17 files changed, 206 insertions(+), 104 deletions(-) create mode 100644 packages/worker/src/middleware/joi-validator.js diff --git a/hosting/envoy.dev.yaml.hbs b/hosting/envoy.dev.yaml.hbs index f7f642a244..c2795fdb5f 100644 --- a/hosting/envoy.dev.yaml.hbs +++ b/hosting/envoy.dev.yaml.hbs @@ -26,6 +26,10 @@ static_resources: cluster: redis-service prefix_rewrite: "/" + - match: { prefix: "/api/admin" } + route: + cluster: worker-dev + - match: { prefix: "/api/" } route: cluster: server-dev @@ -123,3 +127,17 @@ static_resources: address: {{ address }} port_value: 3000 + - name: worker-dev + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: worker-dev + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: {{ address }} + port_value: 4002 + diff --git a/hosting/envoy.yaml b/hosting/envoy.yaml index 8c6081d1a7..1fbd2070ff 100644 --- a/hosting/envoy.yaml +++ b/hosting/envoy.yaml @@ -25,6 +25,11 @@ static_resources: - match: { path: "/" } route: cluster: app-service + + # special case for worker admin API + - match: { path: "/api/admin" } + route: + cluster: worker-service # special case for when API requests are made, can just forward, not to minio - match: { prefix: "/api/" } diff --git a/packages/auth/src/db/utils.js b/packages/auth/src/db/utils.js index 17d09ceaeb..9b6f5d7103 100644 --- a/packages/auth/src/db/utils.js +++ b/packages/auth/src/db/utils.js @@ -32,3 +32,7 @@ exports.getUserParams = (email = "", otherProps = {}) => { endkey: `${DocumentTypes.USER}${SEPARATOR}${email}${UNICODE_MAX}`, } } + +exports.getEmailFromUserID = id => { + return id.split(`${DocumentTypes.USER}${SEPARATOR}`)[1] +} \ No newline at end of file diff --git a/packages/auth/src/index.js b/packages/auth/src/index.js index 51431e4241..b65690b064 100644 --- a/packages/auth/src/index.js +++ b/packages/auth/src/index.js @@ -8,7 +8,7 @@ const { jwt, local, google } = require("./middleware") const { Cookies, UserStatus } = require("./constants") const { hash, compare } = require("./hashing") const { getAppId, setCookie } = require("./utils") -const { generateUserID, getUserParams } = require("./db/utils") +const { generateUserID, getUserParams, getEmailFromUserID } = require("./db/utils") // Strategies passport.use(new LocalStrategy(local.options, local.authenticate)) @@ -36,6 +36,7 @@ module.exports = { StaticDatabases, generateUserID, getUserParams, + getEmailFromUserID, hash, compare, getAppId, diff --git a/packages/server/package.json b/packages/server/package.json index 42ecbe39e0..3ff5997985 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -79,6 +79,7 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { + "@budibase/auth": "^0.0.1", "@budibase/client": "^0.8.9", "@budibase/string-templates": "^0.8.9", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/server/src/api/controllers/auth.js b/packages/server/src/api/controllers/auth.js index 43f7878108..da68aa485b 100644 --- a/packages/server/src/api/controllers/auth.js +++ b/packages/server/src/api/controllers/auth.js @@ -7,7 +7,7 @@ const { generateUserID } = require("../../db/utils") const { setCookie } = require("../../utilities") const { outputProcessing } = require("../../utilities/rowProcessor") const { ViewNames } = require("../../db/utils") -const { UserStatus } = require("../../constants") +const { UserStatus } = require("@budibase/auth") const setBuilderToken = require("../../utilities/builder/setBuilderToken") const INVALID_ERR = "Invalid Credentials" diff --git a/packages/server/src/api/controllers/row.js b/packages/server/src/api/controllers/row.js index 3f531d7e5c..1b3e795f83 100644 --- a/packages/server/src/api/controllers/row.js +++ b/packages/server/src/api/controllers/row.js @@ -48,7 +48,7 @@ async function findRow(db, appId, tableId, rowId) { appId, }, } - await usersController.find(ctx) + await usersController.findMetadata(ctx) row = ctx.body } else { row = await db.get(rowId) @@ -103,7 +103,7 @@ exports.patch = async function(ctx) { ...row, password: ctx.request.body.password, } - await usersController.update(ctx) + await usersController.updateMetadata(ctx) return } @@ -179,7 +179,7 @@ exports.save = async function(ctx) { if (row.tableId === ViewNames.USERS) { // the row has been updated, need to put it into the ctx ctx.request.body = row - await usersController.create(ctx) + await usersController.createMetadata(ctx) return } @@ -310,7 +310,7 @@ exports.fetchTableRows = async function(ctx) { let rows, table = await db.get(ctx.params.tableId) if (ctx.params.tableId === ViewNames.USERS) { - await usersController.fetch(ctx) + await usersController.fetchMetadata(ctx) rows = ctx.body } else { const response = await db.allDocs( diff --git a/packages/server/src/api/controllers/user.js b/packages/server/src/api/controllers/user.js index d9a4af9719..92b038d05e 100644 --- a/packages/server/src/api/controllers/user.js +++ b/packages/server/src/api/controllers/user.js @@ -1,109 +1,137 @@ const CouchDB = require("../../db") -const bcrypt = require("../../utilities/bcrypt") -const { generateUserID, getUserParams, ViewNames } = require("../../db/utils") +const { + generateUserID, + getUserParams, + getEmailFromUserID, +} = require("@budibase/auth") +const { InternalTables } = require("../../db/utils") const { getRole } = require("../../utilities/security/roles") -const { UserStatus } = require("../../constants") +const { checkSlashesInUrl } = require("../../utilities") +const env = require("../../environment") +const fetch = require("node-fetch") -exports.fetch = async function(ctx) { +async function deleteGlobalUser(email) { + const endpoint = `/api/admin/users/${email}` + const reqCfg = { method: "DELETE" } + const response = await fetch( + checkSlashesInUrl(env.WORKER_URL + endpoint), + reqCfg + ) + return response.json() +} + +async function getGlobalUsers(email = null) { + const endpoint = email ? `/api/admin/users/${email}` : `/api/admin/users` + const reqCfg = { method: "GET" } + const response = await fetch( + checkSlashesInUrl(env.WORKER_URL + endpoint), + reqCfg + ) + return response.json() +} + +async function saveGlobalUser(appId, email, body) { + const globalUser = await getGlobalUsers(email) + const roles = globalUser.roles || {} + if (body.roleId) { + roles.appId = body.roleId + } + const endpoint = `/api/admin/users` + const reqCfg = { + method: "POST", + body: { + ...globalUser, + email, + password: body.password, + status: body.status, + roles, + }, + } + + const response = await fetch( + checkSlashesInUrl(env.WORKER_URL + endpoint), + reqCfg + ) + await response.json() + delete body.email + delete body.password + delete body.roleId + delete body.status + return body +} + +exports.fetchMetadata = async function(ctx) { const database = new CouchDB(ctx.appId) - const users = ( + const global = await getGlobalUsers() + const metadata = ( await database.allDocs( getUserParams(null, { include_docs: true, }) ) ).rows.map(row => row.doc) - // user hashed password shouldn't ever be returned - for (let user of users) { - delete user.password + const users = [] + for (let user of global) { + const info = metadata.find(meta => meta._id.includes(user.email)) + users.push({ + ...user, + ...info, + }) } ctx.body = users } -// TODO: need to replace this with something that purely manages metadata -exports.create = async function(ctx) { - const db = new CouchDB(ctx.appId) - const { email, password, roleId } = ctx.request.body - - if (!email || !password) { - ctx.throw(400, "email and Password Required.") - } - - const role = await getRole(ctx.appId, roleId) +exports.createMetadata = async function(ctx) { + const appId = ctx.appId + const db = new CouchDB(appId) + const { email, roleId } = ctx.request.body + // check role valid + const role = await getRole(appId, roleId) if (!role) ctx.throw(400, "Invalid Role") - const hashedPassword = await bcrypt.hash(password) + const metadata = await saveGlobalUser(appId, email, ctx.request.body) + const user = { - ...ctx.request.body, - // these must all be after the object spread, make sure - // any values are overwritten, generateUserID will always - // generate the same ID for the user as it is not UUID based + ...metadata, _id: generateUserID(email), type: "user", - password: hashedPassword, - tableId: ViewNames.USERS, - } - // add the active status to a user if its not provided - if (user.status == null) { - user.status = UserStatus.ACTIVE + tableId: InternalTables.USER_METADATA, } - try { - const response = await db.post(user) - ctx.status = 200 - ctx.message = "User created successfully." - ctx.userId = response.id - ctx.body = { - _rev: response.rev, - email, - } - } catch (err) { - if (err.status === 409) { - ctx.throw(400, "User exists already") - } else { - ctx.throw(err.status, err) - } + const response = await db.post(user) + ctx.body = { + _rev: response.rev, + email, } } -exports.update = async function(ctx) { - const db = new CouchDB(ctx.appId) +exports.updateMetadata = async function(ctx) { + const appId = ctx.appId + const db = new CouchDB(appId) const user = ctx.request.body - let dbUser - if (user.email && !user._id) { - user._id = generateUserID(user.email) - } - // get user incase password removed - if (user._id) { - dbUser = await db.get(user._id) - } - if (user.password) { - user.password = await bcrypt.hash(user.password) - } else { - delete user.password - } + let email = user.email || getEmailFromUserID(user._id) + const metadata = await saveGlobalUser(appId, email, ctx.request.body) - const response = await db.put({ - password: dbUser.password, - ...user, + if (!metadata._id) { + user._id = generateUserID(email) + } + ctx.body = await db.put({ + ...metadata, }) - user._rev = response.rev - - ctx.status = 200 - ctx.body = response } -exports.destroy = async function(ctx) { - const database = new CouchDB(ctx.appId) - await database.destroy(generateUserID(ctx.params.email)) +exports.destroyMetadata = async function(ctx) { + const db = new CouchDB(ctx.appId) + const email = ctx.params.email + await deleteGlobalUser(email) + await db.destroy(generateUserID(email)) ctx.body = { message: `User ${ctx.params.email} deleted.`, } - ctx.status = 200 } -exports.find = async function(ctx) { +exports.findMetadata = async function(ctx) { const database = new CouchDB(ctx.appId) let lookup = ctx.params.email ? generateUserID(ctx.params.email) diff --git a/packages/server/src/api/routes/user.js b/packages/server/src/api/routes/user.js index cdaab0cc5b..b0450b72cc 100644 --- a/packages/server/src/api/routes/user.js +++ b/packages/server/src/api/routes/user.js @@ -11,31 +11,31 @@ const router = Router() router .get( - "/api/users", + "/api/users/metadata", authorized(PermissionTypes.USER, PermissionLevels.READ), - controller.fetch + controller.fetchMetadata ) .get( - "/api/users/:email", + "/api/users/metadata/:email", authorized(PermissionTypes.USER, PermissionLevels.READ), - controller.find + controller.findMetadata ) .put( - "/api/users", + "/api/users/metadata", authorized(PermissionTypes.USER, PermissionLevels.WRITE), - controller.update + controller.updateMetadata ) .post( - "/api/users", + "/api/users/metadata", authorized(PermissionTypes.USER, PermissionLevels.WRITE), usage, - controller.create + controller.createMetadata ) .delete( - "/api/users/:email", + "/api/users/metadata/:email", authorized(PermissionTypes.USER, PermissionLevels.WRITE), usage, - controller.destroy + controller.destroyMetadata ) module.exports = router diff --git a/packages/server/src/automations/steps/createUser.js b/packages/server/src/automations/steps/createUser.js index 147a3f7868..8849415c5a 100644 --- a/packages/server/src/automations/steps/createUser.js +++ b/packages/server/src/automations/steps/createUser.js @@ -75,7 +75,7 @@ module.exports.run = async function({ inputs, appId, apiKey, emitter }) { if (env.isProd()) { await usage.update(apiKey, usage.Properties.USER, 1) } - await userController.create(ctx) + await userController.createMetadata(ctx) return { response: ctx.body, // internal property not returned through the API diff --git a/packages/server/src/constants/index.js b/packages/server/src/constants/index.js index 1e8ebb2721..940c1100dd 100644 --- a/packages/server/src/constants/index.js +++ b/packages/server/src/constants/index.js @@ -1,4 +1,5 @@ const { BUILTIN_ROLE_IDS } = require("../utilities/security/roles") +const { UserStatus } = require("@budibase/auth") exports.LOGO_URL = "https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg" @@ -27,11 +28,6 @@ exports.AuthTypes = { EXTERNAL: "external", } -exports.UserStatus = { - ACTIVE: "active", - INACTIVE: "inactive", -} - exports.USERS_TABLE_SCHEMA = { _id: "ta_users", type: "table", @@ -68,7 +64,7 @@ exports.USERS_TABLE_SCHEMA = { constraints: { type: exports.FieldTypes.STRING, presence: false, - inclusion: Object.values(exports.UserStatus), + inclusion: Object.values(UserStatus), }, }, }, diff --git a/packages/server/src/db/utils.js b/packages/server/src/db/utils.js index 4c31f0398e..8623b99f2c 100644 --- a/packages/server/src/db/utils.js +++ b/packages/server/src/db/utils.js @@ -34,7 +34,10 @@ const DocumentTypes = { const ViewNames = { LINK: "by_link", ROUTING: "screen_routes", - USERS: "ta_users", +} + +const InternalTables = { + USER_METADATA: "ta_users", } const SearchIndexes = { @@ -43,6 +46,7 @@ const SearchIndexes = { exports.StaticDatabases = StaticDatabases exports.ViewNames = ViewNames +exports.InternalTables = InternalTables exports.DocumentTypes = DocumentTypes exports.SEPARATOR = SEPARATOR exports.UNICODE_MAX = UNICODE_MAX diff --git a/packages/server/src/tests/utilities/TestConfiguration.js b/packages/server/src/tests/utilities/TestConfiguration.js index 433cec4a0a..002cf4d004 100644 --- a/packages/server/src/tests/utilities/TestConfiguration.js +++ b/packages/server/src/tests/utilities/TestConfiguration.js @@ -279,7 +279,7 @@ class TestConfiguration { roleId, }, null, - controllers.user.create + controllers.user.createMetadata ) } @@ -289,7 +289,7 @@ class TestConfiguration { { email, }, - controllers.user.find + controllers.user.findMetadata ) return this._req( { @@ -297,7 +297,7 @@ class TestConfiguration { status: "inactive", }, null, - controllers.user.update + controllers.user.updateMetadata ) } diff --git a/packages/worker/package.json b/packages/worker/package.json index 5ab414dab1..37b7435066 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -25,7 +25,7 @@ "bcryptjs": "^2.4.3", "dotenv": "^8.2.0", "got": "^11.8.1", - "joi": "^17.2.1", + "joi": "^17.4.0", "koa": "^2.7.0", "koa-body": "^4.2.0", "koa-compress": "^4.0.1", diff --git a/packages/worker/src/api/routes/admin/index.js b/packages/worker/src/api/routes/admin/index.js index 1c64110d2a..97924ce7cb 100644 --- a/packages/worker/src/api/routes/admin/index.js +++ b/packages/worker/src/api/routes/admin/index.js @@ -3,11 +3,28 @@ const passport = require("@budibase/auth") const controller = require("../../controllers/admin") const authController = require("../../controllers/admin/auth") const authenticated = require("../../../middleware/authenticated") +const joiValidator = require("../../../middleware/joi-validator") +const Joi = require("joi") const router = Router() +function buildUserSaveValidation() { + // prettier-ignore + return joiValidator.body(Joi.object({ + _id: Joi.string(), + _rev: Joi.string(), + email: Joi.string(), + password: Joi.string(), + // maps appId -> roleId for the user + roles: Joi.object() + .pattern(/.*/, Joi.string()) + .required() + .unknown(true) + }).required().unknown(true)) +} + router - .post("/api/admin/users", authenticated, controller.userSave) + .post("/api/admin/users", buildUserSaveValidation(), authenticated, controller.userSave) .post("/api/admin/authenticate", authController.authenticate) .delete("/api/admin/users/:email", authenticated, controller.userDelete) .get("/api/admin/users", authenticated, controller.userFetch) diff --git a/packages/worker/src/middleware/joi-validator.js b/packages/worker/src/middleware/joi-validator.js new file mode 100644 index 0000000000..1686b0e727 --- /dev/null +++ b/packages/worker/src/middleware/joi-validator.js @@ -0,0 +1,28 @@ +function validate(schema, property) { + // Return a Koa middleware function + return (ctx, next) => { + if (!schema) { + return next() + } + let params = null + if (ctx[property] != null) { + params = ctx[property] + } else if (ctx.request[property] != null) { + params = ctx.request[property] + } + const { error } = schema.validate(params) + if (error) { + ctx.throw(400, `Invalid ${property} - ${error.message}`) + return + } + return next() + } +} + +module.exports.body = schema => { + return validate(schema, "body") +} + +module.exports.params = schema => { + return validate(schema, "params") +} diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index df8965f515..6515c5967f 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -1261,10 +1261,10 @@ jmespath@0.15.0, jmespath@^0.15.0: resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= -joi@^17.2.1: - version "17.3.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.3.0.tgz#f1be4a6ce29bc1716665819ac361dfa139fff5d2" - integrity sha512-Qh5gdU6niuYbUIUV5ejbsMiiFmBdw8Kcp8Buj2JntszCkCfxJ9Cz76OtHxOZMPXrt5810iDIXs+n1nNVoquHgg== +joi@^17.4.0: + version "17.4.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.0.tgz#b5c2277c8519e016316e49ababd41a1908d9ef20" + integrity sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg== dependencies: "@hapi/hoek" "^9.0.0" "@hapi/topo" "^5.0.0" From 15900efc35e61f1f0e406e92f1ebb96d1830892b Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 8 Apr 2021 17:39:46 +0100 Subject: [PATCH 025/135] Some changes after trying system for first time. --- hosting/docker-compose.yaml | 1 + hosting/envoy.dev.yaml.hbs | 4 ++++ packages/server/scripts/dev/manage.js | 3 --- packages/server/src/app.js | 3 ++- packages/worker/scripts/dev/manage.js | 4 +--- packages/worker/src/index.js | 3 ++- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/hosting/docker-compose.yaml b/hosting/docker-compose.yaml index 49f8cddccd..5e21cc9efd 100644 --- a/hosting/docker-compose.yaml +++ b/hosting/docker-compose.yaml @@ -35,6 +35,7 @@ services: environment: SELF_HOSTED: 1 PORT: 4003 + JWT_SECRET: ${JWT_SECRET} MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY} MINIO_SECRET_KEY: ${MINIO_SECRET_KEY} MINIO_URL: http://minio-service:9000 diff --git a/hosting/envoy.dev.yaml.hbs b/hosting/envoy.dev.yaml.hbs index c2795fdb5f..40cfc551ef 100644 --- a/hosting/envoy.dev.yaml.hbs +++ b/hosting/envoy.dev.yaml.hbs @@ -46,6 +46,10 @@ static_resources: route: cluster: builder-dev prefix_rewrite: "/builder/" + + # special case in dev to redirect no path to builder + - match: { path: "/" } + redirect: { path_redirect: "/builder/" } # minio is on the default route because this works # best, minio + AWS SDK doesn't handle path proxy diff --git a/packages/server/scripts/dev/manage.js b/packages/server/scripts/dev/manage.js index 7a318ff6ff..20037c7e3c 100644 --- a/packages/server/scripts/dev/manage.js +++ b/packages/server/scripts/dev/manage.js @@ -33,9 +33,6 @@ async function init() { fs.writeFileSync(envoyOutputPath, processStringSync(contents, config)) const envFilePath = path.join(process.cwd(), ".env") - if (fs.existsSync(envFilePath)) { - return - } const envFileJson = { PORT: 4001, MINIO_URL: "http://localhost:10000/", diff --git a/packages/server/src/app.js b/packages/server/src/app.js index e5e9b77084..88776fadac 100644 --- a/packages/server/src/app.js +++ b/packages/server/src/app.js @@ -1,3 +1,5 @@ +// need to load environment first +const env = require("./environment") const Koa = require("koa") const destroyable = require("server-destroy") const electron = require("electron") @@ -5,7 +7,6 @@ const koaBody = require("koa-body") const logger = require("koa-pino-logger") const http = require("http") const api = require("./api") -const env = require("./environment") const eventEmitter = require("./events") const automations = require("./automations/index") const Sentry = require("@sentry/node") diff --git a/packages/worker/scripts/dev/manage.js b/packages/worker/scripts/dev/manage.js index b7e92f6d15..f363bd05ac 100644 --- a/packages/worker/scripts/dev/manage.js +++ b/packages/worker/scripts/dev/manage.js @@ -4,12 +4,10 @@ const fs = require("fs") async function init() { const envFilePath = path.join(process.cwd(), ".env") - if (fs.existsSync(envFilePath)) { - return - } const envFileJson = { SELF_HOSTED: 1, PORT: 4002, + JWT_SECRET: "testsecret", MINIO_ACCESS_KEY: "budibase", MINIO_SECRET_KEY: "budibase", COUCH_DB_USER: "budibase", diff --git a/packages/worker/src/index.js b/packages/worker/src/index.js index 2e031b9f64..55f2705ed1 100644 --- a/packages/worker/src/index.js +++ b/packages/worker/src/index.js @@ -1,3 +1,5 @@ +// need to load environment first +const env = require("./environment") const Koa = require("koa") const destroyable = require("server-destroy") const koaBody = require("koa-body") @@ -5,7 +7,6 @@ const { passport } = require("@budibase/auth") const logger = require("koa-pino-logger") const http = require("http") const api = require("./api") -const env = require("./environment") const app = new Koa() From 0c34f1a108755ad9f98db1d32f1b7e53bce14585 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 8 Apr 2021 18:18:53 +0100 Subject: [PATCH 026/135] Making sure volumes are removed when nuking. --- packages/server/scripts/dev/manage.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/server/scripts/dev/manage.js b/packages/server/scripts/dev/manage.js index 20037c7e3c..4e170d1c63 100644 --- a/packages/server/scripts/dev/manage.js +++ b/packages/server/scripts/dev/manage.js @@ -67,7 +67,11 @@ async function nuke() { console.log( "Clearing down your budibase dev environment, including all containers and volumes... 💥" ) - await compose.down(CONFIG) + await compose.down({ + ...CONFIG, + // stop containers, delete volumes + commandOptions: ["-v", "--remove-orphans"], + }) } const managementCommand = process.argv.slice(2)[0] From 3214abb89a041763a8c661b2983705581acf3a6e Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 9 Apr 2021 15:11:49 +0100 Subject: [PATCH 027/135] Global users now working through the server, all requests proxied. --- package.json | 2 +- packages/auth/src/db/utils.js | 7 +- .../src/components/backend/DataTable/api.js | 5 +- .../components/start/CreateAppModal.svelte | 2 +- .../server/src/api/controllers/application.js | 2 +- packages/server/src/api/controllers/auth.js | 4 +- .../server/src/api/controllers/hosting.js | 2 +- packages/server/src/api/controllers/role.js | 4 +- packages/server/src/api/controllers/row.js | 18 +-- .../src/api/controllers/static/index.js | 2 +- packages/server/src/api/controllers/user.js | 98 ++++----------- packages/server/src/db/utils.js | 21 +++- .../server/src/utilities/builder/hosting.js | 29 +---- .../server/src/utilities/workerRequests.js | 116 ++++++++++++++++++ .../worker/src/api/controllers/admin/index.js | 31 +++-- packages/worker/src/api/routes/app.js | 4 +- .../worker/src/middleware/authenticated.js | 32 ++--- 17 files changed, 219 insertions(+), 160 deletions(-) create mode 100644 packages/server/src/utilities/workerRequests.js diff --git a/package.json b/package.json index b2f572d202..a4b0993fde 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "clean": "lerna clean", "kill-port": "kill-port 4001", "dev": "yarn run kill-port && lerna link && lerna run --parallel dev:builder --concurrency 1", - "dev:noserver": "lerna link && lerna run --parallel dev:builder --concurrency 1 --ignore @budibase/server", + "dev:noserver": "lerna link && lerna run dev:stack:up && lerna run --parallel dev:builder --concurrency 1 --ignore @budibase/server --ignore @budibase/worker", "test": "lerna run test", "lint": "eslint packages", "lint:fix": "eslint --fix packages", diff --git a/packages/auth/src/db/utils.js b/packages/auth/src/db/utils.js index 9b6f5d7103..871423df03 100644 --- a/packages/auth/src/db/utils.js +++ b/packages/auth/src/db/utils.js @@ -26,13 +26,12 @@ exports.generateUserID = email => { * Gets parameters for retrieving users, this is a utility function for the getDocParams function. */ exports.getUserParams = (email = "", otherProps = {}) => { + if (!email) { + email = "" + } return { ...otherProps, startkey: `${DocumentTypes.USER}${SEPARATOR}${email}`, endkey: `${DocumentTypes.USER}${SEPARATOR}${email}${UNICODE_MAX}`, } } - -exports.getEmailFromUserID = id => { - return id.split(`${DocumentTypes.USER}${SEPARATOR}`)[1] -} \ No newline at end of file diff --git a/packages/builder/src/components/backend/DataTable/api.js b/packages/builder/src/components/backend/DataTable/api.js index 91ebc19b26..43c6856540 100644 --- a/packages/builder/src/components/backend/DataTable/api.js +++ b/packages/builder/src/components/backend/DataTable/api.js @@ -1,7 +1,7 @@ import api from "builderStore/api" export async function createUser(user) { - const CREATE_USER_URL = `/api/users` + const CREATE_USER_URL = `/api/users/metadata` const response = await api.post(CREATE_USER_URL, user) return await response.json() } @@ -15,8 +15,7 @@ export async function saveRow(row, tableId) { export async function deleteRow(row) { const DELETE_ROWS_URL = `/api/${row.tableId}/rows/${row._id}/${row._rev}` - const response = await api.delete(DELETE_ROWS_URL) - return response + return api.delete(DELETE_ROWS_URL) } export async function fetchDataForView(view) { diff --git a/packages/builder/src/components/start/CreateAppModal.svelte b/packages/builder/src/components/start/CreateAppModal.svelte index babe7bd0df..c727283b29 100644 --- a/packages/builder/src/components/start/CreateAppModal.svelte +++ b/packages/builder/src/components/start/CreateAppModal.svelte @@ -157,7 +157,7 @@ password: $createAppStore.values.password, roleId: $createAppStore.values.roleId, } - const userResp = await api.post(`/api/users`, user) + const userResp = await api.post(`/api/users/metadata`, user) const json = await userResp.json() $goto(`./${appJson._id}`) } catch (error) { diff --git a/packages/server/src/api/controllers/application.js b/packages/server/src/api/controllers/application.js index cacde4bb00..042474c5b6 100644 --- a/packages/server/src/api/controllers/application.js +++ b/packages/server/src/api/controllers/application.js @@ -74,7 +74,7 @@ async function getAppUrlIfNotInUse(ctx) { if (!env.SELF_HOSTED) { return url } - const deployedApps = await getDeployedApps() + const deployedApps = await getDeployedApps(ctx) if ( deployedApps[url] != null && deployedApps[url].appId !== ctx.params.appId diff --git a/packages/server/src/api/controllers/auth.js b/packages/server/src/api/controllers/auth.js index da68aa485b..6e662f7b9a 100644 --- a/packages/server/src/api/controllers/auth.js +++ b/packages/server/src/api/controllers/auth.js @@ -3,7 +3,7 @@ const CouchDB = require("../../db") const bcrypt = require("../../utilities/bcrypt") const env = require("../../environment") const { getAPIKey } = require("../../utilities/usageQuota") -const { generateUserID } = require("../../db/utils") +const { generateUserMetadataID } = require("../../db/utils") const { setCookie } = require("../../utilities") const { outputProcessing } = require("../../utilities/rowProcessor") const { ViewNames } = require("../../db/utils") @@ -27,7 +27,7 @@ exports.authenticate = async ctx => { let dbUser try { - dbUser = await db.get(generateUserID(email)) + dbUser = await db.get(generateUserMetadataID(email)) } catch (_) { // do not want to throw a 404 - as this could be // used to determine valid emails diff --git a/packages/server/src/api/controllers/hosting.js b/packages/server/src/api/controllers/hosting.js index 4b070cf75b..8b7b31e00a 100644 --- a/packages/server/src/api/controllers/hosting.js +++ b/packages/server/src/api/controllers/hosting.js @@ -40,5 +40,5 @@ exports.fetchUrls = async ctx => { } exports.getDeployedApps = async ctx => { - ctx.body = await getDeployedApps() + ctx.body = await getDeployedApps(ctx) } diff --git a/packages/server/src/api/controllers/role.js b/packages/server/src/api/controllers/role.js index 11f81c1219..d27272a21a 100644 --- a/packages/server/src/api/controllers/role.js +++ b/packages/server/src/api/controllers/role.js @@ -10,7 +10,7 @@ const { const { generateRoleID, getRoleParams, - getUserParams, + getUserMetadataParams, ViewNames, } = require("../../db/utils") @@ -112,7 +112,7 @@ exports.destroy = async function(ctx) { // first check no users actively attached to role const users = ( await db.allDocs( - getUserParams(null, { + getUserMetadataParams(null, { include_docs: true, }) ) diff --git a/packages/server/src/api/controllers/row.js b/packages/server/src/api/controllers/row.js index 1b3e795f83..8b4a461d2c 100644 --- a/packages/server/src/api/controllers/row.js +++ b/packages/server/src/api/controllers/row.js @@ -6,8 +6,8 @@ const { generateRowID, DocumentTypes, SEPARATOR, - ViewNames, - generateUserID, + InternalTables, + generateUserMetadataID, } = require("../../db/utils") const usersController = require("./user") const { @@ -39,7 +39,7 @@ validateJs.extend(validateJs.validators.datetime, { async function findRow(db, appId, tableId, rowId) { let row - if (tableId === ViewNames.USERS) { + if (tableId === InternalTables.USER_METADATA) { let ctx = { params: { userId: rowId, @@ -97,7 +97,7 @@ exports.patch = async function(ctx) { }) // Creation of a new user goes to the user controller - if (row.tableId === ViewNames.USERS) { + if (row.tableId === InternalTables.USER_METADATA) { // the row has been updated, need to put it into the ctx ctx.request.body = { ...row, @@ -142,8 +142,8 @@ exports.save = async function(ctx) { } if (!inputs._rev && !inputs._id) { - if (inputs.tableId === ViewNames.USERS) { - inputs._id = generateUserID(inputs.email) + if (inputs.tableId === InternalTables.USER_METADATA) { + inputs._id = generateUserMetadataID(inputs.email) } else { inputs._id = generateRowID(inputs.tableId) } @@ -176,7 +176,7 @@ exports.save = async function(ctx) { }) // Creation of a new user goes to the user controller - if (row.tableId === ViewNames.USERS) { + if (row.tableId === InternalTables.USER_METADATA) { // the row has been updated, need to put it into the ctx ctx.request.body = row await usersController.createMetadata(ctx) @@ -289,7 +289,7 @@ exports.search = async function(ctx) { const response = await search(searchString) // delete passwords from users - if (tableId === ViewNames.USERS) { + if (tableId === InternalTables.USER_METADATA) { for (let row of response.rows) { delete row.password } @@ -309,7 +309,7 @@ exports.fetchTableRows = async function(ctx) { // special case for users, fetch through the user controller let rows, table = await db.get(ctx.params.tableId) - if (ctx.params.tableId === ViewNames.USERS) { + if (ctx.params.tableId === InternalTables.USER_METADATA) { await usersController.fetchMetadata(ctx) rows = ctx.body } else { diff --git a/packages/server/src/api/controllers/static/index.js b/packages/server/src/api/controllers/static/index.js index 69a12d573b..71e20923a8 100644 --- a/packages/server/src/api/controllers/static/index.js +++ b/packages/server/src/api/controllers/static/index.js @@ -22,7 +22,7 @@ const { objectStoreUrl, clientLibraryPath } = require("../../../utilities") async function checkForSelfHostedURL(ctx) { // the "appId" component of the URL may actually be a specific self hosted URL let possibleAppUrl = `/${encodeURI(ctx.params.appId).toLowerCase()}` - const apps = await getDeployedApps() + const apps = await getDeployedApps(ctx) if (apps[possibleAppUrl] && apps[possibleAppUrl].appId) { return apps[possibleAppUrl].appId } else { diff --git a/packages/server/src/api/controllers/user.js b/packages/server/src/api/controllers/user.js index 92b038d05e..c526050cde 100644 --- a/packages/server/src/api/controllers/user.js +++ b/packages/server/src/api/controllers/user.js @@ -1,71 +1,23 @@ const CouchDB = require("../../db") const { - generateUserID, - getUserParams, - getEmailFromUserID, -} = require("@budibase/auth") + generateUserMetadataID, + getUserMetadataParams, + getEmailFromUserMetadataID, +} = require("../../db/utils") const { InternalTables } = require("../../db/utils") const { getRole } = require("../../utilities/security/roles") -const { checkSlashesInUrl } = require("../../utilities") -const env = require("../../environment") -const fetch = require("node-fetch") - -async function deleteGlobalUser(email) { - const endpoint = `/api/admin/users/${email}` - const reqCfg = { method: "DELETE" } - const response = await fetch( - checkSlashesInUrl(env.WORKER_URL + endpoint), - reqCfg - ) - return response.json() -} - -async function getGlobalUsers(email = null) { - const endpoint = email ? `/api/admin/users/${email}` : `/api/admin/users` - const reqCfg = { method: "GET" } - const response = await fetch( - checkSlashesInUrl(env.WORKER_URL + endpoint), - reqCfg - ) - return response.json() -} - -async function saveGlobalUser(appId, email, body) { - const globalUser = await getGlobalUsers(email) - const roles = globalUser.roles || {} - if (body.roleId) { - roles.appId = body.roleId - } - const endpoint = `/api/admin/users` - const reqCfg = { - method: "POST", - body: { - ...globalUser, - email, - password: body.password, - status: body.status, - roles, - }, - } - - const response = await fetch( - checkSlashesInUrl(env.WORKER_URL + endpoint), - reqCfg - ) - await response.json() - delete body.email - delete body.password - delete body.roleId - delete body.status - return body -} +const { + getGlobalUsers, + saveGlobalUser, + deleteGlobalUser, +} = require("../../utilities/workerRequests") exports.fetchMetadata = async function(ctx) { const database = new CouchDB(ctx.appId) - const global = await getGlobalUsers() + const global = await getGlobalUsers(ctx, ctx.appId) const metadata = ( await database.allDocs( - getUserParams(null, { + getUserMetadataParams(null, { include_docs: true, }) ) @@ -90,11 +42,11 @@ exports.createMetadata = async function(ctx) { const role = await getRole(appId, roleId) if (!role) ctx.throw(400, "Invalid Role") - const metadata = await saveGlobalUser(appId, email, ctx.request.body) + const metadata = await saveGlobalUser(ctx, appId, email, ctx.request.body) const user = { ...metadata, - _id: generateUserID(email), + _id: generateUserMetadataID(email), type: "user", tableId: InternalTables.USER_METADATA, } @@ -110,11 +62,11 @@ exports.updateMetadata = async function(ctx) { const appId = ctx.appId const db = new CouchDB(appId) const user = ctx.request.body - let email = user.email || getEmailFromUserID(user._id) - const metadata = await saveGlobalUser(appId, email, ctx.request.body) + let email = user.email || getEmailFromUserMetadataID(user._id) + const metadata = await saveGlobalUser(ctx, appId, email, ctx.request.body) if (!metadata._id) { - user._id = generateUserID(email) + user._id = generateUserMetadataID(email) } ctx.body = await db.put({ ...metadata, @@ -124,8 +76,8 @@ exports.updateMetadata = async function(ctx) { exports.destroyMetadata = async function(ctx) { const db = new CouchDB(ctx.appId) const email = ctx.params.email - await deleteGlobalUser(email) - await db.destroy(generateUserID(email)) + await deleteGlobalUser(ctx, email) + await db.destroy(generateUserMetadataID(email)) ctx.body = { message: `User ${ctx.params.email} deleted.`, } @@ -133,12 +85,12 @@ exports.destroyMetadata = async function(ctx) { exports.findMetadata = async function(ctx) { const database = new CouchDB(ctx.appId) - let lookup = ctx.params.email - ? generateUserID(ctx.params.email) - : ctx.params.userId - const user = await database.get(lookup) - if (user) { - delete user.password + const email = + ctx.params.email || getEmailFromUserMetadataID(ctx.params.userId) + const global = await getGlobalUsers(ctx, ctx.appId, email) + const user = await database.get(generateUserMetadataID(email)) + ctx.body = { + ...global, + ...user, } - ctx.body = user } diff --git a/packages/server/src/db/utils.js b/packages/server/src/db/utils.js index 8623b99f2c..63d4e30d65 100644 --- a/packages/server/src/db/utils.js +++ b/packages/server/src/db/utils.js @@ -116,16 +116,18 @@ exports.getRowParams = (tableId = null, rowId = null, otherProps = {}) => { /** * Gets a new row ID for the specified table. * @param {string} tableId The table which the row is being created for. + * @param {string|null} id If an ID is to be used then the UUID can be substituted for this. * @returns {string} The new ID which a row doc can be stored under. */ -exports.generateRowID = tableId => { - return `${DocumentTypes.ROW}${SEPARATOR}${tableId}${SEPARATOR}${newid()}` +exports.generateRowID = (tableId, id = null) => { + id = id || newid() + return `${DocumentTypes.ROW}${SEPARATOR}${tableId}${SEPARATOR}${id}` } /** * Gets parameters for retrieving users, this is a utility function for the getDocParams function. */ -exports.getUserParams = (email = "", otherProps = {}) => { +exports.getUserMetadataParams = (email = "", otherProps = {}) => { return exports.getRowParams(ViewNames.USERS, email, otherProps) } @@ -134,8 +136,17 @@ exports.getUserParams = (email = "", otherProps = {}) => { * @param {string} email The email which the ID is going to be built up of. * @returns {string} The new user ID which the user doc can be stored under. */ -exports.generateUserID = email => { - return `${DocumentTypes.ROW}${SEPARATOR}${ViewNames.USERS}${SEPARATOR}${DocumentTypes.USER}${SEPARATOR}${email}` +exports.generateUserMetadataID = email => { + return exports.generateRowID(InternalTables.USER_METADATA, email) +} + +/** + * Breaks up the ID to get the email address back out of it. + */ +exports.getEmailFromUserMetadataID = id => { + return id.split( + `${DocumentTypes.ROW}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}` + )[1] } /** diff --git a/packages/server/src/utilities/builder/hosting.js b/packages/server/src/utilities/builder/hosting.js index f852cefec1..328e98ee98 100644 --- a/packages/server/src/utilities/builder/hosting.js +++ b/packages/server/src/utilities/builder/hosting.js @@ -2,6 +2,7 @@ const CouchDB = require("../../db") const { StaticDatabases } = require("../../db/utils") const fetch = require("node-fetch") const env = require("../../environment") +const { getDeployedApps } = require("../../utilities/workerRequests") const PROD_HOSTING_URL = "app.budi.live" @@ -84,30 +85,4 @@ exports.getTemplatesUrl = async (appId, type, name) => { return `${protocol}${hostingInfo.templatesUrl}/${path}` } -exports.getDeployedApps = async () => { - if (!env.SELF_HOSTED) { - throw "Can only check apps for self hosted environments" - } - const workerUrl = env.WORKER_URL - const hostingKey = env.HOSTING_KEY - try { - const response = await fetch(`${workerUrl}/api/apps`, { - method: "GET", - headers: { - "x-budibase-auth": hostingKey, - }, - }) - const json = await response.json() - const apps = {} - for (let [key, value] of Object.entries(json)) { - if (value.url) { - value.url = value.url.toLowerCase() - apps[key] = value - } - } - return apps - } catch (err) { - // error, cannot determine deployed apps, don't stop app creation - sort this later - return {} - } -} +exports.getDeployedApps = getDeployedApps diff --git a/packages/server/src/utilities/workerRequests.js b/packages/server/src/utilities/workerRequests.js new file mode 100644 index 0000000000..f3bf971257 --- /dev/null +++ b/packages/server/src/utilities/workerRequests.js @@ -0,0 +1,116 @@ +const fetch = require("node-fetch") +const env = require("../environment") +const { checkSlashesInUrl } = require("./index") +const { BUILTIN_ROLE_IDS } = require("./security/roles") + +function getAppRole(appId, user) { + if (!user.roles) { + return user + } + user.roleId = user.roles[appId] + if (!user.roleId) { + user.roleId = BUILTIN_ROLE_IDS.PUBLIC + } + delete user.roles + return user +} + +function prepRequest(ctx, request) { + if (!request.headers) { + request.headers = {} + } + if (request.body) { + request.headers["Content-Type"] = "application/json" + request.body = + typeof request.body === "object" + ? JSON.stringify(request.body) + : request.body + } + request.headers.cookie = ctx.headers.cookie + return request +} + +exports.getDeployedApps = async ctx => { + if (!env.SELF_HOSTED) { + throw "Can only check apps for self hosted environments" + } + try { + const response = await fetch( + checkSlashesInUrl(env.WORKER_URL + `/api/apps`), + prepRequest(ctx, { + method: "GET", + }) + ) + const json = await response.json() + const apps = {} + for (let [key, value] of Object.entries(json)) { + if (value.url) { + value.url = value.url.toLowerCase() + apps[key] = value + } + } + return apps + } catch (err) { + // error, cannot determine deployed apps, don't stop app creation - sort this later + return {} + } +} + +exports.deleteGlobalUser = async (ctx, email) => { + const endpoint = `/api/admin/users/${email}` + const reqCfg = { method: "DELETE" } + const response = await fetch( + checkSlashesInUrl(env.WORKER_URL + endpoint), + prepRequest(ctx, reqCfg) + ) + return response.json() +} + +exports.getGlobalUsers = async (ctx, appId, email = null) => { + const endpoint = email ? `/api/admin/users/${email}` : `/api/admin/users` + const reqCfg = { method: "GET" } + const response = await fetch( + checkSlashesInUrl(env.WORKER_URL + endpoint), + prepRequest(ctx, reqCfg) + ) + let users = await response.json() + if (Array.isArray(users)) { + users = users.map(user => getAppRole(appId, user)) + } else { + users = getAppRole(appId, users) + } + return users +} + +exports.saveGlobalUser = async (ctx, appId, email, body) => { + const globalUser = await exports.getGlobalUsers(ctx, appId, email) + const roles = globalUser.roles || {} + if (body.roleId) { + roles[appId] = body.roleId + } + const endpoint = `/api/admin/users` + const reqCfg = { + method: "POST", + body: { + ...globalUser, + email, + password: body.password, + status: body.status, + roles, + }, + } + + const response = await fetch( + checkSlashesInUrl(env.WORKER_URL + endpoint), + prepRequest(ctx, reqCfg) + ) + const json = await response.json() + if (json.status !== 200 && response.status !== 200) { + ctx.throw(400, "Unable to save global user.") + } + delete body.email + delete body.password + delete body.roleId + delete body.status + return body +} diff --git a/packages/worker/src/api/controllers/admin/index.js b/packages/worker/src/api/controllers/admin/index.js index 515feb8420..305686a3b0 100644 --- a/packages/worker/src/api/controllers/admin/index.js +++ b/packages/worker/src/api/controllers/admin/index.js @@ -14,11 +14,11 @@ exports.userSave = async ctx => { const { email, password, _id } = ctx.request.body const hashedPassword = password ? await hash(password) : null let user = { - ...ctx.request.body, - _id: generateUserID(email), - password: hashedPassword, - }, - dbUser + ...ctx.request.body, + _id: generateUserID(email), + password: hashedPassword, + } + let dbUser // in-case user existed already if (_id) { dbUser = await db.get(_id) @@ -57,13 +57,12 @@ exports.userDelete = async ctx => { // called internally by app server user fetch exports.userFetch = async ctx => { const db = new CouchDB(USER_DB) - const users = ( - await db.allDocs( - getUserParams(null, { - include_docs: true, - }) - ) - ).rows.map(row => row.doc) + const response = await db.allDocs( + getUserParams(null, { + include_docs: true, + }) + ) + const users = response.rows.map(row => row.doc) // user hashed password shouldn't ever be returned for (let user of users) { if (user) { @@ -76,7 +75,13 @@ exports.userFetch = async ctx => { // called internally by app server user find exports.userFind = async ctx => { const db = new CouchDB(USER_DB) - const user = await db.get(generateUserID(ctx.params.email)) + let user + try { + user = await db.get(generateUserID(ctx.params.email)) + } catch (err) { + // no user found, just return nothing + user = {} + } if (user) { delete user.password } diff --git a/packages/worker/src/api/routes/app.js b/packages/worker/src/api/routes/app.js index 10656e5362..75fa7164b0 100644 --- a/packages/worker/src/api/routes/app.js +++ b/packages/worker/src/api/routes/app.js @@ -1,9 +1,9 @@ const Router = require("@koa/router") const controller = require("../controllers/app") -const checkKey = require("../../middleware/check-key") +const authenticated = require("../../middleware/authenticated") const router = Router() -router.get("/api/apps", checkKey, controller.getApps) +router.get("/api/apps", authenticated, controller.getApps) module.exports = router diff --git a/packages/worker/src/middleware/authenticated.js b/packages/worker/src/middleware/authenticated.js index 751e10ee9a..b13ff5c1b7 100644 --- a/packages/worker/src/middleware/authenticated.js +++ b/packages/worker/src/middleware/authenticated.js @@ -11,20 +11,22 @@ module.exports = async (ctx, next) => { appId = cookieAppId } - return passport.authenticate("jwt", async (err, user) => { - if (err) { - return ctx.throw(err.status || 403, err) - } + return next() - try { - ctx.appId = appId - ctx.isAuthenticated = true - // TODO: introduce roles again - ctx.user = user - await next() - } catch (err) { - console.log(err) - ctx.throw(err.status || 403, err.text) - } - })(ctx, next) + // return passport.authenticate("jwt", async (err, user) => { + // if (err) { + // return ctx.throw(err.status || 403, err) + // } + // + // try { + // ctx.appId = appId + // ctx.isAuthenticated = true + // // TODO: introduce roles again + // ctx.user = user + // await next() + // } catch (err) { + // console.log(err) + // ctx.throw(err.status || 403, err.text) + // } + // })(ctx, next) } From e34894dd92f06942402ed993485aa0685da6f4dd Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 9 Apr 2021 16:55:56 +0100 Subject: [PATCH 028/135] Global user management now functioning as expected, there were some errant db.destroy functions from the system previously, this is now cleaned up. --- packages/server/src/api/controllers/row.js | 71 ++++++++++--------- packages/server/src/api/controllers/user.js | 14 +++- .../worker/src/api/controllers/admin/index.js | 3 +- packages/worker/src/api/controllers/app.js | 7 +- 4 files changed, 59 insertions(+), 36 deletions(-) diff --git a/packages/server/src/api/controllers/row.js b/packages/server/src/api/controllers/row.js index 8b4a461d2c..1e32c24c12 100644 --- a/packages/server/src/api/controllers/row.js +++ b/packages/server/src/api/controllers/row.js @@ -9,7 +9,7 @@ const { InternalTables, generateUserMetadataID, } = require("../../db/utils") -const usersController = require("./user") +const userController = require("./user") const { inputProcessing, outputProcessing, @@ -37,18 +37,14 @@ validateJs.extend(validateJs.validators.datetime, { }, }) -async function findRow(db, appId, tableId, rowId) { +async function findRow(ctx, db, tableId, rowId) { let row + // TODO remove special user case in future if (tableId === InternalTables.USER_METADATA) { - let ctx = { - params: { - userId: rowId, - }, - user: { - appId, - }, + ctx.params = { + userId: rowId, } - await usersController.findMetadata(ctx) + await userController.findMetadata(ctx) row = ctx.body } else { row = await db.get(rowId) @@ -96,14 +92,14 @@ exports.patch = async function(ctx) { table, }) - // Creation of a new user goes to the user controller + // TODO remove special user case in future if (row.tableId === InternalTables.USER_METADATA) { // the row has been updated, need to put it into the ctx ctx.request.body = { ...row, password: ctx.request.body.password, } - await usersController.updateMetadata(ctx) + await userController.updateMetadata(ctx) return } @@ -142,6 +138,7 @@ exports.save = async function(ctx) { } if (!inputs._rev && !inputs._id) { + // TODO remove special user case in future if (inputs.tableId === InternalTables.USER_METADATA) { inputs._id = generateUserMetadataID(inputs.email) } else { @@ -175,11 +172,11 @@ exports.save = async function(ctx) { table, }) - // Creation of a new user goes to the user controller + // TODO remove special user case in future if (row.tableId === InternalTables.USER_METADATA) { // the row has been updated, need to put it into the ctx ctx.request.body = row - await usersController.createMetadata(ctx) + await userController.createMetadata(ctx) return } @@ -287,14 +284,6 @@ exports.search = async function(ctx) { } const response = await search(searchString) - - // delete passwords from users - if (tableId === InternalTables.USER_METADATA) { - for (let row of response.rows) { - delete row.password - } - } - const table = await db.get(tableId) ctx.body = { rows: await outputProcessing(appId, table, response.rows), @@ -306,11 +295,11 @@ exports.fetchTableRows = async function(ctx) { const appId = ctx.appId const db = new CouchDB(appId) - // special case for users, fetch through the user controller + // TODO remove special user case in future let rows, table = await db.get(ctx.params.tableId) if (ctx.params.tableId === InternalTables.USER_METADATA) { - await usersController.fetchMetadata(ctx) + await userController.fetchMetadata(ctx) rows = ctx.body } else { const response = await db.allDocs( @@ -328,7 +317,7 @@ exports.find = async function(ctx) { const db = new CouchDB(appId) try { const table = await db.get(ctx.params.tableId) - const row = await findRow(db, appId, ctx.params.tableId, ctx.params.rowId) + const row = await findRow(ctx, db, ctx.params.tableId, ctx.params.rowId) ctx.body = await outputProcessing(appId, table, row) } catch (err) { ctx.throw(400, err) @@ -348,8 +337,15 @@ exports.destroy = async function(ctx) { row, tableId: row.tableId, }) - ctx.body = await db.remove(ctx.params.rowId, ctx.params.revId) - ctx.status = 200 + // TODO remove special user case in future + if (ctx.params.tableId === InternalTables.USER_METADATA) { + ctx.params = { + userId: ctx.params.rowId, + } + await userController.destroyMetadata(ctx) + } else { + ctx.body = await db.remove(ctx.params.rowId, ctx.params.revId) + } // for automations include the row that was deleted ctx.row = row @@ -395,7 +391,7 @@ exports.fetchEnrichedRow = async function(ctx) { // need table to work out where links go in row let [table, row] = await Promise.all([ db.get(tableId), - findRow(db, appId, tableId, rowId), + findRow(ctx, db, tableId, rowId), ]) // get the link docs const linkVals = await linkRows.getLinkDocuments({ @@ -437,7 +433,7 @@ async function bulkDelete(ctx) { const { rows } = ctx.request.body const db = new CouchDB(appId) - const linkUpdates = rows.map(row => + let updates = rows.map(row => linkRows.updateLinks({ appId, eventType: linkRows.EventType.ROW_DELETE, @@ -445,9 +441,20 @@ async function bulkDelete(ctx) { tableId: row.tableId, }) ) - - await db.bulkDocs(rows.map(row => ({ ...row, _deleted: true }))) - await Promise.all(linkUpdates) + // TODO remove special user case in future + if (ctx.params.tableId === InternalTables.USER_METADATA) { + updates = updates.concat( + rows.map(row => { + ctx.params = { + userId: row._id, + } + return userController.destroyMetadata(ctx) + }) + ) + } else { + await db.bulkDocs(rows.map(row => ({ ...row, _deleted: true }))) + } + await Promise.all(updates) rows.forEach(row => { ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row) diff --git a/packages/server/src/api/controllers/user.js b/packages/server/src/api/controllers/user.js index c526050cde..93e6dec1d6 100644 --- a/packages/server/src/api/controllers/user.js +++ b/packages/server/src/api/controllers/user.js @@ -28,6 +28,8 @@ exports.fetchMetadata = async function(ctx) { users.push({ ...user, ...info, + // make sure the ID is always a local ID, not a global one + _id: generateUserMetadataID(user.email), }) } ctx.body = users @@ -75,9 +77,15 @@ exports.updateMetadata = async function(ctx) { exports.destroyMetadata = async function(ctx) { const db = new CouchDB(ctx.appId) - const email = ctx.params.email + const email = + ctx.params.email || getEmailFromUserMetadataID(ctx.params.userId) await deleteGlobalUser(ctx, email) - await db.destroy(generateUserMetadataID(email)) + try { + const dbUser = await db.get(generateUserMetadataID(email)) + await db.remove(dbUser._id, dbUser._rev) + } catch (err) { + // error just means the global user has no config in this app + } ctx.body = { message: `User ${ctx.params.email} deleted.`, } @@ -92,5 +100,7 @@ exports.findMetadata = async function(ctx) { ctx.body = { ...global, ...user, + // make sure the ID is always a local ID, not a global one + _id: generateUserMetadataID(email), } } diff --git a/packages/worker/src/api/controllers/admin/index.js b/packages/worker/src/api/controllers/admin/index.js index 305686a3b0..ff0d2997e7 100644 --- a/packages/worker/src/api/controllers/admin/index.js +++ b/packages/worker/src/api/controllers/admin/index.js @@ -48,7 +48,8 @@ exports.userSave = async ctx => { exports.userDelete = async ctx => { const db = new CouchDB(USER_DB) - await db.destroy(generateUserID(ctx.params.email)) + const dbUser = await db.get(generateUserID(ctx.params.email)) + await db.remove(dbUser._id, dbUser._rev) ctx.body = { message: `User ${ctx.params.email} deleted.`, } diff --git a/packages/worker/src/api/controllers/app.js b/packages/worker/src/api/controllers/app.js index eac0c47c18..bed3b55942 100644 --- a/packages/worker/src/api/controllers/app.js +++ b/packages/worker/src/api/controllers/app.js @@ -15,9 +15,14 @@ exports.getApps = async ctx => { } const appDbNames = allDbs.filter(dbName => dbName.startsWith(APP_PREFIX)) const appPromises = appDbNames.map(db => new CouchDB(db).get(db)) - const apps = await Promise.all(appPromises) + + const apps = await Promise.allSettled(appPromises) const body = {} for (let app of apps) { + if (app.status !== "fulfilled") { + continue + } + app = app.value let url = app.url || encodeURI(`${app.name}`) url = `/${url.replace(URL_REGEX_SLASH, "")}` body[url] = { From e275553f6001d074f58085b8ff7f03f8b118e666 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 9 Apr 2021 16:56:42 +0100 Subject: [PATCH 029/135] Formatting. --- packages/auth/src/index.js | 6 +++++- packages/worker/src/api/routes/admin/index.js | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/auth/src/index.js b/packages/auth/src/index.js index b65690b064..f42b2d8423 100644 --- a/packages/auth/src/index.js +++ b/packages/auth/src/index.js @@ -8,7 +8,11 @@ const { jwt, local, google } = require("./middleware") const { Cookies, UserStatus } = require("./constants") const { hash, compare } = require("./hashing") const { getAppId, setCookie } = require("./utils") -const { generateUserID, getUserParams, getEmailFromUserID } = require("./db/utils") +const { + generateUserID, + getUserParams, + getEmailFromUserID, +} = require("./db/utils") // Strategies passport.use(new LocalStrategy(local.options, local.authenticate)) diff --git a/packages/worker/src/api/routes/admin/index.js b/packages/worker/src/api/routes/admin/index.js index 558c6e2c29..6a89a41dde 100644 --- a/packages/worker/src/api/routes/admin/index.js +++ b/packages/worker/src/api/routes/admin/index.js @@ -22,7 +22,12 @@ function buildUserSaveValidation() { } router - .post("/api/admin/users", buildUserSaveValidation(), authenticated, controller.userSave) + .post( + "/api/admin/users", + buildUserSaveValidation(), + authenticated, + controller.userSave + ) .delete("/api/admin/users/:email", authenticated, controller.userDelete) .get("/api/admin/users", authenticated, controller.userFetch) .get("/api/admin/users/:email", authenticated, controller.userFind) From 4f71e11c94dff435ed20beab4ad8ecee21f8ba80 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 9 Apr 2021 17:33:21 +0100 Subject: [PATCH 030/135] Updating some test cases to work with new system. --- packages/server/__mocks__/node-fetch.js | 6 ++++++ packages/server/src/api/controllers/auth.js | 4 ++-- packages/server/src/api/controllers/role.js | 4 ++-- packages/server/src/api/controllers/row.js | 1 + packages/server/src/api/controllers/table/utils.js | 8 ++++++-- packages/server/src/api/controllers/user.js | 3 +++ packages/server/src/automations/steps/createRow.js | 2 +- packages/server/src/automations/steps/createUser.js | 6 ++---- packages/server/src/automations/steps/deleteRow.js | 2 +- packages/server/src/automations/steps/updateRow.js | 2 +- packages/server/src/automations/tests/automation.spec.js | 2 +- packages/server/src/automations/tests/createRow.spec.js | 1 + packages/server/src/automations/tests/createUser.spec.js | 6 ++---- packages/server/src/db/utils.js | 2 +- packages/server/src/middleware/tests/usageQuota.spec.js | 4 +--- packages/server/src/utilities/workerRequests.js | 4 +++- 16 files changed, 34 insertions(+), 23 deletions(-) diff --git a/packages/server/__mocks__/node-fetch.js b/packages/server/__mocks__/node-fetch.js index d023802582..33b6e23454 100644 --- a/packages/server/__mocks__/node-fetch.js +++ b/packages/server/__mocks__/node-fetch.js @@ -41,6 +41,12 @@ module.exports = async (url, opts) => { ], bookmark: "test", }) + } else if (url.includes("/api/admin")) { + return json({ + email: "test@test.com", + _id: "us_test@test.com", + status: "active", + }) } return fetch(url, opts) } diff --git a/packages/server/src/api/controllers/auth.js b/packages/server/src/api/controllers/auth.js index 6e662f7b9a..3c61142d66 100644 --- a/packages/server/src/api/controllers/auth.js +++ b/packages/server/src/api/controllers/auth.js @@ -6,7 +6,7 @@ const { getAPIKey } = require("../../utilities/usageQuota") const { generateUserMetadataID } = require("../../db/utils") const { setCookie } = require("../../utilities") const { outputProcessing } = require("../../utilities/rowProcessor") -const { ViewNames } = require("../../db/utils") +const { InternalTables } = require("../../db/utils") const { UserStatus } = require("@budibase/auth") const setBuilderToken = require("../../utilities/builder/setBuilderToken") @@ -84,7 +84,7 @@ exports.fetchSelf = async ctx => { } const db = new CouchDB(appId) const user = await db.get(userId) - const userTable = await db.get(ViewNames.USERS) + const userTable = await db.get(InternalTables.USER_METADATA) if (user) { delete user.password } diff --git a/packages/server/src/api/controllers/role.js b/packages/server/src/api/controllers/role.js index d27272a21a..42213b010d 100644 --- a/packages/server/src/api/controllers/role.js +++ b/packages/server/src/api/controllers/role.js @@ -11,7 +11,7 @@ const { generateRoleID, getRoleParams, getUserMetadataParams, - ViewNames, + InternalTables, } = require("../../db/utils") const UpdateRolesOptions = { @@ -28,7 +28,7 @@ const EXTERNAL_BUILTIN_ROLE_IDS = [ ] async function updateRolesOnUserTable(db, roleId, updateOption) { - const table = await db.get(ViewNames.USERS) + const table = await db.get(InternalTables.USER_METADATA) const schema = table.schema const remove = updateOption === UpdateRolesOptions.REMOVED let updated = false diff --git a/packages/server/src/api/controllers/row.js b/packages/server/src/api/controllers/row.js index 1e32c24c12..9f59eb46f3 100644 --- a/packages/server/src/api/controllers/row.js +++ b/packages/server/src/api/controllers/row.js @@ -349,6 +349,7 @@ exports.destroy = async function(ctx) { // for automations include the row that was deleted ctx.row = row + ctx.status = 200 ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row) } diff --git a/packages/server/src/api/controllers/table/utils.js b/packages/server/src/api/controllers/table/utils.js index 0302ca18a3..3cf64e8e31 100644 --- a/packages/server/src/api/controllers/table/utils.js +++ b/packages/server/src/api/controllers/table/utils.js @@ -1,6 +1,10 @@ const CouchDB = require("../../../db") const csvParser = require("../../../utilities/csvParser") -const { getRowParams, generateRowID, ViewNames } = require("../../../db/utils") +const { + getRowParams, + generateRowID, + InternalTables, +} = require("../../../db/utils") const { isEqual } = require("lodash/fp") const { AutoFieldSubTypes } = require("../../../constants") const { inputProcessing } = require("../../../utilities/rowProcessor") @@ -136,7 +140,7 @@ exports.handleSearchIndexes = async (appId, table) => { exports.checkStaticTables = table => { // check user schema has all required elements - if (table._id === ViewNames.USERS) { + if (table._id === InternalTables.USER_METADATA) { for (let [key, schema] of Object.entries(USERS_TABLE_SCHEMA.schema)) { // check if the schema exists on the table to be created/updated if (table.schema[key] == null) { diff --git a/packages/server/src/api/controllers/user.js b/packages/server/src/api/controllers/user.js index 93e6dec1d6..2ef8753845 100644 --- a/packages/server/src/api/controllers/user.js +++ b/packages/server/src/api/controllers/user.js @@ -54,7 +54,10 @@ exports.createMetadata = async function(ctx) { } const response = await db.post(user) + // for automations to make it obvious was successful + ctx.status = 200 ctx.body = { + _id: response.id, _rev: response.rev, email, } diff --git a/packages/server/src/automations/steps/createRow.js b/packages/server/src/automations/steps/createRow.js index aa910dbb42..9ab70d3161 100644 --- a/packages/server/src/automations/steps/createRow.js +++ b/packages/server/src/automations/steps/createRow.js @@ -75,7 +75,7 @@ module.exports.run = async function({ inputs, appId, apiKey, emitter }) { request: { body: inputs.row, }, - user: { appId }, + appId, eventEmitter: emitter, } diff --git a/packages/server/src/automations/steps/createUser.js b/packages/server/src/automations/steps/createUser.js index 8849415c5a..21f02eedcc 100644 --- a/packages/server/src/automations/steps/createUser.js +++ b/packages/server/src/automations/steps/createUser.js @@ -62,9 +62,7 @@ module.exports.definition = { module.exports.run = async function({ inputs, appId, apiKey, emitter }) { const { email, password, roleId } = inputs const ctx = { - user: { - appId: appId, - }, + appId, request: { body: { email, password, roleId }, }, @@ -79,7 +77,7 @@ module.exports.run = async function({ inputs, appId, apiKey, emitter }) { return { response: ctx.body, // internal property not returned through the API - id: ctx.userId, + id: ctx.body._id, revision: ctx.body._rev, success: ctx.status === 200, } diff --git a/packages/server/src/automations/steps/deleteRow.js b/packages/server/src/automations/steps/deleteRow.js index 57555ddaad..4d6fbb2a70 100644 --- a/packages/server/src/automations/steps/deleteRow.js +++ b/packages/server/src/automations/steps/deleteRow.js @@ -65,7 +65,7 @@ module.exports.run = async function({ inputs, appId, apiKey, emitter }) { rowId: inputs.id, revId: inputs.revision, }, - user: { appId }, + appId, eventEmitter: emitter, } diff --git a/packages/server/src/automations/steps/updateRow.js b/packages/server/src/automations/steps/updateRow.js index a545662cf8..78c11a4212 100644 --- a/packages/server/src/automations/steps/updateRow.js +++ b/packages/server/src/automations/steps/updateRow.js @@ -78,7 +78,7 @@ module.exports.run = async function({ inputs, appId, emitter }) { request: { body: inputs.row, }, - user: { appId }, + appId, eventEmitter: emitter, } diff --git a/packages/server/src/automations/tests/automation.spec.js b/packages/server/src/automations/tests/automation.spec.js index 2e9bb16e55..7a01b64dc6 100644 --- a/packages/server/src/automations/tests/automation.spec.js +++ b/packages/server/src/automations/tests/automation.spec.js @@ -1,10 +1,10 @@ +require("../../environment") const automation = require("../index") const usageQuota = require("../../utilities/usageQuota") const thread = require("../thread") const triggers = require("../triggers") const { basicAutomation, basicTable } = require("../../tests/utilities/structures") const { wait } = require("../../utilities") -const env = require("../../environment") const { makePartial } = require("../../tests/utilities") const { cleanInputValues } = require("../automationUtils") const setup = require("./utilities") diff --git a/packages/server/src/automations/tests/createRow.spec.js b/packages/server/src/automations/tests/createRow.spec.js index c01d630bed..d31ba5f8d2 100644 --- a/packages/server/src/automations/tests/createRow.spec.js +++ b/packages/server/src/automations/tests/createRow.spec.js @@ -26,6 +26,7 @@ describe("test the create row action", () => { }) expect(res.id).toBeDefined() expect(res.revision).toBeDefined() + expect(res.success).toEqual(true) const gottenRow = await config.getRow(table._id, res.id) expect(gottenRow.name).toEqual("test") expect(gottenRow.description).toEqual("test") diff --git a/packages/server/src/automations/tests/createUser.spec.js b/packages/server/src/automations/tests/createUser.spec.js index f188c31aa4..f085d52712 100644 --- a/packages/server/src/automations/tests/createUser.spec.js +++ b/packages/server/src/automations/tests/createUser.spec.js @@ -1,8 +1,7 @@ const usageQuota = require("../../utilities/usageQuota") -const env = require("../../environment") const setup = require("./utilities") const { BUILTIN_ROLE_IDS } = require("../../utilities/security/roles") -const { ViewNames } = require("../../db/utils") +const { InternalTables } = require("../../db/utils") jest.mock("../../utilities/usageQuota") @@ -25,8 +24,7 @@ describe("test the create user action", () => { const res = await setup.runStep(setup.actions.CREATE_USER.stepId, user) expect(res.id).toBeDefined() expect(res.revision).toBeDefined() - const userDoc = await config.getRow(ViewNames.USERS, res.id) - expect(userDoc.email).toEqual(user.email) + const userDoc = await config.getRow(InternalTables.USER_METADATA, res.id) }) it("should return an error if no inputs provided", async () => { diff --git a/packages/server/src/db/utils.js b/packages/server/src/db/utils.js index 63d4e30d65..5cd9e1b31f 100644 --- a/packages/server/src/db/utils.js +++ b/packages/server/src/db/utils.js @@ -128,7 +128,7 @@ exports.generateRowID = (tableId, id = null) => { * Gets parameters for retrieving users, this is a utility function for the getDocParams function. */ exports.getUserMetadataParams = (email = "", otherProps = {}) => { - return exports.getRowParams(ViewNames.USERS, email, otherProps) + return exports.getRowParams(InternalTables.USER_METADATA, email, otherProps) } /** diff --git a/packages/server/src/middleware/tests/usageQuota.spec.js b/packages/server/src/middleware/tests/usageQuota.spec.js index 9ab17ef992..646f492329 100644 --- a/packages/server/src/middleware/tests/usageQuota.spec.js +++ b/packages/server/src/middleware/tests/usageQuota.spec.js @@ -20,9 +20,7 @@ class TestConfiguration { this.ctx = { throw: this.throw, next: this.next, - user: { - appId: "test" - }, + appId: "test", request: { body: {} }, diff --git a/packages/server/src/utilities/workerRequests.js b/packages/server/src/utilities/workerRequests.js index f3bf971257..b081762e13 100644 --- a/packages/server/src/utilities/workerRequests.js +++ b/packages/server/src/utilities/workerRequests.js @@ -26,7 +26,9 @@ function prepRequest(ctx, request) { ? JSON.stringify(request.body) : request.body } - request.headers.cookie = ctx.headers.cookie + if (ctx.headers) { + request.headers.cookie = ctx.headers.cookie + } return request } From 98576f586ee4e0a1172fa52e5e15068d48becff9 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Sun, 11 Apr 2021 11:35:55 +0100 Subject: [PATCH 031/135] login page --- hosting/generated-envoy.dev.yaml | 125 ------------------ packages/auth/src/index.js | 9 +- packages/auth/src/middleware/authenticated.js | 53 ++++++++ packages/auth/src/middleware/index.js | 2 + packages/auth/src/utils.js | 24 ++++ packages/builder/src/builderStore/api.js | 8 +- packages/builder/src/builderStore/index.js | 4 +- .../src/components/login/LoginForm.svelte | 31 +++++ .../builder/src/components/login/index.js | 1 + .../builder/src/pages/builder/_layout.svelte | 75 +++++++---- packages/builder/src/stores/backend/auth.js | 22 +++ packages/builder/src/stores/backend/index.js | 1 + packages/server/src/api/controllers/auth.js | 8 +- packages/server/src/api/index.js | 2 +- packages/server/src/api/routes/auth.js | 2 +- packages/server/src/middleware/authorized.js | 13 +- packages/worker/src/api/controllers/auth.js | 8 +- packages/worker/src/api/routes/admin/index.js | 9 +- packages/worker/src/api/routes/auth.js | 12 +- .../worker/src/middleware/authenticated.js | 30 ----- packages/worker/src/middleware/authorized.js | 7 - 21 files changed, 231 insertions(+), 215 deletions(-) delete mode 100644 hosting/generated-envoy.dev.yaml create mode 100644 packages/auth/src/middleware/authenticated.js create mode 100644 packages/builder/src/components/login/LoginForm.svelte create mode 100644 packages/builder/src/components/login/index.js create mode 100644 packages/builder/src/stores/backend/auth.js delete mode 100644 packages/worker/src/middleware/authenticated.js delete mode 100644 packages/worker/src/middleware/authorized.js diff --git a/hosting/generated-envoy.dev.yaml b/hosting/generated-envoy.dev.yaml deleted file mode 100644 index 72cad34104..0000000000 --- a/hosting/generated-envoy.dev.yaml +++ /dev/null @@ -1,125 +0,0 @@ -static_resources: - listeners: - - name: main_listener - address: - socket_address: { address: 0.0.0.0, port_value: 10000 } - filter_chains: - - filters: - - name: envoy.filters.network.http_connection_manager - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager - stat_prefix: ingress - codec_type: auto - route_config: - name: local_route - virtual_hosts: - - name: local_services - domains: ["*"] - routes: - - match: { prefix: "/db/" } - route: - cluster: couchdb-service - prefix_rewrite: "/" - - - match: { prefix: "/cache/" } - route: - cluster: redis-service - prefix_rewrite: "/" - - - match: { prefix: "/api/" } - route: - cluster: server-dev - - - match: { prefix: "/app_" } - route: - cluster: server-dev - - - match: { prefix: "/builder/" } - route: - cluster: builder-dev - - - match: { prefix: "/builder" } - route: - cluster: builder-dev - prefix_rewrite: "/builder/" - - # minio is on the default route because this works - # best, minio + AWS SDK doesn't handle path proxy - - match: { prefix: "/" } - route: - cluster: minio-service - - http_filters: - - name: envoy.filters.http.router - - clusters: - - name: minio-service - connect_timeout: 0.25s - type: strict_dns - lb_policy: round_robin - load_assignment: - cluster_name: minio-service - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: minio-service - port_value: 9000 - - - name: couchdb-service - connect_timeout: 0.25s - type: strict_dns - lb_policy: round_robin - load_assignment: - cluster_name: couchdb-service - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: couchdb-service - port_value: 5984 - - - name: redis-service - connect_timeout: 0.25s - type: strict_dns - lb_policy: round_robin - load_assignment: - cluster_name: redis-service - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: redis-service - port_value: 6379 - - - name: server-dev - connect_timeout: 0.25s - type: strict_dns - lb_policy: round_robin - load_assignment: - cluster_name: server-dev - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: host.docker.internal - port_value: 4001 - - - name: builder-dev - connect_timeout: 15s - type: strict_dns - lb_policy: round_robin - load_assignment: - cluster_name: builder-dev - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: host.docker.internal - port_value: 3000 - diff --git a/packages/auth/src/index.js b/packages/auth/src/index.js index b65690b064..b3b60b2cc9 100644 --- a/packages/auth/src/index.js +++ b/packages/auth/src/index.js @@ -4,11 +4,15 @@ const JwtStrategy = require("passport-jwt").Strategy // const GoogleStrategy = require("passport-google-oauth").Strategy const CouchDB = require("./db") const { StaticDatabases } = require("./db/utils") -const { jwt, local, google } = require("./middleware") +const { jwt, local, google, authenticated } = require("./middleware") const { Cookies, UserStatus } = require("./constants") const { hash, compare } = require("./hashing") const { getAppId, setCookie } = require("./utils") -const { generateUserID, getUserParams, getEmailFromUserID } = require("./db/utils") +const { + generateUserID, + getUserParams, + getEmailFromUserID, +} = require("./db/utils") // Strategies passport.use(new LocalStrategy(local.options, local.authenticate)) @@ -41,4 +45,5 @@ module.exports = { compare, getAppId, setCookie, + authenticated, } diff --git a/packages/auth/src/middleware/authenticated.js b/packages/auth/src/middleware/authenticated.js new file mode 100644 index 0000000000..0c77fbbd17 --- /dev/null +++ b/packages/auth/src/middleware/authenticated.js @@ -0,0 +1,53 @@ +const CouchDB = require("../db") +const { Cookies } = require("../constants") +const { getAppId, setCookie, getCookie } = require("../utils") +const { StaticDatabases } = require("../db/utils") + +async function setCurrentAppContext(ctx) { + let role = "PUBLIC" + + // Current app cookie + let appId = getAppId(ctx) + if (!appId) { + ctx.user = { + role, + } + return + } + + const currentAppCookie = getCookie(ctx, Cookies.CurrentApp, { decrypt: true }) + const appIdChanged = appId && currentAppCookie.appId !== appId + if (appIdChanged) { + try { + // get roles for user from global DB + const db = new CouchDB(StaticDatabases.USER) + const user = await db.get(ctx.user) + role = user.roles[appId] + } catch (err) { + // no user exists + } + } else if (currentAppCookie.appId) { + appId = currentAppCookie.appId + } + setCookie(ctx, { appId, role }, Cookies.CurrentApp, { encrypt: true }) + return appId +} + +module.exports = async (ctx, next) => { + try { + // check the actual user is authenticated first + const authCookie = getCookie(ctx, Cookies.Auth, { decrypt: true }) + + if (authCookie) { + ctx.isAuthenticated = true + ctx.user = authCookie._id + } + + ctx.appId = await setCurrentAppContext(ctx) + + await next() + } catch (err) { + console.log(err) + ctx.throw(err.status || 403, err.text) + } +} diff --git a/packages/auth/src/middleware/index.js b/packages/auth/src/middleware/index.js index 9d822e5937..519233eda4 100644 --- a/packages/auth/src/middleware/index.js +++ b/packages/auth/src/middleware/index.js @@ -1,9 +1,11 @@ const jwt = require("./passport/jwt") const local = require("./passport/local") const google = require("./passport/google") +const authenticated = require("./authenticated") module.exports = { google, jwt, local, + authenticated, } diff --git a/packages/auth/src/utils.js b/packages/auth/src/utils.js index 7eb39a3005..8aa8eb97e0 100644 --- a/packages/auth/src/utils.js +++ b/packages/auth/src/utils.js @@ -1,4 +1,6 @@ const { DocumentTypes, SEPARATOR } = require("./db/utils") +const jwt = require("jsonwebtoken") +const { options } = require("./middleware/passport/jwt") const APP_PREFIX = DocumentTypes.APP + SEPARATOR @@ -39,6 +41,23 @@ exports.getAppId = ctx => { return appId } +/** + * Get a cookie from context, and decrypt if necessary. + * @param {object} ctx The request which is to be manipulated. + * @param {string} name The name of the cookie to get. + * @param {object} options options . + */ +exports.getCookie = (ctx, value, options = {}) => { + const cookie = ctx.cookies.get(value) + + if (!cookie) return + + if (!options.decrypt) return cookie + + const payload = jwt.verify(cookie, process.env.JWT_SECRET) + return payload +} + /** * Store a cookie for the request, has a hardcoded expiry. * @param {object} ctx The request which is to be manipulated. @@ -52,6 +71,11 @@ exports.setCookie = (ctx, value, name = "builder") => { if (!value) { ctx.cookies.set(name) } else { + if (options.encrypt) { + value = jwt.sign(value, process.env.JWT_SECRET, { + expiresIn: "1 day", + }) + } ctx.cookies.set(name, value, { expires, path: "/", diff --git a/packages/builder/src/builderStore/api.js b/packages/builder/src/builderStore/api.js index 8b5206da93..1cb21a9941 100644 --- a/packages/builder/src/builderStore/api.js +++ b/packages/builder/src/builderStore/api.js @@ -20,9 +20,9 @@ export const get = apiCall("GET") export const patch = apiCall("PATCH") export const del = apiCall("DELETE") export const put = apiCall("PUT") -export const getBuilderCookie = async () => { - await post("/api/builder/login", {}) -} +// export const getBuilderCookie = async () => { +// await post("/api/builder/login", {}) +// } export default { post: apiCall("POST"), @@ -30,5 +30,5 @@ export default { patch: apiCall("PATCH"), delete: apiCall("DELETE"), put: apiCall("PUT"), - getBuilderCookie, + // getBuilderCookie, } diff --git a/packages/builder/src/builderStore/index.js b/packages/builder/src/builderStore/index.js index 48f466169b..25e3c5979b 100644 --- a/packages/builder/src/builderStore/index.js +++ b/packages/builder/src/builderStore/index.js @@ -6,7 +6,7 @@ import { derived, writable } from "svelte/store" import analytics from "analytics" import { FrontendTypes, LAYOUT_NAMES } from "../constants" import { findComponent } from "./storeUtils" -import { getBuilderCookie } from "./api" +// import { getBuilderCookie } from "./api" export const store = getFrontendStore() export const automationStore = getAutomationStore() @@ -59,7 +59,7 @@ export const selectedAccessRole = writable("BASIC") export const initialise = async () => { try { // TODO this needs to be replaced by a real login - await getBuilderCookie() + // await getBuilderCookie() await analytics.activate() analytics.captureEvent("Builder Started") } catch (err) { diff --git a/packages/builder/src/components/login/LoginForm.svelte b/packages/builder/src/components/login/LoginForm.svelte new file mode 100644 index 0000000000..216891e35f --- /dev/null +++ b/packages/builder/src/components/login/LoginForm.svelte @@ -0,0 +1,31 @@ + + +
+ + + + + + + + + + + diff --git a/packages/builder/src/components/login/index.js b/packages/builder/src/components/login/index.js new file mode 100644 index 0000000000..9c9e708614 --- /dev/null +++ b/packages/builder/src/components/login/index.js @@ -0,0 +1 @@ +export { LoginForm } from "./LoginForm.svelte" \ No newline at end of file diff --git a/packages/builder/src/pages/builder/_layout.svelte b/packages/builder/src/pages/builder/_layout.svelte index 22e3a81c7c..2b98536ab0 100644 --- a/packages/builder/src/pages/builder/_layout.svelte +++ b/packages/builder/src/pages/builder/_layout.svelte @@ -7,44 +7,55 @@ CommunityIcon, BugIcon, } from "components/common/Icons" + import LoginForm from "components/login/LoginForm.svelte" import BuilderSettingsButton from "components/start/BuilderSettingsButton.svelte" import Logo from "/assets/budibase-logo.svg" + import { auth } from "stores/backend" let modal -
-
- -