diff --git a/packages/builder/cypress/integration/createUser.spec.js b/packages/builder/cypress/integration/createUser.spec.js index cbde6179b2..a5f9934dd7 100644 --- a/packages/builder/cypress/integration/createUser.spec.js +++ b/packages/builder/cypress/integration/createUser.spec.js @@ -9,7 +9,7 @@ context('Create a User', () => { // https://on.cypress.io/interacting-with-elements it('should create a user', () => { - cy.createUser("bbuser", "test", "ADMIN") + cy.createUser("bbuser@test.com", "test", "ADMIN") // // Check to make sure user was created! cy.contains("bbuser").should('be.visible') diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index ecb4eac6ce..8352c5bd6a 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -1,117 +1,117 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add("login", (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) + / *********************************************** + // This example commands.js shows you how to + // create various custom commands and overwrite + // existing commands. + // + // For more comprehensive examples of custom + // commands please read more here: + // https://on.cypress.io/custom-commands + // *********************************************** + // + // + // -- This is a parent command -- + // Cypress.Commands.add("login", (email, password) => { ... }) + // + // + // -- This is a child command -- + // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) + // + // + // -- This is a dual command -- + // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) + // + // + // -- This will overwrite an existing command -- + // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) -Cypress.Commands.add("createApp", name => { - cy.contains("Create New Web App").click() + Cypress.Commands.add("createApp", name => { + cy.contains("Create New Web App").click() - cy.get("body") - .then($body => { - if ($body.find("input[name=apiKey]").length) { - // input was found, do something else here - cy.get("input[name=apiKey]") - .type(name) - .should("have.value", name) - cy.contains("Next").click() - } - }) - .then(() => { - cy.get("input[name=applicationName]") - .type(name) - .should("have.value", name) + cy.get("body") + .then($body => { + if ($body.find("input[name=apiKey]").length) { + // input was found, do something else here + cy.get("input[name=apiKey]") + .type(name) + .should("have.value", name) + cy.contains("Next").click() + } + }) + .then(() => { + cy.get("input[name=applicationName]") + .type(name) + .should("have.value", name) - cy.contains("Next").click() + cy.contains("Next").click() - cy.get("input[name=username]") - .click() - .type("test") - cy.get("input[name=password]") - .click() - .type("test") - cy.contains("Submit").click() - cy.get("[data-cy=new-table]", { - timeout: 20000, - }).should("be.visible") - }) -}) + cy.get("input[name=email]") + .click() + .type("test@test.com") + cy.get("input[name=password]") + .click() + .type("test") + cy.contains("Submit").click() + cy.get("[data-cy=new-table]", { + timeout: 20000, + }).should("be.visible") + }) + }) -Cypress.Commands.add("createTestTableWithData", () => { - cy.createTable("dog") - cy.addColumn("dog", "name", "Text") - cy.addColumn("dog", "age", "Number") -}) + Cypress.Commands.add("createTestTableWithData", () => { + cy.createTable("dog") + cy.addColumn("dog", "name", "Text") + cy.addColumn("dog", "age", "Number") + }) -Cypress.Commands.add("createTable", tableName => { - // Enter table name - cy.get("[data-cy=new-table]").click() - cy.get(".modal").within(() => { - cy.get("input") - .first() - .type(tableName) - cy.get(".buttons") - .contains("Create") - .click() - }) - cy.contains(tableName).should("be.visible") -}) + Cypress.Commands.add("createTable", tableName => { + // Enter table name + cy.get("[data-cy=new-table]").click() + cy.get(".modal").within(() => { + cy.get("input") + .first() + .type(tableName) + cy.get(".buttons") + .contains("Create") + .click() + }) + cy.contains(tableName).should("be.visible") + }) -Cypress.Commands.add("addColumn", (tableName, columnName, type) => { - // Select Table - cy.contains(".nav-item", tableName).click() - cy.contains("Create New Column").click() + Cypress.Commands.add("addColumn", (tableName, columnName, type) => { + // Select Table + cy.contains(".nav-item", tableName).click() + cy.contains("Create New Column").click() - // Configure column - cy.get(".actions").within(() => { - cy.get("input") - .first() - .type(columnName) - // Unset table display column - cy.contains("display column").click() - cy.get("select").select(type) - cy.contains("Save").click() - }) -}) + // Configure column + cy.get(".actions").within(() => { + cy.get("input") + .first() + .type(columnName) + // Unset table display column + cy.contains("display column").click() + cy.get("select").select(type) + cy.contains("Save").click() + }) + }) -Cypress.Commands.add("addRow", values => { - cy.contains("Create New Row").click() + Cypress.Commands.add("addRow", values => { + cy.contains("Create New Row").click() - cy.get(".modal").within(() => { - for (let i = 0; i < values.length; i++) { - cy.get("input") - .eq(i) - .type(values[i]) - } + cy.get(".modal").within(() => { + for (let i = 0; i < values.length; i++) { + cy.get("input") + .eq(i) + .type(values[i]) + } - // Save - cy.get(".buttons") - .contains("Create") - .click() - }) -}) + // Save + cy.get(".buttons") + .contains("Create") + .click() + }) + }) -Cypress.Commands.add("createUser", (username, password, role) => { +Cypress.Commands.add("createUser", (email, password, role) => { // Create User cy.contains("Users").click() @@ -123,7 +123,7 @@ Cypress.Commands.add("createUser", (username, password, role) => { .type(password) cy.get("input") .eq(1) - .type(username) + .type(email) cy.get("select") .first() .select(role) diff --git a/packages/builder/package.json b/packages/builder/package.json index b4ffcf7b66..a4908de3da 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -63,7 +63,7 @@ } }, "dependencies": { - "@budibase/bbui": "^1.50.2", + "@budibase/bbui": "^1.51.0", "@budibase/client": "^0.3.8", "@budibase/colorpicker": "^1.0.1", "@budibase/svelte-ag-grid": "^0.0.16", diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 8bb4dc36dd..7e26b2155e 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -62,6 +62,8 @@ {:else if value.customType === 'password'} + {:else if value.customType === 'email'} + {:else if value.customType === 'table'} {:else if value.customType === 'row'} diff --git a/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte b/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte index c21d3449b6..8b1c2e18e6 100644 --- a/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte +++ b/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte @@ -1,5 +1,12 @@

Create your first User

(blurred.username = true)} - label="Username" - name="username" - placeholder="Username" - type="name" - error={blurred.username && validationErrors.username} /> + on:input={() => (blurred.email = true)} + label="Email" + name="email" + placeholder="Email" + type="email" + error={blurred.email && validationErrors.email} /> (blurred.password = true)} label="Password" diff --git a/packages/builder/src/components/userInterface/temporaryPanelStructure.js b/packages/builder/src/components/userInterface/temporaryPanelStructure.js index 571091b535..81b73d3204 100644 --- a/packages/builder/src/components/userInterface/temporaryPanelStructure.js +++ b/packages/builder/src/components/userInterface/temporaryPanelStructure.js @@ -427,6 +427,36 @@ export default { ], }, }, + { + _component: "@budibase/standard-components/cardstat", + name: "Stat", + description: "A card component for displaying numbers.", + icon: "ri-dual-sim-2-line", + children: [], + properties: { + design: { ...all }, + settings: [ + { + label: "Title", + key: "title", + control: Input, + placeholder: "Total Revenue", + }, + { + label: "Value", + key: "value", + control: Input, + placeholder: "$1,981,983", + }, + { + label: "Label", + key: "label", + control: Input, + placeholder: "Stripe", + }, + ], + }, + }, ], }, { diff --git a/packages/builder/src/constants/backend/index.js b/packages/builder/src/constants/backend/index.js index a735e4b864..bcbce153fe 100644 --- a/packages/builder/src/constants/backend/index.js +++ b/packages/builder/src/constants/backend/index.js @@ -9,6 +9,16 @@ export const FIELDS = { presence: false, }, }, + LONGFORM: { + name: "Long Form Text", + icon: "ri-file-text-line", + type: "longform", + constraints: { + type: "string", + length: {}, + presence: false, + }, + }, OPTIONS: { name: "Options", icon: "ri-list-check-2", diff --git a/packages/builder/src/constants/index.js b/packages/builder/src/constants/index.js index 0f89fa57c0..d8a83fa329 100644 --- a/packages/builder/src/constants/index.js +++ b/packages/builder/src/constants/index.js @@ -3,7 +3,7 @@ export const TableNames = { } // fields on the user table that cannot be edited -export const UNEDITABLE_USER_FIELDS = ["username", "password", "roleId"] +export const UNEDITABLE_USER_FIELDS = ["email", "password", "roleId"] export const DEFAULT_PAGES_OBJECT = { main: { diff --git a/packages/builder/yarn.lock b/packages/builder/yarn.lock index 8dc3a20ab6..57cb2a3ee7 100644 --- a/packages/builder/yarn.lock +++ b/packages/builder/yarn.lock @@ -842,24 +842,17 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" -"@budibase/bbui@^1.50.2": - version "1.50.2" - resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.50.2.tgz#a6b45518ed963717bcd912c028dc48fc92c7e15c" - integrity sha512-uuyKwlQ11io9yrPi2uoHgRG6SbO4B7jsKxfVoEvLqYGNsFH0Gi/iZdC+JEvBsWO0tu1ZnkxRD3qqSasW+4q0Og== +"@budibase/bbui@^1.51.0": + version "1.52.0" + resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.52.0.tgz#81fc8d3f80cb74f01a4f2d62e58389fa8fbfedeb" + integrity sha512-ytDZj/lQKUiwmF4wzz45yAQFTajEFW3Z7HWD7AmfTfxRtbwGXefbX+mF3JkWrYq5OclUtaA2+kluOX7tP1oZmw== 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" - -"@budibase/client@^0.3.8": - version "0.3.8" - resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.3.8.tgz#75df7e97e8f0d9b58c00e2bb0d3b4a55f8d04735" - integrity sha512-tnFdmCdXKS+uZGoipr69Wa0oVoFHmyoV0ydihI6q0gKQH0KutypVHAaul2qPB8t5a/mTZopC//2WdmCeX1GKVg== - dependencies: - deep-equal "^2.0.1" - mustache "^4.0.1" - regexparam "^1.3.0" + turndown "^7.0.0" "@budibase/colorpicker@^1.0.1": version "1.0.1" @@ -1620,6 +1613,11 @@ argparse@^1.0.7: 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== + aria-query@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" @@ -1648,11 +1646,6 @@ array-equal@^1.0.0: resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1720,13 +1713,6 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" - integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== - dependencies: - array-filter "^1.0.0" - aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -2148,14 +2134,6 @@ chokidar@^3.3.0: optionalDependencies: fsevents "~2.1.2" -chrome-remote-interface@^0.27.1: - version "0.27.2" - resolved "https://registry.yarnpkg.com/chrome-remote-interface/-/chrome-remote-interface-0.27.2.tgz#e5605605f092b7ef8575d95304e004039c9d0ab9" - integrity sha512-pVLljQ29SAx8KIv5tSa9sIf8GrEsAZdPJoeWOmY3/nrIzFmE+EryNNHvDkddGod0cmAFTv+GmPG0uvzxi2NWsA== - dependencies: - commander "2.11.x" - ws "^6.1.0" - ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -2294,11 +2272,6 @@ commander@2, commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@2.11.x: - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" - integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== - commander@^5.0.0, commander@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" @@ -2486,14 +2459,6 @@ cssstyle@^2.2.0: dependencies: cssom "~0.3.6" -cypress-log-to-output@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/cypress-log-to-output/-/cypress-log-to-output-1.1.2.tgz#b9635a907ed06961cd53cc1bff8d6f55a981a773" - integrity sha512-C1+ECMc/XXc4HqAEHdlw0X2wFhcoZZ/4qXHZkOAU/rRXMQXnbiO7JJtpLCKrLfOXlxB+jFwDAIdlPxPMfV3cFw== - dependencies: - chalk "^2.4.2" - chrome-remote-interface "^0.27.1" - cypress-terminal-report@^1.4.1: version "1.4.2" resolved "https://registry.yarnpkg.com/cypress-terminal-report/-/cypress-terminal-report-1.4.2.tgz#4eeaf2c6a063b42271ec686aff4ab0d6f7b252a6" @@ -2886,26 +2851,6 @@ deep-equal@^1.0.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" -deep-equal@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.4.tgz#6b0b407a074666033169df3acaf128e1c6f3eab6" - integrity sha512-BUfaXrVoCfgkOQY/b09QdO9L3XNoF2XH0A3aY9IQwQL/ZjLOe8FQgCNVl1wiolhsFo8kFdO9zdPViCPbmaJA5w== - dependencies: - es-abstract "^1.18.0-next.1" - es-get-iterator "^1.1.0" - is-arguments "^1.0.4" - is-date-object "^1.0.2" - is-regex "^1.1.1" - isarray "^2.0.5" - object-is "^1.1.3" - object-keys "^1.1.1" - object.assign "^4.1.1" - regexp.prototype.flags "^1.3.0" - side-channel "^1.0.3" - which-boxed-primitive "^1.0.1" - which-collection "^1.0.1" - which-typed-array "^1.1.2" - deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -3015,6 +2960,11 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" +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== + dotenv@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" @@ -3073,6 +3023,11 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +entities@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" + integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== + errno@^0.1.1, errno@~0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" @@ -3087,7 +3042,7 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.17.5: +es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: version "1.17.7" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g== @@ -3104,7 +3059,7 @@ es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstrac string.prototype.trimend "^1.0.1" string.prototype.trimstart "^1.0.1" -es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1: +es-abstract@^1.18.0-next.1: version "1.18.0-next.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA== @@ -3122,20 +3077,6 @@ es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1: string.prototype.trimend "^1.0.1" string.prototype.trimstart "^1.0.1" -es-get-iterator@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.1.tgz#b93ddd867af16d5118e00881396533c1c6647ad9" - integrity sha512-qorBw8Y7B15DVLaJWy6WdEV/ZkieBcu6QCq/xzWzGOKJqgG1j754vXRfZ3NY7HSShneqU43mPB4OkQBTkvHhFw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.1" - has-symbols "^1.0.1" - is-arguments "^1.0.4" - is-map "^2.0.1" - is-set "^2.0.1" - is-string "^1.0.5" - isarray "^2.0.5" - es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -3514,7 +3455,7 @@ for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -foreach@^2.0.5, foreach@~2.0.1: +foreach@~2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= @@ -3604,7 +3545,7 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.0, get-intrinsic@^1.0.1: +get-intrinsic@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.1.tgz#94a9768fcbdd0595a1c9273aacf4c89d075631be" integrity sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg== @@ -3962,11 +3903,6 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-bigint@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" - integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== - 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" @@ -3974,11 +3910,6 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e" - integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ== - is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -4017,7 +3948,7 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-date-object@^1.0.1, is-date-object@^1.0.2: +is-date-object@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== @@ -4094,11 +4025,6 @@ is-installed-globally@^0.3.2: global-dirs "^2.0.1" is-path-inside "^3.0.1" -is-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" - integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== - is-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" @@ -4109,11 +4035,6 @@ is-negative-zero@^2.0.0: resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= -is-number-object@^1.0.3: - version "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@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -4179,11 +4100,6 @@ is-regex@^1.0.4, is-regex@^1.1.1: dependencies: has-symbols "^1.0.1" -is-set@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" - integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA== - is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -4194,11 +4110,6 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-string@^1.0.4, is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - is-symbol@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" @@ -4206,31 +4117,11 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.1" -is-typed-array@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.3.tgz#a4ff5a5e672e1a55f99c7f54e59597af5c1df04d" - integrity sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ== - dependencies: - available-typed-arrays "^1.0.0" - es-abstract "^1.17.4" - foreach "^2.0.5" - has-symbols "^1.0.1" - is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== - -is-weakset@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83" - integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw== - is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -4256,11 +4147,6 @@ isarray@1.0.0, isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - isbuffer@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/isbuffer/-/isbuffer-0.0.0.tgz#38c146d9df528b8bf9b0701c3d43cf12df3fc39b" @@ -5014,6 +4900,13 @@ 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" + listr-silent-renderer@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" @@ -5214,6 +5107,17 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +markdown-it@^12.0.2: + version "12.0.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.0.2.tgz#4401beae8df8aa2221fc6565a7188e60a06ef0ed" + integrity sha512-4Lkvjbv2kK+moL9TbeV+6/NHx+1Q+R/NIdUlFlkqkkzUcTod4uiyTJRiBidKR9qXSdkNFkgv+AELY8KN9vSgVA== + dependencies: + argparse "^2.0.1" + entities "~2.0.0" + linkify-it "^3.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -5223,6 +5127,11 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -5523,14 +5432,6 @@ object-is@^1.0.1: define-properties "^1.1.3" es-abstract "^1.18.0-next.1" -object-is@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.4.tgz#63d6c83c00a43f4cbc9434eb9757c8a5b8565068" - integrity sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -6130,7 +6031,7 @@ 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, regexp.prototype.flags@^1.3.0: +regexp.prototype.flags@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== @@ -6138,11 +6039,6 @@ regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: define-properties "^1.1.3" es-abstract "^1.17.0-next.1" -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== - regexpu-core@^4.7.1: version "4.7.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" @@ -6606,14 +6502,6 @@ shortid@^2.2.15: dependencies: nanoid "^2.1.0" -side-channel@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3" - integrity sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g== - dependencies: - es-abstract "^1.18.0-next.0" - object-inspect "^1.8.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" @@ -7186,6 +7074,13 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" +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" @@ -7208,6 +7103,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +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== + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -7434,44 +7334,11 @@ whatwg-url@^8.0.0: tr46 "^2.0.2" webidl-conversions "^6.1.0" -which-boxed-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz#cbe8f838ebe91ba2471bb69e9edbda67ab5a5ec1" - integrity sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ== - dependencies: - is-bigint "^1.0.0" - is-boolean-object "^1.0.0" - is-number-object "^1.0.3" - is-string "^1.0.4" - is-symbol "^1.0.2" - -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which-typed-array@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.2.tgz#e5f98e56bda93e3dac196b01d47c1156679c00b2" - integrity sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ== - dependencies: - available-typed-arrays "^1.0.2" - es-abstract "^1.17.5" - foreach "^2.0.5" - function-bind "^1.1.1" - has-symbols "^1.0.1" - is-typed-array "^1.1.3" - which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -7529,7 +7396,7 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" -ws@^6.1.0, ws@^6.2.1: +ws@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== diff --git a/packages/client/src/api/auth.js b/packages/client/src/api/auth.js index 9273a00cc7..ddaaa7a491 100644 --- a/packages/client/src/api/auth.js +++ b/packages/client/src/api/auth.js @@ -3,15 +3,15 @@ import API from "./api" /** * Performs a log in request. */ -export const logIn = async ({ username, password }) => { - if (!username) { - return API.error("Please enter your username") +export const logIn = async ({ email, password }) => { + if (!email) { + return API.error("Please enter your email") } if (!password) { return API.error("Please enter your password") } return await API.post({ url: "/api/authenticate", - body: { username, password }, + body: { email, password }, }) } diff --git a/packages/client/src/store/auth.js b/packages/client/src/store/auth.js index a7c91a0972..d641113b4a 100644 --- a/packages/client/src/store/auth.js +++ b/packages/client/src/store/auth.js @@ -5,8 +5,8 @@ import { writable } from "svelte/store" const createAuthStore = () => { const store = writable("") - const logIn = async ({ username, password }) => { - const user = await API.logIn({ username, password }) + const logIn = async ({ email, password }) => { + const user = await API.logIn({ email, password }) if (!user.error) { store.set(user.token) location.reload() diff --git a/packages/server/src/api/controllers/auth.js b/packages/server/src/api/controllers/auth.js index 43cc4317f4..e8bc000e03 100644 --- a/packages/server/src/api/controllers/auth.js +++ b/packages/server/src/api/controllers/auth.js @@ -10,21 +10,21 @@ exports.authenticate = async ctx => { const appId = ctx.appId if (!appId) ctx.throw(400, "No appId") - const { username, password } = ctx.request.body + const { email, password } = ctx.request.body - if (!username) ctx.throw(400, "Username Required.") + if (!email) ctx.throw(400, "Email Required.") if (!password) ctx.throw(400, "Password Required.") - // Check the user exists in the instance DB by username + // 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(username)) + dbUser = await db.get(generateUserID(email)) } catch (_) { // do not want to throw a 404 - as this could be - // used to determine valid usernames + // used to determine valid emails ctx.throw(401, "Invalid Credentials") } diff --git a/packages/server/src/api/controllers/row.js b/packages/server/src/api/controllers/row.js index c7fb70d50e..344a9753a1 100644 --- a/packages/server/src/api/controllers/row.js +++ b/packages/server/src/api/controllers/row.js @@ -359,6 +359,11 @@ const TYPE_TRANSFORM_MAP = { [null]: "", [undefined]: undefined, }, + longform: { + "": "", + [null]: "", + [undefined]: undefined, + }, number: { "": null, [null]: null, diff --git a/packages/server/src/api/controllers/user.js b/packages/server/src/api/controllers/user.js index bf56e6b181..d605a3dd17 100644 --- a/packages/server/src/api/controllers/user.js +++ b/packages/server/src/api/controllers/user.js @@ -15,10 +15,10 @@ exports.fetch = async function(ctx) { exports.create = async function(ctx) { const db = new CouchDB(ctx.user.appId) - const { username, password, name, roleId } = ctx.request.body + const { email, username, password, name, roleId } = ctx.request.body - if (!username || !password) { - ctx.throw(400, "Username and Password Required.") + if (!email || !password) { + ctx.throw(400, "email and Password Required.") } const role = await getRole(ctx.user.appId, roleId) @@ -26,10 +26,10 @@ exports.create = async function(ctx) { if (!role) ctx.throw(400, "Invalid Role") const user = { - _id: generateUserID(username), - username, + _id: generateUserID(email), + email, password: await bcrypt.hash(password), - name: name || username, + name, type: "user", roleId, tableId: ViewNames.USERS, @@ -42,7 +42,7 @@ exports.create = async function(ctx) { ctx.userId = response._id ctx.body = { _rev: response.rev, - username, + email, name, } } catch (err) { @@ -64,22 +64,22 @@ exports.update = async function(ctx) { user._rev = response.rev ctx.status = 200 - ctx.message = `User ${ctx.request.body.username} updated successfully.` + ctx.message = `User ${ctx.request.body.email} updated successfully.` ctx.body = response } exports.destroy = async function(ctx) { const database = new CouchDB(ctx.user.appId) - await database.destroy(generateUserID(ctx.params.username)) - ctx.message = `User ${ctx.params.username} deleted.` + await database.destroy(generateUserID(ctx.params.email)) + ctx.message = `User ${ctx.params.email} deleted.` ctx.status = 200 } exports.find = async function(ctx) { const database = new CouchDB(ctx.user.appId) - const user = await database.get(generateUserID(ctx.params.username)) + const user = await database.get(generateUserID(ctx.params.email)) ctx.body = { - username: user.username, + email: user.email, name: user.name, _rev: user._rev, } diff --git a/packages/server/src/api/routes/tests/couchTestUtils.js b/packages/server/src/api/routes/tests/couchTestUtils.js index e3a366ac78..463d88e637 100644 --- a/packages/server/src/api/routes/tests/couchTestUtils.js +++ b/packages/server/src/api/routes/tests/couchTestUtils.js @@ -113,7 +113,7 @@ exports.clearApplications = async request => { exports.createUser = async ( request, appId, - username = "babs", + email = "babs@babs.com", password = "babs_password" ) => { const res = await request @@ -121,21 +121,20 @@ exports.createUser = async ( .set(exports.defaultHeaders(appId)) .send({ name: "Bill", - username, + email, password, roleId: BUILTIN_ROLE_IDS.POWER, }) return res.body } -const createUserWithRole = async (request, appId, roleId, username) => { - const password = `password_${username}` +const createUserWithRole = async (request, appId, roleId, email) => { + const password = `password_${email}` await request .post(`/api/users`) .set(exports.defaultHeaders(appId)) .send({ - name: username, - username, + email, password, roleId, }) @@ -155,7 +154,7 @@ const createUserWithRole = async (request, appId, roleId, username) => { Cookie: `budibase:${appId}:local=${anonToken}`, "x-budibase-app-id": appId, }) - .send({ username, password }) + .send({ email, password }) // returning necessary request headers return { @@ -177,7 +176,7 @@ exports.testPermissionsForEndpoint = async ({ request, appId, passRole, - "passUser" + "passUser@budibase.com" ) await createRequest(request, method, url, body) @@ -188,7 +187,7 @@ exports.testPermissionsForEndpoint = async ({ request, appId, failRole, - "failUser" + "failUser@budibase.com" ) await createRequest(request, method, url, body) @@ -207,7 +206,7 @@ exports.builderEndpointShouldBlockNormalUsers = async ({ request, appId, BUILTIN_ROLE_IDS.BASIC, - "basicUser" + "basicUser@budibase.com" ) await createRequest(request, method, url, body) diff --git a/packages/server/src/api/routes/tests/user.spec.js b/packages/server/src/api/routes/tests/user.spec.js index deac296567..fa570172ce 100644 --- a/packages/server/src/api/routes/tests/user.spec.js +++ b/packages/server/src/api/routes/tests/user.spec.js @@ -11,7 +11,6 @@ const { const { cloneDeep } = require("lodash/fp") const baseBody = { - name: "brandNewUser", password: "yeeooo", roleId: BUILTIN_ROLE_IDS.POWER } @@ -38,8 +37,8 @@ describe("/users", () => { describe("fetch", () => { it("returns a list of users from an instance db", async () => { - await createUser(request, appId, "brenda", "brendas_password") - await createUser(request, appId, "pam", "pam_password") + await createUser(request, appId, "brenda@brenda.com", "brendas_password") + await createUser(request, appId, "pam@pam.com", "pam_password") const res = await request .get(`/api/users`) .set(defaultHeaders(appId)) @@ -47,8 +46,8 @@ describe("/users", () => { .expect(200) expect(res.body.length).toBe(2) - expect(res.body.find(u => u.username === "brenda")).toBeDefined() - expect(res.body.find(u => u.username === "pam")).toBeDefined() + expect(res.body.find(u => u.email === "brenda@brenda.com")).toBeDefined() + expect(res.body.find(u => u.email === "pam@pam.com")).toBeDefined() }) it("should apply authorization to endpoint", async () => { @@ -68,7 +67,7 @@ describe("/users", () => { describe("create", () => { it("returns a success message when a user is successfully created", async () => { const body = cloneDeep(baseBody) - body.username = "bill" + body.email = "bill@budibase.com" const res = await request .post(`/api/users`) .set(defaultHeaders(appId)) @@ -82,7 +81,7 @@ describe("/users", () => { it("should apply authorization to endpoint", async () => { const body = cloneDeep(baseBody) - body.username = "brandNewUser" + body.email = "brandNewUser@user.com" await testPermissionsForEndpoint({ request, method: "POST", diff --git a/packages/server/src/api/routes/user.js b/packages/server/src/api/routes/user.js index 9394d842bd..1ad1d2363e 100644 --- a/packages/server/src/api/routes/user.js +++ b/packages/server/src/api/routes/user.js @@ -16,7 +16,7 @@ router controller.fetch ) .get( - "/api/users/:username", + "/api/users/:email", authorized(PermissionTypes.USER, PermissionLevels.READ), controller.find ) @@ -32,7 +32,7 @@ router controller.create ) .delete( - "/api/users/:username", + "/api/users/:email", authorized(PermissionTypes.USER, PermissionLevels.WRITE), usage, controller.destroy diff --git a/packages/server/src/app.js b/packages/server/src/app.js index 10eec1e66f..58526cdf4c 100644 --- a/packages/server/src/app.js +++ b/packages/server/src/app.js @@ -1,4 +1,5 @@ const Koa = require("koa") +const destroyable = require("server-destroy") const electron = require("electron") const koaBody = require("koa-body") const logger = require("koa-pino-logger") @@ -44,6 +45,7 @@ if (electron.app && electron.app.isPackaged) { } const server = http.createServer(app.callback()) +destroyable(server) server.on("close", () => console.log("Server Closed")) @@ -51,3 +53,14 @@ module.exports = server.listen(env.PORT || 4001, () => { console.log(`Budibase running on ${JSON.stringify(server.address())}`) automations.init() }) + +process.on("uncaughtException", err => { + console.error(err) + server.close() + server.destroy() +}) + +process.on("SIGTERM", () => { + server.close() + server.destroy() +}) diff --git a/packages/server/src/automations/steps/createUser.js b/packages/server/src/automations/steps/createUser.js index 2e124b148b..a9dce4b66f 100644 --- a/packages/server/src/automations/steps/createUser.js +++ b/packages/server/src/automations/steps/createUser.js @@ -5,7 +5,7 @@ const usage = require("../../utilities/usageQuota") module.exports.definition = { description: "Create a new user", - tagline: "Create user {{inputs.username}}", + tagline: "Create user {{inputs.email}}", icon: "ri-user-add-line", name: "Create User", type: "ACTION", @@ -16,9 +16,10 @@ module.exports.definition = { schema: { inputs: { properties: { - username: { + email: { type: "string", - title: "Username", + customType: "email", + title: "Email", }, password: { type: "string", @@ -32,7 +33,7 @@ module.exports.definition = { pretty: roles.BUILTIN_ROLE_NAME_ARRAY, }, }, - required: ["username", "password", "roleId"], + required: ["email", "password", "roleId"], }, outputs: { properties: { @@ -59,13 +60,13 @@ module.exports.definition = { } module.exports.run = async function({ inputs, appId, apiKey }) { - const { username, password, roleId } = inputs + const { email, password, roleId } = inputs const ctx = { user: { appId: appId, }, request: { - body: { username, password, roleId }, + body: { email, password, roleId }, }, } diff --git a/packages/server/src/constants/index.js b/packages/server/src/constants/index.js index d691bcee55..587e751600 100644 --- a/packages/server/src/constants/index.js +++ b/packages/server/src/constants/index.js @@ -12,17 +12,18 @@ const USERS_TABLE_SCHEMA = { views: {}, name: "Users", schema: { - username: { + email: { type: "string", constraints: { type: "string", + email: true, length: { maximum: "", }, presence: true, }, - fieldName: "username", - name: "username", + fieldName: "email", + name: "email", }, roleId: { fieldName: "roleId", @@ -35,7 +36,7 @@ const USERS_TABLE_SCHEMA = { }, }, }, - primaryDisplay: "username", + primaryDisplay: "email", } exports.AuthTypes = AuthTypes diff --git a/packages/server/src/db/utils.js b/packages/server/src/db/utils.js index 5dc0161228..6d7ea8bb93 100644 --- a/packages/server/src/db/utils.js +++ b/packages/server/src/db/utils.js @@ -101,17 +101,17 @@ exports.generateRowID = tableId => { /** * Gets parameters for retrieving users, this is a utility function for the getDocParams function. */ -exports.getUserParams = (username = "", otherProps = {}) => { - return exports.getRowParams(ViewNames.USERS, username, otherProps) +exports.getUserParams = (email = "", otherProps = {}) => { + return exports.getRowParams(ViewNames.USERS, email, otherProps) } /** - * Generates a new user ID based on the passed in username. - * @param {string} username The username which the ID is going to be built up of. + * 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 = username => { - return `${DocumentTypes.ROW}${SEPARATOR}${ViewNames.USERS}${SEPARATOR}${DocumentTypes.USER}${SEPARATOR}${username}` +exports.generateUserID = email => { + return `${DocumentTypes.ROW}${SEPARATOR}${ViewNames.USERS}${SEPARATOR}${DocumentTypes.USER}${SEPARATOR}${email}` } /** diff --git a/packages/standard-components/components.json b/packages/standard-components/components.json index d1376384d8..c55c04f119 100644 --- a/packages/standard-components/components.json +++ b/packages/standard-components/components.json @@ -56,7 +56,7 @@ }, "login": { "name": "Login Control", - "description": "A control that accepts username, password an also handles password resets", + "description": "A control that accepts email, password an also handles password resets", "props": { "logo": "string", "title": "string", @@ -257,6 +257,14 @@ } } }, + "cardstat": { + "name": "Stat Card", + "props": { + "title": "string", + "value": "string", + "label": "string" + } + }, "cardhorizontal": { "name": "Horizontal Card", "props": { diff --git a/packages/standard-components/package.json b/packages/standard-components/package.json index 50f429838a..440784e4bb 100644 --- a/packages/standard-components/package.json +++ b/packages/standard-components/package.json @@ -19,6 +19,7 @@ "lodash": "^4.17.15", "rollup": "^2.11.2", "rollup-plugin-livereload": "^1.0.1", + "rollup-plugin-node-builtins": "^2.1.2", "rollup-plugin-postcss": "^3.1.5", "rollup-plugin-svelte": "^6.1.1", "rollup-plugin-terser": "^7.0.2", @@ -32,13 +33,15 @@ "license": "MIT", "gitHead": "284cceb9b703c38566c6e6363c022f79a08d5691", "dependencies": { - "@budibase/bbui": "^1.51.0", + "@budibase/bbui": "^1.52.1", "@budibase/svelte-ag-grid": "^0.0.16", "@fortawesome/fontawesome-free": "^5.14.0", "apexcharts": "^3.22.1", "flatpickr": "^4.6.6", "lodash.debounce": "^4.0.8", + "markdown-it": "^12.0.2", "quill": "^1.3.7", + "turndown": "^7.0.0", "svelte-apexcharts": "^1.0.2", "svelte-flatpickr": "^3.1.0" } diff --git a/packages/standard-components/rollup.config.js b/packages/standard-components/rollup.config.js index c4c7767200..dd8fd47b60 100644 --- a/packages/standard-components/rollup.config.js +++ b/packages/standard-components/rollup.config.js @@ -2,8 +2,11 @@ import commonjs from "@rollup/plugin-commonjs" import resolve from "@rollup/plugin-node-resolve" import svelte from "rollup-plugin-svelte" import postcss from "rollup-plugin-postcss" +import json from "@rollup/plugin-json" import { terser } from "rollup-plugin-terser" +import builtins from "rollup-plugin-node-builtins" + const production = !process.env.ROLLUP_WATCH const externals = ["svelte", "svelte/internal"] @@ -18,6 +21,7 @@ export default { }, ], plugins: [ + builtins(), production && terser(), postcss(), svelte({ @@ -28,5 +32,6 @@ export default { skip: externals, }), commonjs(), + json(), ], } diff --git a/packages/standard-components/src/CardStat.svelte b/packages/standard-components/src/CardStat.svelte new file mode 100644 index 0000000000..e5e40ad862 --- /dev/null +++ b/packages/standard-components/src/CardStat.svelte @@ -0,0 +1,49 @@ + + +
+

{title}

+

{value}

+

{label}

+
+ + diff --git a/packages/standard-components/src/Form.svelte b/packages/standard-components/src/Form.svelte index 03b11307a1..f868956dd9 100644 --- a/packages/standard-components/src/Form.svelte +++ b/packages/standard-components/src/Form.svelte @@ -1,6 +1,13 @@ @@ -42,9 +42,9 @@
@@ -62,7 +62,7 @@
{#if error} -
Incorrect username or password
+
Incorrect email or password
{/if}
diff --git a/packages/standard-components/src/RichText.svelte b/packages/standard-components/src/RichText.svelte index b5b8d56eff..18aca42b1a 100644 --- a/packages/standard-components/src/RichText.svelte +++ b/packages/standard-components/src/RichText.svelte @@ -24,5 +24,5 @@
- +
diff --git a/packages/standard-components/src/grid/CreateRow/Modal.svelte b/packages/standard-components/src/grid/CreateRow/Modal.svelte index 9c7de2b0ff..1cb9aa923d 100644 --- a/packages/standard-components/src/grid/CreateRow/Modal.svelte +++ b/packages/standard-components/src/grid/CreateRow/Modal.svelte @@ -1,6 +1,6 @@