added authorized context
This commit is contained in:
@@ -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: '/',
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
10
client/src/utils/AuthProvider.tsx
Normal file
10
client/src/utils/AuthProvider.tsx
Normal 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: () => {},
|
||||
});
|
||||
@@ -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 ? (
|
||||
|
||||
Reference in New Issue
Block a user