Updated login refresh logic, working on tile grid
This commit is contained in:
@@ -340,6 +340,40 @@ async fn me(auth: JwtAuth) -> HttpResponse {
|
||||
HttpResponse::Ok().json(auth)
|
||||
}
|
||||
|
||||
#[get("/check-session")]
|
||||
async fn check_session(req: HttpRequest) -> HttpResponse {
|
||||
// If there is a access_token cookie, check if it is valid
|
||||
let has_session = match req.cookie("access_token") {
|
||||
Some(cookie) => {
|
||||
let access_token = cookie.value().to_string();
|
||||
let public_key = env::var("ACCESS_TOKEN_PUBLIC_KEY")
|
||||
.expect("ACCESS_TOKEN_PUBLIC_KEY must be set");
|
||||
match verify_token(&access_token, &public_key) {
|
||||
Ok(_) => true,
|
||||
Err(_) => false
|
||||
}
|
||||
},
|
||||
None => false
|
||||
};
|
||||
if !has_session {
|
||||
// If there is a refresh_token cookie, check if it is valid
|
||||
match req.cookie("refresh_token") {
|
||||
Some(cookie) => {
|
||||
let refresh_token = cookie.value().to_string();
|
||||
let public_key = env::var("REFRESH_TOKEN_PUBLIC_KEY")
|
||||
.expect("REFRESH_TOKEN_PUBLIC_KEY must be set");
|
||||
match verify_token(&refresh_token, &public_key) {
|
||||
Ok(_) => return HttpResponse::Ok().json(true),
|
||||
Err(_) => return HttpResponse::Ok().json(false)
|
||||
};
|
||||
},
|
||||
None => return HttpResponse::Ok().json(false)
|
||||
};
|
||||
} else {
|
||||
return HttpResponse::Ok().json(true)
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/roles")]
|
||||
async fn roles() -> HttpResponse {
|
||||
HttpResponse::Ok().json(vec!["admin", "user"])
|
||||
@@ -363,5 +397,6 @@ pub fn init_routes(config: &mut web::ServiceConfig) {
|
||||
.service(logout)
|
||||
.service(me)
|
||||
.service(roles)
|
||||
.service(check_session)
|
||||
);
|
||||
}
|
||||
@@ -42,6 +42,15 @@ export async function me(): Promise<ResponseAuth | undefined> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function hasSession(): Promise<boolean> {
|
||||
const response = await getRequest('auth/check-session');
|
||||
if (response?.status === 200) {
|
||||
return response?.json();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the logged_in cookie every interval. By default, the interval is 14 minutes.
|
||||
* @param interval
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { login, register, refreshLoggedIn } from '@/api/auth';
|
||||
import { login, register } from '@/api/auth';
|
||||
import { User } from '@/api/auth.types';
|
||||
import {
|
||||
Modal,
|
||||
@@ -146,7 +146,6 @@ export function HeaderModal({ type, toggle, setUser, setRefreshId }: HeaderModal
|
||||
const loginResponse = await login(values.email, values.password);
|
||||
if (loginResponse) {
|
||||
setUser(loginResponse.user);
|
||||
setRefreshId(refreshLoggedIn());
|
||||
onClose();
|
||||
notifications.update({
|
||||
id,
|
||||
@@ -222,7 +221,6 @@ export function HeaderModal({ type, toggle, setUser, setRefreshId }: HeaderModal
|
||||
const response = await login(values.email, values.password);
|
||||
if (response) {
|
||||
setUser(response.user);
|
||||
setRefreshId(refreshLoggedIn());
|
||||
onClose();
|
||||
} else {
|
||||
notifications.show({
|
||||
|
||||
@@ -6,7 +6,7 @@ import './header.css';
|
||||
import { Avatar, Button, Card, Center, FileButton, Grid, Group, Menu, Text, UnstyledButton } from '@mantine/core';
|
||||
import Cookies from 'js-cookie';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { logout, refresh, refreshLoggedIn } from '@/api/auth';
|
||||
import { hasSession, logout, refresh, refreshLoggedIn } from '@/api/auth';
|
||||
import { useToggle } from '@mantine/hooks';
|
||||
import { HeaderModal } from './HeaderModal';
|
||||
import { HeaderItem, headerItems } from './headerItems';
|
||||
@@ -14,6 +14,7 @@ import { userState } from '@/state/auth';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { getPicture, setPicture } from '@/api/users';
|
||||
import { BsChevronDown } from 'react-icons/bs';
|
||||
import { User } from '@/api/auth.types';
|
||||
|
||||
export default function Header() {
|
||||
const pathName = usePathname();
|
||||
@@ -25,12 +26,25 @@ export default function Header() {
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (!user || !Cookies.get('logged_in')) {
|
||||
if (!user) {
|
||||
hasSession().then((response) => {
|
||||
if (response) {
|
||||
refresh().then((response) => {
|
||||
if (response) {
|
||||
setRefreshId(refreshLoggedIn());
|
||||
setUser(response.user);
|
||||
if (response.user.profile_picture) {
|
||||
updateUser(response.user);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [user]);
|
||||
|
||||
function updateUser(user?: User) {
|
||||
if (!refreshId) {
|
||||
setRefreshId(refreshLoggedIn());
|
||||
}
|
||||
if (user) {
|
||||
getPicture().then((response) => {
|
||||
if (response) {
|
||||
setProfilePicture(response as File);
|
||||
@@ -38,9 +52,6 @@ export default function Header() {
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [user]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -159,6 +170,8 @@ export default function Header() {
|
||||
await logout();
|
||||
Cookies.remove('logged_in');
|
||||
setUser(undefined);
|
||||
clearInterval(refreshId);
|
||||
setRefreshId(undefined);
|
||||
setProfilePicture(null);
|
||||
if (refreshId) {
|
||||
clearInterval(refreshId);
|
||||
@@ -196,13 +209,7 @@ export default function Header() {
|
||||
toggle={toggle}
|
||||
setUser={(u) => {
|
||||
setUser(u);
|
||||
if (u.profile_picture) {
|
||||
getPicture().then((response) => {
|
||||
if (response) {
|
||||
setProfilePicture(response as File);
|
||||
}
|
||||
});
|
||||
}
|
||||
updateUser(u);
|
||||
}}
|
||||
setRefreshId={setRefreshId}
|
||||
/>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
'use client';
|
||||
|
||||
import { Graphics, Stage, Text } from '@pixi/react';
|
||||
import { Graphics, Stage } from '@pixi/react';
|
||||
import { Graphics as PixiGraphics } from '@pixi/graphics';
|
||||
import { MouseEvent, WheelEvent, useCallback, useEffect, useState } from 'react';
|
||||
import TileControls, { EditTool, Tool, defaultColors } from './TileControls';
|
||||
import { Box } from '@mantine/core';
|
||||
import { TextStyle } from 'pixi.js';
|
||||
|
||||
interface SquareEdit {
|
||||
x: number;
|
||||
@@ -31,24 +30,21 @@ export default function TileGrid() {
|
||||
const [edits, setEdits] = useState<SquareEdit[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (window) {
|
||||
// window.addEventListener(
|
||||
// 'wheel',
|
||||
// (event) => {
|
||||
// event.preventDefault();
|
||||
// },
|
||||
// { passive: false }
|
||||
// );
|
||||
// // Disable right click context menu
|
||||
// window.addEventListener(
|
||||
// 'contextmenu',
|
||||
// (event) => {
|
||||
// event.preventDefault();
|
||||
// },
|
||||
// { passive: false }
|
||||
// );
|
||||
// Prevent context menu from appearing on right click
|
||||
function handleContextmenu(e: any) {
|
||||
e.preventDefault()
|
||||
}
|
||||
}, []);
|
||||
document.addEventListener('contextmenu', handleContextmenu)
|
||||
// Prevent scrollwheel from scrolling page
|
||||
function handleScroll(e: any) {
|
||||
e.preventDefault()
|
||||
}
|
||||
document.addEventListener('wheel', handleScroll, { passive: false })
|
||||
return function cleanup() {
|
||||
document.removeEventListener('contextmenu', handleContextmenu)
|
||||
document.removeEventListener('wheel', handleScroll)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const drawGrid = useCallback(
|
||||
(g: PixiGraphics) => {
|
||||
@@ -65,7 +61,7 @@ export default function TileGrid() {
|
||||
[gridSize, zoom]
|
||||
);
|
||||
|
||||
const drawEdits = useCallback(
|
||||
const drawGridEdits = useCallback(
|
||||
(g: PixiGraphics) => {
|
||||
g.clear();
|
||||
edits.forEach((edit) => {
|
||||
@@ -77,24 +73,10 @@ export default function TileGrid() {
|
||||
[edits, zoom]
|
||||
);
|
||||
|
||||
function clickEvent(e: MouseEvent) {
|
||||
setMouseDown(true);
|
||||
setLastPosition({ x: e.clientX, y: e.clientY });
|
||||
if (tool == Tool.ZOOM) {
|
||||
handleZoom(e.button === 0 ? -100 : 100, e.clientX, e.clientY);
|
||||
} else if (tool == Tool.EDIT) {
|
||||
if (editTool === EditTool.SQUARE) {
|
||||
drawSquare(e.button, e.clientX, e.clientY);
|
||||
} else if (editTool === EditTool.CIRCLE) {
|
||||
// handle circle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawSquare(button: number, clientX: number, clientY: number) {
|
||||
// Calculate tile coordinates
|
||||
const x = Math.floor((clientX - position.x) / (32 * zoom));
|
||||
const y = Math.floor((clientY - position.y) / (32 * zoom));
|
||||
// TODO: Fix y offset, currently appears to be 2 tiles down from mouse
|
||||
const y = Math.floor((clientY - position.y) / (32 * zoom)) - 2;
|
||||
if (button === 1) {
|
||||
// Add new edit if left mouse button is pressed
|
||||
setEdits([...edits, { x, y, color: colors[selectedColor] }]);
|
||||
@@ -104,6 +86,20 @@ export default function TileGrid() {
|
||||
}
|
||||
}
|
||||
|
||||
function clickEvent(e: MouseEvent, isMouseDown: boolean) {
|
||||
setMouseDown(isMouseDown);
|
||||
setLastPosition({ x: e.clientX, y: e.clientY });
|
||||
if (isMouseDown) {
|
||||
if (tool == Tool.ZOOM) {
|
||||
handleZoom(e.buttons === 1 ? -100 : 100, e.clientX, e.clientY);
|
||||
} else if (tool == Tool.EDIT && editTool === EditTool.SQUARE) {
|
||||
drawSquare(e.buttons, e.clientX, e.clientY);
|
||||
} else if (editTool === EditTool.CIRCLE) {
|
||||
// handle circle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function moveEvent(e: MouseEvent) {
|
||||
if (mouseDown) {
|
||||
if (tool == Tool.HAND || e.buttons == 4) {
|
||||
@@ -116,12 +112,10 @@ export default function TileGrid() {
|
||||
dy = Math.max(dy, -gridSize.height * zoom + height);
|
||||
setPosition({ x: dx, y: dy });
|
||||
setLastPosition({ x: e.clientX, y: e.clientY });
|
||||
} else if (tool === Tool.EDIT) {
|
||||
if (editTool === EditTool.SQUARE) {
|
||||
} else if (tool === Tool.EDIT && editTool === EditTool.SQUARE) {
|
||||
drawSquare(e.buttons, e.clientX, e.clientY);
|
||||
} else if (editTool === EditTool.CIRCLE) {
|
||||
} else if (tool === Tool.EDIT && editTool === EditTool.CIRCLE) {
|
||||
// handle circle
|
||||
}
|
||||
} else if (tool === Tool.TOKEN) {
|
||||
// handle token
|
||||
}
|
||||
@@ -141,11 +135,15 @@ export default function TileGrid() {
|
||||
}
|
||||
newZoom = Math.min(newZoom, 3);
|
||||
newZoom = Math.max(newZoom, 0.6);
|
||||
console.log(newZoom);
|
||||
setZoom(newZoom);
|
||||
// Adjust position to zoom in on mouse position
|
||||
const dx = (position.x - clientX) * (newZoom / zoom) + clientX;
|
||||
const dy = (position.y - clientY) * (newZoom / zoom) + clientY;
|
||||
let dx = (position.x - clientX) * (newZoom / zoom) + clientX;
|
||||
let dy = (position.y - clientY) * (newZoom / zoom) + clientY;
|
||||
// Prevent coordinates from going out of bounds
|
||||
dx = Math.min(dx, 0);
|
||||
dx = Math.max(dx, -gridSize.width * newZoom + width);
|
||||
dy = Math.min(dy, 0);
|
||||
dy = Math.max(dy, -gridSize.height * newZoom + height);
|
||||
setPosition({ x: dx, y: dy });
|
||||
}
|
||||
|
||||
@@ -158,13 +156,13 @@ export default function TileGrid() {
|
||||
backgroundColor: 0x333333,
|
||||
antialias: false
|
||||
}}
|
||||
onMouseDown={(e) => clickEvent(e)}
|
||||
onMouseUp={() => setMouseDown(false)}
|
||||
onMouseDown={(e) => clickEvent(e, true)}
|
||||
onMouseUp={(e) => clickEvent(e, false)}
|
||||
onMouseMove={(e) => moveEvent(e)}
|
||||
onWheel={(e) => zoomEvent(e)}
|
||||
>
|
||||
<Graphics x={position.x} y={position.y} draw={drawGrid} />
|
||||
<Graphics x={position.x} y={position.y} draw={drawEdits} />
|
||||
<Graphics x={position.x} y={position.y} draw={drawGridEdits} />
|
||||
</Stage>
|
||||
<TileControls
|
||||
tool={tool}
|
||||
|
||||
@@ -5,8 +5,3 @@ export const userState = atom({
|
||||
key: 'userState',
|
||||
default: undefined as User | undefined
|
||||
});
|
||||
|
||||
export const isAuthenticatedState = atom({
|
||||
key: 'isAuthenticatedState',
|
||||
default: false
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user