Added user system with database features. This is fairly experimental and does not include dockerfile to automatically generate a mongodb. This should be in future commits along with ability to save hosts branching off this database feature.

This commit is contained in:
Karmaa
2025-03-10 23:59:06 -05:00
parent 54f03d73ce
commit 4e277bdd07
13 changed files with 1057 additions and 26 deletions

129
src/User.jsx Normal file
View File

@@ -0,0 +1,129 @@
import { useRef, forwardRef, useImperativeHandle } from "react";
import io from "socket.io-client";
import PropTypes from "prop-types";
let socket;
if (!socket) {
socket = io(
window.location.hostname === "localhost"
? "http://localhost:8082"
: "/",
{
path: "/socket.io",
transports: ["websocket", "polling"],
}
);
}
export const User = forwardRef(({ onLoginSuccess, onCreateSuccess, onDeleteSuccess, onFailure }, ref) => {
const socketRef = useRef(socket);
const currentUser = useRef(null);
const createUser = (userConfig) => {
if (socketRef.current) {
socketRef.current.emit("createUser", {
username: userConfig.username,
password: userConfig.password,
});
socketRef.current.once("userCreated", (data) => {
console.log("User created", data);
currentUser.current = {
id: data.user._id,
username: data.user.username,
sessionToken: data.user.sessionToken,
};
localStorage.setItem('sessionToken', data.user.sessionToken);
onCreateSuccess(data);
});
socketRef.current.once("error", (error) => {
console.error(error);
const errorMsg = (error && typeof error === 'object' && error !== null)
? error.error || error.message || 'An error occurred'
: String(error);
onFailure(errorMsg);
});
}
};
const loginUser = (userConfig) => {
if (socketRef.current) {
setTimeout(() => {
socketRef.current.emit("loginUser", {
username: userConfig.username,
password: userConfig.password,
sessionToken: userConfig.sessionToken,
});
socketRef.current.once("userFound", (data) => {
console.log("User found", data);
currentUser.current = {
id: data._id,
username: data.username,
sessionToken: data.sessionToken,
};
localStorage.setItem('sessionToken', data.sessionToken);
onLoginSuccess(data);
});
socketRef.current.once("error", (error) => {
console.error(error);
const errorMsg = (error && typeof error === 'object' && error !== null)
? error.error || error.message || 'An error occurred'
: String(error);
onFailure(errorMsg);
});
}, 500);
}
};
const logoutUser = () => {
localStorage.removeItem('sessionToken');
currentUser.current = null;
};
const deleteUser = () => {
if (currentUser.current?.id && socketRef.current) {
socketRef.current.emit("deleteUser", {
userId: currentUser.current.id,
});
socketRef.current.once("userDeleted", (data) => {
console.log("User deleted", data);
onDeleteSuccess(data);
currentUser.current = null;
localStorage.removeItem('sessionToken');
});
socketRef.current.once("error", (error) => {
console.error(error);
const errorMsg = (error && typeof error === 'object' && error !== null)
? error.error || error.message || 'An error occurred'
: String(error);
onFailure(errorMsg);
});
} else {
onFailure("No user is currently logged in.");
}
};
useImperativeHandle(ref, () => ({
createUser,
loginUser,
logoutUser,
deleteUser,
}));
return <div></div>;
});
User.displayName = "User";
User.propTypes = {
onLoginSuccess: PropTypes.func.isRequired,
onCreateSuccess: PropTypes.func.isRequired,
onDeleteSuccess: PropTypes.func.isRequired,
onFailure: PropTypes.func.isRequired,
};