WIP: Add login logic
This commit is contained in:
parent
0f21339ea1
commit
791cba91d3
4 changed files with 75 additions and 7 deletions
|
@ -1,5 +1,6 @@
|
|||
from dotenv import load_dotenv
|
||||
from fastapi import APIRouter, FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from starlette.middleware.authentication import AuthenticationMiddleware
|
||||
|
||||
load_dotenv()
|
||||
|
@ -47,6 +48,19 @@ def create_app():
|
|||
app.include_router(api_v1_router)
|
||||
app.mount(path="/v1/ocpp", app=create_ocpp_app())
|
||||
|
||||
origins = [
|
||||
"http://localhost",
|
||||
"http://localhost:5173",
|
||||
]
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=origins,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
return app
|
||||
|
||||
app = create_app()
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import axios from 'axios';
|
||||
import { dev } from '$app/environment';
|
||||
import { goto } from '$app/navigation';
|
||||
import { get } from 'svelte/store';
|
||||
import { persistentSettings } from '$lib/persistent-store';
|
||||
|
||||
if (dev) {
|
||||
axios.defaults.baseURL = "http://localhost:8000/api/v1"
|
||||
|
@ -28,11 +30,17 @@ function createTokenRefreshInterceptor() {
|
|||
|
||||
return axios
|
||||
.post("/auth/refresh", {
|
||||
refresh_token: "",
|
||||
refresh_token: get(persistentSettings).refreshToken,
|
||||
})
|
||||
.then((response) => {
|
||||
// TODO: Save token
|
||||
error.response.config.headers["Authorization"] = "Bearer " + response.data.access_token;
|
||||
// Save new refresh token
|
||||
persistentSettings.update(setting=> setting.refreshToken=response.data.refresh_token)
|
||||
|
||||
// Update access token
|
||||
const authHeader = "Bearer " + response.data.access_token;
|
||||
axios.defaults.headers.common['Authorization'] = authHeader;
|
||||
error.response.config.headers["Authorization"] = authHeader;
|
||||
|
||||
// Retry initial request with new token
|
||||
return axios(error.response.config);
|
||||
})
|
||||
|
@ -48,3 +56,5 @@ function createTokenRefreshInterceptor() {
|
|||
}
|
||||
|
||||
createTokenRefreshInterceptor();
|
||||
|
||||
export default axios;
|
|
@ -2,6 +2,8 @@
|
|||
import { goto } from '$app/navigation'
|
||||
import { persistentSettings } from '$lib/persistent-store'
|
||||
import i18n from '$lib/i18n'
|
||||
import axios from '$lib/axios.svelte'
|
||||
|
||||
let { children } = $props()
|
||||
|
||||
if (!$persistentSettings.loggedIn) {
|
||||
|
@ -9,6 +11,17 @@
|
|||
}
|
||||
|
||||
let drawerOpen = $state(false)
|
||||
|
||||
function logout() {
|
||||
axios.post('/auth/logout').then(() => {
|
||||
$persistentSettings.email = ''
|
||||
$persistentSettings.friendlyName = ''
|
||||
$persistentSettings.loggedIn = false
|
||||
$persistentSettings.refreshToken = ''
|
||||
$persistentSettings.role = 'member'
|
||||
goto('/login?logout')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="w-full h-full p-4 flex flex-col bg-base-200">
|
||||
|
@ -86,7 +99,7 @@
|
|||
class="menu menu-sm dropdown-content bg-base-100 rounded-box z-1 mt-3 w-52 p-2 shadow"
|
||||
>
|
||||
<li><a href="/profile">{$i18n.t('common:navbar.link.profile')}</a></li>
|
||||
<li><a href="/login?logout">{$i18n.t('common:navbar.link.logout')}</a></li>
|
||||
<li><button onclick={logout}>{$i18n.t('common:navbar.link.logout')}</button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { fly } from 'svelte/transition'
|
||||
import i18n from '$lib/i18n'
|
||||
import axios from '$lib/axios.svelte'
|
||||
import { persistentSettings } from '$lib/persistent-store'
|
||||
import { goto } from '$app/navigation'
|
||||
$i18n.loadNamespaces('login')
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search)
|
||||
|
@ -13,6 +16,29 @@
|
|||
showToast = false
|
||||
}, 6000)
|
||||
}
|
||||
|
||||
let email: string = $state('')
|
||||
let password: string = $state('')
|
||||
|
||||
function login() {
|
||||
axios
|
||||
.post('/auth/login', {
|
||||
email,
|
||||
password,
|
||||
})
|
||||
.then((response) => {
|
||||
$persistentSettings.loggedIn = true
|
||||
$persistentSettings.refreshToken = response.data.refresh_token
|
||||
axios.defaults.headers.common['Authorization'] = 'Bearer ' + response.data.access_token
|
||||
axios.get('/me').then((response) => {
|
||||
$persistentSettings.email = response.data.email
|
||||
$persistentSettings.friendlyName = response.data.friendly_name
|
||||
$persistentSettings.role = response.data.role
|
||||
})
|
||||
goto('/')
|
||||
})
|
||||
.catch((error) => {})
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="w-full h-full flex flex-col justify-center items-center bg-base-200">
|
||||
|
@ -30,13 +56,18 @@
|
|||
<fieldset class="fieldset">
|
||||
<label class="fieldset-label input text-base-content">
|
||||
<i class="bi bi-envelope-at"></i>
|
||||
<input type="email" placeholder="me@example.com" required />
|
||||
<input type="email" bind:value={email} placeholder="me@example.com" required />
|
||||
</label>
|
||||
<label class="fieldset-label input text-base-content">
|
||||
<i class="bi bi-key"></i>
|
||||
<input type="password" placeholder={$i18n.t('login:passwordPlaceholder')} required />
|
||||
<input
|
||||
type="password"
|
||||
bind:value={password}
|
||||
placeholder={$i18n.t('login:passwordPlaceholder')}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<button class="btn btn-primary mt-4">{$i18n.t('login:button')}</button>
|
||||
<button class="btn btn-primary mt-4" onclick={login}>{$i18n.t('login:button')}</button>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue