added authorized context

This commit is contained in:
slawk0
2024-10-26 23:06:32 +02:00
parent 21c93d2c18
commit cb99f174d2
6 changed files with 58 additions and 51 deletions

View File

@@ -7,9 +7,10 @@ import { useState } from 'react';
import Chat from './pages/Chat.tsx';
import Login from './pages/Login.tsx';
import Signup from './pages/Signup.tsx';
import ProtectedRoutes, { AuthContext } from './utils/ProtectedRoutes.tsx';
import Settings from './pages/Settings.tsx';
import Lost from './pages/404.tsx';
import { AuthContext } from './utils/AuthProvider.tsx';
import ProtectedRoutes from './utils/ProtectedRoutes.tsx';
const router = createBrowserRouter([
{
path: '/',

View File

@@ -1,8 +1,9 @@
import { useForm, SubmitHandler } from "react-hook-form";
import axios from "axios";
import icon from "../../assets/icon.png";
import { Link, useNavigate } from "react-router-dom";
import { useState } from "react";
import { useForm, SubmitHandler } from 'react-hook-form';
import axios from 'axios';
import icon from '../../assets/icon.png';
import { Link, useNavigate } from 'react-router-dom';
import { useContext, useState } from 'react';
import { AuthContext } from '../utils/AuthProvider.tsx';
type Inputs = {
username: string;
@@ -10,25 +11,28 @@ type Inputs = {
};
export default function Login() {
const { setAuthorized } = useContext(AuthContext);
const { register, handleSubmit } = useForm<Inputs>({
mode: "onChange",
mode: 'onChange',
});
//const [validPassword, setValidPassword] = useState(true);
const [message, setMessage] = useState("");
const [message, setMessage] = useState('');
const navigate = useNavigate();
const onSubmit: SubmitHandler<Inputs> = (data) => {
axios
.post("http://localhost:5173/api/auth/login", data, {
.post('http://localhost:5173/api/auth/login', data, {
withCredentials: true,
})
.then(() => {
navigate("/chat");
setAuthorized(true);
console.log('redirecting');
navigate('/chat');
})
.catch((err) => {
if (err.response) {
setMessage("");
setMessage('');
setTimeout(() => {
setMessage(err.response.data.message);
}, 100);
@@ -58,7 +62,7 @@ export default function Login() {
</label>
<div>
<input
{...register("username")}
{...register('username')}
id="username"
name="username"
type="username"
@@ -81,7 +85,7 @@ export default function Login() {
</div>
<div>
<input
{...register("password")}
{...register('password')}
id="password"
name="password"
type="password"
@@ -103,7 +107,7 @@ export default function Login() {
<div className="text-red-400 text-sm">{message}</div>
</form>
<p className="text-gray-300 mt-10 text-center text-sm">
Don't have account?{" "}
Don't have account?{' '}
<Link
to="/signup"
className="text-green-400 leading-6 hover:text-green-600"

View File

@@ -1,8 +1,9 @@
import icon from "../../assets/icon.png";
import { useForm, SubmitHandler } from "react-hook-form";
import { Link, useNavigate } from "react-router-dom";
import axios from "axios";
import { useState } from "react";
import icon from '../../assets/icon.png';
import { useForm, SubmitHandler } from 'react-hook-form';
import { Link, useNavigate } from 'react-router-dom';
import axios from 'axios';
import { useContext, useState } from 'react';
import { AuthContext } from '../utils/AuthProvider.tsx';
type Inputs = {
username: string;
@@ -11,17 +12,18 @@ type Inputs = {
};
export default function Signup() {
const { setAuthorized } = useContext(AuthContext);
const {
register,
handleSubmit,
formState: { errors },
} = useForm<Inputs>({
mode: "onChange",
mode: 'onChange',
});
const navigate = useNavigate();
const [match, setMatch] = useState(true);
const [message, setMessage] = useState("");
const [message, setMessage] = useState('');
const onSubmit: SubmitHandler<Inputs> = (data) => {
if (data.password !== data.sPassword) {
@@ -35,16 +37,17 @@ export default function Signup() {
setMatch(true);
data.username = data.username.toLowerCase();
axios
.post("http://localhost:5173/api/auth/signup", data, {
.post('http://localhost:5173/api/auth/signup', data, {
withCredentials: true,
})
.then(() => {
navigate("/chat");
console.log("Signed up");
setAuthorized(true);
navigate('/chat');
console.log('Signed up');
})
.catch((err) => {
if (err.response) {
setMessage("");
setMessage('');
setTimeout(() => {
setMessage(err.response.data.message);
}, 100);
@@ -74,7 +77,7 @@ export default function Signup() {
</label>
<div>
<input
{...register("username", {
{...register('username', {
maxLength: 20,
minLength: 4,
pattern: /^[A-Za-z0-9_]+$/i,
@@ -88,17 +91,17 @@ export default function Signup() {
className="pl-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
/>
<div>
{errors?.username?.type === "maxLength" && (
{errors?.username?.type === 'maxLength' && (
<p className="text-red-400 text-sm">
First name cannot exceed 20 characters
</p>
)}
{errors?.username?.type === "minLength" && (
{errors?.username?.type === 'minLength' && (
<p className="text-red-400 text-sm">
Username must be between 4 and 20 characters
</p>
)}
{errors?.username?.type === "pattern" && (
{errors?.username?.type === 'pattern' && (
<p className="text-red-400 text-sm">
Username can only contain letters, numbers and underscores
</p>
@@ -118,7 +121,7 @@ export default function Signup() {
</div>
<div>
<input
{...register("password", {
{...register('password', {
maxLength: 128,
minLength: 8,
})}
@@ -128,12 +131,12 @@ export default function Signup() {
required
className="pl-2 block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
/>
{errors?.password?.type === "maxLength" && (
{errors?.password?.type === 'maxLength' && (
<p className="text-red-400 text-sm">
Password cannot exceed 128 characters
</p>
)}
{errors?.password?.type === "minLength" && (
{errors?.password?.type === 'minLength' && (
<p className="text-red-400 text-sm">
Password must be at least 8 characters long
</p>
@@ -151,7 +154,7 @@ export default function Signup() {
</div>
<div>
<input
{...register("sPassword")}
{...register('sPassword')}
id="sPassword"
name="sPassword"
type="password"
@@ -174,7 +177,7 @@ export default function Signup() {
<div className="text-red-400 text-sm">{message}</div>
</form>
<p className="text-white mt-10 text-center text-sm">
Already have account?{" "}
Already have account?{' '}
<Link
to="/login"
className="text-green-400 leading-6 hover:text-green-600"

View File

@@ -1,16 +1,12 @@
import io from 'socket.io-client';
import Socket = SocketIOClient.Socket;
import { useContext } from 'react';
import { AuthContext } from '../utils/ProtectedRoutes.tsx';
//TODO socket is trying to connect on login page fix it
let socket: Socket | null = null;
function initializeSocket(token: string): Socket | null {
const { authorized } = useContext(AuthContext);
// Only initialize if we don't already have a socket
if (!socket && token && authorized) {
if (!socket && token) {
socket = io({
auth: {
token: token,

View File

@@ -0,0 +1,10 @@
import { createContext } from 'react';
type AuthContextType = {
authorized: boolean | null;
setAuthorized: (value: boolean) => void;
};
export const AuthContext = createContext<AuthContextType>({
authorized: null,
setAuthorized: () => {},
});

View File

@@ -1,24 +1,15 @@
// ProtectedRoutes.tsx
import { Navigate, Outlet } from 'react-router-dom';
import axios from 'axios';
import { useState, useEffect, createContext, useContext } from 'react';
import { useState, useEffect, useContext } from 'react';
import Cookie from 'js-cookie';
import { initializeSocket } from '../socket/socket.tsx';
import { AuthContext } from './AuthProvider.tsx';
export type UsernameType = {
username: string | null;
};
type AuthContextType = {
authorized: boolean | null;
setAuthorized: (value: boolean) => void;
};
export const AuthContext = createContext<AuthContextType>({
authorized: false,
setAuthorized: () => {},
});
//export const useAuth = () => useContext(AuthContext);
function ProtectedRoutes() {
@@ -44,13 +35,15 @@ function ProtectedRoutes() {
.catch((err) => {
setAuthorized(false);
console.log(err);
console.log('Unauthorized');
});
}
validateToken();
}, [setAuthorized]);
//TODO add loader
if (authorized === null) {
return <div>Loading...</div>;
return null;
}
return authorized ? (