Files
ClickerZ/Frontend/src/context/AuthContext.jsx
Tetardtek 91d1616dd7
Some checks failed
CI/CD — Build & Deploy / Build & Deploy (push) Failing after 25s
feat: PKCE auth + CI/CD deploy
- Frontend: PKCE flow (oauth.js, api.js centralized, cookie-based AuthContext)
- Backend: token introspection, cookies httpOnly, refresh endpoint
- Replaced localStorage JWT with httpOnly session cookies
- useSaveSync migrated to cookie auth
- cookie-parser added
- Gitea CI workflow (vps-runner pattern)
2026-03-24 13:01:15 +01:00

80 lines
1.8 KiB
JavaScript
Executable File

import React, { createContext, useContext, useState, useMemo, useEffect } from "react";
import PropTypes from "prop-types";
import { apiFetch } from "../lib/api";
const AuthContext = createContext();
const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const refresh = async () => {
try {
const data = await apiFetch("/auth/me");
setUser(data);
} catch {
setUser(null);
}
};
useEffect(() => {
refresh().finally(() => setLoading(false));
}, []);
useEffect(() => {
const onExpired = () => setUser(null);
window.addEventListener("auth:expired", onExpired);
return () => window.removeEventListener("auth:expired", onExpired);
}, []);
const logout = async () => {
try {
await apiFetch("/auth/logout", { method: "POST" });
} catch {
// ignore
}
setUser(null);
};
const editUser = async (updatedFields) => {
const data = await apiFetch(`/users/${user.id}`, {
method: "PUT",
body: JSON.stringify(updatedFields),
});
setUser((prev) => ({ ...prev, ...data.user }));
return "User updated successfully";
};
const authContextValue = useMemo(
() => ({
user,
loading,
logout,
refresh,
editUser,
setUser: (newUser) => setUser(newUser),
}),
[user, loading]
);
return (
<AuthContext.Provider value={authContextValue}>
{children}
</AuthContext.Provider>
);
};
AuthProvider.propTypes = {
children: PropTypes.node.isRequired,
};
const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error("useAuth must be used within an AuthProvider");
}
return context;
};
export { AuthProvider, useAuth };