mirror of https://github.com/Budibase/budibase.git
36 changed files with 439 additions and 742 deletions
@ -0,0 +1,43 @@ |
|||||
|
<script> |
||||
|
import { Layout, Input } from "@budibase/bbui" |
||||
|
import { |
||||
|
createValidationStore, |
||||
|
requiredValidator, |
||||
|
} from "../../../helpers/validation" |
||||
|
|
||||
|
export let password |
||||
|
export let error |
||||
|
|
||||
|
const [firstPassword, passwordError, firstTouched] = createValidationStore( |
||||
|
"", |
||||
|
requiredValidator |
||||
|
) |
||||
|
const [repeatPassword, _, repeatTouched] = createValidationStore( |
||||
|
"", |
||||
|
requiredValidator |
||||
|
) |
||||
|
|
||||
|
$: password = $firstPassword |
||||
|
$: error = |
||||
|
!$firstPassword || |
||||
|
!$firstTouched || |
||||
|
!$repeatTouched || |
||||
|
$firstPassword !== $repeatPassword |
||||
|
</script> |
||||
|
|
||||
|
<Layout gap="XS" noPadding> |
||||
|
<Input |
||||
|
label="Password" |
||||
|
type="password" |
||||
|
error={$firstTouched && $passwordError} |
||||
|
bind:value={$firstPassword} |
||||
|
/> |
||||
|
<Input |
||||
|
label="Repeat Password" |
||||
|
type="password" |
||||
|
error={$repeatTouched && |
||||
|
$firstPassword !== $repeatPassword && |
||||
|
"Passwords must match"} |
||||
|
bind:value={$repeatPassword} |
||||
|
/> |
||||
|
</Layout> |
||||
@ -0,0 +1,40 @@ |
|||||
|
<script> |
||||
|
import { ModalContent, Body, Input, notifications } from "@budibase/bbui" |
||||
|
import { writable } from "svelte/store" |
||||
|
import { auth } from "stores/backend" |
||||
|
import { saveRow } from "components/backend/DataTable/api" |
||||
|
import { TableNames } from "constants" |
||||
|
|
||||
|
const values = writable({ |
||||
|
firstName: $auth.user.firstName, |
||||
|
lastName: $auth.user.lastName, |
||||
|
}) |
||||
|
|
||||
|
const updateInfo = async () => { |
||||
|
const newUser = { |
||||
|
...$auth.user, |
||||
|
firstName: $values.firstName, |
||||
|
lastName: $values.lastName, |
||||
|
} |
||||
|
console.log(newUser) |
||||
|
const response = await saveRow(newUser, TableNames.USERS) |
||||
|
if (response.ok) { |
||||
|
await auth.checkAuth() |
||||
|
notifications.success("Information updated successfully") |
||||
|
} else { |
||||
|
notifications.error("Failed to update information") |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<ModalContent |
||||
|
title="Update user information" |
||||
|
confirmText="Update information" |
||||
|
onConfirm={updateInfo} |
||||
|
> |
||||
|
<Body size="S"> |
||||
|
Personalise the platform by adding your first name and last name. |
||||
|
</Body> |
||||
|
<Input bind:value={$values.firstName} label="First name" /> |
||||
|
<Input bind:value={$values.lastName} label="Last name" /> |
||||
|
</ModalContent> |
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@ -1,115 +0,0 @@ |
|||||
<script> |
|
||||
import GoogleLogo from "./_logos/Google.svelte" |
|
||||
import { |
|
||||
Button, |
|
||||
Heading, |
|
||||
Divider, |
|
||||
Label, |
|
||||
notifications, |
|
||||
Layout, |
|
||||
Input, |
|
||||
Body, |
|
||||
Page, |
|
||||
} from "@budibase/bbui" |
|
||||
import { onMount } from "svelte" |
|
||||
import api from "builderStore/api" |
|
||||
|
|
||||
const ConfigTypes = { |
|
||||
Google: "google", |
|
||||
// Github: "github", |
|
||||
// AzureAD: "ad", |
|
||||
} |
|
||||
|
|
||||
const ConfigFields = { |
|
||||
Google: ["clientID", "clientSecret", "callbackURL"], |
|
||||
} |
|
||||
|
|
||||
let google |
|
||||
|
|
||||
async function save(doc) { |
|
||||
try { |
|
||||
// Save an oauth config |
|
||||
const response = await api.post(`/api/admin/configs`, doc) |
|
||||
const json = await response.json() |
|
||||
if (response.status !== 200) throw new Error(json.message) |
|
||||
google._rev = json._rev |
|
||||
google._id = json._id |
|
||||
|
|
||||
notifications.success(`Settings saved.`) |
|
||||
} catch (err) { |
|
||||
notifications.error(`Failed to update OAuth settings. ${err}`) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
onMount(async () => { |
|
||||
// fetch the configs for oauth |
|
||||
const googleResponse = await api.get( |
|
||||
`/api/admin/configs/${ConfigTypes.Google}` |
|
||||
) |
|
||||
const googleDoc = await googleResponse.json() |
|
||||
|
|
||||
if (!googleDoc._id) { |
|
||||
google = { |
|
||||
type: ConfigTypes.Google, |
|
||||
config: {}, |
|
||||
} |
|
||||
} else { |
|
||||
google = googleDoc |
|
||||
} |
|
||||
}) |
|
||||
</script> |
|
||||
|
|
||||
<Page> |
|
||||
<header> |
|
||||
<Heading size="M">OAuth</Heading> |
|
||||
<Body size="S"> |
|
||||
Every budibase app comes with basic authentication (email/password) |
|
||||
included. You can add additional authentication methods from the options |
|
||||
below. |
|
||||
</Body> |
|
||||
</header> |
|
||||
<Divider /> |
|
||||
{#if google} |
|
||||
<div class="config-form"> |
|
||||
<Layout gap="S"> |
|
||||
<Heading size="S"> |
|
||||
<span> |
|
||||
<GoogleLogo /> |
|
||||
Google |
|
||||
</span> |
|
||||
</Heading> |
|
||||
{#each ConfigFields.Google as field} |
|
||||
<div class="form-row"> |
|
||||
<Label>{field}</Label> |
|
||||
<Input bind:value={google.config[field]} /> |
|
||||
</div> |
|
||||
{/each} |
|
||||
</Layout> |
|
||||
<Button primary on:click={() => save(google)}>Save</Button> |
|
||||
</div> |
|
||||
<Divider /> |
|
||||
{/if} |
|
||||
</Page> |
|
||||
|
|
||||
<style> |
|
||||
.config-form { |
|
||||
margin-top: 42px; |
|
||||
margin-bottom: 42px; |
|
||||
} |
|
||||
|
|
||||
.form-row { |
|
||||
display: grid; |
|
||||
grid-template-columns: 20% 1fr; |
|
||||
grid-gap: var(--spacing-l); |
|
||||
} |
|
||||
|
|
||||
span { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: var(--spacing-s); |
|
||||
} |
|
||||
|
|
||||
header { |
|
||||
margin-bottom: 42px; |
|
||||
} |
|
||||
</style> |
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@ -1,114 +0,0 @@ |
|||||
<script> |
|
||||
import GoogleLogo from "./_logos/Google.svelte" |
|
||||
import { |
|
||||
Button, |
|
||||
Page, |
|
||||
Heading, |
|
||||
Divider, |
|
||||
Label, |
|
||||
notifications, |
|
||||
Layout, |
|
||||
Input, |
|
||||
Body, |
|
||||
} from "@budibase/bbui" |
|
||||
import { onMount } from "svelte" |
|
||||
import api from "builderStore/api" |
|
||||
|
|
||||
const ConfigTypes = { |
|
||||
Google: "google", |
|
||||
// Github: "github", |
|
||||
// AzureAD: "ad", |
|
||||
} |
|
||||
|
|
||||
const ConfigFields = { |
|
||||
Google: ["clientID", "clientSecret", "callbackURL"], |
|
||||
} |
|
||||
|
|
||||
let google |
|
||||
|
|
||||
async function save(doc) { |
|
||||
try { |
|
||||
// Save an oauth config |
|
||||
const response = await api.post(`/api/admin/configs`, doc) |
|
||||
const json = await response.json() |
|
||||
if (response.status !== 200) throw new Error(json.message) |
|
||||
google._rev = json._rev |
|
||||
google._id = json._id |
|
||||
|
|
||||
notifications.success(`Settings saved.`) |
|
||||
} catch (err) { |
|
||||
notifications.error(`Failed to update OAuth settings. ${err}`) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
onMount(async () => { |
|
||||
// fetch the configs for oauth |
|
||||
const googleResponse = await api.get( |
|
||||
`/api/admin/configs/${ConfigTypes.Google}` |
|
||||
) |
|
||||
const googleDoc = await googleResponse.json() |
|
||||
|
|
||||
if (!googleDoc._id) { |
|
||||
google = { |
|
||||
type: ConfigTypes.Google, |
|
||||
config: {}, |
|
||||
} |
|
||||
} else { |
|
||||
google = googleDoc |
|
||||
} |
|
||||
}) |
|
||||
</script> |
|
||||
|
|
||||
<Page> |
|
||||
<Layout noPadding> |
|
||||
<div> |
|
||||
<Heading size="M">OAuth</Heading> |
|
||||
<Body> |
|
||||
Every budibase app comes with basic authentication (email/password) |
|
||||
included. You can add additional authentication methods from the options |
|
||||
below. |
|
||||
</Body> |
|
||||
</div> |
|
||||
<Divider /> |
|
||||
{#if google} |
|
||||
<div> |
|
||||
<Heading size="S"> |
|
||||
<span> |
|
||||
<GoogleLogo /> |
|
||||
Google |
|
||||
</span> |
|
||||
</Heading> |
|
||||
<Body> |
|
||||
To allow users to authenticate using their Google accounts, fill out |
|
||||
the fields below. |
|
||||
</Body> |
|
||||
</div> |
|
||||
|
|
||||
{#each ConfigFields.Google as field} |
|
||||
<div class="form-row"> |
|
||||
<Label size="L">{field}</Label> |
|
||||
<Input bind:value={google.config[field]} /> |
|
||||
</div> |
|
||||
{/each} |
|
||||
<div> |
|
||||
<Button cta on:click={() => save(google)}>Save</Button> |
|
||||
</div> |
|
||||
<Divider /> |
|
||||
{/if} |
|
||||
</Layout> |
|
||||
</Page> |
|
||||
|
|
||||
<style> |
|
||||
.form-row { |
|
||||
display: grid; |
|
||||
grid-template-columns: 20% 1fr; |
|
||||
grid-gap: var(--spacing-l); |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
span { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
gap: var(--spacing-s); |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,93 +0,0 @@ |
|||||
const authPkg = require("@budibase/auth") |
|
||||
const { google } = require("@budibase/auth/src/middleware") |
|
||||
const { Configs } = require("../../constants") |
|
||||
const CouchDB = require("../../db") |
|
||||
const { clearCookie } = authPkg.utils |
|
||||
const { Cookies } = authPkg.constants |
|
||||
const { passport } = authPkg.auth |
|
||||
|
|
||||
const GLOBAL_DB = authPkg.StaticDatabases.GLOBAL.name |
|
||||
|
|
||||
exports.authenticate = async (ctx, next) => { |
|
||||
return passport.authenticate("local", async (err, user) => { |
|
||||
if (err) { |
|
||||
return ctx.throw(403, "Unauthorized") |
|
||||
} |
|
||||
|
|
||||
const expires = new Date() |
|
||||
expires.setDate(expires.getDate() + 1) |
|
||||
|
|
||||
if (!user) { |
|
||||
return ctx.throw(403, "Unauthorized") |
|
||||
} |
|
||||
|
|
||||
ctx.cookies.set(Cookies.Auth, user.token, { |
|
||||
expires, |
|
||||
path: "/", |
|
||||
httpOnly: false, |
|
||||
overwrite: true, |
|
||||
}) |
|
||||
|
|
||||
delete user.token |
|
||||
|
|
||||
ctx.body = { user } |
|
||||
})(ctx, next) |
|
||||
} |
|
||||
|
|
||||
exports.logout = async ctx => { |
|
||||
clearCookie(ctx, Cookies.Auth) |
|
||||
ctx.body = { message: "User logged out" } |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* The initial call that google authentication makes to take you to the google login screen. |
|
||||
* On a successful login, you will be redirected to the googleAuth callback route. |
|
||||
*/ |
|
||||
exports.googlePreAuth = async (ctx, next) => { |
|
||||
const db = new CouchDB(GLOBAL_DB) |
|
||||
const config = await authPkg.db.getScopedFullConfig(db, { |
|
||||
type: Configs.GOOGLE, |
|
||||
group: ctx.query.group, |
|
||||
}) |
|
||||
const strategy = await google.strategyFactory(config) |
|
||||
|
|
||||
return passport.authenticate(strategy, { |
|
||||
scope: ["profile", "email"], |
|
||||
})(ctx, next) |
|
||||
} |
|
||||
|
|
||||
exports.googleAuth = async (ctx, next) => { |
|
||||
const db = new CouchDB(GLOBAL_DB) |
|
||||
|
|
||||
const config = await authPkg.db.getScopedFullConfig(db, { |
|
||||
type: Configs.GOOGLE, |
|
||||
group: ctx.query.group, |
|
||||
}) |
|
||||
const strategy = await google.strategyFactory(config) |
|
||||
|
|
||||
return passport.authenticate( |
|
||||
strategy, |
|
||||
{ successRedirect: "/", failureRedirect: "/error" }, |
|
||||
async (err, user) => { |
|
||||
if (err) { |
|
||||
return ctx.throw(403, "Unauthorized") |
|
||||
} |
|
||||
|
|
||||
const expires = new Date() |
|
||||
expires.setDate(expires.getDate() + 1) |
|
||||
|
|
||||
if (!user) { |
|
||||
return ctx.throw(403, "Unauthorized") |
|
||||
} |
|
||||
|
|
||||
ctx.cookies.set(Cookies.Auth, user.token, { |
|
||||
expires, |
|
||||
path: "/", |
|
||||
httpOnly: false, |
|
||||
overwrite: true, |
|
||||
}) |
|
||||
|
|
||||
ctx.redirect("/") |
|
||||
} |
|
||||
)(ctx, next) |
|
||||
} |
|
||||
Loading…
Reference in new issue