Handle auth in top level routes and redirect as required. Change default route to be portal
This commit is contained in:
parent
3530d46583
commit
735c724a0d
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<script>
|
||||
import { goto } from "@roxi/routify"
|
||||
$goto("./login")
|
||||
</script>
|
|
@ -0,0 +1,5 @@
|
|||
<script>
|
||||
import LoginForm from "components/login/LoginForm.svelte"
|
||||
</script>
|
||||
|
||||
<LoginForm />
|
|
@ -60,7 +60,7 @@
|
|||
<img
|
||||
src={Logo}
|
||||
alt="budibase icon"
|
||||
on:click={() => $goto(`/builder/`)}
|
||||
on:click={() => $goto(`../../portal/`)}
|
||||
/>
|
||||
</button>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
Index route
|
||||
<script>
|
||||
import { goto } from "@roxi/routify"
|
||||
$goto("./portal")
|
||||
</script>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue