mirror of
https://github.com/dyzulk/trustlab.git
synced 2026-01-26 05:25:36 +07:00
fix: allow owner role to access admin pages
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useMemo } from "react";
|
import React, { useState, useMemo, useEffect } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import axios from "@/lib/axios";
|
import axios from "@/lib/axios";
|
||||||
import PageBreadcrumb from "@/components/common/PageBreadCrumb";
|
import PageBreadcrumb from "@/components/common/PageBreadCrumb";
|
||||||
@@ -17,7 +18,15 @@ const fetcher = (url: string) => axios.get(url).then((res) => res.data);
|
|||||||
|
|
||||||
export default function InquiryClient() {
|
export default function InquiryClient() {
|
||||||
const t = useTranslations("Inquiries");
|
const t = useTranslations("Inquiries");
|
||||||
|
const router = useRouter();
|
||||||
|
const { user, isAdminOrOwner } = useAuth();
|
||||||
const { addToast } = useToast();
|
const { addToast } = useToast();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (user && !isAdminOrOwner) {
|
||||||
|
router.push("/dashboard");
|
||||||
|
}
|
||||||
|
}, [user, isAdminOrOwner, router]);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [statusFilter, setStatusFilter] = useState("all");
|
const [statusFilter, setStatusFilter] = useState("all");
|
||||||
const [isDeleting, setIsDeleting] = useState(false);
|
const [isDeleting, setIsDeleting] = useState(false);
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import axios from "@/lib/axios";
|
|||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { Save, ArrowLeft, Eye, Edit3 } from "lucide-react";
|
import { Save, ArrowLeft, Eye, Edit3 } from "lucide-react";
|
||||||
import { useToast } from "@/context/ToastContext";
|
import { useToast } from "@/context/ToastContext";
|
||||||
|
import { useAuth } from "@/hooks/useAuth";
|
||||||
|
import PageLoader from "@/components/ui/PageLoader";
|
||||||
import PageBreadcrumb from "@/components/common/PageBreadCrumb";
|
import PageBreadcrumb from "@/components/common/PageBreadCrumb";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import ComponentCard from "@/components/common/ComponentCard";
|
import ComponentCard from "@/components/common/ComponentCard";
|
||||||
@@ -12,18 +14,25 @@ import ReactMarkdown from 'react-markdown';
|
|||||||
import remarkGfm from 'remark-gfm';
|
import remarkGfm from 'remark-gfm';
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
interface EditorProps {
|
interface AdminLegalEditorClientProps {
|
||||||
mode: "create" | "edit";
|
mode: "create" | "edit";
|
||||||
initialData?: any;
|
initialData?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AdminLegalEditorClient({ mode, initialData }: EditorProps) {
|
export default function AdminLegalEditorClient({ mode, initialData }: AdminLegalEditorClientProps) {
|
||||||
const t = useTranslations("LegalAdmin");
|
const t = useTranslations("LegalAdmin");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { user, isAdminOrOwner } = useAuth();
|
||||||
const { addToast } = useToast();
|
const { addToast } = useToast();
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const [activeTab, setActiveTab] = useState<'write' | 'preview'>('write');
|
const [activeTab, setActiveTab] = useState<'write' | 'preview'>('write');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (user && !isAdminOrOwner) {
|
||||||
|
router.push("/dashboard");
|
||||||
|
}
|
||||||
|
}, [user, isAdminOrOwner, router]);
|
||||||
|
|
||||||
// Load history if edit mode
|
// Load history if edit mode
|
||||||
const [versionHistory, setVersionHistory] = useState<any[]>([]);
|
const [versionHistory, setVersionHistory] = useState<any[]>([]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useAuth } from "@/hooks/useAuth";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import axios from "@/lib/axios";
|
import axios from "@/lib/axios";
|
||||||
import { Plus, Search, FileText, ChevronRight, Edit3, Trash2 } from "lucide-react";
|
import { Plus, Search, FileText, ChevronRight, Edit3, Trash2 } from "lucide-react";
|
||||||
@@ -15,7 +17,16 @@ const fetcher = (url: string) => axios.get(url).then((res) => res.data);
|
|||||||
|
|
||||||
export default function AdminLegalListClient() {
|
export default function AdminLegalListClient() {
|
||||||
const t = useTranslations("LegalAdmin");
|
const t = useTranslations("LegalAdmin");
|
||||||
|
const router = useRouter();
|
||||||
|
const { user, isAdminOrOwner } = useAuth();
|
||||||
const { addToast } = useToast();
|
const { addToast } = useToast();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (user && !isAdminOrOwner) {
|
||||||
|
router.push("/dashboard");
|
||||||
|
}
|
||||||
|
}, [user, isAdminOrOwner, router]);
|
||||||
|
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const { data, mutate, isLoading } = useSWR("/api/admin/legal-pages", fetcher);
|
const { data, mutate, isLoading } = useSWR("/api/admin/legal-pages", fetcher);
|
||||||
|
|
||||||
|
|||||||
@@ -24,12 +24,13 @@ export default function RootCaManagementClient() {
|
|||||||
const [isRenewing, setIsRenewing] = useState(false);
|
const [isRenewing, setIsRenewing] = useState(false);
|
||||||
const [confirmRenewUuid, setConfirmRenewUuid] = useState<string | null>(null);
|
const [confirmRenewUuid, setConfirmRenewUuid] = useState<string | null>(null);
|
||||||
|
|
||||||
// Redirect if not admin (double security, backend also checks)
|
// Redirect if not admin or owner (double security, backend also checks)
|
||||||
|
const { isAdminOrOwner } = useAuth();
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (user && user.role !== "admin") {
|
if (user && !isAdminOrOwner) {
|
||||||
router.push("/dashboard");
|
router.push("/dashboard");
|
||||||
}
|
}
|
||||||
}, [user, router]);
|
}, [user, isAdminOrOwner, router]);
|
||||||
|
|
||||||
const handleRenew = async (uuid: string) => {
|
const handleRenew = async (uuid: string) => {
|
||||||
setIsRenewing(true);
|
setIsRenewing(true);
|
||||||
|
|||||||
@@ -34,13 +34,14 @@ export default function SmtpTesterPage() {
|
|||||||
const [testEmail, setTestEmail] = useState('');
|
const [testEmail, setTestEmail] = useState('');
|
||||||
const [results, setResults] = useState<{ [key: string]: { success: boolean; message: string } }>({});
|
const [results, setResults] = useState<{ [key: string]: { success: boolean; message: string } }>({});
|
||||||
|
|
||||||
|
const { isAdminOrOwner } = useAuth();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user && user.role !== 'admin') {
|
if (user && !isAdminOrOwner) {
|
||||||
router.push('/dashboard/settings');
|
router.push('/dashboard/settings');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fetchConfigs();
|
fetchConfigs();
|
||||||
}, [user, router]);
|
}, [user, isAdminOrOwner, router]);
|
||||||
|
|
||||||
const fetchConfigs = async () => {
|
const fetchConfigs = async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -31,10 +31,17 @@ const priorityColors: any = {
|
|||||||
|
|
||||||
export default function AdminTicketDetailsClient() {
|
export default function AdminTicketDetailsClient() {
|
||||||
const t = useTranslations("Tickets");
|
const t = useTranslations("Tickets");
|
||||||
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const ticketId = searchParams.get("id");
|
const ticketId = searchParams.get("id");
|
||||||
const { user } = useAuth();
|
const { user, isAdminOrOwner } = useAuth();
|
||||||
const { addToast } = useToast();
|
const { addToast } = useToast();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (user && !isAdminOrOwner) {
|
||||||
|
router.push("/dashboard");
|
||||||
|
}
|
||||||
|
}, [user, isAdminOrOwner, router]);
|
||||||
const [replyMessage, setReplyMessage] = useState("");
|
const [replyMessage, setReplyMessage] = useState("");
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const [isCloseModalOpen, setIsCloseModalOpen] = useState(false);
|
const [isCloseModalOpen, setIsCloseModalOpen] = useState(false);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useAuth } from "@/hooks/useAuth";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import axios from "@/lib/axios";
|
import axios from "@/lib/axios";
|
||||||
import { Search, MessageSquare, Clock, Filter, ChevronRight, User as UserIcon } from "lucide-react";
|
import { Search, MessageSquare, Clock, Filter, ChevronRight, User as UserIcon } from "lucide-react";
|
||||||
@@ -29,7 +31,16 @@ const priorityColors: any = {
|
|||||||
|
|
||||||
export default function AdminTicketListClient() {
|
export default function AdminTicketListClient() {
|
||||||
const t = useTranslations("Tickets");
|
const t = useTranslations("Tickets");
|
||||||
|
const router = useRouter();
|
||||||
|
const { user, isAdminOrOwner } = useAuth();
|
||||||
const { addToast } = useToast();
|
const { addToast } = useToast();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (user && !isAdminOrOwner) {
|
||||||
|
router.push("/dashboard");
|
||||||
|
}
|
||||||
|
}, [user, isAdminOrOwner, router]);
|
||||||
|
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [statusFilter, setStatusFilter] = useState("all");
|
const [statusFilter, setStatusFilter] = useState("all");
|
||||||
const { data, mutate, isLoading } = useSWR("/api/support/tickets?all=true", fetcher);
|
const { data, mutate, isLoading } = useSWR("/api/support/tickets?all=true", fetcher);
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ export default function UsersManagementClient() {
|
|||||||
|
|
||||||
const { data, error, mutate, isLoading } = useSWR("/api/admin/users", fetcher);
|
const { data, error, mutate, isLoading } = useSWR("/api/admin/users", fetcher);
|
||||||
|
|
||||||
const hasAdminAccess = ['admin', 'owner'].includes(currentUser?.role || '');
|
const { isAdmin, isOwner, isAdminOrOwner } = useAuth();
|
||||||
const isOwner = currentUser?.role === "owner";
|
const hasAdminAccess = isAdminOrOwner;
|
||||||
const isAdmin = currentUser?.role === "admin";
|
|
||||||
|
|
||||||
const handleDelete = async (id: string) => {
|
const handleDelete = async (id: string) => {
|
||||||
setIsDeleting(true);
|
setIsDeleting(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user