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