fix csrf token hardset, remove cookie from localstorage
This commit is contained in:
@@ -7,11 +7,9 @@ import * as api from '../api';
|
||||
import type { Collection } from '../types';
|
||||
import { Shield, UserPlus, RefreshCw, UserCog, LogIn, XCircle, Settings as SettingsIcon, KeyRound } from 'lucide-react';
|
||||
import {
|
||||
ACCESS_TOKEN_KEY,
|
||||
IMPERSONATION_KEY,
|
||||
type ImpersonationState,
|
||||
readImpersonationState,
|
||||
REFRESH_TOKEN_KEY,
|
||||
stopImpersonation as restoreImpersonation,
|
||||
USER_KEY,
|
||||
} from '../utils/impersonation';
|
||||
@@ -290,11 +288,9 @@ export const Admin: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const originalAccessToken = localStorage.getItem(ACCESS_TOKEN_KEY);
|
||||
const originalRefreshToken = localStorage.getItem(REFRESH_TOKEN_KEY);
|
||||
const originalUser = localStorage.getItem(USER_KEY);
|
||||
if (!originalAccessToken || !originalRefreshToken || !originalUser) {
|
||||
setError('Missing current session tokens.');
|
||||
if (!originalUser) {
|
||||
setError('Missing current session user state.');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -307,8 +303,6 @@ export const Admin: React.FC = () => {
|
||||
|
||||
const state: ImpersonationState = {
|
||||
original: {
|
||||
accessToken: originalAccessToken,
|
||||
refreshToken: originalRefreshToken,
|
||||
user: JSON.parse(originalUser),
|
||||
},
|
||||
impersonator: {
|
||||
@@ -325,8 +319,6 @@ export const Admin: React.FC = () => {
|
||||
};
|
||||
|
||||
localStorage.setItem(IMPERSONATION_KEY, JSON.stringify(state));
|
||||
localStorage.setItem(ACCESS_TOKEN_KEY, response.data.accessToken);
|
||||
localStorage.setItem(REFRESH_TOKEN_KEY, response.data.refreshToken);
|
||||
localStorage.setItem(USER_KEY, JSON.stringify(response.data.user));
|
||||
|
||||
window.location.href = '/';
|
||||
@@ -339,9 +331,26 @@ export const Admin: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const stopImpersonation = () => {
|
||||
if (!restoreImpersonation()) return;
|
||||
window.location.href = '/admin';
|
||||
const stopImpersonation = async () => {
|
||||
if (!readImpersonationState()) return;
|
||||
|
||||
try {
|
||||
const response = await api.api.post<{
|
||||
user?: { id: string; email: string; name: string };
|
||||
}>('/auth/stop-impersonation');
|
||||
|
||||
restoreImpersonation();
|
||||
if (response.data?.user) {
|
||||
localStorage.setItem(USER_KEY, JSON.stringify(response.data.user));
|
||||
}
|
||||
window.location.href = '/admin';
|
||||
} catch (err: unknown) {
|
||||
let message = 'Failed to stop impersonation';
|
||||
if (api.isAxiosError(err)) {
|
||||
message = err.response?.data?.message || err.response?.data?.error || message;
|
||||
}
|
||||
setError(message);
|
||||
}
|
||||
};
|
||||
|
||||
if (authEnabled === null) {
|
||||
|
||||
@@ -962,7 +962,7 @@ export const Dashboard: React.FC = () => {
|
||||
) : (
|
||||
<div
|
||||
className={clsx("grid gap-3 sm:gap-4 pb-16 sm:pb-24 transition-all duration-300", isDraggingFile && "opacity-20 blur-sm")}
|
||||
style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))' }}
|
||||
style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(320px, 1fr))' }}
|
||||
>
|
||||
{sortedDrawings.length === 0 ? (
|
||||
<div className="col-span-full flex flex-col items-center justify-center py-16 sm:py-32 text-slate-400 dark:text-neutral-500 border-2 border-dashed border-slate-200 dark:border-neutral-700 rounded-3xl bg-slate-50/50 dark:bg-neutral-800/50">
|
||||
|
||||
@@ -257,11 +257,10 @@ export const Editor: React.FC = () => {
|
||||
? window.location.origin
|
||||
: (import.meta.env.VITE_API_URL || 'http://localhost:8000');
|
||||
|
||||
const authToken = localStorage.getItem('excalidash-access-token');
|
||||
const socket = io(socketUrl, {
|
||||
path: '/socket.io',
|
||||
transports: ['websocket', 'polling'],
|
||||
auth: authToken ? { token: authToken } : {},
|
||||
withCredentials: true,
|
||||
});
|
||||
socketRef.current = socket;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useNavigate, Link, useSearchParams } from 'react-router-dom';
|
||||
import { useAuth } from '../context/AuthContext';
|
||||
import { Logo } from '../components/Logo';
|
||||
import * as api from '../api';
|
||||
import { ACCESS_TOKEN_KEY, REFRESH_TOKEN_KEY, USER_KEY } from '../utils/impersonation';
|
||||
import { USER_KEY } from '../utils/impersonation';
|
||||
|
||||
export const Login: React.FC = () => {
|
||||
const [email, setEmail] = useState('');
|
||||
@@ -81,8 +81,6 @@ export const Login: React.FC = () => {
|
||||
refreshToken: string;
|
||||
}>('/auth/must-reset-password', { newPassword });
|
||||
|
||||
localStorage.setItem(ACCESS_TOKEN_KEY, response.data.accessToken);
|
||||
localStorage.setItem(REFRESH_TOKEN_KEY, response.data.refreshToken);
|
||||
localStorage.setItem(USER_KEY, JSON.stringify(response.data.user));
|
||||
|
||||
window.location.href = '/';
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useAuth } from '../context/AuthContext';
|
||||
import * as api from '../api';
|
||||
import type { Collection } from '../types';
|
||||
import { User, Lock, Save, X, Shield } from 'lucide-react';
|
||||
import { ACCESS_TOKEN_KEY, REFRESH_TOKEN_KEY, USER_KEY } from '../utils/impersonation';
|
||||
import { USER_KEY } from '../utils/impersonation';
|
||||
|
||||
export const Profile: React.FC = () => {
|
||||
const { user: authUser, logout, authEnabled } = useAuth();
|
||||
@@ -234,8 +234,6 @@ export const Profile: React.FC = () => {
|
||||
currentPassword: emailCurrentPassword,
|
||||
});
|
||||
|
||||
localStorage.setItem(ACCESS_TOKEN_KEY, response.data.accessToken);
|
||||
localStorage.setItem(REFRESH_TOKEN_KEY, response.data.refreshToken);
|
||||
localStorage.setItem(USER_KEY, JSON.stringify(response.data.user));
|
||||
|
||||
setSuccess('Email updated successfully');
|
||||
|
||||
Reference in New Issue
Block a user