ok so it still works, the settings work more or less properly, and they look better, tho still kinda shit
This commit is contained in:
@@ -38,6 +38,8 @@ export class UsersController {
|
|||||||
@UseGuards(TwoFactorGuard)
|
@UseGuards(TwoFactorGuard)
|
||||||
@Get()
|
@Get()
|
||||||
findOne(@Req() req) {
|
findOne(@Req() req) {
|
||||||
|
console.log("Backend Getting current user");
|
||||||
|
// console.log(this.usersService.findOne(req.user.id));
|
||||||
return this.usersService.findOne(req.user.id);
|
return this.usersService.findOne(req.user.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,19 +6,7 @@
|
|||||||
|
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
console.log('SplashPage testing if logged in')
|
// console.log('SplashPage testing if logged in')
|
||||||
// let user = await fetch('http://transcendance:8080/api/v2/user')
|
|
||||||
// .then((resp) => resp.json())
|
|
||||||
// if (user) {
|
|
||||||
// if (!user.isEnabledTwoFactorAuth) {
|
|
||||||
// loginStatus.update( (old) => ({...old, tfa: true}) );
|
|
||||||
// }
|
|
||||||
// // because the User will only exist if they're logged in to 42?
|
|
||||||
// loginStatus.update( (old) => ({...old, fortyTwo: true}) );
|
|
||||||
// if (user.isEnabledTwoFactorAuth && $loginStatus.tfa)
|
|
||||||
// push('/profile');
|
|
||||||
// // They have to click Login if using tfa and tfa no already done
|
|
||||||
// }
|
|
||||||
|
|
||||||
// hold on, maybe this is all i need?
|
// hold on, maybe this is all i need?
|
||||||
let user = await fetch('http://transcendance:8080/api/v2/user')
|
let user = await fetch('http://transcendance:8080/api/v2/user')
|
||||||
@@ -39,17 +27,7 @@
|
|||||||
// console.log('we have a user');
|
// console.log('we have a user');
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// user === undefined doesn't work cuz we declared user in the scope of onMount
|
||||||
// for some reason unlike in ProfileDisplay here the user is never undefined...
|
|
||||||
// ok i think it's because here i declare the user in the call whereas in ProfileDisplay i declare user before...
|
|
||||||
// if (user !== undefined) {
|
|
||||||
// console.log('user not undefined')
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// console.log('user undefined')
|
|
||||||
|
|
||||||
// to clean up local storage... as a precaution
|
|
||||||
// this condition isn't good enough...
|
|
||||||
// if (user === undefined) {
|
// if (user === undefined) {
|
||||||
if (user && user.statusCode && user.statusCode === 403) {
|
if (user && user.statusCode && user.statusCode === 403) {
|
||||||
console.log('on mount no user, returned status code 403 so logging out of userStore')
|
console.log('on mount no user, returned status code 403 so logging out of userStore')
|
||||||
@@ -63,24 +41,13 @@
|
|||||||
window.location.href = 'http://transcendance:8080/api/v2/auth';
|
window.location.href = 'http://transcendance:8080/api/v2/auth';
|
||||||
// await fetch ('http://transcendance:8080/api/v2/auth');
|
// await fetch ('http://transcendance:8080/api/v2/auth');
|
||||||
console.log('you are now logged in');
|
console.log('you are now logged in');
|
||||||
push('/profile')
|
|
||||||
|
|
||||||
// ok giving our new local storage and store combo a go
|
|
||||||
// what i need is to set the store to the user when this button get's pressed
|
|
||||||
// since there's no apparent return i guess i'll just fetch the user?
|
|
||||||
|
|
||||||
await fetch('http://transcendance:8080/api/v2/user')
|
await fetch('http://transcendance:8080/api/v2/user')
|
||||||
.then((resp) => resp.json())
|
.then((resp) => resp.json())
|
||||||
.then((data) => void userStore.set(data));
|
.then((data) => void userStore.set(data));
|
||||||
|
|
||||||
// loginStatus.allTrue();
|
// decide if do this here on in backend
|
||||||
// this is redundant if TFA is on because they would only get back here after going through the TFA which sets it to True
|
|
||||||
// $loginStatus.tfa = true; // also it doesn't do anything cuz no .update()
|
|
||||||
|
|
||||||
// leave this out for now cuz causing problems
|
|
||||||
// push('/profile');
|
// push('/profile');
|
||||||
// idk why this doesn't work, seems really weird, maybe it's an awit thing?
|
|
||||||
// Maybe it would be better to do it in the Backend?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// i could prolly put this in it's own compoent, i seem to use it in several places... or maybe just some JS? like no need for html
|
// i could prolly put this in it's own compoent, i seem to use it in several places... or maybe just some JS? like no need for html
|
||||||
@@ -97,21 +64,8 @@
|
|||||||
|
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<header class="grid-container">
|
<header class="grid-container">
|
||||||
|
<h1>Potato Pong</h1>
|
||||||
<!-- <div on:mouseenter={enter} on:mouseleave={leave} class:active > -->
|
|
||||||
<h1>Potato Pong</h1>
|
|
||||||
<!-- </div> -->
|
|
||||||
|
|
||||||
<!-- <nav>
|
|
||||||
{#if ($loginStatus.fortyTwo && $loginStatus.tfa) === false}
|
|
||||||
<div on:click={login}>Login</div>
|
|
||||||
{:else}
|
|
||||||
<div on:click={ () => (push('/profile')) }>Profile</div>
|
|
||||||
<div on:click={logout}>Logout</div>
|
|
||||||
{/if}
|
|
||||||
</nav> -->
|
|
||||||
<nav>
|
<nav>
|
||||||
<!-- seems redundant but let's give it a try yea ok it still doesn't work, hate that... -->
|
|
||||||
{#if $userStore !== null}
|
{#if $userStore !== null}
|
||||||
<div on:click={ () => (push('/profile')) }>Profile</div>
|
<div on:click={ () => (push('/profile')) }>Profile</div>
|
||||||
<div on:click={logout}>Logout</div>
|
<div on:click={logout}>Logout</div>
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
let rank = '';
|
let rank = '';
|
||||||
let avatar;
|
let avatar;
|
||||||
|
|
||||||
|
|
||||||
// i think i don't need to do this once i sort out the {wrap} conditions: in theory i could pass values to the Route
|
// i think i don't need to do this once i sort out the {wrap} conditions: in theory i could pass values to the Route
|
||||||
// once the async authentication check is done
|
// once the async authentication check is done
|
||||||
onMount( async() => {
|
onMount( async() => {
|
||||||
@@ -47,6 +46,10 @@
|
|||||||
avatar = url;
|
avatar = url;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// tmp
|
||||||
|
// console.log('mounted Profile Display')
|
||||||
|
// console.log(user);
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -22,14 +22,24 @@
|
|||||||
<!-- The Wave -->
|
<!-- The Wave -->
|
||||||
<!-- <div class="spacer layer1"></div> -->
|
<!-- <div class="spacer layer1"></div> -->
|
||||||
|
|
||||||
<Router routes={profileRoutes} {prefix} />
|
<div>
|
||||||
|
<Router routes={profileRoutes} {prefix} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- <Footer /> -->
|
<!-- <Footer /> -->
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
|
div {
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 40px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* from Haikei */
|
/* from Haikei */
|
||||||
/* for any Haikei image */
|
/* for any Haikei image */
|
||||||
|
|
||||||
|
|||||||
@@ -3,33 +3,60 @@
|
|||||||
import Card from '../../pieces/Card.svelte';
|
import Card from '../../pieces/Card.svelte';
|
||||||
import {onMount} from 'svelte';
|
import {onMount} from 'svelte';
|
||||||
import { push } from 'svelte-spa-router';
|
import { push } from 'svelte-spa-router';
|
||||||
|
import Button from '../../pieces/Button.svelte';
|
||||||
|
|
||||||
let user;
|
let user;
|
||||||
let avatar, postVar, newAvatar, fileinput;
|
let avatar, postVar, newAvatar;
|
||||||
|
// postVar means nothing can i get rid of it or do i need it to do something...
|
||||||
let uploadAvatarSuccess = false;
|
let uploadAvatarSuccess = false;
|
||||||
|
|
||||||
// tbh i might not need this...
|
// tbh i might not need this...
|
||||||
let set = {
|
let set = { username: '', tfa: false };
|
||||||
username: '',
|
let nameTmp; // annoying...
|
||||||
isChecked: false,
|
|
||||||
}
|
|
||||||
const errors = { username: '', checkbox: '', avatar: ''};
|
const errors = { username: '', checkbox: '', avatar: ''};
|
||||||
// let isChecked;
|
|
||||||
let testChecked = true;
|
|
||||||
|
|
||||||
onMount( async() => {
|
onMount( async() => {
|
||||||
user = await fetch('http://transcendance:8080/api/v2/user')
|
user = await fetch('http://transcendance:8080/api/v2/user')
|
||||||
.then( (x) => x.json() );
|
.then( (x) => x.json() );
|
||||||
|
// do a .catch?
|
||||||
|
|
||||||
set.isChecked = user.isEnabledTwoFactorAuth;
|
if (user === undefined) {
|
||||||
})
|
console.log('User did not load, something more official should prolly happen')
|
||||||
|
}
|
||||||
|
// i don't unerstand why this is necessary but it really doesn't like it otherwise
|
||||||
|
nameTmp = user.username;
|
||||||
|
// console.log(user.username)
|
||||||
|
|
||||||
|
set.tfa = user.isEnabledTwoFactorAuth;
|
||||||
|
|
||||||
|
// tmp
|
||||||
|
console.log('this is what is in the avatar before fetch')
|
||||||
|
console.log(avatar)
|
||||||
|
|
||||||
|
await fetch("http://transcendance:8080/api/v2/user/avatar", {method: "GET"})
|
||||||
|
.then(response => {return response.blob()})
|
||||||
|
.then(data => {
|
||||||
|
const url = URL.createObjectURL(data);
|
||||||
|
avatar = url;
|
||||||
|
})
|
||||||
|
.catch(() => errors.avatar = 'Sorry your avatar could not be loaded' );
|
||||||
|
|
||||||
|
// .then(() => errors.avatar = '' ) // unnecessary i think cuz in on mount...
|
||||||
|
|
||||||
|
// tmp
|
||||||
|
console.log('this is what is in the avatar')
|
||||||
|
console.log(avatar)
|
||||||
|
console.log('this is what is in the NEW Avatar')
|
||||||
|
console.log(newAvatar)
|
||||||
|
})
|
||||||
|
|
||||||
const settingsHandler = async() => {
|
const settingsHandler = async() => {
|
||||||
|
|
||||||
let valid = false;
|
let valid = false;
|
||||||
|
|
||||||
if (set.username === user.username) {
|
// I don't really care which i use at this point...
|
||||||
errors.username = "You picked the same username, you're supposesd to change it";
|
// if (set.username === nameTmp) {
|
||||||
|
if (set.username === user.username || set.username.trim() === '') {
|
||||||
|
errors.username = 'Invalid new username';
|
||||||
valid = false;
|
valid = false;
|
||||||
} else {
|
} else {
|
||||||
errors.username = '';
|
errors.username = '';
|
||||||
@@ -43,81 +70,90 @@
|
|||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
username: set.username,
|
"username": set.username,
|
||||||
isEnabledTwoFactorAuth: set.isChecked,
|
"isEnabledTwoFactorAuth": set.tfa
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(result => console.log(result));
|
// .then((result) => console.log(result))
|
||||||
|
// .then(() => console.log('successful sub of new settings'))
|
||||||
push('/profile');
|
.then(() => push('/profile'));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const uploadAvatar = async() => {
|
const uploadAvatar = async() => {
|
||||||
|
errors.avatar = '';
|
||||||
|
if (newAvatar === undefined) {
|
||||||
|
errors.avatar = 'You need to pick a file.'
|
||||||
|
return;
|
||||||
|
}
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
data.append("file", newAvatar[0]);
|
data.append("file", newAvatar[0]);
|
||||||
|
|
||||||
|
// tmp
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
await fetch("http://transcendance:8080/api/v2/user/avatar",
|
await fetch("http://transcendance:8080/api/v2/user/avatar",
|
||||||
{
|
{
|
||||||
method : 'POST',
|
method : 'POST',
|
||||||
body : data,
|
body : data,
|
||||||
})
|
})
|
||||||
.then(() => uploadAvatarSuccess = true) // for some reason it needs to be a function, i think a TS thing, not a promis otherwise
|
.then(() => uploadAvatarSuccess = true ) // for some reason it needs to be a function, i think a TS thing, not a promis otherwise
|
||||||
.catch(() => errors.avatar = "Something went wrong." )
|
.then(() => push('/profile') )
|
||||||
}
|
.catch(() => errors.avatar = 'Sorry failed to upload your new Avatar' )
|
||||||
|
// some of this shit is unnecessary...
|
||||||
|
// also i'm not convinced the .catch works...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<!-- <div class="outter"> -->
|
<h2>Look! You can change stuff</h2>
|
||||||
<h2>Look, you can change stuff</h2>
|
<div class="cards">
|
||||||
<!-- maybe ues a card? -->
|
<Card>
|
||||||
<!-- a form? -->
|
<form on:submit|preventDefault={settingsHandler}>
|
||||||
|
<div class="form-field">
|
||||||
|
<div class="label">New Username</div>
|
||||||
|
<!-- it really hates {user.username} and ${user.username} -->
|
||||||
|
<!-- <input type="text" placeholder="current username: ${user.username}" bind:value={set.username}> -->
|
||||||
|
<input type="text" placeholder="current username: {nameTmp}" bind:value={set.username}>
|
||||||
|
<div class="error">{errors.username}</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-field">
|
||||||
|
<div class="label inline-check">Set Two Factor Authentication</div>
|
||||||
|
<input class="inline-check" type="checkbox" bind:checked={set.tfa}>
|
||||||
|
<div class="error">{errors.checkbox}</div>
|
||||||
|
</div>
|
||||||
|
<Button type="secondary">Update Settings</Button>
|
||||||
|
</form>
|
||||||
|
</Card>
|
||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
<form on:submit|preventDefault={settingsHandler}>
|
<!-- ok so it can't actually show us the file we upload until we've uploaded it... -->
|
||||||
<div class="form-field">
|
<!-- {#if newAvatar !== undefined}
|
||||||
<div class="label">New Username</div>
|
<img class="avatar" src={newAvatar} alt="your new avatar"/>
|
||||||
<!-- <input type="text" placeholder={user.username} bind:value={set.username}> -->
|
{:else if avatar !== undefined}
|
||||||
<input type="text" placeholder="new username" bind:value={set.username}>
|
<img class="avatar" src={avatar} alt="your avatar"/>
|
||||||
<div class="error">{errors.username}</div>
|
{:else}
|
||||||
</div>
|
<p class="error">{errors.avatar}</p>
|
||||||
<div class="form-field">
|
{/if} -->
|
||||||
<div class="label">Set Two Factor Authentication</div>
|
{#if avatar !== undefined}
|
||||||
<input type="checkbox" bind:checked={set.isChecked}>
|
|
||||||
<div class="error">{errors.checkbox}</div>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="form-field">
|
|
||||||
<div class="label">Test</div>
|
|
||||||
<input type="checkbox" bind:checked={testChecked}>
|
|
||||||
</div> -->
|
|
||||||
<button>Update Settings</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card>
|
|
||||||
<form on:submit|preventDefault={uploadAvatar}>
|
|
||||||
{#if avatar}
|
|
||||||
<img class="avatar" src={avatar} alt="your avatar"/>
|
<img class="avatar" src={avatar} alt="your avatar"/>
|
||||||
{/if}
|
{/if}
|
||||||
<input type="text" bind:value={postVar} placeholder={"choose your file"}/>
|
<form on:submit|preventDefault={uploadAvatar}>
|
||||||
<br />
|
<!-- not convinced this has any utility. -->
|
||||||
<input type="file" bind:files={newAvatar}/>
|
<!-- <input type="text" bind:value={postVar} placeholder={"choose your file"}/> -->
|
||||||
<br />
|
<div class="form-field">
|
||||||
<button type="submit">Choose avatar</button>
|
<div class="label">Pick a new Avatar</div>
|
||||||
</form>
|
<input type="file" bind:files={newAvatar}/>
|
||||||
</Card>
|
<div class="error">{errors.avatar}</div>
|
||||||
|
</div>
|
||||||
<!-- </div> -->
|
<Button type={newAvatar === undefined ? "primary" : "secondary"}>Upload Avatar</Button>
|
||||||
|
</form>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
@@ -127,10 +163,26 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
/* display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-gap: 20px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
div.outter{
|
div.cards{
|
||||||
max-width: 500px;
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-gap: 20px;
|
||||||
|
/* text-align: center; */
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
/* we want the image to display as the same size no matter the resolution */
|
||||||
|
/* max-width: fit-content; */
|
||||||
|
/* max-width: 100px; */
|
||||||
|
width: 60px;
|
||||||
|
/* ok this works but i'm guessing i'll need to add some @media ... */
|
||||||
|
/* padding: 10px; */
|
||||||
|
/* this doesn't work either when nothing loads and it's just the words... don't love that */
|
||||||
}
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
@@ -146,6 +198,10 @@
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline-check{
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.error{
|
.error{
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
|
|||||||
48
srcs/requirements/svelte/api_front/src/pieces/Button.svelte
Normal file
48
srcs/requirements/svelte/api_front/src/pieces/Button.svelte
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
// things to make the button more generic, modifable and reusable
|
||||||
|
export let type:string = 'primary';
|
||||||
|
export let flat:boolean = false;
|
||||||
|
export let inverse:boolean = false;
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- the class is not conditional as in class:type={some condition}, no it's just the value of type -->
|
||||||
|
<!-- but class:flat and class:inverse are conditionally dependant, not a function tho, just a var -->
|
||||||
|
<!-- we could do class={flat} but it would just be true or false, what would we do with class:inverse then? -->
|
||||||
|
<!-- basically we are naming the classes flat and inverse directly since the var value can't name them -->
|
||||||
|
<button class={type} class:flat={flat} class:inverse={inverse} on:click>
|
||||||
|
<slot></slot>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
button{
|
||||||
|
border: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
box-shadow: 1px 2px 3px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
.primary{
|
||||||
|
background: #d91b42;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.secondary{
|
||||||
|
background: #45c496;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.flat{
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.primary.inverse{
|
||||||
|
color: #d91b42;
|
||||||
|
background: white;
|
||||||
|
border: 2px solid #d91b42;
|
||||||
|
}
|
||||||
|
.secondary.inverse{
|
||||||
|
color: #45c496;
|
||||||
|
background: white;
|
||||||
|
border: 2px solid #45c496;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -21,12 +21,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<header>
|
<header>
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
||||||
<img src="/img/potato_logo.png" alt="Potato Pong Logo" on:click={() => (push('/'))}>
|
<img src="/img/potato_logo.png" alt="Potato Pong Logo" on:click={() => (push('/'))}>
|
||||||
<!-- /profile or / ? not sure -->
|
|
||||||
<h1>Potato Pong</h1>
|
<h1>Potato Pong</h1>
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
{#if $location !== '/profile'}
|
{#if $location !== '/profile'}
|
||||||
<button on:click={() => (push('/profile'))}>My Profile</button>
|
<button on:click={() => (push('/profile'))}>My Profile</button>
|
||||||
|
|||||||
@@ -15,11 +15,4 @@ userStore.subscribe((value) => {
|
|||||||
else localStorage.removeItem('42User'); // for logout
|
else localStorage.removeItem('42User'); // for logout
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export const userLogout = () => userStore.set(null);
|
export const userLogout = () => userStore.set(null);
|
||||||
|
|
||||||
// ok this is the part where i need to use our API rather than Auth
|
|
||||||
// export async function signUp(username, password, email) {
|
|
||||||
// return Auth.signUp(username, password, email)
|
|
||||||
// .then((data) => void store.set(data));
|
|
||||||
// }
|
|
||||||
Reference in New Issue
Block a user