mirror of
https://github.com/ershisan99/todolist_next.git
synced 2025-12-17 20:59:25 +00:00
switch to bun + biomejs
fix infinite load on failed token refresh
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"parserOptions": {
|
|
||||||
"project": "./tsconfig.json"
|
|
||||||
},
|
|
||||||
"plugins": ["@typescript-eslint"],
|
|
||||||
"extends": [
|
|
||||||
"next/core-web-vitals",
|
|
||||||
"plugin:@typescript-eslint/recommended",
|
|
||||||
"@it-incubator/eslint-config"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"@typescript-eslint/consistent-type-imports": "warn"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8
.idea/biome.xml
generated
Normal file
8
.idea/biome.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="BiomeSettings">
|
||||||
|
<option name="applySafeFixesOnSave" value="true" />
|
||||||
|
<option name="applyUnsafeFixesOnSave" value="true" />
|
||||||
|
<option name="formatOnSave" value="true" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
13
biome.json
Normal file
13
biome.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
|
||||||
|
"organizeImports": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"linter": {
|
||||||
|
"enabled": true,
|
||||||
|
"rules": {
|
||||||
|
"recommended": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"formatter": { "indentStyle": "space", "indentWidth": 2 }
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
"zod": "^3.21.4"
|
"zod": "^3.21.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@biomejs/biome": "1.8.3",
|
||||||
"@it-incubator/eslint-config": "^0.1.0",
|
"@it-incubator/eslint-config": "^0.1.0",
|
||||||
"@it-incubator/prettier-config": "^0.1.0",
|
"@it-incubator/prettier-config": "^0.1.0",
|
||||||
"@types/node": "^18.15.11",
|
"@types/node": "^18.15.11",
|
||||||
|
|||||||
3585
pnpm-lock.yaml
generated
3585
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
/** @type {import("prettier").Config} */
|
|
||||||
module.exports = {
|
|
||||||
plugins: [
|
|
||||||
require.resolve("prettier-plugin-tailwindcss"),
|
|
||||||
require.resolve("@it-incubator/prettier-config"),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
@@ -9,14 +9,14 @@ import { useMeQuery } from "@/services";
|
|||||||
|
|
||||||
export const AuthRedirect: FC<{ children: ReactNode }> = ({ children }) => {
|
export const AuthRedirect: FC<{ children: ReactNode }> = ({ children }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { data: user, isLoading, isError } = useMeQuery();
|
const { data: user, isLoading } = useMeQuery();
|
||||||
const isAuthPage = router.pathname === "/login";
|
const isAuthPage = router.pathname === "/login";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isLoading && !user && !isAuthPage) {
|
if (!isLoading && !user && !isAuthPage) {
|
||||||
router.push("/login");
|
router.push("/login");
|
||||||
}
|
}
|
||||||
}, [user, isError, isLoading, isAuthPage, router]);
|
}, [user, isLoading, isAuthPage, router]);
|
||||||
|
|
||||||
if (isLoading || (!user && !isAuthPage)) {
|
if (isLoading || (!user && !isAuthPage)) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { Mutex } from "async-mutex";
|
import { Mutex } from "async-mutex";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import router from "next/router";
|
||||||
|
|
||||||
const mutex = new Mutex();
|
const mutex = new Mutex();
|
||||||
|
|
||||||
let refreshedAt: number | null = null;
|
let refreshedAt: number | null = null;
|
||||||
|
|
||||||
export const todolistApiInstance = axios.create({
|
export const todolistApiInstance = axios.create({
|
||||||
baseURL: "http://localhost:3000",
|
baseURL: "http://localhost:3000"
|
||||||
});
|
});
|
||||||
|
|
||||||
async function refreshAccessToken(): Promise<string> {
|
async function refreshAccessToken(): Promise<string> {
|
||||||
@@ -17,8 +19,8 @@ async function refreshAccessToken(): Promise<string> {
|
|||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${localStorage.getItem("refreshToken")}`,
|
Authorization: `Bearer ${localStorage.getItem("refreshToken")}`
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -46,9 +48,10 @@ todolistApiInstance.interceptors.request.use(
|
|||||||
todolistApiInstance.interceptors.response.use(
|
todolistApiInstance.interceptors.response.use(
|
||||||
(response) => response,
|
(response) => response,
|
||||||
async (error) => {
|
async (error) => {
|
||||||
|
if(error?.response?.request?.responseURL?.includes("refresh-token")){
|
||||||
|
return }
|
||||||
await mutex.waitForUnlock();
|
await mutex.waitForUnlock();
|
||||||
const originalRequest = error.config;
|
const originalRequest = error.config;
|
||||||
|
|
||||||
// Check for a 401 response and if this request hasn't been retried yet
|
// Check for a 401 response and if this request hasn't been retried yet
|
||||||
if (error.response?.status === 401 && !originalRequest._retry) {
|
if (error.response?.status === 401 && !originalRequest._retry) {
|
||||||
if (!mutex.isLocked()) {
|
if (!mutex.isLocked()) {
|
||||||
@@ -72,6 +75,8 @@ todolistApiInstance.interceptors.response.use(
|
|||||||
originalRequest.headers["Authorization"] = `Bearer ${newAccessToken}`;
|
originalRequest.headers["Authorization"] = `Bearer ${newAccessToken}`;
|
||||||
|
|
||||||
return todolistApiInstance(originalRequest); // Retry the original request with the new token
|
return todolistApiInstance(originalRequest); // Retry the original request with the new token
|
||||||
|
} catch (error) {
|
||||||
|
router.push("/login");
|
||||||
} finally {
|
} finally {
|
||||||
release();
|
release();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user