Handle auth in top level routes and redirect as required. Change default route to be portal

This commit is contained in:
Andrew Kingston 2021-05-06 14:49:11 +01:00
parent 3530d46583
commit 735c724a0d
10 changed files with 86 additions and 170 deletions

View File

@ -1,7 +1,7 @@
<script>
import { goto } from "@roxi/routify"
import {
notifications,
Button,
Link,
Input,
Modal,
@ -19,26 +19,17 @@
password,
})
notifications.success("Logged in successfully.")
$goto("../portal")
} catch (err) {
console.error(err)
notifications.error("Invalid credentials")
}
}
async function createTestUser() {
try {
await auth.firstUser()
notifications.success("Test user created")
} catch (err) {
console.error(err)
notifications.error("Could not create test user")
}
}
</script>
<Modal fixed>
<ModalContent
size="L"
size="M"
title="Log In"
onConfirm={login}
confirmText="Log In"
@ -51,7 +42,6 @@
<Link target="_blank" href="/api/admin/auth/google">
Sign In With Google
</Link>
<Button secondary on:click={createTestUser}>Create Test User</Button>
</div>
</ModalContent>
</Modal>

View File

@ -1,27 +1,26 @@
<script>
import { onMount } from "svelte"
import { goto } from "@roxi/routify"
import {
SideNavigation as Navigation,
SideNavigationItem as Item,
} from "@budibase/bbui"
import { auth } from "stores/backend"
import { admin } from "stores/portal"
import LoginForm from "components/login/LoginForm.svelte"
import BuilderSettingsButton from "components/start/BuilderSettingsButton.svelte"
import LogoutButton from "components/start/LogoutButton.svelte"
import Logo from "/assets/budibase-logo.svg"
import api from "builderStore/api"
let checklist
let checked = false
onMount(async () => {
await admin.init()
if (!$admin?.checklist?.adminUser) {
$goto("./admin")
} else {
$goto("./portal")
await auth.checkAuth()
checked = true
}
})
$: {
if (checked && !$auth.user) {
$goto("./auth/login")
}
}
</script>
{#if $admin.checklist}

View File

@ -0,0 +1,4 @@
<script>
import { goto } from "@roxi/routify"
$goto("./login")
</script>

View File

@ -0,0 +1,5 @@
<script>
import LoginForm from "components/login/LoginForm.svelte"
</script>
<LoginForm />

View File

@ -60,7 +60,7 @@
<img
src={Logo}
alt="budibase icon"
on:click={() => $goto(`/builder/`)}
on:click={() => $goto(`../../portal/`)}
/>
</button>

View File

@ -1,120 +1,4 @@
<script>
import api from "builderStore/api"
import { get } from "builderStore/api"
import CreateAppModal from "components/start/CreateAppModal.svelte"
import { Button, Heading, Modal, ButtonGroup } from "@budibase/bbui"
import TemplateList from "components/start/TemplateList.svelte"
import analytics from "analytics"
import Banner from "/assets/orange-landscape.png"
let hasKey
let template
let modal
async function getApps() {
const res = await get("/api/applications")
const json = await res.json()
if (res.ok) {
return json
} else {
throw new Error(json)
}
}
async function fetchKeys() {
const response = await api.get(`/api/keys/`)
return await response.json()
}
async function checkIfKeysAndApps() {
const keys = await fetchKeys()
const apps = await getApps()
if (keys.userId) {
hasKey = true
analytics.identify(keys.userId)
}
}
function selectTemplate(newTemplate) {
template = newTemplate
modal.show()
}
function initiateAppImport() {
template = { fromFile: true }
modal.show()
}
function closeModal() {
template = null
modal.hide()
}
checkIfKeysAndApps()
import { goto } from "@roxi/routify"
$goto("../portal")
</script>
<div class="container">
<div class="header">
<Heading size="M">Welcome to the Budibase Beta</Heading>
<ButtonGroup>
<Button secondary on:click={initiateAppImport}>Import Web App</Button>
<Button cta on:click={modal.show}>Create New Web App</Button>
</ButtonGroup>
</div>
<div class="banner">
<img src={Banner} alt="rocket" />
<div class="banner-content">
Every accomplishment starts with a decision to try.
</div>
</div>
<!-- <TemplateList onSelect={selectTemplate} /> -->
</div>
<Modal bind:this={modal} padding={false} width="600px" on:hide={closeModal}>
<CreateAppModal {hasKey} {template} />
</Modal>
<style>
.container {
display: grid;
gap: var(--spacing-xl);
margin: 40px 80px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.banner {
display: flex;
align-items: center;
justify-content: center;
position: relative;
text-align: center;
color: white;
border-radius: 16px;
}
.banner img {
height: 250px;
width: 100%;
border-radius: 5px;
}
.banner-content {
position: absolute;
font-size: 24px;
color: white;
font-weight: 500;
}
.button-group {
display: flex;
flex-direction: row;
}
</style>

View File

@ -1 +1,4 @@
Index route
<script>
import { goto } from "@roxi/routify"
$goto("./portal")
</script>

View File

@ -1,5 +1,5 @@
<script>
import { isActive } from "@roxi/routify"
import { isActive, goto } from "@roxi/routify"
import { onMount } from "svelte"
import {
Icon,
@ -11,6 +11,8 @@
} from "@budibase/bbui"
import ConfigChecklist from "components/common/ConfigChecklist.svelte"
import { organisation, apps } from "stores/portal"
import BuilderSettingsButton from "components/start/BuilderSettingsButton.svelte"
import LogoutButton from "components/start/LogoutButton.svelte"
organisation.init()
apps.load()
@ -45,7 +47,7 @@
<div class="nav">
<Layout paddingX="L" paddingY="L">
<div class="branding">
<div class="name">
<div class="name" on:click={() => $goto("./apps")}>
<img
src={$organisation?.logoUrl || "https://i.imgur.com/ZKyklgF.png"}
alt="Logotype"
@ -62,6 +64,8 @@
<Item selected={$isActive(href)} {href} {heading}>{title}</Item>
{/each}
</Navigation>
<BuilderSettingsButton />
<LogoutButton />
</div>
</Layout>
</div>
@ -106,6 +110,9 @@
grid-gap: var(--spacing-m);
align-items: center;
}
.name:hover {
cursor: pointer;
}
.avatar {
display: grid;
grid-template-columns: auto auto;

View File

@ -5,17 +5,43 @@
Button,
ActionButton,
ActionGroup,
ButtonGroup,
Select,
Modal,
} from "@budibase/bbui"
import AppList from "components/start/AppList.svelte"
import CreateAppModal from "components/start/CreateAppModal.svelte"
import api from "builderStore/api"
import analytics from "analytics"
import { onMount } from "svelte"
let layout = "grid"
let modal
let template
async function checkKeys() {
const response = await api.get(`/api/keys/`)
const keys = await response.json()
if (keys.userId) {
analytics.identify(keys.userId)
}
}
function initiateAppImport() {
template = { fromFile: true }
modal.show()
}
onMount(checkKeys)
</script>
<Layout noPadding>
<div class="title">
<Heading>Apps</Heading>
<Button primary>Create new app</Button>
<ButtonGroup>
<Button secondary on:click={initiateAppImport}>Import app</Button>
<Button cta on:click={modal.show}>Create new app</Button>
</ButtonGroup>
</div>
<div class="filter">
<div class="select">
@ -42,6 +68,14 @@
Table
{/if}
</Layout>
<Modal
bind:this={modal}
padding={false}
width="600px"
on:hide={() => (template = null)}
>
<CreateAppModal {template} />
</Modal>
<style>
.title,

View File

@ -1,28 +1,25 @@
import { writable } from "svelte/store"
import api from "../../builderStore/api"
async function checkAuth() {
const response = await api.get("/api/self")
const user = await response.json()
if (response.status === 200) return user
return null
}
export function createAuthStore() {
const { subscribe, set } = writable(null)
checkAuth()
.then(user => set({ user }))
.catch(() => set({ user: null }))
const store = writable({ user: null })
return {
subscribe,
subscribe: store.subscribe,
checkAuth: async () => {
const response = await api.get("/api/self")
const user = await response.json()
if (response.status === 200) {
store.update(state => ({ ...state, user }))
} else {
store.update(state => ({ ...state, user: null }))
}
},
login: async creds => {
const response = await api.post(`/api/admin/auth`, creds)
const json = await response.json()
if (response.status === 200) {
set({ user: json.user })
store.update(state => ({ ...state, user: json.user }))
} else {
throw "Invalid credentials"
}
@ -34,7 +31,7 @@ export function createAuthStore() {
throw "Unable to create logout"
}
await response.json()
set({ user: null })
store.update(state => ({ ...state, user: null }))
},
createUser: async user => {
const response = await api.post(`/api/admin/users`, user)
@ -43,13 +40,6 @@ export function createAuthStore() {
}
await response.json()
},
firstUser: async () => {
const response = await api.post(`/api/admin/users/first`)
if (response.status !== 200) {
throw "Unable to create test user"
}
await response.json()
},
}
}