Worked on ui

This commit is contained in:
Mawoka
2022-02-28 12:38:34 +01:00
parent da09f88751
commit 208bc89a5e
8 changed files with 261 additions and 9 deletions
+10 -2
View File
@@ -5,6 +5,7 @@ from email_validator import validate_email, EmailNotValidError
from classquiz.auth import *
from fastapi.background import BackgroundTasks
from classquiz.emails import send_mail
from classquiz.config import redis
from fastapi.responses import JSONResponse
from classquiz.db.models import *
@@ -54,13 +55,15 @@ async def login_for_cookie_access_token(request: Request, response: Response,
access_token = create_access_token(
data={"sub": user.email}, expires_delta=access_token_expires
)
rememberme_token = create_access_token(
await redis.set(access_token, user.email, ex=settings.access_token_expire_minutes * 60)
rememberme_jwt = create_access_token(
data={"sub": user.email}, expires_delta=timedelta(days=360))
response.set_cookie(key="access_token", value=f"Bearer {access_token}",
httponly=True, samesite='strict')
response.set_cookie(key="expiry", value="", max_age=settings.access_token_expire_minutes * 60)
response.set_cookie(key="rememberme", value="")
response.set_cookie(key="rememberme_token", value=rememberme_token, httponly=True, samesite='strict')
response.set_cookie(key="rememberme_token", value=rememberme_jwt, httponly=True, samesite='strict')
return {"access_token": access_token, "token_type": "bearer"}
@@ -88,3 +91,8 @@ async def logout(request: Request, response: Response):
response.delete_cookie("expiry")
response.delete_cookie("rememberme")
response.delete_cookie("rememberme_token")
@router.get("/check")
async def check_token(user: User = Depends(get_current_user)):
return {"email": user.email}
+2
View File
@@ -25,8 +25,10 @@
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-svelte3": "^3.2.1",
"felte": "^1.0.1",
"ioredis": "^4.28.5",
"js-cookie": "^3.0.1",
"luxon": "^2.3.1",
"node-fetch": "^3.2.0",
"postcss": "^8.4.5",
"postcss-load-config": "^3.1.1",
"prettier": "^2.5.1",
+109
View File
@@ -14,8 +14,10 @@ specifiers:
eslint-config-prettier: ^8.3.0
eslint-plugin-svelte3: ^3.2.1
felte: ^1.0.1
ioredis: ^4.28.5
js-cookie: ^3.0.1
luxon: ^2.3.1
node-fetch: ^3.2.0
postcss: ^8.4.5
postcss-load-config: ^3.1.1
prettier: ^2.5.1
@@ -43,8 +45,10 @@ devDependencies:
eslint-config-prettier: 8.4.0_eslint@7.32.0
eslint-plugin-svelte3: 3.4.1_eslint@7.32.0+svelte@3.46.4
felte: 1.0.1_svelte@3.46.4
ioredis: 4.28.5
js-cookie: 3.0.1
luxon: 2.3.1
node-fetch: 3.2.0
postcss: 8.4.7
postcss-load-config: 3.1.3
prettier: 2.5.1
@@ -614,6 +618,11 @@ packages:
fsevents: 2.3.2
dev: true
/cluster-key-slot/1.1.0:
resolution: {integrity: sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==}
engines: {node: '>=0.10.0'}
dev: true
/color-convert/1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
@@ -670,6 +679,11 @@ packages:
hasBin: true
dev: true
/data-uri-to-buffer/4.0.0:
resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==}
engines: {node: '>= 12'}
dev: true
/debug/4.3.3:
resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==}
engines: {node: '>=6.0'}
@@ -690,6 +704,11 @@ packages:
resolution: {integrity: sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=}
dev: true
/denque/1.5.1:
resolution: {integrity: sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==}
engines: {node: '>=0.10'}
dev: true
/detect-indent/6.1.0:
resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
engines: {node: '>=8'}
@@ -1186,6 +1205,14 @@ packages:
svelte: 3.46.4
dev: true
/fetch-blob/3.1.4:
resolution: {integrity: sha512-Eq5Xv5+VlSrYWEqKrusxY1C3Hm/hjeAsCGVG3ft7pZahlUAChpGZT/Ms1WmSLnEAisEXszjzu/s+ce6HZB2VHA==}
engines: {node: ^12.20 || >= 14.13}
dependencies:
node-domexception: 1.0.0
web-streams-polyfill: 3.2.0
dev: true
/file-entry-cache/6.0.1:
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
engines: {node: ^10.12.0 || >=12.0.0}
@@ -1212,6 +1239,13 @@ packages:
resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==}
dev: true
/formdata-polyfill/4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
dependencies:
fetch-blob: 3.1.4
dev: true
/fraction.js/4.1.3:
resolution: {integrity: sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==}
dev: true
@@ -1347,6 +1381,25 @@ packages:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
dev: true
/ioredis/4.28.5:
resolution: {integrity: sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==}
engines: {node: '>=6'}
dependencies:
cluster-key-slot: 1.1.0
debug: 4.3.3
denque: 1.5.1
lodash.defaults: 4.2.0
lodash.flatten: 4.4.0
lodash.isarguments: 3.1.0
p-map: 2.1.0
redis-commands: 1.7.0
redis-errors: 1.2.0
redis-parser: 3.0.0
standard-as-callback: 2.1.0
transitivePeerDependencies:
- supports-color
dev: true
/is-arrayish/0.2.1:
resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=}
dev: true
@@ -1449,6 +1502,18 @@ packages:
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
dev: true
/lodash.defaults/4.2.0:
resolution: {integrity: sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=}
dev: true
/lodash.flatten/4.4.0:
resolution: {integrity: sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=}
dev: true
/lodash.isarguments/3.1.0:
resolution: {integrity: sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=}
dev: true
/lodash.merge/4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true
@@ -1537,6 +1602,20 @@ packages:
resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=}
dev: true
/node-domexception/1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
dev: true
/node-fetch/3.2.0:
resolution: {integrity: sha512-8xeimMwMItMw8hRrOl3C9/xzU49HV/yE6ORew/l+dxWimO5A4Ra8ld2rerlJvc/O7et5Z1zrWsPX43v1QBjCxw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
data-uri-to-buffer: 4.0.0
fetch-blob: 3.1.4
formdata-polyfill: 4.0.10
dev: true
/node-releases/2.0.2:
resolution: {integrity: sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==}
dev: true
@@ -1574,6 +1653,11 @@ packages:
word-wrap: 1.2.3
dev: true
/p-map/2.1.0:
resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==}
engines: {node: '>=6'}
dev: true
/parent-module/1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
@@ -1732,6 +1816,22 @@ packages:
picomatch: 2.3.1
dev: true
/redis-commands/1.7.0:
resolution: {integrity: sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==}
dev: true
/redis-errors/1.2.0:
resolution: {integrity: sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=}
engines: {node: '>=4'}
dev: true
/redis-parser/3.0.0:
resolution: {integrity: sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=}
engines: {node: '>=4'}
dependencies:
redis-errors: 1.2.0
dev: true
/regenerator-runtime/0.13.9:
resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==}
dev: true
@@ -1897,6 +1997,10 @@ packages:
resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=}
dev: true
/standard-as-callback/2.1.0:
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
dev: true
/string-width/4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
@@ -2179,6 +2283,11 @@ packages:
fsevents: 2.3.2
dev: true
/web-streams-polyfill/3.2.0:
resolution: {integrity: sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==}
engines: {node: '>= 8'}
dev: true
/which/2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
+7 -1
View File
@@ -5,7 +5,13 @@
declare namespace App {
// interface Locals {}
// interface Platform {}
// interface Session {}
interface Session {
authenticated: boolean;
token: string | null;
email: string | null;
}
// interface Stuff {}
}
+57
View File
@@ -0,0 +1,57 @@
import * as cookie from 'cookie';
import fetch from 'node-fetch';
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL);
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
const cookies = cookie.parse(event.request.headers.get('cookie') || '');
const regex_token = /^Bearer (.*)$/gm.exec(cookies.access_token);
if (regex_token === null) {
event.locals.token = null;
} else {
event.locals.token = regex_token[1];
}
event.locals.rememberme = cookies.rememberme_token;
return await resolve(event);
}
/** @type {import('@sveltejs/kit').GetSession} */
export async function getSession(event) {
const redis_res = await redis.get(event.locals.token);
let user_email: string;
if (redis_res === null) {
const res = await fetch(`${process.env.API_URL}/api/v1/users/check`, {
headers: {
Cookie: `access_token=Bearer ${event.locals.token}`
}
});
if (res.ok) {
const json = await res.json();
// @ts-ignore
user_email = json.email;
} else {
user_email = null;
}
} else {
user_email = redis_res;
}
if (user_email === null) {
return {
authenticated: false,
token: event.locals.token,
email: null
};
} else {
return {
authenticated: true,
token: event.locals.token,
email: user_email
};
}
}
+5 -6
View File
@@ -1,15 +1,14 @@
<!--<script context='module' lang='ts'>
export async function load({ session }) {
console.log(import.meta.env.VITE_BASE_ADDRESS);
<script context='module' lang='ts'>
export async function load({ session, request }) {
if (session.authenticated) {
return {
status: 302,
redirect: '/'
redirect: "/"
};
}
return {};
return {}
}
</script>-->
</script>
<script lang='ts'>
//import { rememberme } from '$lib/utils/clientAuth';
+15
View File
@@ -0,0 +1,15 @@
<script context='module' lang='ts'>
export async function load({ session }) {
if (!session.authenticated) {
return {
status: 302,
redirect: '/account/login'
};
}
return {
props: {
email: session.email
}
};
}
</script>
+56
View File
@@ -0,0 +1,56 @@
<script context='module' lang='ts'>
export async function load({ url }) {
const token = url.searchParams.get('token');
return {
props: {
game_pin: token === null ? '' : token
}
};
}
</script>
<script lang='ts'>
import { socket } from '$lib/socket';
export let game_pin: string;
let game_pin_valid = false;
console.log(game_pin);
const setUsername = (username: string) => {
console.log(username);
};
const setGamePin = (game_pin: string) => {
socket.emit()
};
$: console.log(game_pin.length);
</script>
<div>
{#if game_pin === "" || game_pin.length <= 7 || !game_pin_valid}
<div class='flex flex-col justify-center align-center w-screen h-screen'>
<form on:submit|preventDefault={setGamePin} class='flex-col flex justify-center align-center mx-auto'>
<h1 class='text-lg text-center'>Game Pin</h1>
<input class='border border-amber-800 self-center text-center' bind:value={game_pin} maxlength='8'>
<br>
<button class='bg-amber-800 hover:bg-amber-700 text-white font-bold py-2 px-4 rounded'
type='submit'>
Submit
</button>
</form>
</div>
{:else}
<div class='flex flex-col justify-center align-center w-screen h-screen'>
<form on:submit|preventDefault={setUsername} class='flex-col flex justify-center align-center mx-auto'>
<h1 class='text-lg text-center'>Username</h1>
<input class='border border-amber-800'>
<button class='bg-amber-800 hover:bg-amber-700 text-white font-bold py-2 px-4 rounded' type='submit'>
Submit
</button>
</form>
</div>
{/if}
</div>