use proper sessions

This commit is contained in:
beerpiss 2024-02-24 15:17:02 +07:00
parent d2983c6092
commit 5670903795
22 changed files with 258 additions and 985 deletions

View File

@ -20,6 +20,7 @@
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toast": "^1.1.5",
"@react-spring/web": "^9.7.3",
"@types/bcrypt": "^5.0.2",
"@types/cookie": "^0.5.4",
"@types/js-cookie": "^3.0.5",
@ -43,7 +44,6 @@
"react-hook-form": "^7.49.2",
"react-icons": "^4.12.0",
"react-select": "^5.8.0",
"react-spring": "^9.7.3",
"react-switch": "^7.0.0",
"react-toastify": "^9.1.3",
"rg-stats": "^0.5.4",

View File

@ -126,8 +126,7 @@ def main(data_folder, option_folder, output_folder):
subdirectories = find_subdirectories(
[data_folder, option_folder], relevant_subdirs)
output_path = os.path.join(
os.path.expanduser('~'), 'Desktop', output_folder)
output_path = output_folder
if not os.path.exists(output_path):
os.makedirs(output_path)

View File

@ -1,49 +0,0 @@
import { serialize } from "cookie"
import { COOKIE_NAME, MAX_EXPIRE_AGE } from "@/constants"
import axios from "axios"
export async function POST(request: Request) {
try {
const body = await request.json()
const { username, password } = body
// Authenticate the user by verifying their credentials
const { data } = await axios.post(
`${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/verifyUser`,
{
username,
password,
},
)
const isCookieSecure =
process.env.NEXT_PUBLIC_COOKIE_SECURE_HTTPS === "true"
// Use data.token directly without signing again
const token = data.token
// Serialize cookies
const cookieOptions = {
httpOnly: false,
secure: isCookieSecure,
sameSite: "strict" as const, // as const assertion for string literal types
maxAge: MAX_EXPIRE_AGE,
path: "/",
}
const serializedToken = serialize(COOKIE_NAME, token, cookieOptions)
// Return a response with the token cookie set (excluding USER_ID_COOKIE)
return new Response("", {
status: 200,
headers: {
"Set-Cookie": serializedToken,
},
})
} catch (error) {
// Check if it's an AxiosError and extract the status code if available
if (axios.isAxiosError(error) && error.response) {
return new Response("", { status: error.response.status })
}
// For other types of errors, return a generic server error
return new Response("", { status: 500 })
}
}

View File

@ -1,21 +0,0 @@
import { serialize } from "cookie"
const removeCookie = (cookieName: string): string =>
serialize(cookieName, "", {
httpOnly: false,
secure: true,
sameSite: "strict",
maxAge: -1,
path: "/",
})
export async function POST(): Promise<Response> {
const serializedToken = removeCookie("LOGIN_INFO")
return new Response("", {
status: 200,
headers: {
"Set-Cookie": serializedToken,
},
})
}

View File

@ -1,19 +0,0 @@
// check if user is authenticated
import { COOKIE_NAME } from "@/constants"
import { cookies } from "next/headers"
export async function GET() {
const cookieStore = cookies()
const token = cookieStore.get(COOKIE_NAME)
if (!token) {
return new Response("", { status: 401 })
}
const response = {
user: "Authenticated",
}
return new Response(JSON.stringify(response), {
status: 200,
})
}

View File

@ -1,65 +0,0 @@
import { serialize } from "cookie"
import { COOKIE_NAME, MAX_EXPIRE_AGE } from "@/constants"
import axios from "axios"
export async function POST(request: Request) {
const body = await request.json()
const { email, accessCode, username, password } = body
try {
if (!accessCode) {
console.log("Access code is missing. Bad Request.")
return new Response("", { status: 400 }) // 400 indicates Bad Request
}
// Attempt to register the user
const registrationResponse = await axios.post(
`${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/registerUser`,
{
email,
accessCode,
username,
password,
},
)
const userData = registrationResponse.data
const isCookieSecure =
process.env.NEXT_PUBLIC_COOKIE_SECURE_HTTPS === "true"
// Use accessCode directly without signing again
const token = userData.token
// Serialize the token cookie
const serializedToken = serialize(COOKIE_NAME, token, {
httpOnly: false,
secure: isCookieSecure,
sameSite: "strict",
maxAge: MAX_EXPIRE_AGE,
path: "/",
})
console.log("Token serialized:", serializedToken)
// Do not serialize the access code cookie with userId
// Return a response with only the token cookie set
console.log("Signup successful. Returning response.")
return new Response(JSON.stringify({ message: "Signup successful" }), {
status: 200,
headers: {
"Set-Cookie": serializedToken,
},
})
} catch (error) {
if (axios.isAxiosError(error) && error.response) {
console.error("Axios error:", error.response.status)
return new Response("", { status: error.response.status })
}
console.error("Unexpected error:", error)
return new Response("", { status: 500 })
}
}

View File

@ -1,8 +1,7 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { Dispatch, SetStateAction, useEffect, useState } from "react"
import axios from "axios"
import { useCookies } from "next-client-cookies"
import jwt from "jsonwebtoken"
import { ApiFetch } from "@/lib/api"
type AvatarItemList = {
id: number
@ -20,34 +19,16 @@ interface UseAvatarItemListParams {
setError: Dispatch<SetStateAction<string | null>>
}
axios.defaults.withCredentials = true;
export const UseAvatarItemList = ({
setAvatarItemList,
setLoading,
setError,
}: UseAvatarItemListParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const source = axios.CancelToken.source()
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/items?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/items`;
axios
.get(apiUrl, { cancelToken: source.token })
@ -69,7 +50,7 @@ export const UseAvatarItemList = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setAvatarItemList, setLoading, setError])
}, [setAvatarItemList, setLoading, setError])
}
type bestTop = {
@ -108,29 +89,8 @@ export const useBestTop = ({
setLoading,
setError,
}: UseBestTopScoresParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-best-and-top?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-best-and-top`
const source = axios.CancelToken.source()
axios
@ -152,7 +112,7 @@ export const useBestTop = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setBestTop, setLoading, setError])
}, [setBestTop, setLoading, setError])
}
type playerRecentRatingTable = {
@ -179,28 +139,8 @@ export const usePlayerRecentRatingTable = ({
setLoading,
setError,
}: UsePlayerRecentRatingTableParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: string
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-recent?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-recent`
const source = axios.CancelToken.source()
@ -223,7 +163,7 @@ export const usePlayerRecentRatingTable = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setPlayerRecentRatingTable, setLoading, setError])
}, [setPlayerRecentRatingTable, setLoading, setError])
}
type playerAvatarSelection = {
@ -249,29 +189,9 @@ export const UsePlayerInfo = ({
setLoading,
setError,
}: UseCharacterDataParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const source = axios.CancelToken.source()
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/profile-data?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/profile-data`
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
@ -293,7 +213,7 @@ export const UsePlayerInfo = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [token, setPlayerInfo, setLoading, setError])
}, [setPlayerInfo, setLoading, setError])
}
type playerVoiceIdSelection = {
@ -311,29 +231,9 @@ export const UsePlayerVoiceId = ({
setLoading,
setError,
}: UsePlayerVoiceIdParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const source = axios.CancelToken.source()
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/profile-data?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/profile-data`
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
@ -355,7 +255,7 @@ export const UsePlayerVoiceId = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [token, setPlayerVoiceId, setLoading, setError])
}, [setPlayerVoiceId, setLoading, setError])
}
type playerMapIconSelection = {
@ -373,29 +273,9 @@ export const UsePlayerMapIcon = ({
setLoading,
setError,
}: UsePlayerMapIconParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const source = axios.CancelToken.source()
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/profile-data?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/profile-data`
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
@ -417,7 +297,7 @@ export const UsePlayerMapIcon = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [token, setPlayerMapIcon, setLoading, setError])
}, [setPlayerMapIcon, setLoading, setError])
}
type playerNamePlateIconSelection = {
@ -435,29 +315,9 @@ export const UsePlayerNamePlates = ({
setLoading,
setError,
}: UsePlayerNameplateParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const source = axios.CancelToken.source()
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/profile-data?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/profile-data`
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
@ -479,7 +339,7 @@ export const UsePlayerNamePlates = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [token, setPlayerNameplate, setLoading, setError])
}, [setPlayerNameplate, setLoading, setError])
}
type PlayerScoreLogType = any
@ -494,45 +354,27 @@ export const useFetchPlayerScoreLog = ({
setLoading,
setError,
}: UseFetchPlayerScoreLogParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
let isMounted = true
const source = axios.CancelToken.source()
async function fetchProfileData() {
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-score-playlog?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-score-playlog`
try {
const response = await axios.get(apiUrl, { cancelToken: source.token })
if (response.status !== 200) {
throw new Error("Network response was not ok")
}
const user = await ApiFetch<{ body: { version: number; } }>("/SDHD/user");
// Check if the version in the response is the expected version
if (decodedToken.version !== 14) {
if (user.body.body.version !== 14) {
setError("Please update to the latest version")
setLoading(false)
return
}
const response = await axios.get(apiUrl, { cancelToken: source.token })
if (response.status !== 200) {
throw new Error("Network response was not ok")
}
if (isMounted) {
setPlayerScoreLog(response.data)
setLoading(false)
@ -556,7 +398,7 @@ export const useFetchPlayerScoreLog = ({
isMounted = false
source.cancel("Operation canceled by the user.")
}
}, [cookies, setError, setLoading, setPlayerScoreLog, token])
}, [setError, setLoading, setPlayerScoreLog])
}
type playerStaticMusic = any
@ -571,45 +413,27 @@ export const useFetchStaticMusic = ({
setLoading,
setError,
}: UsePlayerStaticMusicParam) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
let isMounted = true
const source = axios.CancelToken.source()
async function fetchProfileData() {
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-static-music?version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-static-music`
try {
const response = await axios.get(apiUrl, { cancelToken: source.token })
if (response.status !== 200) {
throw new Error("Network response was not ok")
}
const user = await ApiFetch<{ body: { version: number; } }>("/SDHD/user");
// Check if the version in the response is the expected version
if (decodedToken.version !== 14) {
if (user.body.body.version !== 14) {
setError("Please update to the latest version")
setLoading(false)
return
}
const response = await axios.get(apiUrl, { cancelToken: source.token })
if (response.status !== 200) {
throw new Error("Network response was not ok")
}
if (isMounted) {
setPlayerStaticMusic(response.data)
setLoading(false)
@ -633,7 +457,7 @@ export const useFetchStaticMusic = ({
isMounted = false
source.cancel("Operation canceled by the user.")
}
}, [cookies, setError, setLoading, setPlayerStaticMusic, token])
}, [setError, setLoading, setPlayerStaticMusic])
}
type PlayerTeam = {
@ -653,29 +477,9 @@ export const UsePlayerTeams = ({
setLoading,
setError,
}: usePlayerTeamsParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
const source = axios.CancelToken.source()
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-player-team?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-player-team`
axios
.get(apiUrl, { cancelToken: source.token })
@ -697,7 +501,7 @@ export const UsePlayerTeams = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setPlayerTeams, setLoading, setError])
}, [setPlayerTeams, setLoading, setError])
}
type PlayerRivalList = any
@ -715,28 +519,13 @@ export const usePlayerRivalList = ({
setError,
refreshRivalList, // Include it in the parameters
}: UsePlayerRivalListParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
const fetchData = async () => {
const source = axios.CancelToken.source()
try {
if (!token) {
throw new Error("JWT token not available")
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version: number
}
if (!decodedToken.userId) {
throw new Error("User ID not available")
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/listRivals?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/listRivals`
const response = await axios.get(apiUrl, { cancelToken: source.token })
@ -760,11 +549,9 @@ export const usePlayerRivalList = ({
fetchData()
}, [
cookies,
setPlayerRivalList,
setLoading,
setError,
token,
refreshRivalList,
]) // Include refreshRivalList as a dependency
}
@ -790,27 +577,12 @@ export const usePlayerFavoriteSongsList =
const [loading, setLoading] = useState<boolean>(true)
const [error, setError] = useState<string | null>(null)
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
const fetchData = async () => {
const source = axios.CancelToken.source()
try {
if (!token) {
throw new Error("JWT token not available")
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version: number
}
if (!decodedToken.userId) {
throw new Error("User ID not available")
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/list-favorite-songs?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/list-favorite-songs`
const response = await axios.get(apiUrl, { cancelToken: source.token })
@ -832,7 +604,7 @@ export const usePlayerFavoriteSongsList =
useEffect(() => {
fetchData()
}, [cookies, token])
}, [])
const refetchPlayerFavoriteSongs = () => {
setLoading(true)
@ -857,29 +629,10 @@ export const UsePlayerAimeCard = ({
setLoading,
setError,
}: usePlayerAimeCardParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
const source = axios.CancelToken.source()
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/access-code?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/access-code`
axios
.get(apiUrl, { cancelToken: source.token })
@ -901,7 +654,7 @@ export const UsePlayerAimeCard = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setPlayAimeCard, setLoading, setError])
}, [])
}
type PlayerProfileTrophies = {
@ -921,29 +674,10 @@ export const UsePlayerProfileTrophies = ({
setLoading,
setError,
}: usePlayerProfileTrophiesParam) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
const source = axios.CancelToken.source()
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/profile-data?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/profile-data`
axios
.get(apiUrl, { cancelToken: source.token })
@ -965,7 +699,7 @@ export const UsePlayerProfileTrophies = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setPlayerProfileTrophies, setLoading, setError])
}, [setPlayerProfileTrophies, setLoading, setError])
}
type PlayerTrophies = {
@ -988,29 +722,10 @@ export const UsePlayerTrophies = ({
setLoading,
setError,
}: usePlayerTrophiesParam) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
const source = axios.CancelToken.source()
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/get-trophies?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/get-trophies`
axios
.get(apiUrl, { cancelToken: source.token })
@ -1032,7 +747,7 @@ export const UsePlayerTrophies = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setPlayerTrophies, setLoading, setError])
}, [setPlayerTrophies, setLoading, setError])
}
type PlayerAvatarItems = {
@ -1057,29 +772,10 @@ export const UsePlayerAvatarItems = ({
setLoading,
setError,
}: usePlayerAvatarItemsParam) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
const source = axios.CancelToken.source()
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-avatar-items?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-avatar-items`
axios
.get(apiUrl, { cancelToken: source.token })
@ -1101,7 +797,7 @@ export const UsePlayerAvatarItems = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setPlayerAvatarItems, setLoading, setError])
}, [setPlayerAvatarItems, setLoading, setError])
}
type PlayerDuelCompletions = {
@ -1122,30 +818,10 @@ export const UsePlayerDuelCompletions = ({
setError,
onSuccess,
}: UsePlayerDuelCompletionsParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
const source = axios.CancelToken.source()
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-duel-items?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-duel-items`
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
@ -1166,7 +842,7 @@ export const UsePlayerDuelCompletions = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setPlayerDuelCompletions, setLoading, setError])
}, [setPlayerDuelCompletions, setLoading, setError])
}
type playerAvailableNameplates = {
@ -1190,29 +866,10 @@ export const UsePlayerAvailableNameplates = ({
setError,
onSuccess,
}: UsePlayerAvailableNameplatesParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
const source = axios.CancelToken.source()
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-nameplate-items?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-nameplate-items`
axios
.get(apiUrl, { cancelToken: source.token })
@ -1234,7 +891,7 @@ export const UsePlayerAvailableNameplates = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setPlayerAvailableNameplates, setLoading, setError])
}, [setPlayerAvailableNameplates, setLoading, setError])
}
type playerAvailableMapIcons = {
@ -1258,29 +915,10 @@ export const UsePlayerAvailableMapIcons = ({
setError,
onSuccess,
}: UsePlayerAvailableMapIconsParams) => {
const cookies = useCookies()
const token = cookies.get("LOGIN_INFO")
useEffect(() => {
const source = axios.CancelToken.source()
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token as string) as {
userId?: string
version?: number
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-map-items?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/chuni-map-items`
axios
.get(apiUrl, { cancelToken: source.token })
@ -1302,5 +940,5 @@ export const UsePlayerAvailableMapIcons = ({
return () => {
source.cancel("Operation canceled by the user.")
}
}, [cookies, setPlayerAvailableMapIcons, setLoading, setError])
}, [setPlayerAvailableMapIcons, setLoading, setError])
}

View File

@ -1,6 +1,4 @@
import axios from "axios"
import { useCookies } from "next-client-cookies"
import jwt from "jsonwebtoken" // Import the jsonwebtoken library
type AvatarData = any
interface UsePostAvatarItemListParams {
@ -9,37 +7,19 @@ interface UsePostAvatarItemListParams {
setError: (error: string | null) => void
}
axios.defaults.withCredentials = true;
export const UsePostAvatarItemList = ({
onPostSuccess,
setLoading,
setError,
}: UsePostAvatarItemListParams) => {
const cookies = useCookies()
const postAvatarData = (avatarData: AvatarData) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as { userId?: string }
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/updateAvatarCustomization?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/updateAvatarCustomization`
axios
.post(apiUrl, avatarData, {
@ -81,32 +61,13 @@ export const UsePostNewKeychip = ({
setLoading,
setError,
}: UsePostNewKeychipParams) => {
const cookies = useCookies()
const createNewKeychip = (postTeamData: KeychipCreation) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as { userId?: string }
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/create_keychip?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/create_keychip`
axios
.post(apiUrl, postTeamData, {
@ -147,32 +108,13 @@ export const UsePostMapIcon = ({
setLoading,
setError,
}: UsePostMapIconParams) => {
const cookies = useCookies()
const postMapIcon = (avatarData: MapIcon) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as { userId?: string }
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_item_mapchar?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_item_mapchar`
axios
.post(apiUrl, avatarData, {
@ -214,32 +156,14 @@ export const UsePostNamePlate = ({
setLoading,
setError,
}: UsePostNameplateIdParams) => {
const cookies = useCookies()
const postNamePlate = (avatarData: NameplateId) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as { userId?: string }
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_nameplateId?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_nameplateId`
axios
.post(apiUrl, avatarData, {
@ -280,32 +204,13 @@ export const UsePostPlayerTeam = ({
setLoading,
setError,
}: UsePostPlayerTeamParams) => {
const cookies = useCookies()
const postTeamName = (PostTeamData: PlayerTeam) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as { userId?: string }
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_player_team?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_player_team`
axios
.post(apiUrl, PostTeamData, {
@ -347,34 +252,15 @@ export const UsePostPlayerTeamProfile = ({
setLoading,
setError,
}: UsePostPlayerTeamProfileParams) => {
const cookies = useCookies()
const postTeamNameProfile = (
postPlayerTeamProfileData: PlayerTeamProfile,
) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as { userId?: string }
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_profile_player_team?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_profile_player_team`
axios
.post(apiUrl, postPlayerTeamProfileData, {
@ -416,32 +302,13 @@ export const UsePostSystemVoice = ({
setLoading,
setError,
}: UsePostSystemVoiceParams) => {
const cookies = useCookies()
const postVoiceID = (avatarData: SystemVoice) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as { userId?: string }
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_item_duel?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_item_duel`
axios
.post(apiUrl, avatarData, {
@ -483,32 +350,13 @@ export const UsePostTrophy = ({
setLoading,
setError,
}: UsePostTrophyParams) => {
const cookies = useCookies()
const postTrophy = (avatarData: TrophyName) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as { userId?: string }
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_trophyid?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_trophyid`
axios
.post(apiUrl, avatarData, {
@ -549,32 +397,13 @@ export const UsePostPlayerRival = ({
setLoading,
setError,
}: UsePostPlayerRivalParams) => {
const cookies = useCookies()
const postRival = (avatarData: playerRivals) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as { userId?: string }
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_player_rivals?user=${decodedToken.userId}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_player_rivals`
axios
.post(apiUrl, avatarData, {
@ -616,35 +445,12 @@ export const UsePostFavoriteSongs = ({
setLoading,
setError,
}: UsePostPlayerFavoriteSongsParams) => {
const cookies = useCookies()
const postFavoriteSong = (FavoriteSong: playerFavoriteSongs) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as {
userId?: string
version?: string
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_favorite_music/?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/update_chuni_favorite_music`;
axios
.post(apiUrl, FavoriteSong, {
@ -686,35 +492,13 @@ export const UsePostNewCard = ({
setLoading,
setError,
}: UsePostNewAccessCodeParam) => {
const cookies = useCookies()
const postAccessCode = (accesscodeData: NewPlayerCard) => {
setLoading(true)
const source = axios.CancelToken.source()
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO")
if (!token) {
setError("JWT token not available")
setLoading(false)
return
}
const decodedToken = jwt.decode(token) as {
userId?: string
version?: string
}
if (!decodedToken.userId) {
setError("User ID not available")
setLoading(false)
return
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/updateAccessCode?user=${decodedToken.userId}&version=${decodedToken.version}`
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/SDHD/updateAccessCode`
axios
.post(

View File

@ -4,6 +4,7 @@ import axios from "axios"
import { useState, useEffect } from "react"
import { AxiosError } from "axios"
import { useRouter } from "next/navigation"
import { IsLoggedIn } from "@/lib/auth"
interface UserResponse {
user: string | null
@ -20,9 +21,7 @@ export default function DashboardLayout({
useEffect(() => {
;(async () => {
const { user, error } = await getUser()
if (error) {
if (!await IsLoggedIn()) {
router.push("/")
return
}
@ -33,20 +32,4 @@ export default function DashboardLayout({
if (!isSuccess) {
}
return <main>{children}</main>
async function getUser(): Promise<UserResponse> {
try {
const { data } = await axios.get("/api/auth/me")
return {
user: data,
error: null,
}
} catch (e) {
const error = e as AxiosError
return {
user: null,
error: error,
}
}
}
}

View File

@ -4,6 +4,7 @@ import axios from "axios"
import { useState, useEffect } from "react"
import { AxiosError } from "axios"
import { useRouter } from "next/navigation"
import { IsLoggedIn } from "@/lib/auth"
interface UserResponse {
user: string | null
@ -20,9 +21,7 @@ export default function DashboardLayout({
useEffect(() => {
;(async () => {
const { user, error } = await getUser()
if (error) {
if (!await IsLoggedIn()) {
router.push("/")
return
}
@ -33,20 +32,4 @@ export default function DashboardLayout({
if (!isSuccess) {
}
return <main>{children}</main>
async function getUser(): Promise<UserResponse> {
try {
const { data } = await axios.get("/api/auth/me")
return {
user: data,
error: null,
}
} catch (e) {
const error = e as AxiosError
return {
user: null,
error: error,
}
}
}
}

View File

@ -4,6 +4,7 @@ import axios from "axios"
import { useState, useEffect } from "react"
import { AxiosError } from "axios"
import { useRouter } from "next/navigation"
import { IsLoggedIn } from "@/lib/auth"
interface UserResponse {
user: string | null
@ -20,9 +21,7 @@ export default function DashboardLayout({
useEffect(() => {
;(async () => {
const { user, error } = await getUser()
if (error) {
if (!await IsLoggedIn()) {
router.push("/")
return
} // if error duid not happen everything is alright
@ -33,20 +32,4 @@ export default function DashboardLayout({
if (!isSuccess) {
}
return <main>{children}</main>
async function getUser(): Promise<UserResponse> {
try {
const { data } = await axios.get("/api/auth/me")
return {
user: data,
error: null,
}
} catch (e) {
const error = e as AxiosError
return {
user: null,
error: error,
}
}
}
}

View File

@ -9,6 +9,7 @@ import { FaSpinner } from "react-icons/fa"
import { z, ZodError } from "zod" // Import Zod for input validation
import Link from "next/link"
import { Input } from "@/components/ui/input"
import { ApiFetch } from "@/lib/api"
const loginSchema = z.object({
username: z.string().min(3).max(20),
@ -33,7 +34,22 @@ export default function Home() {
setLoading(true)
await axios.post("/api/auth/login", formValues)
const response = await ApiFetch(
"/SDHD/verifyUser",
{
method: "POST",
body: JSON.stringify(formValues),
headers: {
"Content-Type": "application/json",
},
},
false,
true,
)
if (response.statusCode !== 200) {
return;
}
toast.success("Login successful!", {
className: "success-toast",

View File

@ -4,6 +4,7 @@ import axios from "axios"
import { useState, useEffect } from "react"
import { AxiosError } from "axios"
import { useRouter } from "next/navigation"
import { IsLoggedIn } from "@/lib/auth"
interface UserResponse {
user: string | null
@ -20,9 +21,7 @@ export default function DashboardLayout({
useEffect(() => {
;(async () => {
const { user, error } = await getUser()
if (error) {
if (!await IsLoggedIn()) {
router.push("/")
return
} // if error duid not happen everything is alright
@ -33,20 +32,4 @@ export default function DashboardLayout({
if (!isSuccess) {
}
return <main>{children}</main>
async function getUser(): Promise<UserResponse> {
try {
const { data } = await axios.get("/api/auth/me")
return {
user: data,
error: null,
}
} catch (e) {
const error = e as AxiosError
return {
user: null,
error: error,
}
}
}
}

View File

@ -7,6 +7,7 @@ import { toast, ToastContainer } from "react-toastify"
import "react-toastify/dist/ReactToastify.css"
import { z, ZodError } from "zod" // Import Zod for input validation
import { Input } from "@/components/ui/input"
import { ApiFetch } from "@/lib/api"
// Define the Zod schema for signup form data
const signupSchema = z.object({
@ -66,13 +67,24 @@ export default function Signup() {
password: event.currentTarget.password.value,
}
// Validate form data using Zod
signupSchema.parse(formValues)
signupSchema.parse(formValues);
// Make the API call
const response = await axios.post("/api/auth/signup", formValues)
const response = await ApiFetch(
"/SDHD/registerUser",
{
method: "POST",
body: JSON.stringify(formValues),
headers: {
"Content-Type": "application/json",
},
},
false,
true,
);
// Log after successful API call
console.log("API call successful:", response.data)
if (response.statusCode !== 200) {
return;
}
// Display success toast and redirect
toast.success("Signup successful!", {
@ -80,7 +92,8 @@ export default function Signup() {
bodyClassName: "toast-body",
closeButton: false,
theme: "colored",
})
});
push("/chunithm")
} catch (error) {
handleSignUpError(error)

View File

@ -4,6 +4,7 @@ import axios from "axios"
import { useState, useEffect } from "react"
import { AxiosError } from "axios"
import { useRouter } from "next/navigation"
import { IsLoggedIn } from "@/lib/auth"
interface UserResponse {
user: string | null
@ -20,9 +21,7 @@ export default function DashboardLayout({
useEffect(() => {
;(async () => {
const { user, error } = await getUser()
if (error) {
if (!await IsLoggedIn()) {
router.push("/")
return
}
@ -33,20 +32,4 @@ export default function DashboardLayout({
if (!isSuccess) {
}
return <main>{children}</main>
async function getUser(): Promise<UserResponse> {
try {
const { data } = await axios.get("/api/auth/me")
return {
user: data,
error: null,
}
} catch (e) {
const error = e as AxiosError
return {
user: null,
error: error,
}
}
}
}

View File

@ -1,22 +1,18 @@
"use client"
import React, { useEffect, useState } from "react"
import { UsePostPlayerRival } from "@/app/axios/usePostApi"
import { useCookies } from "next-client-cookies"
import jwt from "jsonwebtoken"
import { usePlayerRivalList } from "@/app/axios/useFetchApi"
import { Input } from "./ui/input"
import { RivalData } from "@/lib/types"
import { ApiFetch } from "@/lib/api"
const RivalComponent = () => {
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [successMessage, setSuccessMessage] = useState<string | null>(null)
const [showAccessCode, setShowAccessCode] = useState(false)
const [rivalData, setRivalData] = useState<RivalData>({
user1: "",
rivalCode: "",
version: 13,
})
const [ownRivalCode, setOwnRivalCode] = useState(-1)
const [targetRivalCode, setTargetRivalCode] = useState(0)
const [rivals, setRivals] = useState<{ username: string }[]>([])
const [refreshRivalList, setRefreshRivalList] = useState(false)
@ -31,28 +27,14 @@ const RivalComponent = () => {
setError,
})
const handleInputChange = (field: keyof RivalData, value: string) => {
setRivalData((prevData) => ({ ...prevData, [field]: value }))
}
const handlePostRival = () => {
if (rivalData.user1 && rivalData.rivalCode) {
if (targetRivalCode) {
postRival({
user1: rivalData.user1,
user2: "", // User2 will be set based on rivalCode on the server
rivalCode: rivalData.rivalCode,
version: rivalData.version,
rivalCode: targetRivalCode,
})
}
}
const { get } = useCookies()
const token = get("LOGIN_INFO")
const decodedToken = jwt.decode(token as string) as {
userId?: string
rivalCode?: string
}
usePlayerRivalList({
setPlayerRivalList: setRivals,
setLoading,
@ -61,13 +43,14 @@ const RivalComponent = () => {
})
useEffect(() => {
if (decodedToken.userId) {
handleInputChange("user1", decodedToken.userId)
async function fetchData() {
const user = (await ApiFetch<UserDataResponse>("/SDHD/user")).body.body;
setOwnRivalCode(user.rivalCode);
}
if (decodedToken.rivalCode) {
handleInputChange("rivalCode", decodedToken.rivalCode)
}
}, [decodedToken.userId, decodedToken.rivalCode])
fetchData();
}, []);
useEffect(() => {
const successTimeout = setTimeout(() => {
@ -87,9 +70,9 @@ const RivalComponent = () => {
Enter Rival Aime Card:
</label>
<Input
type="text"
type="number"
placeholder="Enter Rival Code:"
onChange={(e) => handleInputChange("rivalCode", e.target.value)}
onChange={(e) => setTargetRivalCode(e.target.valueAsNumber)}
className="w-[300px] rounded-md border-gray-300 py-2 pl-3 pr-10 shadow-sm focus:outline-none sm:w-[200px] sm:text-sm md:w-[200px] lg:w-[300px]"
/>
</div>
@ -116,7 +99,7 @@ const RivalComponent = () => {
Your Rival code:
</label>
<div className="text-lg font-bold text-typography">
{decodedToken.rivalCode}
{ownRivalCode}
</div>
</div>
)}

View File

@ -1,28 +1,33 @@
"use client"
import React, { useEffect, useState } from "react"
import jwt from "jsonwebtoken"
import { useCookies } from "next-client-cookies"
import { UsePostNewKeychip } from "@/app/axios/usePostApi"
import { Input } from "./ui/input"
import { ApiFetch } from "@/lib/api"
const NewKeychipComponent = () => {
const { get } = useCookies()
const token = get("LOGIN_INFO")
const decodedToken = jwt.decode(token as string) as { userId?: string }
const initialKeychipData = {
arcade_nickname: "",
name: "",
serial: "",
namcopcbid: "",
user: `${decodedToken.userId}`,
}
const [userId, setUserId] = useState(0)
const [keychipData, setKeychipData] = useState(initialKeychipData)
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const [accessCodeError, setAccessCodeError] = useState<string | null>(null)
const [successMessage, setSuccessMessage] = useState<string>("")
useEffect(() => {
async function fetchData() {
const user = (await ApiFetch<UserDataResponse>("/SDHD/user")).body.body;
setUserId(user.userId);
}
fetchData();
}, []);
const { createNewKeychip } = UsePostNewKeychip({
onPostSuccess: (data) => {
setSuccessMessage("Keychip created successfully!")
@ -40,7 +45,7 @@ const NewKeychipComponent = () => {
setKeychipData({ ...keychipData, [e.target.name]: e.target.value })
}
const allowedUserIds = ["10000", "10011"]
const allowedUserIds = [10000, 10011];
const handleSubmit = () => {
// Check if any of the input fields are empty
@ -57,7 +62,7 @@ const NewKeychipComponent = () => {
return
}
if (allowedUserIds.includes(keychipData.user)) {
if (allowedUserIds.includes(userId)) {
createNewKeychip(keychipData)
console.log("Submitting keychip data", keychipData)
} else {
@ -92,7 +97,7 @@ const NewKeychipComponent = () => {
if (loading) return <div>Loading...</div>
if (error) return <div>Error: {error}</div>
if (!allowedUserIds.includes(keychipData.user)) {
if (!allowedUserIds.includes(userId)) {
return <div></div>
}
return (

View File

@ -4,6 +4,7 @@ import Link from "next/link"
import { useRouter } from "next/navigation"
import { serialize } from "cookie"
import { AxiosError } from "axios"
import { ApiFetch } from "@/lib/api"
const removeCookie = (cookieName: string): string =>
serialize(cookieName, "", {
@ -15,22 +16,10 @@ const removeCookie = (cookieName: string): string =>
})
const removeLoginInfoCookie = async (): Promise<void> => {
const serializedToken = removeCookie("LOGIN_INFO")
try {
await fetch("/api/auth/logout", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
})
// Remove the LOGIN_INFO cookie
document.cookie = serializedToken
} catch (e) {
const error = e as AxiosError
// Handle errors if needed
console.error("Logout failed:", error)
}
const serializedToken = removeCookie("ArtemisAPI_SESSION");
document.cookie = serializedToken;
await ApiFetch("/SDHD/logoutUser", { method: "POST" }, true, true);
}
const NavigationBar = () => {

View File

@ -1,2 +0,0 @@
export const COOKIE_NAME = "LOGIN_INFO"
export const MAX_EXPIRE_AGE = 60 * 60 * 24 * 7 // 7 days

71
src/lib/api.ts Normal file
View File

@ -0,0 +1,71 @@
import { toast } from "react-toastify";
const BASE_OPTIONS = {
credentials: "include",
};
const BASE_URL = process.env.NEXT_PUBLIC_ARTEMIS_API_URL;
if (!BASE_URL) {
throw new Error("Cannot run -- no NEXT_PUBLIC_ARTEMIS_API_URL provided?");
}
export function ToApiUrl(url: string) {
if (url[0] === "/") {
url = url.substring(1)
}
return `${BASE_URL}/${url}`;
}
export type ApiFetchReturn<T> = {
body: T,
statusCode: number;
}
export async function ApiFetch<T = unknown>(
url: string,
options: RequestInit = {},
displaySuccess = false,
displayFailure = false,
): Promise<ApiFetchReturn<T>> {
const mergedOptions = Object.assign({}, BASE_OPTIONS, options);
try {
const res = await fetch(ToApiUrl(url), mergedOptions);
// Some endpoints don't return JSON.
const rt = await res.text();
const rj = (rt[0] === "{" || rt[0] === "[") ? JSON.parse(rt) : null;
if (!res.ok) {
const errorMessage = rj?.message ?? rj?.error ?? rt;
console.warn(errorMessage);
if (displayFailure) {
toast.error(errorMessage, {
className: "error-toast",
bodyClassName: "toast-body",
closeButton: false,
theme: "colored",
});
}
}
if (res.ok && displaySuccess && rj?.message) {
toast.success(rj.message, {
className: "success-toast",
bodyClassName: "toast-body",
closeButton: false,
theme: "colored",
})
}
return { body: rj ?? rt, statusCode: res.status };
} catch (err) {
console.error(err);
throw err;
}
}

7
src/lib/auth.ts Normal file
View File

@ -0,0 +1,7 @@
import { ApiFetch } from "./api";
export async function IsLoggedIn() {
const response = await ApiFetch("/SDHD/user");
return response.statusCode == 200;
}

View File

@ -0,0 +1,9 @@
interface UserDataResponse {
body: UserData;
}
interface UserData {
userId: number;
version: number;
rivalCode: number;
}