Skip to content

Commit

Permalink
🔥 wip: add namespace support
Browse files Browse the repository at this point in the history
[skip ci]
  • Loading branch information
zcubbs committed Oct 24, 2023
1 parent 57562ff commit c2a3a55
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 249 deletions.
1 change: 1 addition & 0 deletions cmd/server/api/rpc_logout_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func (s *Server) LogoutUser(ctx context.Context, req *pb.LogoutUserRequest) (*pb
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
}

log.Info("logout user", "user", u.ID, "session", req.SessionId)
sessionId, err := uuid.Parse(req.SessionId)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid session id")
Expand Down
18 changes: 14 additions & 4 deletions cmd/server/docs/swagger/tlz.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,12 @@
},
"parameters": [
{
"name": "sessionId",
"in": "query",
"required": false,
"type": "string"
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/pbLogoutUserRequest"
}
}
],
"tags": [
Expand Down Expand Up @@ -529,6 +531,14 @@
}
}
},
"pbLogoutUserRequest": {
"type": "object",
"properties": {
"sessionId": {
"type": "string"
}
}
},
"pbNamespace": {
"type": "object",
"properties": {
Expand Down
3 changes: 0 additions & 3 deletions cmd/server/web/src/components/require-auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ const RequireAuth = ({ allowedRoles }: RequireAuthProps): ReactElement | null =>
const { auth } = useAuth();
const location = useLocation();

console.log("RequireAuth: auth", auth);
console.log("RequireAuth: allowedRoles", allowedRoles);

// If the user is not authenticated, redirect to login
if (!auth?.user) {
return <Navigate to="/login" state={{ from: location }} replace />;
Expand Down
43 changes: 25 additions & 18 deletions cmd/server/web/src/components/ui/user-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
DropdownMenuTrigger,
} from "./dropdown-menu";
import {useContext} from "react";
import AuthContext from "@/context/auth-provider.tsx";
import AuthContext, {Auth} from "@/context/auth-provider.tsx";
import {useNavigate} from "react-router-dom";
import axios from "@/api/axios.ts";

Expand All @@ -24,28 +24,35 @@ export function UserNav() {

const logout = async () => {
try {
axios.post('/api/v1/logout', {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('token')
const savedAuthData = localStorage.getItem('authData');
const authData: Auth = JSON.parse(savedAuthData);
const accessToken = authData ? authData.access_token : '';

const response = await axios.post('/api/v1/logout_user',
{
session_id: authData?.session_id
},
}).then((response) => {
if (response.status >= 200 && response.status < 300) {
// Clearing the authentication context
if (setAuth) {
setAuth(undefined);
{
headers: {
Authorization: `Bearer ${accessToken}`, // Authorization header
}
} else {
console.error(response)
}
});
});

if (response.status === 200) {
// Clearing auth data from localStorage and context
localStorage.removeItem('authData');

navigate('/');
// Redirect to the login page or another page as per your application flow
location.href = '/login';
} else {
// Handle unsuccessful logout attempt
localStorage.removeItem('authData');
console.error('Logout failed:', response);
}
} catch (error) {
// TODO: Handle error, e.g., show a notification to the user
console.error("An error occurred during logout:", error);
console.error('An error occurred during logout:', error);
}
};
}

return (
<DropdownMenu>
Expand Down
13 changes: 9 additions & 4 deletions cmd/server/web/src/context/auth-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import {createContext, Dispatch, PropsWithChildren, SetStateAction, useMemo, use

interface AuthContextProps {
auth?: Auth;
setAuth?: Dispatch<SetStateAction<Auth | undefined>>;
setAuth?: Dispatch<SetStateAction<Auth>>;
}

const AuthContext = createContext<AuthContextProps>({});

type User = {
export type User = {
id: string;
username: string;
full_name: string;
Expand All @@ -16,16 +16,21 @@ type User = {
created_at: string;
}

type Auth = {
export type Auth = {
user: User;
session_id: string;
access_token: string;
refresh_token: string;
access_token_expires_at: string;
refresh_token_expires_at: string;
}

export const AuthProvider = ({ children }: PropsWithChildren<{}>) => {
const [auth, setAuth] = useState<Auth>();
// Loading auth data from localStorage
const savedAuthData = localStorage.getItem('authData');
const initialAuth: Auth = savedAuthData ? JSON.parse(savedAuthData) : undefined;

const [auth, setAuth] = useState<Auth>(initialAuth);

const value = useMemo(() => ({ auth, setAuth }), [auth, setAuth]);

Expand Down
2 changes: 0 additions & 2 deletions cmd/server/web/src/hooks/use-refresh-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ const useRefreshToken = () => {
});
if (setAuth) {
setAuth((prev: any) => {
console.log(JSON.stringify(prev));
console.log(response.data.accessToken);
return {...prev, accessToken: response.data.accessToken}
});
}
Expand Down
35 changes: 30 additions & 5 deletions cmd/server/web/src/pages/login/components/user-login-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import {Button} from "@/components/ui/button"
import {Input} from "@/components/ui/input"
import {Label} from "@/components/ui/label"
import {Icons} from "@/components/ui/icons.tsx";
import {SyntheticEvent, useState} from "react";
import {SyntheticEvent, useEffect, useState} from "react";
import {useLocation, useNavigate} from "react-router-dom";
import useAuth from "@/hooks/use-auth.ts";
import {Auth} from "@/context/auth-provider.tsx";

interface UserLoginFormProps extends React.HTMLAttributes<HTMLDivElement> {
}
Expand All @@ -21,7 +22,7 @@ export function UserLoginForm({className, ...props}: UserLoginFormProps) {
const [username, setUsername] = useState<string>("")
const [password, setPassword] = useState<string>("")

const {setAuth} = useAuth();
const {auth, setAuth} = useAuth();

const onSubmit = async (event: SyntheticEvent) => {
event.preventDefault()
Expand Down Expand Up @@ -51,20 +52,44 @@ export function UserLoginForm({className, ...props}: UserLoginFormProps) {

if (response.ok) {
response.json().then((data) => {
let auth: Auth = {
user: {
id: data?.user?.id,
username: data?.user?.username,
full_name: data?.user?.full_name,
role: data?.user?.role,
password_changed_at: data?.user?.password_changed_at,
created_at: data?.user?.created_at,
},
session_id: data?.session_id,
access_token: data?.access_token,
refresh_token: data?.refresh_token,
access_token_expires_at: data?.access_token_expires_at,
refresh_token_expires_at: data?.refresh_token_expires_at,
}

// Setting the authentication context
if (setAuth) {
setAuth(data)
setAuth(auth);
localStorage.setItem('authData', JSON.stringify(auth));
}
});
navigate(from, { replace: true });
}

}).catch((error) => {
console.error(error)
}).finally(() => {
setIsLoading(false)
})

setIsLoading(false)
}

useEffect(() => {
if (auth?.user) {
navigate(from, { replace: true });
}
});

return (
<div className={cn("grid gap-6", className)} {...props}>
<div className="flex flex-col space-y-2 text-center">
Expand Down
Loading

0 comments on commit c2a3a55

Please sign in to comment.