Cleand authentication-code up

This commit is contained in:
Mawoka
2022-07-26 22:50:39 +02:00
parent ba79c6a8c1
commit 29bda964b0
7 changed files with 111 additions and 136 deletions
+46
View File
@@ -12,6 +12,9 @@ from fastapi.background import BackgroundTasks
from fastapi.responses import JSONResponse, RedirectResponse, PlainTextResponse
from fastapi.security import OAuth2PasswordRequestForm
import html
from jose import jwt, JWTError
from classquiz import oauth
from classquiz.helpers.avatar import gzipped_user_avatar
import base64
@@ -266,3 +269,46 @@ async def get_other_avatar(respo: Response, user_id: uuid.UUID):
raise HTTPException(status_code=404, detail="User not found")
respo.headers.append("Content-Type", "image/svg+xml")
return gzip.decompress(base64.b64decode(user.avatar))
class InternalAuthData(BaseModel):
rememberme: str
jwt: str | None
@router.post("/auth/internal")
async def internal_auth(data: InternalAuthData, resp: Response):
try:
data.jwt = data.jwt.replace("Bearer ", "")
except AttributeError:
pass
if data.jwt is not None:
try:
payload = jwt.decode(data.jwt, settings.secret_key, algorithms=["HS256"])
email: str = payload.get("sub")
if email is None:
resp.status_code = 401
return resp
except JWTError:
resp.status_code = 401
return resp
else:
return await rememberme_check(data.rememberme, resp)
class GetEmailFromJWT(BaseModel):
jwt: str
@router.post("/auth/internal/email")
async def get_email_from_jwt(data: GetEmailFromJWT):
try:
data.jwt = data.jwt.replace("Bearer ", "")
except AttributeError:
pass
try:
payload = jwt.decode(data.jwt, settings.secret_key, algorithms=["HS256"])
return payload.get("sub")
except JWTError as e:
print(e)
raise HTTPException(status_code=401)
+1 -4
View File
@@ -25,11 +25,8 @@ RUN corepack enable && corepack prepare pnpm@7.5.0 --activate && pnpm i
# copy the generated modules and all other files to the container
COPY . .
RUN apt update && \
apt install -y redis-server
# build the application
RUN nohup bash -c "redis-server &" && sleep 4 && pnpm run build
RUN pnpm run build
### Serve Step
# pull the Node.js Docker image
-1
View File
@@ -48,7 +48,6 @@
"felte": "^1.2.2",
"highlight.js": "^11.5.1",
"i18next-browser-languagedetector": "^6.1.4",
"ioredis": "^5.1.0",
"js-cookie": "^3.0.1",
"luxon": "^2.4.0",
"mapbox-gl": "^2.9.1",
-84
View File
@@ -36,7 +36,6 @@ specifiers:
highlight.js: ^11.5.1
i18next: ^21.8.13
i18next-browser-languagedetector: ^6.1.4
ioredis: ^5.1.0
js-cookie: ^3.0.1
luxon: ^2.4.0
mapbox-gl: ^2.9.1
@@ -101,7 +100,6 @@ devDependencies:
felte: 1.2.2_svelte@3.49.0
highlight.js: 11.6.0
i18next-browser-languagedetector: 6.1.4
ioredis: 5.2.1
js-cookie: 3.0.1
luxon: 2.5.0
mapbox-gl: 2.9.2
@@ -251,13 +249,6 @@ packages:
}
dev: true
/@ioredis/commands/1.2.0:
resolution:
{
integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==
}
dev: true
/@jridgewell/resolve-uri/3.1.0:
resolution:
{
@@ -1439,14 +1430,6 @@ packages:
}
dev: true
/cluster-key-slot/1.1.0:
resolution:
{
integrity: sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==
}
engines: { node: '>=0.10.0' }
dev: true
/color-convert/2.0.1:
resolution:
{
@@ -1724,14 +1707,6 @@ packages:
}
dev: true
/denque/2.1.0:
resolution:
{
integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==
}
engines: { node: '>=0.10' }
dev: true
/detect-indent/6.1.0:
resolution:
{
@@ -2797,26 +2772,6 @@ packages:
}
dev: true
/ioredis/5.2.1:
resolution:
{
integrity: sha512-+rgPUIawiT+L3am9FbUcwjI7R7KtLDUSJNYWF82NZmlUXCZELws7iJkVDuECQoNUHqZTf/EGn3uw9IA+PlBiyg==
}
engines: { node: '>=12.22.0' }
dependencies:
'@ioredis/commands': 1.2.0
cluster-key-slot: 1.1.0
debug: 4.3.4
denque: 2.1.0
lodash.defaults: 4.2.0
lodash.isarguments: 3.1.0
redis-errors: 1.2.0
redis-parser: 3.0.0
standard-as-callback: 2.1.0
transitivePeerDependencies:
- supports-color
dev: true
/is-binary-path/2.1.0:
resolution:
{
@@ -2979,20 +2934,6 @@ packages:
}
dev: true
/lodash.defaults/4.2.0:
resolution:
{
integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==
}
dev: true
/lodash.isarguments/3.1.0:
resolution:
{
integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==
}
dev: true
/lodash.isplainobject/4.0.6:
resolution:
{
@@ -4088,24 +4029,6 @@ packages:
picomatch: 2.3.1
dev: true
/redis-errors/1.2.0:
resolution:
{
integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==
}
engines: { node: '>=4' }
dev: true
/redis-parser/3.0.0:
resolution:
{
integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==
}
engines: { node: '>=4' }
dependencies:
redis-errors: 1.2.0
dev: true
/regenerator-runtime/0.13.9:
resolution:
{
@@ -4418,13 +4341,6 @@ packages:
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
dev: true
/standard-as-callback/2.1.0:
resolution:
{
integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==
}
dev: true
/string-width/4.2.3:
resolution:
{
+18
View File
@@ -3,3 +3,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/// <reference types="@sveltejs/kit" />
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
// and what to do when importing types
declare namespace App {
interface Locals {
email: string | null;
}
// interface Platform {}
interface Session {
authenticated: boolean;
email: string | null;
}
// interface Stuff {}
}
+41 -44
View File
@@ -5,56 +5,53 @@
*/
import * as cookie from 'cookie';
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL);
import type { Handle, GetSession } from '@sveltejs/kit';
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
export const handle: Handle = async ({ 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`, {
const jwt = /^Bearer (.*)$/gm.exec(cookies.access_token);
const rememberme_token = cookies.rememberme_token;
if (rememberme_token) {
const res = await fetch(`${process.env.API_URL}/api/v1/users/auth/internal`, {
method: 'POST',
headers: {
Cookie: `access_token=Bearer ${event.locals.token}` // skipcq: JS-0378
}
'Content-Type': 'application/json'
},
body: JSON.stringify({
rememberme: rememberme_token,
jwt: jwt === null ? undefined : jwt[0]
})
});
if (res.ok) {
const json = await res.json();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore // skipcq: JS-0295
user_email = json.email;
let new_jwt;
if (jwt) {
new_jwt = jwt[0];
} else {
user_email = null;
new_jwt = cookie.parse(res.headers.get('set-cookie')).access_token;
}
event.locals.email = await (
await fetch(`${process.env.API_URL}/api/v1/users/auth/internal/email`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
jwt: new_jwt
})
})
).text();
const resp = await resolve(event);
resp.headers.set('Set-Cookie', res.headers.get('set-cookie'));
return resp;
} else {
user_email = redis_res;
event.locals.email = null;
return resolve(event);
}
if (user_email === null) {
return {
authenticated: false,
token: event.locals.token,
email: null
};
} else {
return {
authenticated: true,
token: event.locals.token,
email: user_email
};
}
}
};
export const getSession: GetSession = async (event) => {
return {
email: event.locals.email,
authenticated: Boolean(event.locals.email)
};
};
+5 -3
View File
@@ -9,7 +9,7 @@
<footer class="text-center text-white border-black w-screen">
<div class="grid grid-cols-12 w-full pt-4 bg-gray-700 pb-2">
<p class="col-start-2 col-end-12 text-center w-full">
<p class="col-start-3 col-end-11 text-center w-full">
Made with ❤️ by
<a
href="https://mawoka.eu?utm_source=ClassQuiz&utm_medium=footer"
@@ -36,14 +36,16 @@
>More details are here.</a
>
</p>
<div class="flex flex-col items-center min-h-full h-full md:block hidden">
<div
class="flex flex-col items-center min-h-full h-full md:block hidden col-start-11 col-end-12"
>
<div class="my-auto mr-16">
<LanguageToggle />
</div>
</div>
</div>
<div class="md:hidden block">
<div class="self-end flex justify-center min-h-full h-full bg-gray-700 md:pb-2">
<div class="self-end flex justify-center min-h-full h-full bg-gray-700 pb-2 md:pb-0">
<div class="m-auto md:invisible visible">
<LanguageToggle />
</div>