updated fetchers
This commit is contained in:
parent
f8184246d9
commit
a8ff968962
|
|
@ -0,0 +1,38 @@
|
|||
import { ApiResponse, CookieObject } from "./types";
|
||||
import NextCrypto from "next-crypto";
|
||||
|
||||
const tokenSecretEnv = process.env.TOKENSECRET_90;
|
||||
const tokenSecret = tokenSecretEnv || "e781d1b0-9418-40b3-9940-385abf81a0b7";
|
||||
const nextCrypto = new NextCrypto(tokenSecret);
|
||||
|
||||
const cookieObject: CookieObject = {
|
||||
httpOnly: true,
|
||||
path: "/",
|
||||
sameSite: "none",
|
||||
secure: true,
|
||||
maxAge: 3600,
|
||||
priority: "high",
|
||||
};
|
||||
|
||||
const DEFAULT_TIMEOUT: number = 10000; // 10 seconds
|
||||
const defaultHeaders: Record<string, string> = {
|
||||
accept: "application/json",
|
||||
language: "tr",
|
||||
domain: "evyos.com.tr",
|
||||
tz: "GMT+3",
|
||||
"Content-type": "application/json",
|
||||
};
|
||||
const DEFAULT_RESPONSE: ApiResponse = {
|
||||
error: "Hata tipi belirtilmedi",
|
||||
status: 500,
|
||||
data: {},
|
||||
};
|
||||
|
||||
export {
|
||||
DEFAULT_TIMEOUT,
|
||||
DEFAULT_RESPONSE,
|
||||
defaultHeaders,
|
||||
tokenSecret,
|
||||
cookieObject,
|
||||
nextCrypto,
|
||||
};
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
"use server";
|
||||
import { DEFAULT_RESPONSE, defaultHeaders, DEFAULT_TIMEOUT } from "./base";
|
||||
import { FetchOptions, HttpMethod, ApiResponse } from "./types";
|
||||
import { retrieveAccessToken } from "./mutual/cookies/token";
|
||||
|
||||
/**
|
||||
* Creates a promise that rejects after a specified timeout
|
||||
* @param ms Timeout in milliseconds
|
||||
* @param controller AbortController to abort the fetch request
|
||||
* @returns A promise that rejects after the timeout
|
||||
*/
|
||||
const createTimeoutPromise = (
|
||||
ms: number,
|
||||
controller: AbortController
|
||||
): Promise<never> => {
|
||||
return new Promise((_, reject) => {
|
||||
setTimeout(() => {
|
||||
controller.abort();
|
||||
reject(new Error(`Request timed out after ${ms}ms`));
|
||||
}, ms);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Core fetch function with timeout and error handling
|
||||
* @param url The URL to fetch
|
||||
* @param options Fetch options
|
||||
* @param headers Request headers
|
||||
* @param payload Request payload
|
||||
* @returns API response
|
||||
*/
|
||||
async function coreFetch<T>(
|
||||
url: string,
|
||||
options: FetchOptions = {},
|
||||
headers: Record<string, string> = defaultHeaders,
|
||||
payload?: any
|
||||
): Promise<ApiResponse<T>> {
|
||||
const { method = "POST", cache = false, timeout = DEFAULT_TIMEOUT } = options;
|
||||
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const fetchOptions: RequestInit = {
|
||||
method,
|
||||
headers,
|
||||
cache: cache ? "force-cache" : "no-cache",
|
||||
signal: controller.signal,
|
||||
};
|
||||
|
||||
if (method !== "GET" && payload) {
|
||||
fetchOptions.body = JSON.stringify(
|
||||
payload.payload ? payload.payload : payload
|
||||
);
|
||||
}
|
||||
const timeoutPromise = createTimeoutPromise(timeout, controller);
|
||||
const response = await Promise.race([
|
||||
fetch(url, fetchOptions),
|
||||
timeoutPromise,
|
||||
]);
|
||||
const responseData = await response.json();
|
||||
return {
|
||||
status: response.status,
|
||||
data: responseData || ({} as T),
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`API Error (${url}):`, error);
|
||||
return {
|
||||
...DEFAULT_RESPONSE,
|
||||
error: error instanceof Error ? error.message : "Network error",
|
||||
} as ApiResponse<T>;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch data without authentication
|
||||
*/
|
||||
async function fetchData<T>(
|
||||
endpoint: string,
|
||||
payload?: any,
|
||||
method: HttpMethod = "POST",
|
||||
cache: boolean = false,
|
||||
timeout: number = DEFAULT_TIMEOUT
|
||||
): Promise<ApiResponse<T>> {
|
||||
return coreFetch<T>(
|
||||
endpoint,
|
||||
{ method, cache, timeout },
|
||||
defaultHeaders,
|
||||
payload
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch data with authentication token
|
||||
*/
|
||||
async function fetchDataWithToken<T>(
|
||||
endpoint: string,
|
||||
payload?: any,
|
||||
method: HttpMethod = "POST",
|
||||
cache: boolean = false,
|
||||
timeout: number = DEFAULT_TIMEOUT
|
||||
): Promise<ApiResponse<T>> {
|
||||
const accessToken = await retrieveAccessToken();
|
||||
const headers = { ...defaultHeaders, "eys-acs-tkn": accessToken };
|
||||
return coreFetch<T>(endpoint, { method, cache, timeout }, headers, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update data with authentication token and UUID
|
||||
*/
|
||||
async function updateDataWithToken<T>(
|
||||
endpoint: string,
|
||||
uuid: string,
|
||||
payload?: any,
|
||||
method: HttpMethod = "POST",
|
||||
cache: boolean = false,
|
||||
timeout: number = DEFAULT_TIMEOUT
|
||||
): Promise<ApiResponse<T>> {
|
||||
const accessToken = await retrieveAccessToken();
|
||||
const headers = { ...defaultHeaders, "eys-acs-tkn": accessToken };
|
||||
return coreFetch<T>(
|
||||
`${endpoint}/${uuid}`,
|
||||
{ method, cache, timeout },
|
||||
headers,
|
||||
payload
|
||||
);
|
||||
}
|
||||
|
||||
export { fetchData, fetchDataWithToken, updateDataWithToken };
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import { formatServiceUrl } from "./utils";
|
||||
|
||||
const baseUrlAuth = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_AUTH_SERVICE_URL || "auth_service:8001"
|
||||
);
|
||||
const baseUrlRestriction = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_RESTRICTION_SERVICE_URL || "restriction_service:8002"
|
||||
);
|
||||
const baseUrlApplication = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_MANAGEMENT_SERVICE_URL || "management_service:8003"
|
||||
);
|
||||
const baseUrlAccount = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_ACCOUNT_SERVICE_URL || "account_service:8004"
|
||||
);
|
||||
const baseUrlBuilding = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_BUILDING_SERVICE_URL || "building_service:8006"
|
||||
);
|
||||
const baseUrlPeople = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_VALIDATION_SERVICE_URL || "validation_service:8009"
|
||||
);
|
||||
|
||||
const urlCheckToken = `${baseUrlAuth}/authentication/token/check`;
|
||||
const urlPageValid = `${baseUrlRestriction}/restrictions/page/valid`;
|
||||
const urlSiteUrls = `${baseUrlRestriction}/restrictions/sites/list`;
|
||||
|
||||
export {
|
||||
baseUrlAuth,
|
||||
baseUrlPeople,
|
||||
baseUrlApplication,
|
||||
baseUrlAccount,
|
||||
baseUrlBuilding,
|
||||
baseUrlRestriction,
|
||||
urlCheckToken,
|
||||
urlPageValid,
|
||||
urlSiteUrls,
|
||||
};
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
'use server';
|
||||
import { cookies } from "next/headers";
|
||||
import { cookieObject } from "@/fetchers/base";
|
||||
import { ResponseCookie } from "next/dist/compiled/@edge-runtime/cookies";
|
||||
|
||||
/**
|
||||
* Server action to delete all access cookies at once
|
||||
* This is a direct server action that can be called from server components
|
||||
*/
|
||||
export async function deleteAllCookies() {
|
||||
try {
|
||||
const cookieStore = await cookies();
|
||||
if (cookieStore.has("eys-zzz")) { cookieStore.delete({ name: "eys-zzz", ...cookieObject } as ResponseCookie); }
|
||||
if (cookieStore.has("eys-yyy")) { cookieStore.delete({ name: "eys-yyy", ...cookieObject } as ResponseCookie); }
|
||||
if (cookieStore.has("eys-sel")) { cookieStore.delete({ name: "eys-sel", ...cookieObject } as ResponseCookie); }
|
||||
return true;
|
||||
} catch (error) { console.error("Error in deleteAllCookies:", error); return false }
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import { cookies } from "next/headers";
|
||||
import { fetchDataWithToken } from "@/fetchers/fecther";
|
||||
import { urlCheckToken, urlPageValid, urlSiteUrls } from "@/fetchers/index";
|
||||
import { nextCrypto } from "@/fetchers/base";
|
||||
import { AuthError } from "@/validations/mutual/context/validations";
|
||||
import { fetchResponseStatus } from "@/fetchers/utils";
|
||||
|
||||
async function checkAccessTokenIsValid() {
|
||||
try {
|
||||
const response = await fetchDataWithToken(urlCheckToken, {}, "GET", false);
|
||||
return fetchResponseStatus(response);
|
||||
} catch (error) { throw new AuthError("No access token found") }
|
||||
}
|
||||
|
||||
async function retrievePageList() {
|
||||
const response: any = await fetchDataWithToken(urlSiteUrls, {}, "GET", false);
|
||||
return fetchResponseStatus(response) ? response.data?.sites : null;
|
||||
}
|
||||
|
||||
async function retrieveApplicationbyUrl(pageUrl: string) {
|
||||
const response: any = await fetchDataWithToken(urlPageValid, { page_url: pageUrl }, "POST", false);
|
||||
return fetchResponseStatus(response) ? response.data?.application : null;
|
||||
}
|
||||
|
||||
async function retrieveAccessToken() {
|
||||
const cookieStore = await cookies();
|
||||
try {
|
||||
const encrpytAccessToken = cookieStore.get("eys-zzz")?.value || "";
|
||||
return await nextCrypto.decrypt(encrpytAccessToken) || "";
|
||||
}
|
||||
catch (error) { throw new AuthError("No access token found") }
|
||||
}
|
||||
|
||||
async function retrieveAccessObjects() {
|
||||
const cookieStore = await cookies();
|
||||
try {
|
||||
const encrpytAccessObject = cookieStore.get("eys-yyy")?.value || "";
|
||||
return await nextCrypto.decrypt(encrpytAccessObject) || "";
|
||||
}
|
||||
catch (error) { throw new AuthError("No access objects found") }
|
||||
}
|
||||
|
||||
export {
|
||||
checkAccessTokenIsValid,
|
||||
retrieveAccessToken,
|
||||
retrieveAccessObjects,
|
||||
retrieveApplicationbyUrl,
|
||||
retrievePageList,
|
||||
};
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
||||
|
||||
interface ApiResponse<T = any> {
|
||||
status: number;
|
||||
data: T;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
interface FetchOptions {
|
||||
method?: HttpMethod;
|
||||
cache?: boolean;
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
interface CookieObject {
|
||||
httpOnly: boolean;
|
||||
path: string;
|
||||
sameSite: string;
|
||||
secure: boolean;
|
||||
maxAge: number;
|
||||
priority: string;
|
||||
}
|
||||
|
||||
export type { HttpMethod, ApiResponse, FetchOptions, CookieObject };
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
const formatServiceUrl = (url: string) => {
|
||||
if (!url) return "";
|
||||
return url.startsWith("http") ? url : `http://${url}`;
|
||||
};
|
||||
|
||||
function fetchResponseStatus(response: any) {
|
||||
return 199 < response?.status && response?.status < 300;
|
||||
}
|
||||
|
||||
export { formatServiceUrl, fetchResponseStatus };
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
// 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 };
|
||||
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import { ApiResponse, CookieObject } from "./types";
|
||||
import NextCrypto from "next-crypto";
|
||||
|
||||
const tokenSecretEnv = process.env.TOKENSECRET_90;
|
||||
const tokenSecret = tokenSecretEnv || "e781d1b0-9418-40b3-9940-385abf81a0b7";
|
||||
const nextCrypto = new NextCrypto(tokenSecret);
|
||||
|
||||
const cookieObject: CookieObject = {
|
||||
httpOnly: true,
|
||||
path: "/",
|
||||
sameSite: "none",
|
||||
secure: true,
|
||||
maxAge: 3600,
|
||||
priority: "high",
|
||||
};
|
||||
|
||||
const DEFAULT_TIMEOUT: number = 10000; // 10 seconds
|
||||
const defaultHeaders: Record<string, string> = {
|
||||
accept: "application/json",
|
||||
language: "tr",
|
||||
domain: "evyos.com.tr",
|
||||
tz: "GMT+3",
|
||||
"Content-type": "application/json",
|
||||
};
|
||||
const DEFAULT_RESPONSE: ApiResponse = {
|
||||
error: "Hata tipi belirtilmedi",
|
||||
status: 500,
|
||||
data: {},
|
||||
};
|
||||
|
||||
export {
|
||||
DEFAULT_TIMEOUT,
|
||||
DEFAULT_RESPONSE,
|
||||
defaultHeaders,
|
||||
tokenSecret,
|
||||
cookieObject,
|
||||
nextCrypto,
|
||||
};
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
"use server";
|
||||
import { DEFAULT_RESPONSE, defaultHeaders, DEFAULT_TIMEOUT } from "./base";
|
||||
import { FetchOptions, HttpMethod, ApiResponse } from "./types";
|
||||
import { retrieveAccessToken } from "./mutual/cookies/token";
|
||||
|
||||
/**
|
||||
* Creates a promise that rejects after a specified timeout
|
||||
* @param ms Timeout in milliseconds
|
||||
* @param controller AbortController to abort the fetch request
|
||||
* @returns A promise that rejects after the timeout
|
||||
*/
|
||||
const createTimeoutPromise = (
|
||||
ms: number,
|
||||
controller: AbortController
|
||||
): Promise<never> => {
|
||||
return new Promise((_, reject) => {
|
||||
setTimeout(() => {
|
||||
controller.abort();
|
||||
reject(new Error(`Request timed out after ${ms}ms`));
|
||||
}, ms);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Core fetch function with timeout and error handling
|
||||
* @param url The URL to fetch
|
||||
* @param options Fetch options
|
||||
* @param headers Request headers
|
||||
* @param payload Request payload
|
||||
* @returns API response
|
||||
*/
|
||||
async function coreFetch<T>(
|
||||
url: string,
|
||||
options: FetchOptions = {},
|
||||
headers: Record<string, string> = defaultHeaders,
|
||||
payload?: any
|
||||
): Promise<ApiResponse<T>> {
|
||||
const { method = "POST", cache = false, timeout = DEFAULT_TIMEOUT } = options;
|
||||
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const fetchOptions: RequestInit = {
|
||||
method,
|
||||
headers,
|
||||
cache: cache ? "force-cache" : "no-cache",
|
||||
signal: controller.signal,
|
||||
};
|
||||
|
||||
if (method !== "GET" && payload) {
|
||||
fetchOptions.body = JSON.stringify(
|
||||
payload.payload ? payload.payload : payload
|
||||
);
|
||||
}
|
||||
const timeoutPromise = createTimeoutPromise(timeout, controller);
|
||||
const response = await Promise.race([
|
||||
fetch(url, fetchOptions),
|
||||
timeoutPromise,
|
||||
]);
|
||||
const responseData = await response.json();
|
||||
return {
|
||||
status: response.status,
|
||||
data: responseData || ({} as T),
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`API Error (${url}):`, error);
|
||||
return {
|
||||
...DEFAULT_RESPONSE,
|
||||
error: error instanceof Error ? error.message : "Network error",
|
||||
} as ApiResponse<T>;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch data without authentication
|
||||
*/
|
||||
async function fetchData<T>(
|
||||
endpoint: string,
|
||||
payload?: any,
|
||||
method: HttpMethod = "POST",
|
||||
cache: boolean = false,
|
||||
timeout: number = DEFAULT_TIMEOUT
|
||||
): Promise<ApiResponse<T>> {
|
||||
return coreFetch<T>(
|
||||
endpoint,
|
||||
{ method, cache, timeout },
|
||||
defaultHeaders,
|
||||
payload
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch data with authentication token
|
||||
*/
|
||||
async function fetchDataWithToken<T>(
|
||||
endpoint: string,
|
||||
payload?: any,
|
||||
method: HttpMethod = "POST",
|
||||
cache: boolean = false,
|
||||
timeout: number = DEFAULT_TIMEOUT
|
||||
): Promise<ApiResponse<T>> {
|
||||
const accessToken = await retrieveAccessToken();
|
||||
const headers = { ...defaultHeaders, "eys-acs-tkn": accessToken };
|
||||
return coreFetch<T>(endpoint, { method, cache, timeout }, headers, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update data with authentication token and UUID
|
||||
*/
|
||||
async function updateDataWithToken<T>(
|
||||
endpoint: string,
|
||||
uuid: string,
|
||||
payload?: any,
|
||||
method: HttpMethod = "POST",
|
||||
cache: boolean = false,
|
||||
timeout: number = DEFAULT_TIMEOUT
|
||||
): Promise<ApiResponse<T>> {
|
||||
const accessToken = await retrieveAccessToken();
|
||||
const headers = { ...defaultHeaders, "eys-acs-tkn": accessToken };
|
||||
return coreFetch<T>(
|
||||
`${endpoint}/${uuid}`,
|
||||
{ method, cache, timeout },
|
||||
headers,
|
||||
payload
|
||||
);
|
||||
}
|
||||
|
||||
export { fetchData, fetchDataWithToken, updateDataWithToken };
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import { formatServiceUrl } from "./utils";
|
||||
|
||||
const baseUrlAuth = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_AUTH_SERVICE_URL || "auth_service:8001"
|
||||
);
|
||||
const baseUrlRestriction = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_RESTRICTION_SERVICE_URL || "restriction_service:8002"
|
||||
);
|
||||
const baseUrlApplication = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_MANAGEMENT_SERVICE_URL || "management_service:8003"
|
||||
);
|
||||
const baseUrlAccount = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_ACCOUNT_SERVICE_URL || "account_service:8004"
|
||||
);
|
||||
const baseUrlBuilding = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_BUILDING_SERVICE_URL || "building_service:8006"
|
||||
);
|
||||
const baseUrlPeople = formatServiceUrl(
|
||||
process.env.NEXT_PUBLIC_VALIDATION_SERVICE_URL || "validation_service:8009"
|
||||
);
|
||||
|
||||
const urlCheckToken = `${baseUrlAuth}/authentication/token/check`;
|
||||
const urlPageValid = `${baseUrlRestriction}/restrictions/page/valid`;
|
||||
const urlSiteUrls = `${baseUrlRestriction}/restrictions/sites/list`;
|
||||
|
||||
export {
|
||||
baseUrlAuth,
|
||||
baseUrlPeople,
|
||||
baseUrlApplication,
|
||||
baseUrlAccount,
|
||||
baseUrlBuilding,
|
||||
baseUrlRestriction,
|
||||
urlCheckToken,
|
||||
urlPageValid,
|
||||
urlSiteUrls,
|
||||
};
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
'use server';
|
||||
import { cookies } from "next/headers";
|
||||
import { cookieObject } from "@/fetchers/base";
|
||||
import { ResponseCookie } from "next/dist/compiled/@edge-runtime/cookies";
|
||||
|
||||
/**
|
||||
* Server action to delete all access cookies at once
|
||||
* This is a direct server action that can be called from server components
|
||||
*/
|
||||
export async function deleteAllCookies() {
|
||||
try {
|
||||
const cookieStore = await cookies();
|
||||
if (cookieStore.has("eys-zzz")) { cookieStore.delete({ name: "eys-zzz", ...cookieObject } as ResponseCookie); }
|
||||
if (cookieStore.has("eys-yyy")) { cookieStore.delete({ name: "eys-yyy", ...cookieObject } as ResponseCookie); }
|
||||
if (cookieStore.has("eys-sel")) { cookieStore.delete({ name: "eys-sel", ...cookieObject } as ResponseCookie); }
|
||||
return true;
|
||||
} catch (error) { console.error("Error in deleteAllCookies:", error); return false }
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import { cookies } from "next/headers";
|
||||
import { fetchDataWithToken } from "@/fetchers/fecther";
|
||||
import { urlCheckToken, urlPageValid, urlSiteUrls } from "@/fetchers/index";
|
||||
import { nextCrypto } from "@/fetchers/base";
|
||||
import { AuthError } from "@/validations/mutual/context/validations";
|
||||
import { fetchResponseStatus } from "@/fetchers/utils";
|
||||
|
||||
async function checkAccessTokenIsValid() {
|
||||
try {
|
||||
const response = await fetchDataWithToken(urlCheckToken, {}, "GET", false);
|
||||
return fetchResponseStatus(response);
|
||||
} catch (error) { throw new AuthError("No access token found") }
|
||||
}
|
||||
|
||||
async function retrievePageList() {
|
||||
const response: any = await fetchDataWithToken(urlSiteUrls, {}, "GET", false);
|
||||
return fetchResponseStatus(response) ? response.data?.sites : null;
|
||||
}
|
||||
|
||||
async function retrieveApplicationbyUrl(pageUrl: string) {
|
||||
const response: any = await fetchDataWithToken(urlPageValid, { page_url: pageUrl }, "POST", false);
|
||||
return fetchResponseStatus(response) ? response.data?.application : null;
|
||||
}
|
||||
|
||||
async function retrieveAccessToken() {
|
||||
const cookieStore = await cookies();
|
||||
try {
|
||||
const encrpytAccessToken = cookieStore.get("eys-zzz")?.value || "";
|
||||
return await nextCrypto.decrypt(encrpytAccessToken) || "";
|
||||
}
|
||||
catch (error) { throw new AuthError("No access token found") }
|
||||
}
|
||||
|
||||
async function retrieveAccessObjects() {
|
||||
const cookieStore = await cookies();
|
||||
try {
|
||||
const encrpytAccessObject = cookieStore.get("eys-yyy")?.value || "";
|
||||
return await nextCrypto.decrypt(encrpytAccessObject) || "";
|
||||
}
|
||||
catch (error) { throw new AuthError("No access objects found") }
|
||||
}
|
||||
|
||||
export {
|
||||
checkAccessTokenIsValid,
|
||||
retrieveAccessToken,
|
||||
retrieveAccessObjects,
|
||||
retrieveApplicationbyUrl,
|
||||
retrievePageList,
|
||||
};
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
||||
|
||||
interface ApiResponse<T = any> {
|
||||
status: number;
|
||||
data: T;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
interface FetchOptions {
|
||||
method?: HttpMethod;
|
||||
cache?: boolean;
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
interface CookieObject {
|
||||
httpOnly: boolean;
|
||||
path: string;
|
||||
sameSite: string;
|
||||
secure: boolean;
|
||||
maxAge: number;
|
||||
priority: string;
|
||||
}
|
||||
|
||||
export type { HttpMethod, ApiResponse, FetchOptions, CookieObject };
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
const formatServiceUrl = (url: string) => {
|
||||
if (!url) return "";
|
||||
return url.startsWith("http") ? url : `http://${url}`;
|
||||
};
|
||||
|
||||
function fetchResponseStatus(response: any) {
|
||||
return 199 < response?.status && response?.status < 300;
|
||||
}
|
||||
|
||||
export { formatServiceUrl, fetchResponseStatus };
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
## Contexts
|
||||
|
||||
- [Component Contexts](./docs/contexts/component_contexts.md)
|
||||
- [Component Menu](./docs/contexts/component_menu.md)
|
||||
- [Component User](./docs/contexts/component_user.md)
|
||||
- [Component Online](./docs/contexts/component_online.md)
|
||||
- [Component Selection](./docs/contexts/component_selection.md)
|
||||
- [Component Contexts](./contexts/component_contexts.md)
|
||||
- [Component Menu](./contexts/component_menu.md)
|
||||
- [Component User](./contexts/component_user.md)
|
||||
- [Component Online](./contexts/component_online.md)
|
||||
- [Component Selection](./contexts/component_selection.md)
|
||||
|
||||
## Language Selection
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue