forked from tsai/budibase
25 changed files with 497 additions and 390 deletions
@ -1,62 +0,0 @@ |
|||||
<script> |
|
||||
import { |
|
||||
notifications, |
|
||||
Input, |
|
||||
Button, |
|
||||
Layout, |
|
||||
Body, |
|
||||
Heading, |
|
||||
} from "@budibase/bbui" |
|
||||
import { organisation, auth } from "stores/portal" |
|
||||
|
|
||||
let email = "" |
|
||||
|
|
||||
async function forgot() { |
|
||||
try { |
|
||||
await auth.forgotPassword(email) |
|
||||
notifications.success("Email sent - please check your inbox") |
|
||||
} catch (err) { |
|
||||
notifications.error("Unable to send reset password link") |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<div class="login"> |
|
||||
<div class="main"> |
|
||||
<Layout> |
|
||||
<Layout noPadding justifyItems="center"> |
|
||||
<img src={$organisation.logoUrl || "https://i.imgur.com/ZKyklgF.png"} /> |
|
||||
</Layout> |
|
||||
<Layout gap="XS" noPadding> |
|
||||
<Heading textAlign="center">Forgotten your password?</Heading> |
|
||||
<Body size="S" textAlign="center"> |
|
||||
No problem! Just enter your account's email address and we'll send you |
|
||||
a link to reset it. |
|
||||
</Body> |
|
||||
<Input label="Email" bind:value={email} /> |
|
||||
</Layout> |
|
||||
<Button cta on:click={forgot} disabled={!email}> |
|
||||
Reset your password |
|
||||
</Button> |
|
||||
</Layout> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<style> |
|
||||
.login { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.main { |
|
||||
width: 300px; |
|
||||
} |
|
||||
|
|
||||
img { |
|
||||
width: 48px; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,84 +0,0 @@ |
|||||
<script> |
|
||||
import { goto, params } from "@roxi/routify" |
|
||||
import { |
|
||||
notifications, |
|
||||
Input, |
|
||||
Button, |
|
||||
Divider, |
|
||||
ActionButton, |
|
||||
Layout, |
|
||||
Body, |
|
||||
Heading, |
|
||||
} from "@budibase/bbui" |
|
||||
import GoogleButton from "./GoogleButton.svelte" |
|
||||
import { organisation, auth } from "stores/portal" |
|
||||
|
|
||||
let username = "" |
|
||||
let password = "" |
|
||||
|
|
||||
async function login() { |
|
||||
try { |
|
||||
await auth.login({ |
|
||||
username, |
|
||||
password, |
|
||||
}) |
|
||||
if ($params["?returnUrl"]) { |
|
||||
window.location = decodeURIComponent($params["?returnUrl"]) |
|
||||
} else { |
|
||||
notifications.success("Logged in successfully") |
|
||||
$goto("../portal") |
|
||||
} |
|
||||
} catch (err) { |
|
||||
console.error(err) |
|
||||
notifications.error("Invalid credentials") |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<div class="login"> |
|
||||
<div class="main"> |
|
||||
<Layout> |
|
||||
<Layout noPadding justifyItems="center"> |
|
||||
<img src={$organisation.logoUrl || "https://i.imgur.com/ZKyklgF.png"} /> |
|
||||
<Heading>Sign in to Budibase</Heading> |
|
||||
</Layout> |
|
||||
<GoogleButton /> |
|
||||
<Divider noGrid /> |
|
||||
<Layout gap="XS" noPadding> |
|
||||
<Body size="S" textAlign="center">Sign in with email</Body> |
|
||||
<Input label="Email" bind:value={username} /> |
|
||||
<Input |
|
||||
label="Password" |
|
||||
type="password" |
|
||||
on:change |
|
||||
bind:value={password} |
|
||||
/> |
|
||||
</Layout> |
|
||||
<Layout gap="XS" noPadding> |
|
||||
<Button cta on:click={login}>Sign in to Budibase</Button> |
|
||||
<ActionButton quiet on:click={() => $goto("./forgot")}> |
|
||||
Forgot password? |
|
||||
</ActionButton> |
|
||||
</Layout> |
|
||||
</Layout> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<style> |
|
||||
.login { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.main { |
|
||||
width: 300px; |
|
||||
} |
|
||||
|
|
||||
img { |
|
||||
width: 48px; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1,59 +0,0 @@ |
|||||
<script> |
|
||||
import { notifications, Button, Layout, Body, Heading } from "@budibase/bbui" |
|
||||
import { organisation, auth } from "stores/portal" |
|
||||
import PasswordRepeatInput from "components/common/users/PasswordRepeatInput.svelte" |
|
||||
import { params, goto } from "@roxi/routify" |
|
||||
|
|
||||
const resetCode = $params["?code"] |
|
||||
let password, error |
|
||||
|
|
||||
async function reset() { |
|
||||
try { |
|
||||
await auth.resetPassword(password, resetCode) |
|
||||
notifications.success("Password reset successfully") |
|
||||
// send them to login if reset successful |
|
||||
$goto("./login") |
|
||||
} catch (err) { |
|
||||
notifications.error("Unable to reset password") |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<div class="login"> |
|
||||
<div class="main"> |
|
||||
<Layout> |
|
||||
<Layout noPadding justifyItems="center"> |
|
||||
<img src={$organisation.logoUrl || "https://i.imgur.com/ZKyklgF.png"} /> |
|
||||
</Layout> |
|
||||
<Layout gap="XS" noPadding> |
|
||||
<Heading textAlign="center">Reset your password</Heading> |
|
||||
<Body size="S" textAlign="center"> |
|
||||
Please enter the new password you'd like to use. |
|
||||
</Body> |
|
||||
<PasswordRepeatInput bind:password bind:error /> |
|
||||
</Layout> |
|
||||
<Button cta on:click={reset} disabled={error || !resetCode}> |
|
||||
Reset your password |
|
||||
</Button> |
|
||||
</Layout> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<style> |
|
||||
.login { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.main { |
|
||||
width: 260px; |
|
||||
} |
|
||||
|
|
||||
img { |
|
||||
width: 48px; |
|
||||
} |
|
||||
</style> |
|
||||
@ -1 +0,0 @@ |
|||||
export { LoginForm } from "./LoginForm.svelte" |
|
||||
@ -1,5 +1,62 @@ |
|||||
<script> |
<script> |
||||
import ForgotForm from "components/login/ForgotForm.svelte" |
import { |
||||
|
notifications, |
||||
|
Input, |
||||
|
Button, |
||||
|
Layout, |
||||
|
Body, |
||||
|
Heading, |
||||
|
} from "@budibase/bbui" |
||||
|
import { organisation, auth } from "stores/portal" |
||||
|
|
||||
|
let email = "" |
||||
|
|
||||
|
async function forgot() { |
||||
|
try { |
||||
|
await auth.forgotPassword(email) |
||||
|
notifications.success("Email sent - please check your inbox") |
||||
|
} catch (err) { |
||||
|
notifications.error("Unable to send reset password link") |
||||
|
} |
||||
|
} |
||||
</script> |
</script> |
||||
|
|
||||
<ForgotForm /> |
<div class="login"> |
||||
|
<div class="main"> |
||||
|
<Layout> |
||||
|
<Layout noPadding justifyItems="center"> |
||||
|
<img src={$organisation.logoUrl || "https://i.imgur.com/ZKyklgF.png"} /> |
||||
|
</Layout> |
||||
|
<Layout gap="XS" noPadding> |
||||
|
<Heading textAlign="center">Forgotten your password?</Heading> |
||||
|
<Body size="S" textAlign="center"> |
||||
|
No problem! Just enter your account's email address and we'll send you |
||||
|
a link to reset it. |
||||
|
</Body> |
||||
|
<Input label="Email" bind:value={email} /> |
||||
|
</Layout> |
||||
|
<Button cta on:click={forgot} disabled={!email}> |
||||
|
Reset your password |
||||
|
</Button> |
||||
|
</Layout> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.login { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.main { |
||||
|
width: 300px; |
||||
|
} |
||||
|
|
||||
|
img { |
||||
|
width: 48px; |
||||
|
} |
||||
|
</style> |
||||
|
|||||
@ -1,5 +1,89 @@ |
|||||
<script> |
<script> |
||||
import LoginForm from "components/login/LoginForm.svelte" |
import { |
||||
|
ActionButton, |
||||
|
Body, |
||||
|
Button, |
||||
|
Divider, |
||||
|
Heading, |
||||
|
Input, |
||||
|
Layout, |
||||
|
notifications, |
||||
|
} from "@budibase/bbui" |
||||
|
import { goto, params } from "@roxi/routify" |
||||
|
import { auth, organisation } from "stores/portal" |
||||
|
import GoogleButton from "./_components/GoogleButton.svelte" |
||||
|
|
||||
|
let username = "" |
||||
|
let password = "" |
||||
|
|
||||
|
async function login() { |
||||
|
try { |
||||
|
await auth.login({ |
||||
|
username, |
||||
|
password, |
||||
|
}) |
||||
|
notifications.success("Logged in successfully") |
||||
|
if ($auth?.user?.forceResetPassword) { |
||||
|
$goto("./reset") |
||||
|
} else { |
||||
|
if ($params["?returnUrl"]) { |
||||
|
window.location = decodeURIComponent($params["?returnUrl"]) |
||||
|
} else { |
||||
|
notifications.success("Logged in successfully") |
||||
|
$goto("../portal") |
||||
|
} |
||||
|
} |
||||
|
} catch (err) { |
||||
|
console.error(err) |
||||
|
notifications.error("Invalid credentials") |
||||
|
} |
||||
|
} |
||||
</script> |
</script> |
||||
|
|
||||
<LoginForm /> |
<div class="login"> |
||||
|
<div class="main"> |
||||
|
<Layout> |
||||
|
<Layout noPadding justifyItems="center"> |
||||
|
<img src={$organisation.logoUrl || "https://i.imgur.com/ZKyklgF.png"} /> |
||||
|
<Heading>Sign in to Budibase</Heading> |
||||
|
</Layout> |
||||
|
<GoogleButton /> |
||||
|
<Divider noGrid /> |
||||
|
<Layout gap="XS" noPadding> |
||||
|
<Body size="S" textAlign="center">Sign in with email</Body> |
||||
|
<Input label="Email" bind:value={username} /> |
||||
|
<Input |
||||
|
label="Password" |
||||
|
type="password" |
||||
|
on:change |
||||
|
bind:value={password} |
||||
|
/> |
||||
|
</Layout> |
||||
|
<Layout gap="XS" noPadding> |
||||
|
<Button cta on:click={login}>Sign in to Budibase</Button> |
||||
|
<ActionButton quiet on:click={() => $goto("./forgot")}> |
||||
|
Forgot password? |
||||
|
</ActionButton> |
||||
|
</Layout> |
||||
|
</Layout> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.login { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.main { |
||||
|
width: 300px; |
||||
|
} |
||||
|
|
||||
|
img { |
||||
|
width: 48px; |
||||
|
} |
||||
|
</style> |
||||
|
|||||
@ -1,5 +1,76 @@ |
|||||
<script> |
<script> |
||||
import ResetForm from "components/login/ResetForm.svelte" |
import { Body, Button, Heading, Layout, notifications } from "@budibase/bbui" |
||||
|
import { goto, params } from "@roxi/routify" |
||||
|
import PasswordRepeatInput from "components/common/users/PasswordRepeatInput.svelte" |
||||
|
import { auth, organisation } from "stores/portal" |
||||
|
|
||||
|
const resetCode = $params["?code"] |
||||
|
let password, error |
||||
|
|
||||
|
$: forceResetPassword = $auth?.user?.forceResetPassword |
||||
|
|
||||
|
async function reset() { |
||||
|
try { |
||||
|
if (forceResetPassword) { |
||||
|
await auth.updateSelf({ |
||||
|
...$auth.user, |
||||
|
password, |
||||
|
forceResetPassword: false, |
||||
|
}) |
||||
|
$goto("../portal/") |
||||
|
} else { |
||||
|
await auth.resetPassword(password, resetCode) |
||||
|
notifications.success("Password reset successfully") |
||||
|
// send them to login if reset successful |
||||
|
$goto("./login") |
||||
|
} |
||||
|
} catch (err) { |
||||
|
notifications.error("Unable to reset password") |
||||
|
} |
||||
|
} |
||||
</script> |
</script> |
||||
|
|
||||
<ResetForm /> |
<div class="login"> |
||||
|
<div class="main"> |
||||
|
<Layout> |
||||
|
<Layout noPadding justifyItems="center"> |
||||
|
<img |
||||
|
src={$organisation.logoUrl || "https://i.imgur.com/ZKyklgF.png"} |
||||
|
alt="Organisation logo" |
||||
|
/> |
||||
|
</Layout> |
||||
|
<Layout gap="XS" noPadding> |
||||
|
<Heading textAlign="center">Reset your password</Heading> |
||||
|
<Body size="S" textAlign="center"> |
||||
|
Please enter the new password you'd like to use. |
||||
|
</Body> |
||||
|
<PasswordRepeatInput bind:password bind:error /> |
||||
|
</Layout> |
||||
|
<Button |
||||
|
cta |
||||
|
on:click={reset} |
||||
|
disabled={error || (forceResetPassword ? false : !resetCode)} |
||||
|
>Reset your password</Button |
||||
|
> |
||||
|
</Layout> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<style> |
||||
|
.login { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.main { |
||||
|
width: 260px; |
||||
|
} |
||||
|
|
||||
|
img { |
||||
|
width: 48px; |
||||
|
} |
||||
|
</style> |
||||
|
|||||
@ -0,0 +1,6 @@ |
|||||
|
<script> |
||||
|
import { email } from "stores/portal" |
||||
|
email.templates.fetch() |
||||
|
</script> |
||||
|
|
||||
|
<slot /> |
||||
@ -0,0 +1,41 @@ |
|||||
|
<script> |
||||
|
import { createEventDispatcher } from "svelte" |
||||
|
import { ModalContent, Body, Input, notifications } from "@budibase/bbui" |
||||
|
import { users } from "stores/portal" |
||||
|
|
||||
|
const dispatch = createEventDispatcher() |
||||
|
|
||||
|
export let user |
||||
|
|
||||
|
const password = Math.random().toString(36).substr(2, 20) |
||||
|
|
||||
|
async function resetPassword() { |
||||
|
const res = await users.save({ |
||||
|
...user, |
||||
|
password, |
||||
|
forceResetPassword: true, |
||||
|
}) |
||||
|
if (res.status) { |
||||
|
notifications.error(res.message) |
||||
|
} else { |
||||
|
notifications.success("Password reset.") |
||||
|
dispatch("update") |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<ModalContent |
||||
|
onConfirm={resetPassword} |
||||
|
size="M" |
||||
|
title="Force Reset User Password" |
||||
|
confirmText="Reset password" |
||||
|
cancelText="Cancel" |
||||
|
showCloseIcon={false} |
||||
|
> |
||||
|
<Body noPadding |
||||
|
>Before you reset the users password, do not forget to copy the new |
||||
|
password. The user will need this to login. Once the user has logged in they |
||||
|
will be asked to create a new password that is more secure.</Body |
||||
|
> |
||||
|
<Input disabled label="Password" value={password} /> |
||||
|
</ModalContent> |
||||
@ -0,0 +1,7 @@ |
|||||
|
<script> |
||||
|
import { Page } from "@budibase/bbui" |
||||
|
</script> |
||||
|
|
||||
|
<Page> |
||||
|
<slot /> |
||||
|
</Page> |
||||
Loading…
Reference in new issue