Merge pull request #893 from Budibase/username-email
Replace username with email across the board
This commit is contained in:
commit
ab9c594de9
|
@ -9,7 +9,7 @@ context('Create a User', () => {
|
||||||
|
|
||||||
// https://on.cypress.io/interacting-with-elements
|
// https://on.cypress.io/interacting-with-elements
|
||||||
it('should create a user', () => {
|
it('should create a user', () => {
|
||||||
cy.createUser("bbuser", "test", "ADMIN")
|
cy.createUser("bbuser@test.com", "test", "ADMIN")
|
||||||
|
|
||||||
// // Check to make sure user was created!
|
// // Check to make sure user was created!
|
||||||
cy.contains("bbuser").should('be.visible')
|
cy.contains("bbuser").should('be.visible')
|
||||||
|
|
|
@ -44,9 +44,9 @@ Cypress.Commands.add("createApp", name => {
|
||||||
|
|
||||||
cy.contains("Next").click()
|
cy.contains("Next").click()
|
||||||
|
|
||||||
cy.get("input[name=username]")
|
cy.get("input[name=email]")
|
||||||
.click()
|
.click()
|
||||||
.type("test")
|
.type("test@test.com")
|
||||||
cy.get("input[name=password]")
|
cy.get("input[name=password]")
|
||||||
.click()
|
.click()
|
||||||
.type("test")
|
.type("test")
|
||||||
|
@ -111,7 +111,7 @@ Cypress.Commands.add("addRow", values => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Cypress.Commands.add("createUser", (username, password, accessLevel) => {
|
Cypress.Commands.add("createUser", (email, password, accessLevel) => {
|
||||||
// Create User
|
// Create User
|
||||||
cy.contains("Users").click()
|
cy.contains("Users").click()
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ Cypress.Commands.add("createUser", (username, password, accessLevel) => {
|
||||||
.type(password)
|
.type(password)
|
||||||
cy.get("input")
|
cy.get("input")
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.type(username)
|
.type(email)
|
||||||
cy.get("select")
|
cy.get("select")
|
||||||
.first()
|
.first()
|
||||||
.select(accessLevel)
|
.select(accessLevel)
|
||||||
|
|
|
@ -62,6 +62,8 @@
|
||||||
</Select>
|
</Select>
|
||||||
{:else if value.customType === 'password'}
|
{:else if value.customType === 'password'}
|
||||||
<Input type="password" extraThin bind:value={block.inputs[key]} />
|
<Input type="password" extraThin bind:value={block.inputs[key]} />
|
||||||
|
{:else if value.customType === 'email'}
|
||||||
|
<Input type="email" extraThin bind:value={block.inputs[key]} />
|
||||||
{:else if value.customType === 'table'}
|
{:else if value.customType === 'table'}
|
||||||
<TableSelector bind:value={block.inputs[key]} />
|
<TableSelector bind:value={block.inputs[key]} />
|
||||||
{:else if value.customType === 'row'}
|
{:else if value.customType === 'row'}
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { Input, Select, Label, DatePicker, Toggle, RichText } from "@budibase/bbui"
|
import {
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
Label,
|
||||||
|
DatePicker,
|
||||||
|
Toggle,
|
||||||
|
RichText,
|
||||||
|
} from "@budibase/bbui"
|
||||||
import { backendUiStore } from "builderStore"
|
import { backendUiStore } from "builderStore"
|
||||||
import { TableNames } from "constants"
|
import { TableNames } from "constants"
|
||||||
import Dropzone from "components/common/Dropzone.svelte"
|
import Dropzone from "components/common/Dropzone.svelte"
|
||||||
|
|
|
@ -52,7 +52,9 @@
|
||||||
applicationName: string().required("Your application must have a name."),
|
applicationName: string().required("Your application must have a name."),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
username: string().required("Your application needs a first user."),
|
email: string()
|
||||||
|
.email()
|
||||||
|
.required("Your application needs a first user."),
|
||||||
password: string().required(
|
password: string().required(
|
||||||
"Please enter a password for your first user."
|
"Please enter a password for your first user."
|
||||||
),
|
),
|
||||||
|
@ -164,8 +166,7 @@
|
||||||
|
|
||||||
// Create user
|
// Create user
|
||||||
const user = {
|
const user = {
|
||||||
name: $createAppStore.values.username,
|
email: $createAppStore.values.email,
|
||||||
username: $createAppStore.values.username,
|
|
||||||
password: $createAppStore.values.password,
|
password: $createAppStore.values.password,
|
||||||
accessLevelId: $createAppStore.values.accessLevelId,
|
accessLevelId: $createAppStore.values.accessLevelId,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,18 @@
|
||||||
import { Input, Select } from "@budibase/bbui"
|
import { Input, Select } from "@budibase/bbui"
|
||||||
export let validationErrors
|
export let validationErrors
|
||||||
|
|
||||||
let blurred = { username: false, password: false }
|
let blurred = { email: false, password: false }
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h2>Create your first User</h2>
|
<h2>Create your first User</h2>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<Input
|
<Input
|
||||||
on:input={() => (blurred.username = true)}
|
on:input={() => (blurred.email = true)}
|
||||||
label="Username"
|
label="Email"
|
||||||
name="username"
|
name="email"
|
||||||
placeholder="Username"
|
placeholder="Email"
|
||||||
type="name"
|
type="email"
|
||||||
error={blurred.username && validationErrors.username} />
|
error={blurred.email && validationErrors.email} />
|
||||||
<Input
|
<Input
|
||||||
on:input={() => (blurred.password = true)}
|
on:input={() => (blurred.password = true)}
|
||||||
label="Password"
|
label="Password"
|
||||||
|
|
|
@ -3,7 +3,7 @@ export const TableNames = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fields on the user table that cannot be edited
|
// fields on the user table that cannot be edited
|
||||||
export const UNEDITABLE_USER_FIELDS = ["username", "password", "accessLevelId"]
|
export const UNEDITABLE_USER_FIELDS = ["email", "password", "accessLevelId"]
|
||||||
|
|
||||||
export const DEFAULT_PAGES_OBJECT = {
|
export const DEFAULT_PAGES_OBJECT = {
|
||||||
main: {
|
main: {
|
||||||
|
|
|
@ -3,15 +3,15 @@ import API from "./api"
|
||||||
/**
|
/**
|
||||||
* Performs a log in request.
|
* Performs a log in request.
|
||||||
*/
|
*/
|
||||||
export const logIn = async ({ username, password }) => {
|
export const logIn = async ({ email, password }) => {
|
||||||
if (!username) {
|
if (!email) {
|
||||||
return API.error("Please enter your username")
|
return API.error("Please enter your email")
|
||||||
}
|
}
|
||||||
if (!password) {
|
if (!password) {
|
||||||
return API.error("Please enter your password")
|
return API.error("Please enter your password")
|
||||||
}
|
}
|
||||||
return await API.post({
|
return await API.post({
|
||||||
url: "/api/authenticate",
|
url: "/api/authenticate",
|
||||||
body: { username, password },
|
body: { email, password },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ import { writable } from "svelte/store"
|
||||||
const createAuthStore = () => {
|
const createAuthStore = () => {
|
||||||
const store = writable("")
|
const store = writable("")
|
||||||
|
|
||||||
const logIn = async ({ username, password }) => {
|
const logIn = async ({ email, password }) => {
|
||||||
const user = await API.logIn({ username, password })
|
const user = await API.logIn({ email, password })
|
||||||
if (!user.error) {
|
if (!user.error) {
|
||||||
store.set(user.token)
|
store.set(user.token)
|
||||||
location.reload()
|
location.reload()
|
||||||
|
|
|
@ -10,21 +10,21 @@ exports.authenticate = async ctx => {
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
if (!appId) ctx.throw(400, "No 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.")
|
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 db = new CouchDB(appId)
|
||||||
const app = await db.get(appId)
|
const app = await db.get(appId)
|
||||||
|
|
||||||
let dbUser
|
let dbUser
|
||||||
try {
|
try {
|
||||||
dbUser = await db.get(generateUserID(username))
|
dbUser = await db.get(generateUserID(email))
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
// do not want to throw a 404 - as this could be
|
// 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")
|
ctx.throw(401, "Invalid Credentials")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,16 +20,10 @@ exports.fetch = async function(ctx) {
|
||||||
|
|
||||||
exports.create = async function(ctx) {
|
exports.create = async function(ctx) {
|
||||||
const db = new CouchDB(ctx.user.appId)
|
const db = new CouchDB(ctx.user.appId)
|
||||||
const {
|
const { email, password, accessLevelId, permissions } = ctx.request.body
|
||||||
username,
|
|
||||||
password,
|
|
||||||
name,
|
|
||||||
accessLevelId,
|
|
||||||
permissions,
|
|
||||||
} = ctx.request.body
|
|
||||||
|
|
||||||
if (!username || !password) {
|
if (!email || !password) {
|
||||||
ctx.throw(400, "Username and Password Required.")
|
ctx.throw(400, "email and Password Required.")
|
||||||
}
|
}
|
||||||
|
|
||||||
const accessLevel = await checkAccessLevel(db, accessLevelId)
|
const accessLevel = await checkAccessLevel(db, accessLevelId)
|
||||||
|
@ -37,10 +31,9 @@ exports.create = async function(ctx) {
|
||||||
if (!accessLevel) ctx.throw(400, "Invalid Access Level")
|
if (!accessLevel) ctx.throw(400, "Invalid Access Level")
|
||||||
|
|
||||||
const user = {
|
const user = {
|
||||||
_id: generateUserID(username),
|
_id: generateUserID(email),
|
||||||
username,
|
email,
|
||||||
password: await bcrypt.hash(password),
|
password: await bcrypt.hash(password),
|
||||||
name: name || username,
|
|
||||||
type: "user",
|
type: "user",
|
||||||
accessLevelId,
|
accessLevelId,
|
||||||
permissions: permissions || [BUILTIN_PERMISSION_NAMES.POWER],
|
permissions: permissions || [BUILTIN_PERMISSION_NAMES.POWER],
|
||||||
|
@ -54,8 +47,7 @@ exports.create = async function(ctx) {
|
||||||
ctx.userId = response._id
|
ctx.userId = response._id
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
_rev: response.rev,
|
_rev: response.rev,
|
||||||
username,
|
email,
|
||||||
name,
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.status === 409) {
|
if (err.status === 409) {
|
||||||
|
@ -76,22 +68,22 @@ exports.update = async function(ctx) {
|
||||||
user._rev = response.rev
|
user._rev = response.rev
|
||||||
|
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
ctx.message = `User ${ctx.request.body.username} updated successfully.`
|
ctx.message = `User ${ctx.request.body.email} updated successfully.`
|
||||||
ctx.body = response
|
ctx.body = response
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.destroy = async function(ctx) {
|
exports.destroy = async function(ctx) {
|
||||||
const database = new CouchDB(ctx.user.appId)
|
const database = new CouchDB(ctx.user.appId)
|
||||||
await database.destroy(generateUserID(ctx.params.username))
|
await database.destroy(generateUserID(ctx.params.email))
|
||||||
ctx.message = `User ${ctx.params.username} deleted.`
|
ctx.message = `User ${ctx.params.email} deleted.`
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.find = async function(ctx) {
|
exports.find = async function(ctx) {
|
||||||
const database = new CouchDB(ctx.user.appId)
|
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 = {
|
ctx.body = {
|
||||||
username: user.username,
|
email: user.email,
|
||||||
name: user.name,
|
name: user.name,
|
||||||
_rev: user._rev,
|
_rev: user._rev,
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ exports.clearApplications = async request => {
|
||||||
exports.createUser = async (
|
exports.createUser = async (
|
||||||
request,
|
request,
|
||||||
appId,
|
appId,
|
||||||
username = "babs",
|
email = "babs@babs.com",
|
||||||
password = "babs_password"
|
password = "babs_password"
|
||||||
) => {
|
) => {
|
||||||
const res = await request
|
const res = await request
|
||||||
|
@ -126,7 +126,7 @@ exports.createUser = async (
|
||||||
.set(exports.defaultHeaders(appId))
|
.set(exports.defaultHeaders(appId))
|
||||||
.send({
|
.send({
|
||||||
name: "Bill",
|
name: "Bill",
|
||||||
username,
|
email,
|
||||||
password,
|
password,
|
||||||
accessLevelId: BUILTIN_LEVEL_IDS.POWER,
|
accessLevelId: BUILTIN_LEVEL_IDS.POWER,
|
||||||
})
|
})
|
||||||
|
@ -174,15 +174,14 @@ const createUserWithPermissions = async (
|
||||||
request,
|
request,
|
||||||
appId,
|
appId,
|
||||||
permissions,
|
permissions,
|
||||||
username
|
email
|
||||||
) => {
|
) => {
|
||||||
const password = `password_${username}`
|
const password = `password_${email}`
|
||||||
await request
|
await request
|
||||||
.post(`/api/users`)
|
.post(`/api/users`)
|
||||||
.set(exports.defaultHeaders(appId))
|
.set(exports.defaultHeaders(appId))
|
||||||
.send({
|
.send({
|
||||||
name: username,
|
email,
|
||||||
username,
|
|
||||||
password,
|
password,
|
||||||
accessLevelId: BUILTIN_LEVEL_IDS.POWER,
|
accessLevelId: BUILTIN_LEVEL_IDS.POWER,
|
||||||
permissions,
|
permissions,
|
||||||
|
@ -203,7 +202,7 @@ const createUserWithPermissions = async (
|
||||||
Cookie: `budibase:${appId}:local=${anonToken}`,
|
Cookie: `budibase:${appId}:local=${anonToken}`,
|
||||||
"x-budibase-app-id": appId,
|
"x-budibase-app-id": appId,
|
||||||
})
|
})
|
||||||
.send({ username, password })
|
.send({ email, password })
|
||||||
|
|
||||||
// returning necessary request headers
|
// returning necessary request headers
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -34,8 +34,8 @@ describe("/users", () => {
|
||||||
|
|
||||||
describe("fetch", () => {
|
describe("fetch", () => {
|
||||||
it("returns a list of users from an instance db", async () => {
|
it("returns a list of users from an instance db", async () => {
|
||||||
await createUser(request, appId, "brenda", "brendas_password")
|
await createUser(request, appId, "brenda@brenda.com", "brendas_password")
|
||||||
await createUser(request, appId, "pam", "pam_password")
|
await createUser(request, appId, "pam@pam.com", "pam_password")
|
||||||
const res = await request
|
const res = await request
|
||||||
.get(`/api/users`)
|
.get(`/api/users`)
|
||||||
.set(defaultHeaders(appId))
|
.set(defaultHeaders(appId))
|
||||||
|
@ -43,12 +43,12 @@ describe("/users", () => {
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
|
||||||
expect(res.body.length).toBe(2)
|
expect(res.body.length).toBe(2)
|
||||||
expect(res.body.find(u => u.username === "brenda")).toBeDefined()
|
expect(res.body.find(u => u.email === "brenda@brenda.com")).toBeDefined()
|
||||||
expect(res.body.find(u => u.username === "pam")).toBeDefined()
|
expect(res.body.find(u => u.email === "pam@pam.com")).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should apply authorization to endpoint", async () => {
|
it("should apply authorization to endpoint", async () => {
|
||||||
await createUser(request, appId, "brenda", "brendas_password")
|
await createUser(request, appId, "brenda@brenda.com", "brendas_password")
|
||||||
await testPermissionsForEndpoint({
|
await testPermissionsForEndpoint({
|
||||||
request,
|
request,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
@ -62,12 +62,11 @@ describe("/users", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("create", () => {
|
describe("create", () => {
|
||||||
|
|
||||||
it("returns a success message when a user is successfully created", async () => {
|
it("returns a success message when a user is successfully created", async () => {
|
||||||
const res = await request
|
const res = await request
|
||||||
.post(`/api/users`)
|
.post(`/api/users`)
|
||||||
.set(defaultHeaders(appId))
|
.set(defaultHeaders(appId))
|
||||||
.send({ name: "Bill", username: "bill", password: "bills_password", accessLevelId: BUILTIN_LEVEL_IDS.POWER })
|
.send({ email: "bill@bill.com", password: "bills_password", accessLevelId: BUILTIN_LEVEL_IDS.POWER })
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
|
|
||||||
|
@ -79,7 +78,7 @@ describe("/users", () => {
|
||||||
await testPermissionsForEndpoint({
|
await testPermissionsForEndpoint({
|
||||||
request,
|
request,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: { name: "brandNewUser", username: "brandNewUser", password: "yeeooo", accessLevelId: BUILTIN_LEVEL_IDS.POWER },
|
body: { email: "brandNewUser@user.com", password: "yeeooo", accessLevelId: BUILTIN_LEVEL_IDS.POWER },
|
||||||
url: `/api/users`,
|
url: `/api/users`,
|
||||||
appId: appId,
|
appId: appId,
|
||||||
permName1: BUILTIN_PERMISSION_NAMES.ADMIN,
|
permName1: BUILTIN_PERMISSION_NAMES.ADMIN,
|
||||||
|
|
|
@ -16,7 +16,7 @@ router
|
||||||
controller.fetch
|
controller.fetch
|
||||||
)
|
)
|
||||||
.get(
|
.get(
|
||||||
"/api/users/:username",
|
"/api/users/:email",
|
||||||
authorized(PermissionTypes.USER, PermissionLevels.READ),
|
authorized(PermissionTypes.USER, PermissionLevels.READ),
|
||||||
controller.find
|
controller.find
|
||||||
)
|
)
|
||||||
|
@ -32,7 +32,7 @@ router
|
||||||
controller.create
|
controller.create
|
||||||
)
|
)
|
||||||
.delete(
|
.delete(
|
||||||
"/api/users/:username",
|
"/api/users/:email",
|
||||||
authorized(PermissionTypes.USER, PermissionLevels.WRITE),
|
authorized(PermissionTypes.USER, PermissionLevels.WRITE),
|
||||||
usage,
|
usage,
|
||||||
controller.destroy
|
controller.destroy
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const Koa = require("koa")
|
const Koa = require("koa")
|
||||||
|
const destroyable = require("server-destroy")
|
||||||
const electron = require("electron")
|
const electron = require("electron")
|
||||||
const koaBody = require("koa-body")
|
const koaBody = require("koa-body")
|
||||||
const logger = require("koa-pino-logger")
|
const logger = require("koa-pino-logger")
|
||||||
|
@ -44,6 +45,7 @@ if (electron.app && electron.app.isPackaged) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const server = http.createServer(app.callback())
|
const server = http.createServer(app.callback())
|
||||||
|
destroyable(server)
|
||||||
|
|
||||||
server.on("close", () => console.log("Server Closed"))
|
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())}`)
|
console.log(`Budibase running on ${JSON.stringify(server.address())}`)
|
||||||
automations.init()
|
automations.init()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
process.on("uncaughtException", err => {
|
||||||
|
console.error(err)
|
||||||
|
server.close()
|
||||||
|
server.destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
process.on("SIGTERM", () => {
|
||||||
|
server.close()
|
||||||
|
server.destroy()
|
||||||
|
})
|
||||||
|
|
|
@ -5,7 +5,7 @@ const usage = require("../../utilities/usageQuota")
|
||||||
|
|
||||||
module.exports.definition = {
|
module.exports.definition = {
|
||||||
description: "Create a new user",
|
description: "Create a new user",
|
||||||
tagline: "Create user {{inputs.username}}",
|
tagline: "Create user {{inputs.email}}",
|
||||||
icon: "ri-user-add-line",
|
icon: "ri-user-add-line",
|
||||||
name: "Create User",
|
name: "Create User",
|
||||||
type: "ACTION",
|
type: "ACTION",
|
||||||
|
@ -16,9 +16,10 @@ module.exports.definition = {
|
||||||
schema: {
|
schema: {
|
||||||
inputs: {
|
inputs: {
|
||||||
properties: {
|
properties: {
|
||||||
username: {
|
email: {
|
||||||
type: "string",
|
type: "string",
|
||||||
title: "Username",
|
customType: "email",
|
||||||
|
title: "Email",
|
||||||
},
|
},
|
||||||
password: {
|
password: {
|
||||||
type: "string",
|
type: "string",
|
||||||
|
@ -32,7 +33,7 @@ module.exports.definition = {
|
||||||
pretty: accessLevels.BUILTIN_LEVEL_NAME_ARRAY,
|
pretty: accessLevels.BUILTIN_LEVEL_NAME_ARRAY,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
required: ["username", "password", "accessLevelId"],
|
required: ["email", "password", "accessLevelId"],
|
||||||
},
|
},
|
||||||
outputs: {
|
outputs: {
|
||||||
properties: {
|
properties: {
|
||||||
|
@ -59,13 +60,13 @@ module.exports.definition = {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.run = async function({ inputs, appId, apiKey }) {
|
module.exports.run = async function({ inputs, appId, apiKey }) {
|
||||||
const { username, password, accessLevelId } = inputs
|
const { email, password, accessLevelId } = inputs
|
||||||
const ctx = {
|
const ctx = {
|
||||||
user: {
|
user: {
|
||||||
appId: appId,
|
appId: appId,
|
||||||
},
|
},
|
||||||
request: {
|
request: {
|
||||||
body: { username, password, accessLevelId },
|
body: { email, password, accessLevelId },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,17 +12,18 @@ const USERS_TABLE_SCHEMA = {
|
||||||
views: {},
|
views: {},
|
||||||
name: "Users",
|
name: "Users",
|
||||||
schema: {
|
schema: {
|
||||||
username: {
|
email: {
|
||||||
type: "string",
|
type: "string",
|
||||||
constraints: {
|
constraints: {
|
||||||
type: "string",
|
type: "string",
|
||||||
|
email: true,
|
||||||
length: {
|
length: {
|
||||||
maximum: "",
|
maximum: "",
|
||||||
},
|
},
|
||||||
presence: true,
|
presence: true,
|
||||||
},
|
},
|
||||||
fieldName: "username",
|
fieldName: "email",
|
||||||
name: "username",
|
name: "email",
|
||||||
},
|
},
|
||||||
accessLevelId: {
|
accessLevelId: {
|
||||||
fieldName: "accessLevelId",
|
fieldName: "accessLevelId",
|
||||||
|
@ -35,7 +36,7 @@ const USERS_TABLE_SCHEMA = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
primaryDisplay: "username",
|
primaryDisplay: "email",
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.AuthTypes = AuthTypes
|
exports.AuthTypes = AuthTypes
|
||||||
|
|
|
@ -101,21 +101,21 @@ exports.generateRowID = tableId => {
|
||||||
/**
|
/**
|
||||||
* Gets parameters for retrieving users, this is a utility function for the getDocParams function.
|
* Gets parameters for retrieving users, this is a utility function for the getDocParams function.
|
||||||
*/
|
*/
|
||||||
exports.getUserParams = (username = "", otherProps = {}) => {
|
exports.getUserParams = (email = "", otherProps = {}) => {
|
||||||
return getDocParams(
|
return getDocParams(
|
||||||
DocumentTypes.ROW,
|
DocumentTypes.ROW,
|
||||||
`${ViewNames.USERS}${SEPARATOR}${DocumentTypes.USER}${SEPARATOR}${username}`,
|
`${ViewNames.USERS}${SEPARATOR}${DocumentTypes.USER}${SEPARATOR}${email}`,
|
||||||
otherProps
|
otherProps
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a new user ID based on the passed in username.
|
* 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.
|
* @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.
|
* @returns {string} The new user ID which the user doc can be stored under.
|
||||||
*/
|
*/
|
||||||
exports.generateUserID = username => {
|
exports.generateUserID = email => {
|
||||||
return `${DocumentTypes.ROW}${SEPARATOR}${ViewNames.USERS}${SEPARATOR}${DocumentTypes.USER}${SEPARATOR}${username}`
|
return `${DocumentTypes.ROW}${SEPARATOR}${ViewNames.USERS}${SEPARATOR}${DocumentTypes.USER}${SEPARATOR}${email}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"name": "Login Control",
|
"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": {
|
"props": {
|
||||||
"logo": "string",
|
"logo": "string",
|
||||||
"title": "string",
|
"title": "string",
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { Label, DatePicker, Input, Select, Toggle, RichText } from "@budibase/bbui"
|
import {
|
||||||
|
Label,
|
||||||
|
DatePicker,
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
Toggle,
|
||||||
|
RichText,
|
||||||
|
} from "@budibase/bbui"
|
||||||
import Dropzone from "./attachments/Dropzone.svelte"
|
import Dropzone from "./attachments/Dropzone.svelte"
|
||||||
import LinkedRowSelector from "./LinkedRowSelector.svelte"
|
import LinkedRowSelector from "./LinkedRowSelector.svelte"
|
||||||
import { capitalise } from "./helpers"
|
import { capitalise } from "./helpers"
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
export let buttonClass = ""
|
export let buttonClass = ""
|
||||||
export let inputClass = ""
|
export let inputClass = ""
|
||||||
|
|
||||||
let username = ""
|
let email = ""
|
||||||
let password = ""
|
let password = ""
|
||||||
let loading = false
|
let loading = false
|
||||||
let error = false
|
let error = false
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
const login = async () => {
|
const login = async () => {
|
||||||
loading = true
|
loading = true
|
||||||
await authStore.actions.logIn({ username, password })
|
await authStore.actions.logIn({ email, password })
|
||||||
loading = false
|
loading = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -42,9 +42,9 @@
|
||||||
<div class="form-root">
|
<div class="form-root">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input
|
<input
|
||||||
bind:value={username}
|
bind:value={email}
|
||||||
type="text"
|
type="email"
|
||||||
placeholder="Username"
|
placeholder="Email"
|
||||||
class={_inputClass} />
|
class={_inputClass} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if error}
|
{#if error}
|
||||||
<div class="incorrect-details-panel">Incorrect username or password</div>
|
<div class="incorrect-details-panel">Incorrect email or password</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue