({ mutationFn: deleteDashboard, handleSuccess });
-
const handleDeleteClick = () => {
const handleDelete = async () => {
if (!id) return;
@@ -74,6 +68,11 @@ export default function DashboardEdit() {
useEffect(() => {
const handleInitialLoad = async () => {
+ try {
+ setIsPublic(await checkPublic(Number(id)));
+ } catch {
+ redirectIfNoPermission(-1);
+ }
setIsPublic(await checkPublic(Number(id)));
setIsFavorite(await checkFavorite(Number(user?.id), Number(id)));
};
@@ -81,6 +80,14 @@ export default function DashboardEdit() {
handleInitialLoad();
}, [id]);
+ useEffect(() => {
+ if (dashboard) {
+ redirectIfNoPermission(dashboard.userId);
+ } else if (error) {
+ redirectIfNoPermission(-1);
+ }
+ }, [dashboard, error]);
+
return (
{
+const useRedirectIfAuth = () => {
const { user } = useSelector((state: RootState) => state.user);
- const router = useRouter();
const { openNotificationModal } = useModal();
- const [isRedirecting, setIsRedirecting] = useState(true);
+ const router = useRouter();
+ const [isRedirecting, setIsRedirecting] = useState(false);
const [initialCheck, setInitialCheck] = useState(true);
- useEffect(() => {
+ return () => {
if (initialCheck) {
if (user) {
openNotificationModal({ text: '이미 로그인하셨습니다.' });
@@ -22,9 +22,9 @@ const useRedirectIfAuthenticated = () => {
setIsRedirecting(false);
setInitialCheck(false);
}
- }, [user, initialCheck]);
- return isRedirecting;
+ return isRedirecting;
+ };
};
-export default useRedirectIfAuthenticated;
+export default useRedirectIfAuth;
diff --git a/src/hooks/useRedirectIfNoPermission.ts b/src/hooks/useRedirectIfNoPermission.ts
new file mode 100644
index 00000000..d7df9879
--- /dev/null
+++ b/src/hooks/useRedirectIfNoPermission.ts
@@ -0,0 +1,33 @@
+import { useRouter } from 'next/router';
+import { useState } from 'react';
+import { useSelector } from 'react-redux';
+
+import useModal from '@/hooks/useModal';
+import { RootState } from '@/store/store';
+
+const useRedirectIfNoPermission = () => {
+ const { user } = useSelector((state: RootState) => state.user);
+ const { openNotificationModal } = useModal();
+ const router = useRouter();
+ const [isRedirecting, setIsRedirecting] = useState(false);
+ const [initialCheck, setInitialCheck] = useState(true);
+
+ return (creatorId: number) => {
+ if (initialCheck) {
+ if (creatorId !== user?.id) {
+ openNotificationModal({ text: '접근 권한이 없습니다.' });
+ setIsRedirecting(true);
+ if (user) {
+ router.replace('/mydashboard');
+ } else {
+ router.replace('/signin');
+ }
+ }
+ setIsRedirecting(false);
+ setInitialCheck(false);
+ }
+ return isRedirecting;
+ };
+};
+
+export default useRedirectIfNoPermission;
diff --git a/src/hooks/useRedirectIfNotAuth.ts b/src/hooks/useRedirectIfNotAuth.ts
index a13b00f8..bef73e1e 100644
--- a/src/hooks/useRedirectIfNotAuth.ts
+++ b/src/hooks/useRedirectIfNotAuth.ts
@@ -1,5 +1,5 @@
import { useRouter } from 'next/router';
-import { useEffect, useState } from 'react';
+import { useState } from 'react';
import { useSelector } from 'react-redux';
import useModal from '@/hooks/useModal';
@@ -7,12 +7,12 @@ import { RootState } from '@/store/store';
const useRedirectIfNotAuth = () => {
const { user } = useSelector((state: RootState) => state.user);
- const router = useRouter();
const { openNotificationModal } = useModal();
- const [isRedirecting, setIsRedirecting] = useState(true);
+ const router = useRouter();
+ const [isRedirecting, setIsRedirecting] = useState(false);
const [initialCheck, setInitialCheck] = useState(true);
- useEffect(() => {
+ return () => {
if (initialCheck) {
if (!user) {
openNotificationModal({ text: '로그인이 필요합니다.' });
@@ -22,9 +22,9 @@ const useRedirectIfNotAuth = () => {
setIsRedirecting(false);
setInitialCheck(false);
}
- }, [user, initialCheck]);
- return isRedirecting;
+ return isRedirecting;
+ };
};
export default useRedirectIfNotAuth;
diff --git a/src/hooks/useRedirectIfNotMember.ts b/src/hooks/useRedirectIfNotMember.ts
new file mode 100644
index 00000000..5d7da60c
--- /dev/null
+++ b/src/hooks/useRedirectIfNotMember.ts
@@ -0,0 +1,30 @@
+import { useRouter } from 'next/router';
+import { useState } from 'react';
+import { useSelector } from 'react-redux';
+
+import useModal from '@/hooks/useModal';
+import { RootState } from '@/store/store';
+
+const useRedirectIfNotMember = () => {
+ const { user } = useSelector((state: RootState) => state.user);
+ const { openNotificationModal } = useModal();
+ const router = useRouter();
+ const [isRedirecting, setIsRedirecting] = useState(false);
+ const [initialCheck, setInitialCheck] = useState(true);
+
+ return () => {
+ if (initialCheck) {
+ openNotificationModal({ text: '접근 권한이 없습니다.' });
+ setIsRedirecting(true);
+ if (user) {
+ router.replace('/mydashboard');
+ } else {
+ router.replace('/signin');
+ }
+ setInitialCheck(false);
+ }
+ return isRedirecting;
+ };
+};
+
+export default useRedirectIfNotMember;
diff --git a/src/pages/dashboard/[id]/index.tsx b/src/pages/dashboard/[id]/index.tsx
index 75b845e9..b54b101a 100644
--- a/src/pages/dashboard/[id]/index.tsx
+++ b/src/pages/dashboard/[id]/index.tsx
@@ -1,4 +1,3 @@
-import Head from 'next/head';
import { useRouter } from 'next/router';
import ColumnsSection from '@/containers/dashboard/ColumnsSection';
diff --git a/src/services/axios.ts b/src/services/axios.ts
index 98c6fa0b..020394a4 100644
--- a/src/services/axios.ts
+++ b/src/services/axios.ts
@@ -1,4 +1,4 @@
-import axios, { AxiosError } from 'axios';
+import axios, { AxiosError, InternalAxiosRequestConfig } from 'axios';
import { store } from '@/store/store';
@@ -20,7 +20,17 @@ instance.interceptors.response.use(
(res) => res,
async (error: AxiosError) => {
const originalRequest = error.config;
- if (originalRequest && !originalRequest.headers._retry) {
+ const checkMethodForPublic = (request: InternalAxiosRequestConfig) =>
+ (request.method === 'get' &&
+ !request.headers.memberTest &&
+ (request.url?.includes('/dashboards/') ||
+ request.url?.includes('/columns') ||
+ request.url?.includes('/members') ||
+ request.url?.includes('/cards') ||
+ request.url?.includes('/comments'))) ||
+ (request.method === 'put' && request.url?.includes('/invitations'));
+
+ if (originalRequest && checkMethodForPublic(originalRequest) && !originalRequest.headers._retry) {
originalRequest.headers._retry = true;
originalRequest.headers.Authorization = `Bearer ${process.env.NEXT_PUBLIC_SHARE_ACCOUNT_TOKEN}`;
return instance(originalRequest);
diff --git a/src/types/Modal.interface.ts b/src/types/Modal.interface.ts
index c8a49a6e..16465ffe 100644
--- a/src/types/Modal.interface.ts
+++ b/src/types/Modal.interface.ts
@@ -39,6 +39,7 @@ export interface EditCardModalProps extends ModalProps {
export interface TodoCardModalProps extends ModalProps {
card: Card;
column: Column;
+ isMember: boolean;
onClick?: () => void;
}