fetchers updated
This commit is contained in:
parent
a8ff968962
commit
df3f59bd8e
|
|
@ -0,0 +1,5 @@
|
|||
const BASE_URL = "http://localhost:3000";
|
||||
const API_URL = "http://localhost:3000/api";
|
||||
export const WEB_BASE_URL = process.env.WEB_BASE_URL || BASE_URL;
|
||||
export const API_BASE_URL = process.env.API_BASE_URL || API_URL;
|
||||
0
|
||||
|
|
@ -3,8 +3,8 @@ import NextCrypto from "next-crypto";
|
|||
|
||||
const tokenSecretEnv = process.env.TOKENSECRET_90;
|
||||
const tokenSecret = tokenSecretEnv || "e781d1b0-9418-40b3-9940-385abf81a0b7";
|
||||
const REDIS_TIMEOUT = 5000; // Redis operation timeout (5 seconds)
|
||||
const nextCrypto = new NextCrypto(tokenSecret);
|
||||
|
||||
const cookieObject: CookieObject = {
|
||||
httpOnly: true,
|
||||
path: "/",
|
||||
|
|
@ -13,7 +13,6 @@ const cookieObject: CookieObject = {
|
|||
maxAge: 3600,
|
||||
priority: "high",
|
||||
};
|
||||
|
||||
const DEFAULT_TIMEOUT: number = 10000; // 10 seconds
|
||||
const defaultHeaders: Record<string, string> = {
|
||||
accept: "application/json",
|
||||
|
|
@ -31,6 +30,7 @@ const DEFAULT_RESPONSE: ApiResponse = {
|
|||
export {
|
||||
DEFAULT_TIMEOUT,
|
||||
DEFAULT_RESPONSE,
|
||||
REDIS_TIMEOUT,
|
||||
defaultHeaders,
|
||||
tokenSecret,
|
||||
cookieObject,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientRedisToken, defaultClientRedisToken } from "@/fetchers/types/context";
|
||||
import { REDIS_TIMEOUT } from "@/fetchers/base";
|
||||
|
||||
/**
|
||||
* Gets the complete data from Redis with improved error handling and timeouts
|
||||
* @returns The complete Redis data or default values if there's an error
|
||||
*/
|
||||
const getCompleteFromRedis = async (): Promise<ClientRedisToken> => {
|
||||
try {
|
||||
let decrpytUserSelection;
|
||||
try { decrpytUserSelection = await functionRetrieveUserSelection() } catch (error) { return defaultClientRedisToken }
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) { return defaultClientRedisToken }
|
||||
if (redisKey === "default") { return defaultClientRedisToken }
|
||||
|
||||
try {
|
||||
const timeoutPromise = new Promise<string | null>((_, reject) => {
|
||||
setTimeout(() => reject(new Error('Redis operation timed out')), REDIS_TIMEOUT);
|
||||
});
|
||||
const result = await Promise.race([redis.get(`${redisKey}`), timeoutPromise]);
|
||||
if (!result) { return defaultClientRedisToken }
|
||||
try { const parsedResult = JSON.parse(result); return parsedResult } catch (parseError) { return defaultClientRedisToken }
|
||||
} catch (redisError) { return defaultClientRedisToken }
|
||||
} catch (error) { return defaultClientRedisToken }
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the complete data in Redis with improved error handling and timeouts
|
||||
* @param completeObject The complete data to set in Redis
|
||||
* @returns True if successful, false otherwise
|
||||
*/
|
||||
const setCompleteToRedis = async (completeObject: ClientRedisToken): Promise<boolean> => {
|
||||
try {
|
||||
if (!completeObject) { return false }
|
||||
let decrpytUserSelection;
|
||||
try { decrpytUserSelection = await functionRetrieveUserSelection() } catch (error) { return false }
|
||||
if (!decrpytUserSelection) { return false }
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) { return false }
|
||||
try {
|
||||
const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Redis operation timed out')), REDIS_TIMEOUT) });
|
||||
await Promise.race([redis.set(redisKey, JSON.stringify(completeObject)), timeoutPromise]);
|
||||
return true;
|
||||
} catch (redisError) { return false }
|
||||
} catch (error) { return false }
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets new complete data in Redis with a specific key with improved error handling and timeouts
|
||||
* @param completeObject The complete data to set in Redis
|
||||
* @param redisKey The specific Redis key to use
|
||||
* @returns True if successful, false otherwise
|
||||
*/
|
||||
const setNewCompleteToRedis = async (completeObject: ClientRedisToken, redisKey: string): Promise<boolean> => {
|
||||
try {
|
||||
if (!redisKey) { return false }
|
||||
if (!completeObject) { return false }
|
||||
try {
|
||||
const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Redis operation timed out')), REDIS_TIMEOUT) });
|
||||
await Promise.race([redis.set(redisKey, JSON.stringify(completeObject)), timeoutPromise])
|
||||
return true;
|
||||
} catch (redisError) { return false }
|
||||
} catch (error) { return false }
|
||||
}
|
||||
|
||||
export { getCompleteFromRedis, setCompleteToRedis, setNewCompleteToRedis };
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientSelection, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
|
||||
const getSelectionFromRedis = async (): Promise<ClientSelection> => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection();
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (redisKey === "default") { return { selectionList: [], activeSelection: {} } }
|
||||
const result = await redis.get(`${redisKey}`);
|
||||
if (!result) { return { selectionList: [], activeSelection: {} } }
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.selection) { return { selectionList: [], activeSelection: {} } }
|
||||
return parsedResult.selection;
|
||||
} catch (error) { return { selectionList: [], activeSelection: {} } }
|
||||
}
|
||||
|
||||
const setSelectionToRedis = async (selectionObject: ClientSelection) => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
|
||||
if (!selectionObject) throw new AuthError("No selection object provided");
|
||||
|
||||
const oldData = await getCompleteFromRedis();
|
||||
if (!oldData) throw new AuthError("No old data found in redis");
|
||||
|
||||
await setCompleteToRedis({ ...oldData, selection: selectionObject })
|
||||
return true;
|
||||
} catch (error) {
|
||||
// Re-throw AuthError instances, wrap other errors as AuthError
|
||||
if (error instanceof AuthError) {
|
||||
throw error;
|
||||
} else {
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { getSelectionFromRedis, setSelectionToRedis };
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientSettings, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
|
||||
const getSettingsFromRedis = async (): Promise<ClientSettings> => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
const result = await redis.get(`${redisKey}`);
|
||||
if (!result) throw new AuthError("No data found in redis");
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.settings) throw new AuthError("No settings found in redis");
|
||||
return parsedResult.settings;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
const setSettingsToRedis = async (settingsObject: ClientSettings) => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
if (!settingsObject) throw new AuthError("No settings object provided");
|
||||
const oldData = await getCompleteFromRedis();
|
||||
if (!oldData) throw new AuthError("No old data found in redis");
|
||||
await setCompleteToRedis({ ...oldData, settings: settingsObject })
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
export { getSettingsFromRedis, setSettingsToRedis };
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientUser, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
|
||||
const getUserFromRedis = async (): Promise<ClientUser> => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
const result = await redis.get(`${redisKey}`);
|
||||
if (!result) throw new AuthError("No data found in redis");
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.user) throw new AuthError("No user found in redis");
|
||||
return parsedResult.user;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
const setUserToRedis = async (userObject: ClientUser) => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
if (!userObject) throw new AuthError("No user object provided");
|
||||
const oldData = await getCompleteFromRedis();
|
||||
if (!oldData) throw new AuthError("No old data found in redis");
|
||||
await setCompleteToRedis({ ...oldData, user: userObject });
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
export { getUserFromRedis, setUserToRedis };
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientSettings, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
|
||||
const getConfigFromRedis = async (): Promise<ClientSettings> => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
const result = await redis.get(`${redisKey}`);
|
||||
if (!result) throw new AuthError("No data found in redis");
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.settings) throw new AuthError("No settings found in redis");
|
||||
return parsedResult.settings;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
const setConfigToRedis = async (settingsObject: ClientSettings) => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
if (!settingsObject) throw new AuthError("No settings object provided");
|
||||
const oldData = await getCompleteFromRedis();
|
||||
if (!oldData) throw new AuthError("No old data found in redis");
|
||||
await setCompleteToRedis({ ...oldData, settings: settingsObject });
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
export { getConfigFromRedis, setConfigToRedis };
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientMenu, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
|
||||
const getMenuFromRedis = async (): Promise<ClientMenu> => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
const result = await redis.get(`${redisKey}`);
|
||||
if (!result) throw new AuthError("No data found in redis");
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.menu) throw new AuthError("No menu found in redis");
|
||||
return parsedResult.menu;
|
||||
} catch (error) { if (error instanceof AuthError) { throw error } else { throw new AuthError(error instanceof Error ? error.message : "Unknown error") } }
|
||||
}
|
||||
|
||||
const setMenuToRedis = async (menuObject: ClientMenu) => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
if (!menuObject) throw new AuthError("No menu object provided");
|
||||
const oldData = await getCompleteFromRedis();
|
||||
if (!oldData) throw new AuthError("No old data found in redis");
|
||||
await setCompleteToRedis({ ...oldData, menu: menuObject });
|
||||
return true;
|
||||
} catch (error) { if (error instanceof AuthError) { throw error } else { throw new AuthError(error instanceof Error ? error.message : "Unknown error") } }
|
||||
}
|
||||
|
||||
export { getMenuFromRedis, setMenuToRedis };
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientOnline, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
import { REDIS_TIMEOUT } from "@/fetchers/base";
|
||||
|
||||
/**
|
||||
* Gets the online state from Redis
|
||||
* @returns The online state object
|
||||
*/
|
||||
const getOnlineFromRedis = async (): Promise<ClientOnline> => {
|
||||
try {
|
||||
let result;
|
||||
let decrpytUserSelection;
|
||||
try { decrpytUserSelection = await functionRetrieveUserSelection() } catch (error) { throw new AuthError('Failed to retrieve user selection') }
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) { throw new AuthError('No redis key found') }
|
||||
if (redisKey === "default") { throw new AuthError('Invalid redis key') }
|
||||
try {
|
||||
const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Redis operation timed out')), REDIS_TIMEOUT) });
|
||||
result = await Promise.race([redis.get(`${redisKey}`), timeoutPromise]) as string | null;
|
||||
} catch (redisError) { throw new AuthError('Failed to access Redis data') }
|
||||
|
||||
if (!result) { throw new AuthError('No data found in redis') }
|
||||
|
||||
try {
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.online) { throw new AuthError('No online data found in redis') }
|
||||
return parsedResult.online;
|
||||
} catch (parseError) { throw new AuthError('Invalid data format in redis') }
|
||||
} catch (error) { if (error instanceof AuthError) { throw error } else { throw new AuthError(error instanceof Error ? error.message : 'Unknown error') } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the online state in Redis
|
||||
* @param onlineObject The online state to set
|
||||
* @returns True if successful, false otherwise
|
||||
*/
|
||||
const setOnlineToRedis = async (onlineObject: ClientOnline): Promise<boolean> => {
|
||||
try {
|
||||
if (!onlineObject) { throw new AuthError('No online object provided') }
|
||||
|
||||
let decrpytUserSelection;
|
||||
let oldData;
|
||||
|
||||
try { decrpytUserSelection = await functionRetrieveUserSelection() } catch (error) { throw new AuthError('Failed to retrieve user selection') }
|
||||
if (!decrpytUserSelection) { throw new AuthError('No user selection found') }
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) { throw new AuthError('No redis key found') }
|
||||
try { oldData = await getCompleteFromRedis() } catch (error) { throw new AuthError('Failed to retrieve existing data from Redis') }
|
||||
if (!oldData) { throw new AuthError('No old data found in redis') }
|
||||
try {
|
||||
const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Redis operation timed out')), REDIS_TIMEOUT) });
|
||||
await Promise.race([setCompleteToRedis({ ...oldData, online: onlineObject }), timeoutPromise]);
|
||||
return true;
|
||||
} catch (redisError) { throw new AuthError('Failed to update Redis data') }
|
||||
} catch (error) { if (error instanceof AuthError) throw error; throw new AuthError(error instanceof Error ? error.message : 'Unknown error') }
|
||||
}
|
||||
|
||||
export { getOnlineFromRedis, setOnlineToRedis };
|
||||
|
|
@ -1,7 +1,75 @@
|
|||
"use server";
|
||||
import { DEFAULT_RESPONSE, defaultHeaders, DEFAULT_TIMEOUT } from "./base";
|
||||
import {
|
||||
DEFAULT_RESPONSE,
|
||||
defaultHeaders,
|
||||
DEFAULT_TIMEOUT,
|
||||
nextCrypto,
|
||||
} from "./base";
|
||||
import { FetchOptions, HttpMethod, ApiResponse } from "./types";
|
||||
import { retrieveAccessToken } from "./mutual/cookies/token";
|
||||
import { cookies } from "next/headers";
|
||||
import { cookieObject } from "@/fetchers/base";
|
||||
|
||||
/**
|
||||
* Retrieves user selection from cookies with graceful fallback
|
||||
* @returns User selection object or default selection if not found
|
||||
*/
|
||||
const functionRetrieveUserSelection = async () => {
|
||||
try {
|
||||
const cookieStore = await cookies();
|
||||
const encrpytUserSelection = cookieStore.get("eys-sel")?.value || "";
|
||||
if (!encrpytUserSelection) {
|
||||
return {
|
||||
redisKey: "default",
|
||||
uuid: "",
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
try {
|
||||
const decrpytUserSelection = await nextCrypto.decrypt(
|
||||
encrpytUserSelection
|
||||
);
|
||||
if (!decrpytUserSelection) {
|
||||
return {
|
||||
redisKey: "default",
|
||||
uuid: "",
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
return JSON.parse(decrpytUserSelection);
|
||||
} catch (decryptError) {
|
||||
return {
|
||||
redisKey: "default",
|
||||
uuid: "",
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
redisKey: "default",
|
||||
uuid: "",
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const functionSetUserSelection = async (userSelection: any) => {
|
||||
const cookieStore = await cookies();
|
||||
const encrpytUserSelection = await nextCrypto.encrypt(
|
||||
JSON.stringify(userSelection)
|
||||
);
|
||||
if (!encrpytUserSelection) throw new Error("No user selection found");
|
||||
cookieStore.set({
|
||||
name: "eys-sel",
|
||||
value: encrpytUserSelection,
|
||||
...cookieObject,
|
||||
} as any);
|
||||
};
|
||||
|
||||
const functionRemoveUserSelection = async () => {
|
||||
const cookieStore = await cookies();
|
||||
cookieStore.delete("eys-sel");
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a promise that rejects after a specified timeout
|
||||
|
|
@ -124,4 +192,11 @@ async function updateDataWithToken<T>(
|
|||
);
|
||||
}
|
||||
|
||||
export { fetchData, fetchDataWithToken, updateDataWithToken };
|
||||
export {
|
||||
fetchData,
|
||||
fetchDataWithToken,
|
||||
updateDataWithToken,
|
||||
functionRetrieveUserSelection,
|
||||
functionSetUserSelection,
|
||||
functionRemoveUserSelection,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
import { ClientRedisOnline } from "@/fetchers/types/context/online/validations";
|
||||
import { ClientPageConfig } from "@/fetchers/types/context/pageConfig/validations";
|
||||
import { ClientMenu } from "@/fetchers/types/context/menu/validations";
|
||||
import { ClientHeader } from "@/fetchers/types/context/header/validations";
|
||||
import { ClientSelection } from "@/fetchers/types/context/selection/validations";
|
||||
import { ClientUser } from "@/fetchers/types/context/user/validations";
|
||||
import { ClientSettings } from "@/fetchers/types/context/settings/validations";
|
||||
import { defaultValuesOnline } from "@/fetchers/types/context/online/validations";
|
||||
import { defaultValuesPageConfig } from "@/fetchers/types/context/pageConfig/validations";
|
||||
import { defaultValuesMenu } from "@/fetchers/types/context/menu/validations";
|
||||
import { defaultValuesHeader } from "@/fetchers/types/context/header/validations";
|
||||
import { defaultValuesSelection } from "@/fetchers/types/context/selection/validations";
|
||||
import { defaultValuesUser } from "@/fetchers/types/context/user/validations";
|
||||
import { defaultValuesSettings } from "@/fetchers/types/context/settings/validations";
|
||||
|
||||
interface ClientRedisToken {
|
||||
online: ClientRedisOnline;
|
||||
pageConfig: ClientPageConfig;
|
||||
menu: ClientMenu;
|
||||
header: ClientHeader;
|
||||
selection: ClientSelection;
|
||||
user: ClientUser;
|
||||
settings: ClientSettings;
|
||||
chatRoom: string[];
|
||||
notifications: string[];
|
||||
messages: string[];
|
||||
}
|
||||
|
||||
const defaultClientRedisToken: ClientRedisToken = {
|
||||
online: defaultValuesOnline,
|
||||
pageConfig: defaultValuesPageConfig,
|
||||
menu: defaultValuesMenu,
|
||||
header: defaultValuesHeader,
|
||||
selection: defaultValuesSelection,
|
||||
user: defaultValuesUser,
|
||||
settings: defaultValuesSettings,
|
||||
chatRoom: [],
|
||||
notifications: [],
|
||||
messages: [],
|
||||
};
|
||||
|
||||
export type { ClientRedisToken };
|
||||
export { defaultClientRedisToken };
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
interface ClientHeader {
|
||||
header: string[];
|
||||
activeDomain: string;
|
||||
listOfDomains: string[];
|
||||
connections: string[];
|
||||
}
|
||||
|
||||
const defaultValuesHeader: ClientHeader = {
|
||||
header: [],
|
||||
activeDomain: "",
|
||||
listOfDomains: [],
|
||||
connections: [],
|
||||
};
|
||||
|
||||
export type { ClientHeader };
|
||||
export { defaultValuesHeader };
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
import {
|
||||
ClientRedisToken,
|
||||
defaultClientRedisToken,
|
||||
} from "@/fetchers/types/context/complete/validations";
|
||||
import {
|
||||
ClientPageConfig,
|
||||
defaultValuesPageConfig,
|
||||
} from "@/fetchers/types/context/pageConfig/validations";
|
||||
import {
|
||||
ClientMenu,
|
||||
defaultValuesMenu,
|
||||
} from "@/fetchers/types/context/menu/validations";
|
||||
import {
|
||||
ClientHeader,
|
||||
defaultValuesHeader,
|
||||
} from "@/fetchers/types/context/header/validations";
|
||||
import {
|
||||
ClientSelection,
|
||||
defaultValuesSelection,
|
||||
} from "@/fetchers/types/context/selection/validations";
|
||||
import {
|
||||
ClientUser,
|
||||
defaultValuesUser,
|
||||
} from "@/fetchers/types/context/user/validations";
|
||||
import {
|
||||
ClientSettings,
|
||||
defaultValuesSettings,
|
||||
} from "@/fetchers/types/context/settings/validations";
|
||||
import {
|
||||
ClientOnline,
|
||||
defaultValuesOnline,
|
||||
} from "@/fetchers/types/context/online/validations";
|
||||
|
||||
class AuthError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = "AuthError";
|
||||
}
|
||||
}
|
||||
|
||||
export type {
|
||||
ClientRedisToken,
|
||||
ClientOnline,
|
||||
ClientPageConfig,
|
||||
ClientMenu,
|
||||
ClientHeader,
|
||||
ClientSelection,
|
||||
ClientUser,
|
||||
ClientSettings,
|
||||
};
|
||||
|
||||
export {
|
||||
defaultClientRedisToken,
|
||||
defaultValuesOnline,
|
||||
defaultValuesPageConfig,
|
||||
defaultValuesMenu,
|
||||
defaultValuesHeader,
|
||||
defaultValuesSelection,
|
||||
defaultValuesUser,
|
||||
defaultValuesSettings,
|
||||
AuthError,
|
||||
};
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
interface ClientMenu {
|
||||
selectionList: string[];
|
||||
activeSelection: string;
|
||||
}
|
||||
|
||||
const defaultValuesMenu: ClientMenu = {
|
||||
selectionList: ["/dashboard"],
|
||||
activeSelection: "/dashboard",
|
||||
};
|
||||
|
||||
export type { ClientMenu };
|
||||
export { defaultValuesMenu };
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
interface ClientOnline {
|
||||
lastLogin: Date;
|
||||
lastLogout: Date;
|
||||
lastAction: Date;
|
||||
lastPage: string;
|
||||
userType: string;
|
||||
lang: string;
|
||||
timezone: string;
|
||||
}
|
||||
|
||||
const defaultValuesOnline: ClientOnline = {
|
||||
lastLogin: new Date(),
|
||||
lastLogout: new Date(),
|
||||
lastAction: new Date(),
|
||||
lastPage: "/dashboard",
|
||||
userType: "employee",
|
||||
lang: "tr",
|
||||
timezone: "GMT+3",
|
||||
};
|
||||
|
||||
export type { ClientOnline };
|
||||
export { defaultValuesOnline };
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
interface ClientPageConfig {
|
||||
mode: string;
|
||||
textFont: number;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
const defaultValuesPageConfig: ClientPageConfig = {
|
||||
mode: "light",
|
||||
textFont: 14,
|
||||
theme: "default",
|
||||
};
|
||||
|
||||
export type { ClientPageConfig };
|
||||
export { defaultValuesPageConfig };
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
interface ClientSelection {
|
||||
selectionList: string[];
|
||||
activeSelection: Record<string, any>;
|
||||
}
|
||||
|
||||
const defaultValuesSelection: ClientSelection = {
|
||||
selectionList: ["/dashboard"],
|
||||
activeSelection: {},
|
||||
};
|
||||
|
||||
export type { ClientSelection };
|
||||
export { defaultValuesSelection };
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
interface ClientSettings {
|
||||
lastOnline: Date;
|
||||
token: string;
|
||||
}
|
||||
|
||||
const defaultValuesSettings: ClientSettings = {
|
||||
lastOnline: new Date(),
|
||||
token: "",
|
||||
};
|
||||
|
||||
export type { ClientSettings };
|
||||
export { defaultValuesSettings };
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
interface Person {
|
||||
uuid: string;
|
||||
firstname: string;
|
||||
surname: string;
|
||||
middle_name: string;
|
||||
sex_code: string;
|
||||
person_tag: string;
|
||||
country_code: string;
|
||||
birth_date: string;
|
||||
}
|
||||
|
||||
interface ClientUser {
|
||||
uuid: string;
|
||||
avatar: string;
|
||||
email: string;
|
||||
phone_number: string;
|
||||
user_tag: string;
|
||||
password_expiry_begins: string;
|
||||
person: Person;
|
||||
}
|
||||
|
||||
const defaultValuesPerson: Person = {
|
||||
uuid: "",
|
||||
firstname: "",
|
||||
surname: "",
|
||||
middle_name: "",
|
||||
sex_code: "",
|
||||
person_tag: "",
|
||||
country_code: "",
|
||||
birth_date: "",
|
||||
};
|
||||
|
||||
const defaultValuesUser: ClientUser = {
|
||||
uuid: "",
|
||||
avatar: "",
|
||||
email: "",
|
||||
phone_number: "",
|
||||
user_tag: "",
|
||||
password_expiry_begins: new Date().toISOString(),
|
||||
person: defaultValuesPerson,
|
||||
};
|
||||
|
||||
export type { ClientUser };
|
||||
export { defaultValuesUser };
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
// From Redis objects
|
||||
export class AuthError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'AuthError';
|
||||
}
|
||||
}
|
||||
|
||||
interface ClientOnline {
|
||||
lastLogin: Date;
|
||||
lastLogout: Date;
|
||||
lastAction: Date;
|
||||
lastPage: string;
|
||||
userType: string;
|
||||
lang: string;
|
||||
timezone: string;
|
||||
}
|
||||
|
||||
interface ClientPageConfig {
|
||||
mode: string;
|
||||
textFont: number;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
interface ClientHeader {
|
||||
header: any[];
|
||||
activeDomain: string;
|
||||
listOfDomains: string[];
|
||||
connections: any[];
|
||||
}
|
||||
|
||||
interface ClientMenu {
|
||||
selectionList: string[];
|
||||
activeSelection: string;
|
||||
}
|
||||
|
||||
interface ClientSelection {
|
||||
selectionList: any[];
|
||||
activeSelection: Record<string, any>;
|
||||
}
|
||||
|
||||
interface ClientUser {
|
||||
uuid: string;
|
||||
avatar: string;
|
||||
email: string;
|
||||
phone_number: string;
|
||||
user_tag: string;
|
||||
password_expiry_begins: string;
|
||||
person: {
|
||||
uuid: string;
|
||||
firstname: string;
|
||||
surname: string;
|
||||
middle_name: string;
|
||||
sex_code: string;
|
||||
person_tag: string;
|
||||
country_code: string;
|
||||
birth_date: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface ClientSettings {
|
||||
lastOnline: Date;
|
||||
token: string;
|
||||
}
|
||||
|
||||
interface LinkList {
|
||||
linkList: any[];
|
||||
}
|
||||
|
||||
interface ClientRedisToken {
|
||||
online: ClientOnline;
|
||||
pageConfig: ClientPageConfig;
|
||||
menu: ClientMenu;
|
||||
header: ClientHeader;
|
||||
selection: ClientSelection;
|
||||
user: ClientUser;
|
||||
settings: ClientSettings;
|
||||
chatRoom: LinkList;
|
||||
notifications: LinkList;
|
||||
messages: LinkList;
|
||||
}
|
||||
|
||||
const defaultClientOnline: ClientOnline = {
|
||||
lastLogin: new Date(),
|
||||
lastLogout: new Date(),
|
||||
lastAction: new Date(),
|
||||
lastPage: "/dashboard",
|
||||
userType: "employee",
|
||||
lang: "tr",
|
||||
timezone: "GMT+3",
|
||||
};
|
||||
|
||||
const defaultClientPageConfig: ClientPageConfig = {
|
||||
mode: "light",
|
||||
textFont: 14,
|
||||
theme: "default",
|
||||
};
|
||||
|
||||
const defaultClientMenu: ClientMenu = {
|
||||
selectionList: [],
|
||||
activeSelection: "/dashboard",
|
||||
};
|
||||
|
||||
const defaultClientHeader: ClientHeader = {
|
||||
header: [],
|
||||
activeDomain: "",
|
||||
listOfDomains: [],
|
||||
connections: [],
|
||||
};
|
||||
|
||||
const defaultClientSelection: ClientSelection = {
|
||||
selectionList: [],
|
||||
activeSelection: {},
|
||||
};
|
||||
|
||||
const defaultClientUser: ClientUser = {
|
||||
uuid: "",
|
||||
avatar: "",
|
||||
email: "",
|
||||
phone_number: "",
|
||||
user_tag: "",
|
||||
password_expiry_begins: new Date().toISOString(),
|
||||
person: {
|
||||
uuid: "",
|
||||
firstname: "",
|
||||
surname: "",
|
||||
middle_name: "",
|
||||
sex_code: "",
|
||||
person_tag: "",
|
||||
country_code: "",
|
||||
birth_date: "",
|
||||
},
|
||||
};
|
||||
|
||||
const defaultClientSettings: ClientSettings = {
|
||||
lastOnline: new Date(),
|
||||
token: "",
|
||||
};
|
||||
|
||||
const defaultLinkList: LinkList = {
|
||||
linkList: [],
|
||||
};
|
||||
|
||||
const defaultClientRedisToken: ClientRedisToken = {
|
||||
online: defaultClientOnline,
|
||||
pageConfig: defaultClientPageConfig,
|
||||
menu: defaultClientMenu,
|
||||
header: defaultClientHeader,
|
||||
selection: defaultClientSelection,
|
||||
user: defaultClientUser,
|
||||
settings: defaultClientSettings,
|
||||
chatRoom: defaultLinkList,
|
||||
notifications: defaultLinkList,
|
||||
messages: defaultLinkList,
|
||||
};
|
||||
|
||||
const generateRedisKey = (userType: string, uuId: string) => {
|
||||
const userTypeToUpper = userType.toUpperCase();
|
||||
if (!userTypeToUpper || !uuId) throw new Error("Invalid user type or uuId");
|
||||
return `CLIENT:${userTypeToUpper}:${uuId}`;
|
||||
};
|
||||
|
||||
const readRedisKey = (redisKey: string) => {
|
||||
if (redisKey.split(":").length !== 2) throw new Error("Invalid redis key");
|
||||
const userTypeToUpper = redisKey.split(":")[1];
|
||||
const uuId = redisKey.split(":")[2];
|
||||
if (!userTypeToUpper || !uuId) throw new Error("Invalid user type or uuId");
|
||||
return { userType: userTypeToUpper.toLowerCase(), uuId };
|
||||
};
|
||||
|
||||
export {
|
||||
defaultClientOnline,
|
||||
defaultClientPageConfig,
|
||||
defaultClientMenu,
|
||||
defaultClientHeader,
|
||||
defaultClientSelection,
|
||||
defaultClientUser,
|
||||
defaultClientSettings,
|
||||
defaultLinkList,
|
||||
defaultClientRedisToken,
|
||||
};
|
||||
export type {
|
||||
ClientOnline,
|
||||
ClientPageConfig,
|
||||
ClientMenu,
|
||||
ClientHeader,
|
||||
ClientSelection,
|
||||
ClientUser,
|
||||
ClientSettings,
|
||||
LinkList,
|
||||
ClientRedisToken,
|
||||
};
|
||||
export { generateRedisKey, readRedisKey };
|
||||
|
|
@ -3,8 +3,8 @@ import NextCrypto from "next-crypto";
|
|||
|
||||
const tokenSecretEnv = process.env.TOKENSECRET_90;
|
||||
const tokenSecret = tokenSecretEnv || "e781d1b0-9418-40b3-9940-385abf81a0b7";
|
||||
const REDIS_TIMEOUT = 5000; // Redis operation timeout (5 seconds)
|
||||
const nextCrypto = new NextCrypto(tokenSecret);
|
||||
|
||||
const cookieObject: CookieObject = {
|
||||
httpOnly: true,
|
||||
path: "/",
|
||||
|
|
@ -13,7 +13,6 @@ const cookieObject: CookieObject = {
|
|||
maxAge: 3600,
|
||||
priority: "high",
|
||||
};
|
||||
|
||||
const DEFAULT_TIMEOUT: number = 10000; // 10 seconds
|
||||
const defaultHeaders: Record<string, string> = {
|
||||
accept: "application/json",
|
||||
|
|
@ -31,6 +30,7 @@ const DEFAULT_RESPONSE: ApiResponse = {
|
|||
export {
|
||||
DEFAULT_TIMEOUT,
|
||||
DEFAULT_RESPONSE,
|
||||
REDIS_TIMEOUT,
|
||||
defaultHeaders,
|
||||
tokenSecret,
|
||||
cookieObject,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientRedisToken, defaultClientRedisToken } from "@/fetchers/types/context";
|
||||
import { REDIS_TIMEOUT } from "@/fetchers/base";
|
||||
|
||||
/**
|
||||
* Gets the complete data from Redis with improved error handling and timeouts
|
||||
* @returns The complete Redis data or default values if there's an error
|
||||
*/
|
||||
const getCompleteFromRedis = async (): Promise<ClientRedisToken> => {
|
||||
try {
|
||||
let decrpytUserSelection;
|
||||
try { decrpytUserSelection = await functionRetrieveUserSelection() } catch (error) { return defaultClientRedisToken }
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) { return defaultClientRedisToken }
|
||||
if (redisKey === "default") { return defaultClientRedisToken }
|
||||
|
||||
try {
|
||||
const timeoutPromise = new Promise<string | null>((_, reject) => {
|
||||
setTimeout(() => reject(new Error('Redis operation timed out')), REDIS_TIMEOUT);
|
||||
});
|
||||
const result = await Promise.race([redis.get(`${redisKey}`), timeoutPromise]);
|
||||
if (!result) { return defaultClientRedisToken }
|
||||
try { const parsedResult = JSON.parse(result); return parsedResult } catch (parseError) { return defaultClientRedisToken }
|
||||
} catch (redisError) { return defaultClientRedisToken }
|
||||
} catch (error) { return defaultClientRedisToken }
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the complete data in Redis with improved error handling and timeouts
|
||||
* @param completeObject The complete data to set in Redis
|
||||
* @returns True if successful, false otherwise
|
||||
*/
|
||||
const setCompleteToRedis = async (completeObject: ClientRedisToken): Promise<boolean> => {
|
||||
try {
|
||||
if (!completeObject) { return false }
|
||||
let decrpytUserSelection;
|
||||
try { decrpytUserSelection = await functionRetrieveUserSelection() } catch (error) { return false }
|
||||
if (!decrpytUserSelection) { return false }
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) { return false }
|
||||
try {
|
||||
const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Redis operation timed out')), REDIS_TIMEOUT) });
|
||||
await Promise.race([redis.set(redisKey, JSON.stringify(completeObject)), timeoutPromise]);
|
||||
return true;
|
||||
} catch (redisError) { return false }
|
||||
} catch (error) { return false }
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets new complete data in Redis with a specific key with improved error handling and timeouts
|
||||
* @param completeObject The complete data to set in Redis
|
||||
* @param redisKey The specific Redis key to use
|
||||
* @returns True if successful, false otherwise
|
||||
*/
|
||||
const setNewCompleteToRedis = async (completeObject: ClientRedisToken, redisKey: string): Promise<boolean> => {
|
||||
try {
|
||||
if (!redisKey) { return false }
|
||||
if (!completeObject) { return false }
|
||||
try {
|
||||
const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Redis operation timed out')), REDIS_TIMEOUT) });
|
||||
await Promise.race([redis.set(redisKey, JSON.stringify(completeObject)), timeoutPromise])
|
||||
return true;
|
||||
} catch (redisError) { return false }
|
||||
} catch (error) { return false }
|
||||
}
|
||||
|
||||
export { getCompleteFromRedis, setCompleteToRedis, setNewCompleteToRedis };
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientSelection, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
|
||||
const getSelectionFromRedis = async (): Promise<ClientSelection> => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection();
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (redisKey === "default") { return { selectionList: [], activeSelection: {} } }
|
||||
const result = await redis.get(`${redisKey}`);
|
||||
if (!result) { return { selectionList: [], activeSelection: {} } }
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.selection) { return { selectionList: [], activeSelection: {} } }
|
||||
return parsedResult.selection;
|
||||
} catch (error) { return { selectionList: [], activeSelection: {} } }
|
||||
}
|
||||
|
||||
const setSelectionToRedis = async (selectionObject: ClientSelection) => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
|
||||
if (!selectionObject) throw new AuthError("No selection object provided");
|
||||
|
||||
const oldData = await getCompleteFromRedis();
|
||||
if (!oldData) throw new AuthError("No old data found in redis");
|
||||
|
||||
await setCompleteToRedis({ ...oldData, selection: selectionObject })
|
||||
return true;
|
||||
} catch (error) {
|
||||
// Re-throw AuthError instances, wrap other errors as AuthError
|
||||
if (error instanceof AuthError) {
|
||||
throw error;
|
||||
} else {
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { getSelectionFromRedis, setSelectionToRedis };
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientSettings, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
|
||||
const getSettingsFromRedis = async (): Promise<ClientSettings> => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
const result = await redis.get(`${redisKey}`);
|
||||
if (!result) throw new AuthError("No data found in redis");
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.settings) throw new AuthError("No settings found in redis");
|
||||
return parsedResult.settings;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
const setSettingsToRedis = async (settingsObject: ClientSettings) => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
if (!settingsObject) throw new AuthError("No settings object provided");
|
||||
const oldData = await getCompleteFromRedis();
|
||||
if (!oldData) throw new AuthError("No old data found in redis");
|
||||
await setCompleteToRedis({ ...oldData, settings: settingsObject })
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
export { getSettingsFromRedis, setSettingsToRedis };
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientUser, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
|
||||
const getUserFromRedis = async (): Promise<ClientUser> => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
const result = await redis.get(`${redisKey}`);
|
||||
if (!result) throw new AuthError("No data found in redis");
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.user) throw new AuthError("No user found in redis");
|
||||
return parsedResult.user;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
const setUserToRedis = async (userObject: ClientUser) => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
if (!userObject) throw new AuthError("No user object provided");
|
||||
const oldData = await getCompleteFromRedis();
|
||||
if (!oldData) throw new AuthError("No old data found in redis");
|
||||
await setCompleteToRedis({ ...oldData, user: userObject });
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
export { getUserFromRedis, setUserToRedis };
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientSettings, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
|
||||
const getConfigFromRedis = async (): Promise<ClientSettings> => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
const result = await redis.get(`${redisKey}`);
|
||||
if (!result) throw new AuthError("No data found in redis");
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.settings) throw new AuthError("No settings found in redis");
|
||||
return parsedResult.settings;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
const setConfigToRedis = async (settingsObject: ClientSettings) => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
if (!settingsObject) throw new AuthError("No settings object provided");
|
||||
const oldData = await getCompleteFromRedis();
|
||||
if (!oldData) throw new AuthError("No old data found in redis");
|
||||
await setCompleteToRedis({ ...oldData, settings: settingsObject });
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error instanceof AuthError) { throw error }
|
||||
throw new AuthError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
export { getConfigFromRedis, setConfigToRedis };
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientMenu, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
|
||||
const getMenuFromRedis = async (): Promise<ClientMenu> => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
const result = await redis.get(`${redisKey}`);
|
||||
if (!result) throw new AuthError("No data found in redis");
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.menu) throw new AuthError("No menu found in redis");
|
||||
return parsedResult.menu;
|
||||
} catch (error) { if (error instanceof AuthError) { throw error } else { throw new AuthError(error instanceof Error ? error.message : "Unknown error") } }
|
||||
}
|
||||
|
||||
const setMenuToRedis = async (menuObject: ClientMenu) => {
|
||||
try {
|
||||
const decrpytUserSelection = await functionRetrieveUserSelection()
|
||||
if (!decrpytUserSelection) throw new AuthError("No user selection found");
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) throw new AuthError("No redis key found");
|
||||
if (!menuObject) throw new AuthError("No menu object provided");
|
||||
const oldData = await getCompleteFromRedis();
|
||||
if (!oldData) throw new AuthError("No old data found in redis");
|
||||
await setCompleteToRedis({ ...oldData, menu: menuObject });
|
||||
return true;
|
||||
} catch (error) { if (error instanceof AuthError) { throw error } else { throw new AuthError(error instanceof Error ? error.message : "Unknown error") } }
|
||||
}
|
||||
|
||||
export { getMenuFromRedis, setMenuToRedis };
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
"use server";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
|
||||
import { ClientOnline, AuthError } from "@/fetchers/types/context";
|
||||
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
|
||||
import { REDIS_TIMEOUT } from "@/fetchers/base";
|
||||
|
||||
/**
|
||||
* Gets the online state from Redis
|
||||
* @returns The online state object
|
||||
*/
|
||||
const getOnlineFromRedis = async (): Promise<ClientOnline> => {
|
||||
try {
|
||||
let result;
|
||||
let decrpytUserSelection;
|
||||
try { decrpytUserSelection = await functionRetrieveUserSelection() } catch (error) { throw new AuthError('Failed to retrieve user selection') }
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) { throw new AuthError('No redis key found') }
|
||||
if (redisKey === "default") { throw new AuthError('Invalid redis key') }
|
||||
try {
|
||||
const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Redis operation timed out')), REDIS_TIMEOUT) });
|
||||
result = await Promise.race([redis.get(`${redisKey}`), timeoutPromise]) as string | null;
|
||||
} catch (redisError) { throw new AuthError('Failed to access Redis data') }
|
||||
|
||||
if (!result) { throw new AuthError('No data found in redis') }
|
||||
|
||||
try {
|
||||
const parsedResult = JSON.parse(result);
|
||||
if (!parsedResult.online) { throw new AuthError('No online data found in redis') }
|
||||
return parsedResult.online;
|
||||
} catch (parseError) { throw new AuthError('Invalid data format in redis') }
|
||||
} catch (error) { if (error instanceof AuthError) { throw error } else { throw new AuthError(error instanceof Error ? error.message : 'Unknown error') } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the online state in Redis
|
||||
* @param onlineObject The online state to set
|
||||
* @returns True if successful, false otherwise
|
||||
*/
|
||||
const setOnlineToRedis = async (onlineObject: ClientOnline): Promise<boolean> => {
|
||||
try {
|
||||
if (!onlineObject) { throw new AuthError('No online object provided') }
|
||||
|
||||
let decrpytUserSelection;
|
||||
let oldData;
|
||||
|
||||
try { decrpytUserSelection = await functionRetrieveUserSelection() } catch (error) { throw new AuthError('Failed to retrieve user selection') }
|
||||
if (!decrpytUserSelection) { throw new AuthError('No user selection found') }
|
||||
const redisKey = decrpytUserSelection?.redisKey;
|
||||
if (!redisKey) { throw new AuthError('No redis key found') }
|
||||
try { oldData = await getCompleteFromRedis() } catch (error) { throw new AuthError('Failed to retrieve existing data from Redis') }
|
||||
if (!oldData) { throw new AuthError('No old data found in redis') }
|
||||
try {
|
||||
const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Redis operation timed out')), REDIS_TIMEOUT) });
|
||||
await Promise.race([setCompleteToRedis({ ...oldData, online: onlineObject }), timeoutPromise]);
|
||||
return true;
|
||||
} catch (redisError) { throw new AuthError('Failed to update Redis data') }
|
||||
} catch (error) { if (error instanceof AuthError) throw error; throw new AuthError(error instanceof Error ? error.message : 'Unknown error') }
|
||||
}
|
||||
|
||||
export { getOnlineFromRedis, setOnlineToRedis };
|
||||
|
|
@ -1,7 +1,75 @@
|
|||
"use server";
|
||||
import { DEFAULT_RESPONSE, defaultHeaders, DEFAULT_TIMEOUT } from "./base";
|
||||
import {
|
||||
DEFAULT_RESPONSE,
|
||||
defaultHeaders,
|
||||
DEFAULT_TIMEOUT,
|
||||
nextCrypto,
|
||||
} from "./base";
|
||||
import { FetchOptions, HttpMethod, ApiResponse } from "./types";
|
||||
import { retrieveAccessToken } from "./mutual/cookies/token";
|
||||
import { cookies } from "next/headers";
|
||||
import { cookieObject } from "@/fetchers/base";
|
||||
|
||||
/**
|
||||
* Retrieves user selection from cookies with graceful fallback
|
||||
* @returns User selection object or default selection if not found
|
||||
*/
|
||||
const functionRetrieveUserSelection = async () => {
|
||||
try {
|
||||
const cookieStore = await cookies();
|
||||
const encrpytUserSelection = cookieStore.get("eys-sel")?.value || "";
|
||||
if (!encrpytUserSelection) {
|
||||
return {
|
||||
redisKey: "default",
|
||||
uuid: "",
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
try {
|
||||
const decrpytUserSelection = await nextCrypto.decrypt(
|
||||
encrpytUserSelection
|
||||
);
|
||||
if (!decrpytUserSelection) {
|
||||
return {
|
||||
redisKey: "default",
|
||||
uuid: "",
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
return JSON.parse(decrpytUserSelection);
|
||||
} catch (decryptError) {
|
||||
return {
|
||||
redisKey: "default",
|
||||
uuid: "",
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
redisKey: "default",
|
||||
uuid: "",
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const functionSetUserSelection = async (userSelection: any) => {
|
||||
const cookieStore = await cookies();
|
||||
const encrpytUserSelection = await nextCrypto.encrypt(
|
||||
JSON.stringify(userSelection)
|
||||
);
|
||||
if (!encrpytUserSelection) throw new Error("No user selection found");
|
||||
cookieStore.set({
|
||||
name: "eys-sel",
|
||||
value: encrpytUserSelection,
|
||||
...cookieObject,
|
||||
} as any);
|
||||
};
|
||||
|
||||
const functionRemoveUserSelection = async () => {
|
||||
const cookieStore = await cookies();
|
||||
cookieStore.delete("eys-sel");
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a promise that rejects after a specified timeout
|
||||
|
|
@ -124,4 +192,11 @@ async function updateDataWithToken<T>(
|
|||
);
|
||||
}
|
||||
|
||||
export { fetchData, fetchDataWithToken, updateDataWithToken };
|
||||
export {
|
||||
fetchData,
|
||||
fetchDataWithToken,
|
||||
updateDataWithToken,
|
||||
functionRetrieveUserSelection,
|
||||
functionSetUserSelection,
|
||||
functionRemoveUserSelection,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
import { ClientRedisOnline } from "@/fetchers/types/context/online/validations";
|
||||
import { ClientPageConfig } from "@/fetchers/types/context/pageConfig/validations";
|
||||
import { ClientMenu } from "@/fetchers/types/context/menu/validations";
|
||||
import { ClientHeader } from "@/fetchers/types/context/header/validations";
|
||||
import { ClientSelection } from "@/fetchers/types/context/selection/validations";
|
||||
import { ClientUser } from "@/fetchers/types/context/user/validations";
|
||||
import { ClientSettings } from "@/fetchers/types/context/settings/validations";
|
||||
import { defaultValuesOnline } from "@/fetchers/types/context/online/validations";
|
||||
import { defaultValuesPageConfig } from "@/fetchers/types/context/pageConfig/validations";
|
||||
import { defaultValuesMenu } from "@/fetchers/types/context/menu/validations";
|
||||
import { defaultValuesHeader } from "@/fetchers/types/context/header/validations";
|
||||
import { defaultValuesSelection } from "@/fetchers/types/context/selection/validations";
|
||||
import { defaultValuesUser } from "@/fetchers/types/context/user/validations";
|
||||
import { defaultValuesSettings } from "@/fetchers/types/context/settings/validations";
|
||||
|
||||
interface ClientRedisToken {
|
||||
online: ClientRedisOnline;
|
||||
pageConfig: ClientPageConfig;
|
||||
menu: ClientMenu;
|
||||
header: ClientHeader;
|
||||
selection: ClientSelection;
|
||||
user: ClientUser;
|
||||
settings: ClientSettings;
|
||||
chatRoom: string[];
|
||||
notifications: string[];
|
||||
messages: string[];
|
||||
}
|
||||
|
||||
const defaultClientRedisToken: ClientRedisToken = {
|
||||
online: defaultValuesOnline,
|
||||
pageConfig: defaultValuesPageConfig,
|
||||
menu: defaultValuesMenu,
|
||||
header: defaultValuesHeader,
|
||||
selection: defaultValuesSelection,
|
||||
user: defaultValuesUser,
|
||||
settings: defaultValuesSettings,
|
||||
chatRoom: [],
|
||||
notifications: [],
|
||||
messages: [],
|
||||
};
|
||||
|
||||
export type { ClientRedisToken };
|
||||
export { defaultClientRedisToken };
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
interface ClientHeader {
|
||||
header: string[];
|
||||
activeDomain: string;
|
||||
listOfDomains: string[];
|
||||
connections: string[];
|
||||
}
|
||||
|
||||
const defaultValuesHeader: ClientHeader = {
|
||||
header: [],
|
||||
activeDomain: "",
|
||||
listOfDomains: [],
|
||||
connections: [],
|
||||
};
|
||||
|
||||
export type { ClientHeader };
|
||||
export { defaultValuesHeader };
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
import {
|
||||
ClientRedisToken,
|
||||
defaultClientRedisToken,
|
||||
} from "@/fetchers/types/context/complete/validations";
|
||||
import {
|
||||
ClientPageConfig,
|
||||
defaultValuesPageConfig,
|
||||
} from "@/fetchers/types/context/pageConfig/validations";
|
||||
import {
|
||||
ClientMenu,
|
||||
defaultValuesMenu,
|
||||
} from "@/fetchers/types/context/menu/validations";
|
||||
import {
|
||||
ClientHeader,
|
||||
defaultValuesHeader,
|
||||
} from "@/fetchers/types/context/header/validations";
|
||||
import {
|
||||
ClientSelection,
|
||||
defaultValuesSelection,
|
||||
} from "@/fetchers/types/context/selection/validations";
|
||||
import {
|
||||
ClientUser,
|
||||
defaultValuesUser,
|
||||
} from "@/fetchers/types/context/user/validations";
|
||||
import {
|
||||
ClientSettings,
|
||||
defaultValuesSettings,
|
||||
} from "@/fetchers/types/context/settings/validations";
|
||||
import {
|
||||
ClientOnline,
|
||||
defaultValuesOnline,
|
||||
} from "@/fetchers/types/context/online/validations";
|
||||
|
||||
class AuthError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = "AuthError";
|
||||
}
|
||||
}
|
||||
|
||||
export type {
|
||||
ClientRedisToken,
|
||||
ClientOnline,
|
||||
ClientPageConfig,
|
||||
ClientMenu,
|
||||
ClientHeader,
|
||||
ClientSelection,
|
||||
ClientUser,
|
||||
ClientSettings,
|
||||
};
|
||||
|
||||
export {
|
||||
defaultClientRedisToken,
|
||||
defaultValuesOnline,
|
||||
defaultValuesPageConfig,
|
||||
defaultValuesMenu,
|
||||
defaultValuesHeader,
|
||||
defaultValuesSelection,
|
||||
defaultValuesUser,
|
||||
defaultValuesSettings,
|
||||
AuthError,
|
||||
};
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
interface ClientMenu {
|
||||
selectionList: string[];
|
||||
activeSelection: string;
|
||||
}
|
||||
|
||||
const defaultValuesMenu: ClientMenu = {
|
||||
selectionList: ["/dashboard"],
|
||||
activeSelection: "/dashboard",
|
||||
};
|
||||
|
||||
export type { ClientMenu };
|
||||
export { defaultValuesMenu };
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
interface ClientOnline {
|
||||
lastLogin: Date;
|
||||
lastLogout: Date;
|
||||
lastAction: Date;
|
||||
lastPage: string;
|
||||
userType: string;
|
||||
lang: string;
|
||||
timezone: string;
|
||||
}
|
||||
|
||||
const defaultValuesOnline: ClientOnline = {
|
||||
lastLogin: new Date(),
|
||||
lastLogout: new Date(),
|
||||
lastAction: new Date(),
|
||||
lastPage: "/dashboard",
|
||||
userType: "employee",
|
||||
lang: "tr",
|
||||
timezone: "GMT+3",
|
||||
};
|
||||
|
||||
export type { ClientOnline };
|
||||
export { defaultValuesOnline };
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
interface ClientPageConfig {
|
||||
mode: string;
|
||||
textFont: number;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
const defaultValuesPageConfig: ClientPageConfig = {
|
||||
mode: "light",
|
||||
textFont: 14,
|
||||
theme: "default",
|
||||
};
|
||||
|
||||
export type { ClientPageConfig };
|
||||
export { defaultValuesPageConfig };
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
interface ClientSelection {
|
||||
selectionList: string[];
|
||||
activeSelection: Record<string, any>;
|
||||
}
|
||||
|
||||
const defaultValuesSelection: ClientSelection = {
|
||||
selectionList: ["/dashboard"],
|
||||
activeSelection: {},
|
||||
};
|
||||
|
||||
export type { ClientSelection };
|
||||
export { defaultValuesSelection };
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
interface ClientSettings {
|
||||
lastOnline: Date;
|
||||
token: string;
|
||||
}
|
||||
|
||||
const defaultValuesSettings: ClientSettings = {
|
||||
lastOnline: new Date(),
|
||||
token: "",
|
||||
};
|
||||
|
||||
export type { ClientSettings };
|
||||
export { defaultValuesSettings };
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
interface Person {
|
||||
uuid: string;
|
||||
firstname: string;
|
||||
surname: string;
|
||||
middle_name: string;
|
||||
sex_code: string;
|
||||
person_tag: string;
|
||||
country_code: string;
|
||||
birth_date: string;
|
||||
}
|
||||
|
||||
interface ClientUser {
|
||||
uuid: string;
|
||||
avatar: string;
|
||||
email: string;
|
||||
phone_number: string;
|
||||
user_tag: string;
|
||||
password_expiry_begins: string;
|
||||
person: Person;
|
||||
}
|
||||
|
||||
const defaultValuesPerson: Person = {
|
||||
uuid: "",
|
||||
firstname: "",
|
||||
surname: "",
|
||||
middle_name: "",
|
||||
sex_code: "",
|
||||
person_tag: "",
|
||||
country_code: "",
|
||||
birth_date: "",
|
||||
};
|
||||
|
||||
const defaultValuesUser: ClientUser = {
|
||||
uuid: "",
|
||||
avatar: "",
|
||||
email: "",
|
||||
phone_number: "",
|
||||
user_tag: "",
|
||||
password_expiry_begins: new Date().toISOString(),
|
||||
person: defaultValuesPerson,
|
||||
};
|
||||
|
||||
export type { ClientUser };
|
||||
export { defaultValuesUser };
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
interface FetcherRequest {
|
||||
url: string;
|
||||
isNoCache: boolean;
|
||||
}
|
||||
|
||||
interface PostFetcherRequest<T> extends FetcherRequest {
|
||||
body: Record<string, T>;
|
||||
}
|
||||
|
||||
interface GetFetcherRequest extends FetcherRequest {
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface DeleteFetcherRequest extends GetFetcherRequest {}
|
||||
interface PutFetcherRequest<T> extends PostFetcherRequest<T> {}
|
||||
interface PatchFetcherRequest<T> extends PostFetcherRequest<T> {}
|
||||
|
||||
interface FetcherRespose {
|
||||
success: boolean;
|
||||
}
|
||||
interface PaginationResponse {
|
||||
onPage: number;
|
||||
onPageCount: number;
|
||||
totalPage: number;
|
||||
totalCount: number;
|
||||
next: boolean;
|
||||
back: boolean;
|
||||
}
|
||||
|
||||
interface FetcherDataResponse<T> extends FetcherRespose {
|
||||
data: Record<string, T> | null;
|
||||
pagination?: PaginationResponse;
|
||||
}
|
||||
|
||||
export type {
|
||||
FetcherRequest,
|
||||
PostFetcherRequest,
|
||||
GetFetcherRequest,
|
||||
DeleteFetcherRequest,
|
||||
PutFetcherRequest,
|
||||
PatchFetcherRequest,
|
||||
FetcherRespose,
|
||||
FetcherDataResponse,
|
||||
};
|
||||
Loading…
Reference in New Issue