CSRF refresh fixes
This commit is contained in:
parent
a8dc0b3647
commit
f0e8e20c24
15 changed files with 12111 additions and 51665 deletions
|
|
@ -8,7 +8,7 @@
|
||||||
"outDir": "build/main",
|
"outDir": "build/main",
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"types": ["jest", "node", "long"],
|
"types": ["node", "long"],
|
||||||
"lib": ["es2020", "DOM"],
|
"lib": ["es2020", "DOM"],
|
||||||
"composite": true
|
"composite": true
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ export const TicketCreateDialog: FC<TicketCreateDialogProps> = ({
|
||||||
);
|
);
|
||||||
const [liveFormState, setLiveFormState] = useState(formState);
|
const [liveFormState, setLiveFormState] = useState(formState);
|
||||||
const updateFormState = (field: string, value: any) => {
|
const updateFormState = (field: string, value: any) => {
|
||||||
console.log({ value });
|
|
||||||
const newState = { ...liveFormState };
|
const newState = { ...liveFormState };
|
||||||
newState.values[field] = value;
|
newState.values[field] = value;
|
||||||
setLiveFormState(newState);
|
setLiveFormState(newState);
|
||||||
|
|
@ -68,7 +67,6 @@ export const TicketCreateDialog: FC<TicketCreateDialogProps> = ({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchGroups = async () => {
|
const fetchGroups = async () => {
|
||||||
const result = await getGroupsAction();
|
const result = await getGroupsAction();
|
||||||
console.log({ result });
|
|
||||||
setGroups(result);
|
setGroups(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ export const getGroupsAction = async () => {
|
||||||
|
|
||||||
return formattedGroups;
|
return formattedGroups;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export const getOverviewTicketCountsAction = async () => {
|
||||||
|
|
||||||
return counts;
|
return counts;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -91,7 +91,7 @@ export const getOverviewTicketsAction = async (name: string) => {
|
||||||
|
|
||||||
return { tickets: sortedTickets };
|
return { tickets: sortedTickets };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return { tickets, message: e.message ?? "" };
|
return { tickets, message: e.message ?? "" };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export const searchAllAction = async (query: string, limit: number) => {
|
||||||
|
|
||||||
return result?.search;
|
return result?.search;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export const createTicketAction = async (
|
||||||
success: true,
|
success: true,
|
||||||
};
|
};
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log({ e });
|
console.error(e.message);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
values: {},
|
values: {},
|
||||||
|
|
@ -63,7 +63,7 @@ export const createTicketArticleAction = async (
|
||||||
success: true,
|
success: true,
|
||||||
};
|
};
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log({ e });
|
console.error(e.message);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: e?.message ?? "Unknown error",
|
message: e?.message ?? "Unknown error",
|
||||||
|
|
@ -117,7 +117,7 @@ export const updateTicketAction = async (
|
||||||
success: true,
|
success: true,
|
||||||
};
|
};
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log({ e });
|
console.error(e.message);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: e?.message ?? "Unknown error",
|
message: e?.message ?? "Unknown error",
|
||||||
|
|
@ -134,7 +134,7 @@ export const getTicketAction = async (id: string) => {
|
||||||
|
|
||||||
return ticketData?.ticket;
|
return ticketData?.ticket;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -148,7 +148,7 @@ export const getTicketArticlesAction = async (id: string) => {
|
||||||
|
|
||||||
return ticketData?.ticketArticles;
|
return ticketData?.ticketArticles;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -167,7 +167,7 @@ export const getTicketStatesAction = async () => {
|
||||||
|
|
||||||
return formattedStates;
|
return formattedStates;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -180,7 +180,7 @@ export const getTagsAction = async () => {
|
||||||
|
|
||||||
return tags;
|
return tags;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -199,7 +199,7 @@ export const getTicketPrioritiesAction = async () => {
|
||||||
|
|
||||||
return formattedPriorities;
|
return formattedPriorities;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export const getAgentsAction = async () => {
|
||||||
|
|
||||||
return formattedAgents;
|
return formattedAgents;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -39,7 +39,7 @@ export const getCustomersAction = async () => {
|
||||||
|
|
||||||
return formattedCustomers;
|
return formattedCustomers;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -59,7 +59,7 @@ export const getUsersAction = async () => {
|
||||||
|
|
||||||
return formattedUsers;
|
return formattedUsers;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e.message);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,33 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { FC, PropsWithChildren, useState, useEffect } from "react";
|
import { FC, PropsWithChildren, useEffect } from "react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
|
|
||||||
export const CSRFProvider: FC<PropsWithChildren> = ({ children }) => {
|
export const CSRFProvider: FC<PropsWithChildren> = ({ children }) => {
|
||||||
const { data: session, status, update } = useSession();
|
const { data: session, status, update } = useSession();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [redirectCount, setRedirectCount] = useState(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const interval = setInterval(async () => {
|
const checkSession = async () => {
|
||||||
console.log("Checking session status...");
|
console.log("Checking session status...");
|
||||||
console.log(status);
|
console.log(status);
|
||||||
if (status === "authenticated") {
|
if (status === "authenticated") {
|
||||||
const response = await fetch("/api/v1/users/me");
|
const response = await fetch("/api/v1/users/me", {
|
||||||
console.log(response.ok);
|
method: "GET",
|
||||||
console.log(!!router);
|
});
|
||||||
if (!response.ok && !!router) {
|
|
||||||
|
if (response.status !== 200 && !!router) {
|
||||||
console.log("redirecting");
|
console.log("redirecting");
|
||||||
setRedirectCount(redirectCount + 1);
|
window.location.href = "/auth/sso";
|
||||||
router.push("/setup");
|
|
||||||
} else {
|
} else {
|
||||||
setRedirectCount(0);
|
|
||||||
const token = response.headers.get("CSRF-Token");
|
const token = response.headers.get("CSRF-Token");
|
||||||
update({ csrfToken: token });
|
update({ zammadCsrfToken: token });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 15000);
|
};
|
||||||
|
|
||||||
|
const interval = setInterval(checkSession, 15000);
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [session, status, update, router]);
|
}, [session, status, update, router]);
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ export const authOptions: NextAuthOptions = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session && trigger === "update") {
|
if (session && trigger === "update") {
|
||||||
token.zammadCsrfToken = session.csrfToken;
|
token.zammadCsrfToken = session.zammadCsrfToken;
|
||||||
}
|
}
|
||||||
return token;
|
return token;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ const getHeaders = async () => {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
"X-CSRF-Token": session.user.zammadCsrfToken,
|
"X-CSRF-Token": session.user.zammadCsrfToken,
|
||||||
|
"X-Browser-Fingerprint": `${session.expires}`,
|
||||||
Cookie: allCookies
|
Cookie: allCookies
|
||||||
.map((cookie: any) => `${cookie.name}=${cookie.value}`)
|
.map((cookie: any) => `${cookie.name}=${cookie.value}`)
|
||||||
.join("; "),
|
.join("; "),
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
"target": "esnext",
|
||||||
"strict": false,
|
"strict": false,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
|
|
|
||||||
63698
package-lock.json
generated
63698
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -51,7 +51,8 @@
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"dotenv-cli": "latest",
|
"dotenv-cli": "latest",
|
||||||
"eslint": "^8"
|
"eslint": "^8",
|
||||||
|
"typescript": "latest"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"eslint-config-next": {
|
"eslint-config-next": {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,10 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc"
|
"build": "tsc"
|
||||||
},
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5",
|
||||||
|
"@types/node": "^22"
|
||||||
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "AGPL-3.0-or-later"
|
"license": "AGPL-3.0-or-later"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"target": "es2020",
|
"target": "es2020",
|
||||||
"lib": [
|
"lib": ["es2020"],
|
||||||
"es2020"
|
|
||||||
],
|
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
|
|
@ -22,9 +20,6 @@
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"types": [
|
"types": ["node"]
|
||||||
"node",
|
|
||||||
"jest"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue