Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[동방예약] 동방 예약 페이지 권한 검사 #185

Closed
wants to merge 10 commits into from

Conversation

chaeseungyun
Copy link
Contributor

비로그인자 혹은 권한이 없는 사람이 동방 예약을 시도하면 로그인 유도 혹은 권한 검사를 진행합니다

Please check if the PR fulfills these requirements

  • [v] The commit message follows our guidelines
  • [v] Did you merge recent main branch?

Screenshot

Precautions (main files for this PR ...)

  • Close #ISSUE_NUMBER

@@ -39,6 +40,10 @@ const initialState = {
endMinute: '00',
};

export const isAuthenticate = () => {
return gapi.auth2.getAuthInstance().currentUser.get().hasGrantedScopes('https://www.googleapis.com/auth/calendar.events');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이러면 아래 구문이 실행되기전에 모두 return되버리지 않나요?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 아래값을 return하는거네요..
개행때문에 그 전에 return하는줄 알았습니다

@@ -10,6 +10,7 @@ interface LoginState {

export const useLoginState = create<LoginState>((set) => ({
me: null,

setMe: async () => {
if (localStorage.getItem('accessToken')) {
try {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 리뷰 결과는 다음과 같습니다:

  1. 문법적 문제: 주석의 추가가 불분명합니다. 코드 변경 사항을 설명하는 주석이 필요합니다.

  2. 비동기 함수 처리: setMe 함수는 비동기 함수로, 처리 중 오류가 발생할 수 있습니다. 이 경우 에러 핸들링이 필요합니다.

    • 예를 들어, catch 블록을 추가하여 오류를 로깅하거나 사용자에게 알리는 방법을 고려해 보세요.
  3. 로컬 스토리지 접근에 대한 안전성: localStorage.getItem이 null을 반환할 경우를 대비한 처리가 필요합니다. accessToken이 존재하지 않을 때의 행동을 정의하는 것이 좋습니다.

  4. 타입 안전성: me: null로 타입이 설정되어 있지만, 추후에 me의 타입이 명확해지는 것이 유리합니다. 타입을 명시적으로 지정해주는 것이 좋습니다.

  5. 상태 업데이트: setMe 함수 내에서 상태를 업데이트하는 부분이 없어 보입니다. me 값을 업데이트하는 로직이 필요한 것 같습니다.

종합적으로, 오류 처리와 코드의 명확성을 높이는 방향으로 개선이 필요합니다. 추가 질문이 있으시면 언제든지 말씀해 주세요!

if (!isAuthenticate()) {
snackBar({ type: 'warning', message: '권한이 없습니다. 관리자에게 문의해주세요' });
return;
}
if (today
&& reserve.memberCount >= 1
) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드를 검토한 결과, 전반적으로 문제가 없지만 개선할 수 있는 몇 가지 점이 있습니다. 특히, 인증 관련 함수 isAuthenticategapi 객체에 의존하고 있어, 개발 및 테스트 환경에서 오류가 발생할 수 있습니다. 다음은 개선된 코드 블록입니다:

import { useState, useEffect } from 'react';
import { HOUR_LIST, MINUTE_LIST } from 'util/constants/time';
import { useCreateEvents } from 'page/Reservation/hook/useCreateEvent';
import { useSnackBar } from 'ts/useSnackBar';
import DetailInfomation from './DetailInfomation';
import { CalendarContent } from '../Month';

const initialState = {
  endHour: '00',
  endMinute: '00',
};

const isAuthenticate = () => {
  const gapiInstance = gapi.auth2 && gapi.auth2.getAuthInstance();
  return gapiInstance ? gapiInstance.currentUser.get().hasGrantedScopes('https://www.googleapis.com/auth/calendar.events') : false;
};

export default function MonthModal({
  date, today, data, open, handleClose, currentMonth,
}: ModalContent) {
  const snackBar = useSnackBar();

  const checkDateValidity = (dateToCheck) => {
    const nowMonth = new Date().getMonth();
    const currentDate = new Date().getDate();
    return dateToCheck && nowMonth === currentMonth && dateToCheck >= currentDate;
  };

  const changeMemberCount = (e) => {
    setReserve((prev) => ({
      ...prev,
      memberCount: e.target.value ? e.target.value : 0,
    }));
  };

  const postReservation = () => {
    if (!isAuthenticate()) {
      snackBar({ type: 'warning', message: '권한이 없습니다. 관리자에게 문의해주세요' });
      return;
    }
    
    if (today && reserve.memberCount >= 1) {
      // 예약 처리 로직 추가
    }
  };

  // 생략된 다른 함수 및 JSX
}

개선 사항:

  1. gapi 객체 사용 보호: gapi 객체가 정의되지 않은 경우에 대비해 체크했습니다.
  2. 상태 업데이트 함수 사용 최적화: setReserve를 사용할 때 이전 상태를 참조하여 보다 안전하게 업데이트하도록 했습니다.
  3. 불필요한 JSX 주석 제거: 코드 가독성을 높이기 위해 불필요한 주석을 정리했습니다.

이렇게 수정하면 코드의 안정성과 가독성이 향상될 것입니다.

setTimeout(() => gapi.auth2.getAuthInstance().signIn(), 500);
return;
}
}
if (event.target instanceof HTMLElement) setAlignment(newAlignment);
};

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드를 검토해본 결과, 아래와 같은 몇 가지 개선 사항이 있습니다.

  1. gapi 객체의 안전성: gapi 객체가 정의되어 있는지 확인해야 합니다. 만약 정의되지 않았다면, 코드 실행 중 오류가 발생할 수 있습니다.
  2. 타입 핸들링: eventnewAlignment 타입을 명확히 표현하여 TypeScript의 장점을 최대한 활용하는 것이 좋습니다.

개선된 코드는 다음과 같습니다:

import {
    // ... 다른 import 문
} from '@mui/material';
import { useState } from 'react';
import { useGetCalender } from 'page/Reservation/hook/useGetCalender';
import { useSnackBar } from 'ts/useSnackBar';
import { style } from './MonthModal';
import DetailInfomation from './DetailInfomation';

type Alignment = 'information' | 'passed' | 'reservation';

export const useToggleButtonGroup = () => {
    const [alignment, setAlignment] = useState<Alignment>('information');
    const snackBar = useSnackBar();

    const handleChange = (
        event: React.MouseEvent<HTMLElement>,
        newAlignment: Alignment,
    ) => {
        if (newAlignment === 'reservation') {
            const gapiInstance = gapi?.auth2?.getAuthInstance();
            if (gapiInstance) {
                const currentUser = gapiInstance.currentUser.get();
                const accessToken = currentUser.get().getAuthResponse()?.access_token;
                
                if (!accessToken) {
                    snackBar({ type: 'error', message: '구글 로그인이 필요한 서비스입니다' });
                    // 스낵바 노출 후 로그인창 열기
                    setTimeout(() => gapiInstance.signIn(), 500);
                    return;
                }
            } else {
                snackBar({ type: 'error', message: 'Google API 초기화 실패' });
                return;
            }
        }
        
        if (event.target instanceof HTMLElement) {
            setAlignment(newAlignment);
        }
    };

    // 나머지 로직...
};

이렇게 수정하면 gapi 객체의 존재 여부를 체크하고, 추가적인 에러 핸들링도 포함되어 코드의 안정성을 높일 수 있습니다.

if (today
&& reserve.memberCount >= 1
) {
// 필요한 값만 할당
mutate.mutate({
memberCount: reserve.memberCount,
reason: reserve.reason,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제공하신 코드에서 몇 가지 오류 및 개선 사항을 제안합니다.

코드 검토 및 개선 사항

  1. gapi 객체의 사용 확인:

    • gapi 객체가 코드에 정의되지 않은 것 같습니다. 이 객체가 올바르게 임포트되었는지 또는 사용 가능한 지점에서 타당한지 확인해야 합니다.
  2. canReserve 함수의 날짜 비교 로직 개선:

    • nowMonthcurrentMonth를 비교할 때, 단순히 월만 비교하는 것이 아닌 연도를 함께 고려하여 정확한 날짜 비교를 진행하는 것이 좋습니다.
  3. 에러 핸들링 추가:

    • 인증 체크가 실패했을 때 사용자에게 피드백을 제공하는 것은 좋은 접근입니다. 그러나 isAuthenticate() 호출 중 에러가 발생할 경우를 대비한 에러 핸들링을 추가하는 것이 좋습니다.
  4. 상수 및 메시지의 중앙 집중화:

    • 경고 메시지나 다른 상수를 변수로 만들어 여러 곳에서 재사용 가능하도록 하십시오.
  5. 타입스크립트 관련:

    • e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> 부분을 공통 인터페이스나 타입으로 추출하면 코드의 가독성을 높일 수 있습니다.

GitHub의 Add a Suggestion으로 제안

아래는 GitHub에서 제안할 수 있는 개선 사항입니다:

@@ -1,6 +1,7 @@
 import { useState } from 'react';
 import { HOUR_LIST, MINUTE_LIST } from 'util/constants/time';
 import { useCreateEvents } from 'page/Reservation/hook/useCreateEvent';
+import gapi from 'path/to/gapi'; // gapi import 확인 필요
 import { useSnackBar } from 'ts/useSnackBar';
 import DetailInfomation from './DetailInfomation';
 import { CalendarContent } from '../Month';

@@ -39,7 +40,8 @@ const initialState = {
 export const isAuthenticate = () => {
   try {
     return gapi.auth2.getAuthInstance().currentUser.get().hasGrantedScopes('https://www.googleapis.com/auth/calendar.events');
   } catch (error) {
-    console.error(error);
+    console.error("Authentication check failed:", error); // 에러 로그 추가
     return false;
   }
 };

@@ -48,6 +50,10 @@ export default function MonthModal({
   const canReserve = () => {
     if (currentMonth > nowMonth) return true;
-    if (date && nowMonth === currentMonth && date >= currentDate) return true;
+    if (date && nowMonth === currentMonth && date >= currentDate) return true; // 날짜 비교 로직 확인
+    // 현재 연도와 함께 비교
+    const currentYear = new Date().getFullYear();
+    if (date?.year < currentYear || (date.year === currentYear && date.month < nowMonth)) return false;
     return false;
   };

   const snackBar = useSnackBar();

이와 같은 방식으로 코드를 수정하고 개선 사항을 반영할 수 있습니다.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -87,6 +87,7 @@ export default function Month() {
const {
currentMonth, currentYear, setCurrentMonth, setCurrentYear,
} = useDateStore();
const snackbar = useSnackBar();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

소소한 카멜케이스 맞추기!

Suggested change
const snackbar = useSnackBar();
const snackbar = useSnackbar();
const snackBar = useSnackBar();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants