forked from Kernel360/f1-KernelSquare-admin-frontend
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from KernelSquare/dev
✨ FEAT: 로그인 기능 구현 및 관리자 페이지 배포
- Loading branch information
Showing
24 changed files
with
445 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
name: Admin-CICD | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout source code | ||
uses: actions/checkout@v3 | ||
|
||
- name: Install pnpm | ||
run: npm install pnpm -g | ||
|
||
- name: Install dependencies | ||
run: pnpm install | ||
|
||
- name: build | ||
env: | ||
VITE_API_MOCKING: ${{secrets.VITE_API_MOCKING}} | ||
VITE_SERVER: ${{secrets.VITE_SERVER}} | ||
VITE_CRYPTO_KEY_NAME: ${{secrets.VITE_CRYPTO_KEY_NAME}} | ||
VITE_CRYPTO_KEY_LENGTH: ${{secrets.VITE_CRYPTO_KEY_LENGTH}} | ||
run: pnpm run build | ||
|
||
deploy: | ||
runs-on: ubuntu-latest | ||
needs: build | ||
steps: | ||
- name: Configure AWS credentials | ||
uses: aws-actions/configure-aws-credentials@v1 | ||
with: | ||
aws-access-key-id: ${{ secrets.AWS_S3_ACCESS_KEY_ID }} | ||
aws-secret-access-key: ${{ secrets.AWS_S3_SECRET_ACCESS_KEY_ID }} | ||
aws-region: ${{ secrets.AWS_REGION }} | ||
|
||
- name: Upload to S3 | ||
env: | ||
BUCKET_NAME: ${{ secrets.AWS_S3_BUCKET_NAME}} | ||
run: | | ||
aws s3 sync \ | ||
./build s3://$BUCKET_NAME | ||
- name: Invalidate CloudFront Cache | ||
uses: chetan/invalidate-cloudfront-action@master | ||
env: | ||
AWS_DISTRIBUTION: ${{ secrets.AWS_DISTRIBUTION_ID }} | ||
PATHS: '/index.html' | ||
continue-on-error: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,17 @@ | ||
import { Navigate } from 'react-router-dom' | ||
|
||
import useUserDataStore from '@/features/hooks/store/useUserDataStore' | ||
import GlobalLayout from '@/shared/layout/GlobalLayout' | ||
|
||
const PrivateRoute = () => { | ||
// 로그인 로직 구현 후 수정 예정 | ||
const isAuthorized = true | ||
const { userData } = useUserDataStore() | ||
const userRole = userData?.roles | ||
|
||
return isAuthorized ? <GlobalLayout /> : <Navigate to="/signIn" /> | ||
return userRole?.includes('ROLE_ADMIN') ? ( | ||
<GlobalLayout /> | ||
) : ( | ||
<Navigate to="/signIn" /> | ||
) | ||
} | ||
|
||
export default PrivateRoute |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/** | ||
* @ BaseResponse | ||
* : 기본 API 응답 | ||
* - code: 응답 코드 | ||
* - msg: 응답 message | ||
* - data: 응답 data | ||
*/ | ||
|
||
export type BaseResponse<T = string> = { | ||
code: number | ||
msg: string | ||
data?: T | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { BaseResponse } from '../../baseResponses' | ||
import { LoginFormType } from '../../form' | ||
import { UserRole } from '../../user' | ||
|
||
/** | ||
* @ LoginRequest | ||
* - LoginFormType: { email: string, password: string } | ||
*/ | ||
export interface LoginRequest extends LoginFormType {} | ||
|
||
/** | ||
* @ LoginUserData | ||
* - member_id: 사용자 id (number) | ||
* - nickname: 사용자 닉네임 (string) | ||
* - experience: 사용자 경험치 (number) | ||
* - introduction: 사용자 소개글 (string) | ||
* - image_url: 사용자 프로필 사진 URL (string) | ||
* - level: 사용자 레벨 정보 (number) | ||
* - roles: 사용자 역할 (사용자, 멘토, 관리자) | ||
*/ | ||
export type LoginUserData = { | ||
member_id: number | ||
nickname: string | ||
experience: number | ||
introduction: string | ||
image_url: string | ||
level: number | ||
roles: UserRole[] | ||
} | ||
|
||
/** | ||
* @ LoginTokenData | ||
* - accesstoken (string) | ||
* - refreshtoken (string) | ||
*/ | ||
export type LoginTokenData = { | ||
token_dto: { access_token: string; refresh_token: string } | ||
} | ||
|
||
export type LoginPayload = LoginUserData & LoginTokenData | ||
|
||
export interface LoginResponse extends BaseResponse<LoginPayload> {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export type LoginFormType = { | ||
email: string | ||
password: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export type UserRole = 'ROLE_USER' | 'ROLE_MENTOR' | 'ROLE_ADMIN' |
File renamed without changes.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import tokenKey from '@/shared/constants/tokenKey' | ||
|
||
import { getCookie, removeCookie, setCookie } from '../../utils/cookies/cookies' | ||
|
||
const useAuthCookies = () => { | ||
const getAccessToken = () => getCookie(tokenKey.ACCESS_TOKEN) | ||
|
||
const getAuthCookies = () => { | ||
try { | ||
const [accessToken, refreshToken] = [ | ||
getCookie(tokenKey.ACCESS_TOKEN), | ||
getCookie(tokenKey.REFRESH_TOKEN), | ||
] | ||
|
||
return { | ||
accessToken: accessToken?.value, | ||
refreshToken: refreshToken?.value, | ||
} | ||
} catch (err) { | ||
return { | ||
accessToken: undefined, | ||
refreshToken: undefined, | ||
} | ||
} | ||
} | ||
|
||
const setAuthCookies = ( | ||
accessToken: string, | ||
refreshToken: string, | ||
expires: string, | ||
) => [ | ||
setCookie(tokenKey.ACCESS_TOKEN, accessToken, { | ||
path: '/', | ||
expires: new Date(expires), | ||
// httpOnly: true, | ||
}), | ||
setCookie(tokenKey.REFRESH_TOKEN, refreshToken, { | ||
path: '/', | ||
maxAge: 60 * 60 * 24 * 20, | ||
// httpOnly: true, | ||
}), | ||
] | ||
|
||
const removeAuthCookies = () => { | ||
removeCookie(tokenKey.ACCESS_TOKEN) | ||
removeCookie(tokenKey.REFRESH_TOKEN, { maxAge: 60 * 60 * 24 * 20 }) | ||
} | ||
|
||
return { | ||
getAccessToken, | ||
getAuthCookies, | ||
setAuthCookies, | ||
removeAuthCookies, | ||
} | ||
} | ||
|
||
export default useAuthCookies |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
const CRYPTO_KEY_NAME = import.meta.env.VITE_CRYPTO_KEY_NAME | ||
const CRYPTO_KEY_LENGTH = import.meta.env.VITE_CRYPTO_KEY_LENGTH | ||
|
||
const useCrypto = () => { | ||
const encrypt = async (data: string) => { | ||
const encoder = new TextEncoder() | ||
const dataBuffer = encoder.encode(data) | ||
|
||
const key = await crypto.subtle.generateKey( | ||
{ name: CRYPTO_KEY_NAME, length: Number(CRYPTO_KEY_LENGTH) }, | ||
true, | ||
['encrypt'], | ||
) | ||
|
||
const encryptedBuffer = await crypto.subtle.encrypt( | ||
{ name: CRYPTO_KEY_NAME, iv: crypto.getRandomValues(new Uint8Array(12)) }, | ||
key, | ||
dataBuffer, | ||
) | ||
|
||
const encryptedArray = Array.from(new Uint8Array(encryptedBuffer)) | ||
|
||
return btoa(String.fromCharCode.apply(null, encryptedArray)) | ||
} | ||
|
||
const decrypt = async (data: string) => { | ||
const encryptedData = data | ||
|
||
// 암호화된 데이터가 없을 경우 | ||
if (!encryptedData) return | ||
|
||
const encryptedBuffer = Uint8Array.from(atob(encryptedData), c => | ||
c.charCodeAt(0), | ||
) | ||
|
||
const key = await crypto.subtle.generateKey( | ||
{ name: CRYPTO_KEY_NAME, length: Number(CRYPTO_KEY_LENGTH) }, | ||
true, | ||
['decrypt'], | ||
) | ||
const decryptedBuffer = await crypto.subtle.decrypt( | ||
{ name: CRYPTO_KEY_NAME, iv: crypto.getRandomValues(new Uint8Array(12)) }, | ||
key, | ||
encryptedBuffer, | ||
) | ||
|
||
const decoder = new TextDecoder() | ||
const decryptedData = decoder.decode(decryptedBuffer) | ||
|
||
return JSON.parse(decryptedData) | ||
} | ||
|
||
return { encrypt, decrypt } | ||
} | ||
|
||
export default useCrypto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { create } from 'zustand' | ||
import { createJSONStorage, persist } from 'zustand/middleware' | ||
|
||
import { LoginUserData } from '@/entities/interfaces/dto/auth/login.dto' | ||
|
||
type UserDataStoreType = { | ||
userData: LoginUserData | undefined | ||
// eslint-disable-next-line no-unused-vars | ||
setUserData: (data: LoginUserData) => void | ||
clearUserData: () => void | ||
} | ||
|
||
const useUserDataStore = create<UserDataStoreType>()( | ||
persist( | ||
set => ({ | ||
userData: undefined, | ||
setUserData: (data: LoginUserData) => set({ userData: data }), | ||
clearUserData: () => set({ userData: undefined }), | ||
}), | ||
{ | ||
name: 'user-data-storage', | ||
storage: createJSONStorage(() => sessionStorage), | ||
}, | ||
), | ||
) | ||
|
||
export default useUserDataStore |
Empty file.
Oops, something went wrong.