chore: upload parte 1 - logica
DevSecOps Enterprise Pipeline / security-gate-and-deploy (push) Failing after 41s

This commit is contained in:
2026-06-01 15:35:53 +01:00
parent a63625d228
commit 9c14a19a87
127 changed files with 22255 additions and 0 deletions
+152
View File
@@ -0,0 +1,152 @@
"use client";
import React, { createContext, useContext, useEffect, useState, useCallback } from "react";
import { useRouter, usePathname } from "next/navigation";
export interface UserPermissions {
sections: string[];
can_view_financial: boolean;
can_edit: boolean;
can_create: boolean;
can_delete: boolean;
can_download: boolean;
}
export interface User {
id: number;
email: string;
name: string;
role: "admin" | "user";
permissions: UserPermissions;
}
interface AuthContextType {
user: User | null;
loading: boolean;
logout: () => Promise<void>;
refreshSession: () => Promise<void>;
hasPermission: (permission: keyof Omit<UserPermissions, "sections">) => boolean;
canAccessSection: (section: string) => boolean;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
const PUBLIC_PATHS = ["/login"];
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const router = useRouter();
const pathname = usePathname();
const refreshSession = useCallback(async () => {
try {
console.log("[v0] Refreshing session...");
const res = await fetch("/api/auth/session", {
credentials: "include",
});
if (res.ok) {
const data = await res.json();
console.log("[v0] Session data:", data);
setUser(data.user);
} else {
console.log("[v0] Session fetch failed:", res.status);
setUser(null);
}
} catch (err) {
console.log("[v0] Session error:", err);
setUser(null);
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
refreshSession();
}, [refreshSession]);
useEffect(() => {
if (!loading) {
const isPublicPath = PUBLIC_PATHS.includes(pathname);
if (!user && !isPublicPath) {
router.push("/login");
} else if (user && isPublicPath) {
router.push("/");
}
}
}, [user, loading, pathname, router]);
const logout = useCallback(async () => {
try {
await fetch("/api/auth/logout", { method: "POST" });
setUser(null);
router.push("/login");
} catch (error) {
console.error("Logout failed:", error);
}
}, [router]);
const hasPermission = useCallback(
(permission: keyof Omit<UserPermissions, "sections">) => {
if (!user) return false;
if (user.role === "admin") return true;
return user.permissions[permission] === true;
},
[user]
);
const canAccessSection = useCallback(
(section: string) => {
if (!user) return false;
if (user.role === "admin") return true;
return user.permissions?.sections?.includes(section) || false;
},
[user]
);
// Show nothing while checking auth on protected routes
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center bg-background">
<div className="flex flex-col items-center gap-4">
<div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
<p className="text-sm text-muted-foreground">Loading...</p>
</div>
</div>
);
}
// Allow public paths without auth
if (!user && PUBLIC_PATHS.includes(pathname)) {
return <>{children}</>;
}
// Block protected routes if not authenticated
if (!user) {
return null;
}
return (
<AuthContext.Provider
value={{
user,
loading,
logout,
refreshSession,
hasPermission,
canAccessSection,
}}
>
{children}
</AuthContext.Provider>
);
}
export function useAuth() {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Error("useAuth must be used within an AuthProvider");
}
return context;
}