Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add backend connection to user login #115

Merged
merged 31 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
07678d7
add de localization for login, put data into component
MaHaWo Oct 15, 2024
cf3b2f3
Merge branch 'add-forgot-password-component' into add-backend-connect…
MaHaWo Oct 15, 2024
6681845
use localization, remove some mock functions for backend
MaHaWo Oct 15, 2024
98a5a65
add button styling
MaHaWo Oct 15, 2024
9e2a73c
add new verify logic skeleton
MaHaWo Oct 15, 2024
1a59ef1
Merge branch 'main' into add-backend-connection-to-user-login
MaHaWo Oct 15, 2024
24c17a2
work on using backend in user registration
MaHaWo Oct 15, 2024
5d92407
work on submission of data in userregistration
MaHaWo Oct 15, 2024
60deb5b
add user registration verify and success page
MaHaWo Oct 15, 2024
93d2b7e
remove commented out code
MaHaWo Oct 15, 2024
2b2a4ca
update openapi.json & openapi-ts client, run pnpm format
github-actions[bot] Oct 15, 2024
3f99112
Merge branch 'main' into add-backend-connection-to-user-login
MaHaWo Oct 16, 2024
32f3aec
add role, e-mail to login
MaHaWo Oct 16, 2024
2fc5758
add store for current user
MaHaWo Oct 16, 2024
4c0e3a2
work on making login persistent
MaHaWo Oct 16, 2024
e914f4c
add localizations
MaHaWo Oct 16, 2024
f221554
update openapi.json & openapi-ts client, run pnpm format
github-actions[bot] Oct 16, 2024
122d477
change around debug output
MaHaWo Oct 16, 2024
38c296c
update openapi.json & openapi-ts client, run pnpm format
github-actions[bot] Oct 16, 2024
d13f4b4
add verified warning page
MaHaWo Oct 16, 2024
8c4624f
Merge branch 'add-backend-connection-to-user-login' of github.com:ssc…
MaHaWo Oct 16, 2024
ebc9bb0
update openapi.json & openapi-ts client, run pnpm format
github-actions[bot] Oct 16, 2024
4fce6e6
add data deletion
MaHaWo Oct 16, 2024
e1241e6
Merge branch 'add-backend-connection-to-user-login' of github.com:ssc…
MaHaWo Oct 16, 2024
9d3e45f
some corrections
MaHaWo Oct 16, 2024
46b1fa0
update openapi.json & openapi-ts client, run pnpm format
github-actions[bot] Oct 16, 2024
8676995
add database writing to on_after_register
MaHaWo Oct 16, 2024
f149b6f
fix error in database rewriting
MaHaWo Oct 17, 2024
4e43ab7
better comment
MaHaWo Oct 17, 2024
ac61c69
update comments
MaHaWo Oct 17, 2024
39cc4b2
use async_session_maker and session.get to set user as verified
lkeegan Oct 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions default.cert
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFCTCCAvGgAwIBAgIUbvD0dvnZOCfstZkE6ByRwYah4VMwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MTAxNjA4NDM0OFoXDTI1MTAx
NjA4NDM0OFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEApiFVMNAFtrai9s/xP+kYxsa7NzmPBlJg07MsFlW7JPek
FMAy/4HSSZd8gG3fWz73U3cy4J+Oecdy3O0T708ImVBcYskN/Hi/JCBuTRSJZqH4
SlFFqoqR5E8H1bVDL9l4QQgWqoBzNiAEwBMlPSTAeoL91a02qYIPTNjVx93d+1Ua
eGq3/4HhYxogD6vjJOol32T2Twe7xMJ2j4IIsaQLvprA05HhYpJOxRkeuJQO7TEv
o5VcwxURtKm15z8GN6Fj0/MQ/edvj6l59g4ywtNeqIKyQHq/B9QVsfYQIK3HA9j/
Z5cVEfvMjhMl2x6Bh29npg2DRWiucRJioEwRYsxP5G8DO6f0maP+siY8lZrrioxV
LVbyz4z6skFSoGR0lY59oe4+V4UR8Djww/WxuzmI8UJFT0/2cV1ux8mY/UAePjUo
HOzkUn7E669eabRldcBzWpb0ocmeufPdi+LWGHvZxE4v3iUVsxv+GgH7QAYy2LV3
XW5PwHGEMbOkrb772oe13IEYiXCXKgPheI26u3dw6LUKk9V2w+aGvjfjY7IQMDZy
kZ6r5XdLeyUMYfu2UEs+8e8WTW+DYade35k9Hd2AWYYjoGeUjEoht1KKVA9cTyMg
Mf34u40bR5xb9TRLSZc9ZR3OBIIT3gea0gdNQ59XBwRHzcdW1bgOARFcYGcjWOkC
AwEAAaNTMFEwHQYDVR0OBBYEFJS1zAOTGWa0+TgIne/tFIk2h3dsMB8GA1UdIwQY
MBaAFJS1zAOTGWa0+TgIne/tFIk2h3dsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
hvcNAQELBQADggIBACAc9yR77JcUdFYPqVwwkm/hLPTKzcJCEgUZ/8MuYk8CEDxf
ZPeckksEaKHOCi4R6pUqGRudQ7+jW7z9+1zU4iS3s6TxoydTuIFIWlVWfvlCRtWi
CldfpHJH/fw8c7g0pV5neEMKmA1E2tNz8escjSqIDy8Ow8TUbZQvupId+izIg705
gd5Bjb88WlGsEIEY7myIgU7MvSFwv2hogqUGomjJIv9dArOS3hDcLoFcL5Nb3W7/
CqLgwOUPsLy+/bS8DvYe3Q6knPUmiPYA+jI0XNYmDqadrv00/5sYKEU27dKsu2RZ
GSD+M0cgxrDfO+hthlYVefak0edz0T3WYxVc+PFGmm6CjDd0Y2iCabaAID8RJzEf
GUwZRbrF0sQWWwvwxtMUvxvCY1I8N1gTFYaH6mDPPYPd72Cbu5UBtsOg1SHJ3WuE
rSUWgkjieQIS87kDMgFKcgrUUogkkivJhXy0dBWDQAZtHbG5qUuqypRlmGgST1zI
aRQD+tIR8aY6lsG8GAGXrSXA8YOyDHNwkR+7LpC6eNi96GDbOJdy6aF7qmJ3beRw
vP5MDwsITZp9BM3IofFQVS7MVEuPQ71plM/aqM5Jf0tqZFpzPN3S+udycyzHfPrK
5OBU6MSaClmyrsTjsh0TjCdOVZrX1nNvfg+2WlfzMn9XfQlpd+iXbjuShFuP
-----END CERTIFICATE-----
51 changes: 29 additions & 22 deletions frontend/src/lib/components/UserLandingPage.svelte
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
<script lang="ts">
import { activeTabChildren, activeTabPersonal, componentTable } from '$lib/stores/componentStore';
import { currentUser } from '$lib/stores/userStore';
import { TabItem, Tabs } from 'flowbite-svelte';
import { GridPlusSolid, ProfileCardSolid } from 'flowbite-svelte-icons';
import { get } from 'svelte/store';
import UserVerify from './UserVerify.svelte';

import { activeTabChildren, activeTabPersonal, componentTable } from '$lib/stores/componentStore';
import { onDestroy } from 'svelte';

export let userData: any[];
console.log('user: ', get(currentUser));
const isVerifed = get(currentUser)?.is_verified;
let currentPersonal = 'userDataInput';
let currentChildren = 'childrenGallery';
export let userData: any[];

const unsubscribePersonal = activeTabPersonal.subscribe((value) => {
console.log('personal tab: ', value);
currentPersonal = value;
});

const unsubscribeChildren = activeTabChildren.subscribe((value) => {
console.log('children tab: ', value);
currentChildren = value;
});

Expand All @@ -25,21 +28,25 @@
});
</script>

<div class="m-2 p-2">
<Tabs tabStyle="pill">
<TabItem open={true}>
<div slot="title" class="flex items-center gap-2 text-lg">
<ProfileCardSolid size="lg" />
Persönliche Daten
</div>
<svelte:component this={componentTable[currentPersonal]} data={userData} />
</TabItem>
<TabItem>
<div slot="title" class="flex items-center gap-2 text-lg">
<GridPlusSolid size="lg" />
Kinder
</div>
<svelte:component this={componentTable[currentChildren]} />
</TabItem>
</Tabs>
</div>
{#if isVerifed === true}
<div class="m-2 p-2">
<Tabs tabStyle="pill">
<TabItem open={true}>
<div slot="title" class="flex items-center gap-2 text-lg">
<ProfileCardSolid size="lg" />
Persönliche Daten
</div>
<svelte:component this={componentTable[currentPersonal]} data={userData} />
</TabItem>
<TabItem>
<div slot="title" class="flex items-center gap-2 text-lg">
<GridPlusSolid size="lg" />
Kinder
</div>
<svelte:component this={componentTable[currentChildren]} />
</TabItem>
</Tabs>
</div>
{:else}
<UserVerify />
{/if}
219 changes: 101 additions & 118 deletions frontend/src/lib/components/UserLogin.svelte
Original file line number Diff line number Diff line change
@@ -1,102 +1,95 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { base } from '$app/paths';

import UserLoginUtil from '$lib/components//UserLoginUtil.svelte';
import AlertMessage from '$lib/components/AlertMessage.svelte';
import DataInput from '$lib/components/DataInput/DataInput.svelte';
import NavigationButtons from '$lib/components/Navigation/NavigationButtons.svelte';

import { hash, users, type UserData } from '$lib/stores/userStore';
import { Card, Heading } from 'flowbite-svelte';
import { onDestroy, onMount } from 'svelte';
import { goto } from '$app/navigation';
import { authCookieLogin, usersCurrentUser } from '$lib/client/services.gen';
import { type AuthCookieLoginData, type UserRead } from '$lib/client/types.gen';
import { currentUser } from '$lib/stores/userStore';
import { preventDefault } from '$lib/util';
import { Button, Card, Heading, Input } from 'flowbite-svelte';
import { _ } from 'svelte-i18n';

async function refresh(): Promise<string> {
const returned = await usersCurrentUser();
if (returned.error) {
console.log('Error getting current user: ', returned.error.detail);
currentUser.set(null);
return returned.error.detail;
} else {
console.log('Successfully retrieved active user');
currentUser.set(returned.data as UserRead);
return 'success';
}
}

// functionality
async function submitData(): Promise<void> {
const loginData: AuthCookieLoginData = {
body: {
username: formData[0].value,
password: formData[1].value
}
};

/**
* This currently immitates the behavior of a login system by fetching data from
* the userstore that has been precreated. What fetchWithCredentials does currently will later go into the backend
*/
async function validateCredentials() {
// README: this should not be set here but in the child component. However, indication of something missing should
// not happen immediatelly in the first round of entry, so this code here defers it until the first hit of the login button.

const user = await users.fetchWithCredentials(
data[0].value,
await hash(data[1].value),
data[2].value
);
const authReturn = await authCookieLogin(loginData);

console.log(user);
// forget user data again to not have a plain text password lying around in memory somewhere
MaHaWo marked this conversation as resolved.
Show resolved Hide resolved
// any longer than needed

if (user) {
userID = user.id;
if (authReturn.error) {
showAlert = true;
} else {
const status: string = await refresh();

if (remember) {
localStorage.setItem('currentUser', JSON.stringify(userID));
if (status !== 'success') {
console.log('error during retrieving active users: ', status);
showAlert = true;
alertMessage = $_('login.unauthorized') + ': ' + status;
} else {
localStorage.removeItem('currentUser');
console.log('login and user retrieval successful');
goto('/userLand/userLandingpage');
}

await users.setLoggedIn(userID);

await users.save();

goto(`${base}/userLand/userLandingpage/`);
} else {
showAlert = true;
data = data.map((element) => {
element.value = null;
return element;
});
}
}

// data and variables
export let data: any[];

const buttons = [
// form data and variables
let formData = [
{
component: Input,
value: '',
props: {
label: $_('login.usernameLabel'),
type: 'email',
placeholder: $_('login.usernameLabel'),
required: true,
id: 'username'
}
},
{
label: 'Login',
href: null,
onclick: validateCredentials
component: Input,
value: '',
props: {
label: $_('login.passwordLabel'),
type: 'password',
placeholder: $_('login.passwordLabel'),
required: true,
id: 'password'
}
}
];

let alertMessage = 'Eingaben sind falsch';
let userID: string;
let remember: boolean = false;
let showAlert: boolean = false;
const heading = 'Einloggen';

// check if credentials are stored
onMount(async () => {
// make dummyUser if not already there
users.load();

// check if credentials are saved
const savedUID = JSON.parse(localStorage.getItem('currentUser'));

if (savedUID) {
userID = savedUID;

const user: UserData = (await users.fetch(userID)) as UserData;

data[0].value = user.name;
data[1].value = user.password;
data[2].value = user.role;
remember = true;
}
});

onDestroy(async () => {
await users.save();
});
let alertMessage: string = $_('login.badCredentials');
</script>

{#if showAlert}
<AlertMessage
title={'Fehler'}
title={$_('login.alertMessageTitle')}
message={alertMessage}
lastpage={`${base}/userLand/userLogin`}
onclick={() => {
Expand All @@ -105,53 +98,43 @@
/>
{/if}

{#if users.get()['loggedIn'] && users.get()['loggedIn'] !== null}
<AlertMessage
title={'Fehler'}
message={`Sie sind bereits angemeldet. Melden sie sich zuerst ab um den Account zu wechseln.`}
lastpage={`${base}`}
onclick={() => {
showAlert = false;
}}
/>
{:else}
<div class="container m-1 mx-auto w-full max-w-xl">
<Card class="container m-1 mx-auto mb-6 w-full max-w-xl pb-6">
{#if heading}
<Heading
tag="h3"
class="m-1 mb-3 p-1 text-center font-bold tracking-tight text-gray-700 dark:text-gray-400"
>{heading}</Heading
>
{/if}

<form class="m-1 m-3 mx-auto w-full flex-col space-y-6">
{#each data as element}
<DataInput
component={element.component}
label={element.props.label}
bind:value={element.value}
properties={element.props}
eventHandlers={{
'on:change': element.onchange,
'on:blur': element.onblur,
'on:click': element.onclick
}}
/>
{/each}
</form>
<div class="container m-2 mx-auto w-full max-w-xl">
<Card class="container m-2 mx-auto mb-6 w-full max-w-xl pb-6">
<Heading
tag="h3"
class="m-2 mb-3 p-2 text-center font-bold tracking-tight text-gray-700 dark:text-gray-400"
>{$_('login.heading')}</Heading
>

<UserLoginUtil cls="p-6 mb-3" bind:checked={remember} />
<form onsubmit={preventDefault(submitData)} class="m-2 mx-auto w-full flex-col space-y-6">
{#each formData as element}
<DataInput
component={element.component}
label={element.props.label}
bind:value={element.value}
properties={element.props}
eventHandlers={{
'on:change': element.onchange,
'on:blur': element.onblur,
'on:click': element.onclick
}}
/>
{/each}

<NavigationButtons {buttons} />
</Card>
<UserLoginUtil cls="p-6 mb-3" bind:checked={remember} />

<span class="container mx-auto w-full text-gray-700 dark:text-gray-400">Not registered?</span>
<a
href={`${base}/userLand/userRegistration`}
class="text-primary-700 hover:underline dark:text-primary-500"
>
Create account
</a>
</div>
{/if}
<Button
class="dark:bg-primay-700 w-full bg-primary-700 text-center text-sm text-white hover:bg-primary-800 hover:text-white dark:hover:bg-primary-800"
type="submit">{$_('login.submitButtonLabel')}</Button
>
</form>
</Card>

<span class="container mx-auto w-full text-gray-700 dark:text-gray-400">Not registered?</span>
<a
href={`${base}/userLand/userRegistration`}
class="text-primary-700 hover:underline dark:text-primary-500"
>
Create account
</a>
</div>
Loading