@soramux/node-auth-sdk 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react.js +5 -5
- package/dist/cjs/react.js.map +1 -1
- package/dist/cjs/server.js +2 -2
- package/dist/cjs/server.js.map +1 -1
- package/dist/esm/index.d.mts +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/{interceptor-CbsDF_WC.d.mts → interceptor-BvJQ3XFz.d.mts} +11 -4
- package/dist/esm/react.d.mts +29 -16
- package/dist/esm/react.js +5 -5
- package/dist/esm/react.js.map +1 -1
- package/dist/esm/server.d.mts +1 -1
- package/dist/esm/server.js +2 -2
- package/dist/esm/server.js.map +1 -1
- package/package.json +1 -1
package/dist/esm/server.d.mts
CHANGED
package/dist/esm/server.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
function
|
|
2
|
-
export{
|
|
1
|
+
function b(){let n=typeof window>"u",e=typeof import.meta<"u"&&import.meta.env?import.meta.env:{},t=typeof process<"u"?process.env:{},s=e.VITE_TRIEOH_AUTH_PROJECT_ID||t.NEXT_PUBLIC_TRIEOH_AUTH_PROJECT_ID||t.PUBLIC_TRIEOH_AUTH_PROJECT_ID||"",r=n&&t.TRIEOH_AUTH_API_KEY||"";return {PROJECT_ID:s,API_KEY:r,BASE_URL:"https://api.default.com"}}var T=null,L={};function R(){return T||(T={...b(),...L}),T}var o={get PROJECT_ID(){return R().PROJECT_ID},get API_KEY(){return R().API_KEY},get BASE_URL(){return R().BASE_URL}};function p(n,e){if(e.startsWith("http"))return e;let t=n.replace(/\/$/,""),s=e.replace(/^\//,"");return `${t}/${s}`}var d={isAuthenticated:false,isUpToDate:false},E=new Set,w=()=>E.forEach(n=>n()),S={subscribe:n=>(E.add(n),()=>E.delete(n)),getSnapshot:()=>d,getServerSnapshot:()=>d,set:n=>{d={...d,...n},w();},reset:()=>{d={isAuthenticated:false,isUpToDate:false},w();}};var y="trieoh_access_expiry",A="trieoh_refresh_expiry",P="trieoh_is_up_to_date",H="path=/; secure; samesite=none";function l(n,e,t){if(typeof window>"u")return;let s=t?`; expires=${t}`:"";document.cookie=`${n}=${e}; ${H}${s}`;}function x(n){l(n,"","Thu, 01 Jan 1970 00:00:00 GMT");}function I(n){let e=new Date(n.refresh_expiry_date).getTime(),t=n.access_data.exp*1e3;isNaN(e)?console.error("[TRIEOH SDK] Invalid refresh_expiry_date received:",n.refresh_expiry_date):localStorage.setItem(A,String(e)),isNaN(t)?console.error("[TRIEOH SDK] Invalid access expiry received:",n.access_data.exp):localStorage.setItem(y,String(t)),n.is_up_to_date!==void 0&&localStorage.setItem(P,String(n.is_up_to_date)),console.log("[TRIEOH SDK] Token claims saved");}function O(n=30){try{let e=localStorage.getItem(y);if(!e)return !0;let t=parseInt(e,10);if(isNaN(t))return !0;let s=Date.now(),r=n*1e3;return t-s<=r}catch(e){return console.warn("[TRIEOH SDK] Error reading access expiry date:",e),true}}function C(n=10){try{let e=localStorage.getItem(A);if(!e)return !0;let t=parseInt(e,10);if(isNaN(t))return !0;let s=Date.now(),r=n*1e3;return t-s<=r}catch(e){return console.warn("[TRIEOH SDK] Error reading refresh expiry date:",e),true}}function u(){localStorage.removeItem(y),localStorage.removeItem(A),localStorage.removeItem(P),x("svc_session"),x("refresh_token"),S.reset(),console.log("[TRIEOH SDK] Auth tokens and claims cleared");}var g=class{constructor(e){this.isRefreshing=false;this.refreshPromise=null;this.authBaseURL=e?.authBaseURL||o.BASE_URL,this.baseURL=e?.baseURL||this.authBaseURL,this.onTokenRefreshed=e?.onTokenRefreshed,this.onRefreshFailed=e?.onRefreshFailed;}async fetchClaimsAndSave(e){let s=await(await fetch(p(this.authBaseURL,"/sessions/me"),{method:"GET",headers:{"Content-Type":"application/json"},credentials:"include"})).json();if(s.code!==200||!s.data)throw u(),new Error(s.message||"Failed to fetch session claims after refresh");let r={...s.data,is_up_to_date:e};return I(r),r}async exchange(e,t,s){let i=await(await fetch(p(this.authBaseURL,"/auth/exchange"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},credentials:"include"})).json();if(i.code!==200)throw u(),new Error(i.message||"Failed to exchange tokens for session");let _=new Date(i.data.expires_at).toUTCString();l("svc_session",i.data.service_session_id,_);let v=await this.fetchClaimsAndSave(s),U=new Date(v.refresh_expiry_date).toUTCString();return l("refresh_token",t,U),v}async refreshToken(){return this.isRefreshing&&this.refreshPromise?this.refreshPromise:(this.isRefreshing=true,this.refreshPromise=(async()=>{try{let t=await(await fetch(p(this.authBaseURL,"/auth/refresh"),{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include"})).json();if(t.code!==200)throw t.code!==503&&u(),new Error(t.message||"Failed to refresh token");let{access_token:s,refresh_token:r,is_up_to_date:i}=t.data,_=await this.exchange(s,r,i);this.onTokenRefreshed?.(_),console.log("[TRIEOH SDK] Token refreshed successfully");}catch(e){throw console.warn("[TRIEOH SDK] Failed to refresh token:",e),u(),this.onRefreshFailed?.(e),e}finally{this.isRefreshing=false,this.refreshPromise=null;}})(),this.refreshPromise)}async beforeRequest(){if(C()){u();return}if(O(30)){console.log("[TRIEOH SDK] Token expiring soon, refreshing...");try{await this.refreshToken();}catch(e){console.warn("[TRIEOH SDK] Refresh interceptor failed:",e);}}}async fetch(e,t){let s=t?.requiresAuth!==false,r=!t?.skipRefresh;s&&r&&await this.beforeRequest();let i=p(this.baseURL,e);return fetch(i,{...t,credentials:"include",headers:{"Content-Type":"application/json",...t?.headers}})}};var m=class{constructor(e,t,s){this.baseURL=e||o.BASE_URL,this.authInterceptor=new g({baseURL:this.baseURL,authBaseURL:t,onTokenRefreshed:s});}get headers(){return {"Content-Type":"application/json"}}async request(e,t){try{let s=await this.authInterceptor.fetch(e,{...t,headers:{...this.headers,...t?.headers??{}}}),r=await s.json().catch(()=>({module:"Client",message:s.statusText||"Unknown error",timestamp:new Date().toISOString(),code:s.status,error_id:"CLIENT_PARSE_ERROR",trace:["Failed to parse API response as JSON"]}));return s.ok?{success:!0,module:r.module,message:r.message,timestamp:r.timestamp,code:r.code,data:r.data}:{success:!1,module:r.module||"Unknown",message:r.message||s.statusText||"An unknown error occurred",timestamp:r.timestamp||new Date().toISOString(),code:r.code||s.status,error_id:r.error_id||"UNKNOWN_ERROR",trace:r.trace}}catch(s){let r=s instanceof Error?s.message:"A network or unknown error occurred.";return {success:false,module:"Network",message:r,timestamp:new Date().toISOString(),code:503,error_id:"CLIENT_NETWORK_ERROR",trace:s instanceof Error?[s.stack||r]:[r]}}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,s){return this.request(e,{...s,method:"POST",body:t?JSON.stringify(t):void 0})}put(e,t,s){return this.request(e,{...s,method:"PUT",body:t?JSON.stringify(t):void 0})}patch(e,t,s){return this.request(e,{...s,method:"PATCH",body:t?JSON.stringify(t):void 0})}delete(e,t,s){return this.request(e,{...s,method:"DELETE",body:t?JSON.stringify(t):void 0})}};var h=()=>{if(!o.PROJECT_ID||o.PROJECT_ID.trim()==="")throw new Error("[TRIEOH SDK] Project ID is missing. Please set PUBLIC_TRIEOH_AUTH_PROJECT_ID, NEXT_PUBLIC_TRIEOH_AUTH_PROJECT_ID or VITE_TRIEOH_AUTH_PROJECT_ID.")},f=()=>{if(!o.API_KEY||o.API_KEY.trim()==="")throw new Error("[TRIEOH SDK] Private API Key is missing. This operation requires TRIEOH_AUTH_API_KEY to be set in a server-side environment.")};var D=n=>({getProjectLatestRegisterFields:async e=>{h(),f();let t=`/projects/${o.PROJECT_ID}/schemas/lookup/latest`,s=new URLSearchParams;return s.append("flow_id",e),s.append("schema_type","context"),t+=`?${s.toString()}`,n.get(t,{headers:{Authorization:`Bearer ${o.API_KEY}`,"Content-Type":"application/json"}})},getProjectRegisterFields:async e=>{h(),f();let s=`/projects/${o.PROJECT_ID}/schemas/lookup/v1`,r=new URLSearchParams;return r.append("flow_id",e),r.append("schema_type","context"),s+=`?${r.toString()}`,n.get(s,{headers:{Authorization:`Bearer ${o.API_KEY}`,"Content-Type":"application/json"}})},assignRoleByNameToUser:async(e,t,s)=>{h(),f();let r=`/projects/${o.PROJECT_ID}/identities/${e}/roles/by-name`;return n.post(r,{role_name:t,scope_id:s},{headers:{Authorization:`Bearer ${o.API_KEY}`,"Content-Type":"application/json"}})},removeRoleByNameFromUser:async(e,t,s)=>{h(),f();let r=`/projects/${o.PROJECT_ID}/identities/${e}/roles/by-name`;return n.delete(r,{role_name:t,scope_id:s},{headers:{Authorization:`Bearer ${o.API_KEY}`,"Content-Type":"application/json"}})}});var ge=n=>D(new m(n));
|
|
2
|
+
export{ge as createServerAuth};//# sourceMappingURL=server.js.map
|
|
3
3
|
//# sourceMappingURL=server.js.map
|
package/dist/esm/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/env.ts","../../src/utils/url-utils.ts","../../src/utils/token-utils.ts","../../src/core/interceptor.ts","../../src/core/api.ts","../../src/utils/env-validator.ts","../../src/core/services.ts","../../src/server.ts"],"names":["resolveEnv","isServer","viteEnv","safeProcessEnv","resolvedProjectId","resolvedApiKey","memoizedEnv","overrides","getEnv","env","joinUrl","base","path","cleanBase","cleanPath","ACCESS_EXPIRY_KEY","REFRESH_EXPIRY_KEY","saveTokenClaims","claims","isTokenExpiringSoon","thresholdSeconds","expiryStr","accessExpiryTimestamp","now","e","isRefreshSessionExpired","refreshExpiryTimestamp","clearAuthTokens","AuthInterceptor","config","resJson","data","error","url","options","shouldAuth","shouldRefresh","finalUrl","Api","baseURL","authBaseURL","response","raw","errorMessage","body","validateProjectKey","validateApiKey","createServerAuthService","apiInstance","flow_id","params","user_id","role_name","scope_id","createServerAuth"],"mappings":"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","file":"server.js","sourcesContent":["export interface TrieOHEnv {\n PROJECT_ID: string;\n API_KEY: string;\n BASE_URL: string;\n}\n\nexport function resolveEnv(): TrieOHEnv {\n const isServer = typeof window === \"undefined\";\n\n const viteEnv = (\n typeof import.meta !== \"undefined\" && import.meta.env\n ? import.meta.env\n : {}\n ) as Partial<ImportMetaEnv>;\n\n const safeProcessEnv: NodeJS.ProcessEnv = \n typeof process !== \"undefined\" ? process.env : {};\n\n const resolvedProjectId =\n viteEnv.VITE_TRIEOH_AUTH_PROJECT_ID ||\n safeProcessEnv.NEXT_PUBLIC_TRIEOH_AUTH_PROJECT_ID ||\n safeProcessEnv.PUBLIC_TRIEOH_AUTH_PROJECT_ID ||\n \"\";\n\n const resolvedApiKey = isServer\n ? (safeProcessEnv.TRIEOH_AUTH_API_KEY || \"\")\n : \"\";\n\n return {\n PROJECT_ID: resolvedProjectId,\n API_KEY: resolvedApiKey,\n BASE_URL: \"https://api.default.com\",\n };\n}\nlet memoizedEnv: TrieOHEnv | null = null;\nlet overrides: Partial<TrieOHEnv> = {};\n\n/**\n * Configure the SDK manually. This will override any environment variables.\n */\nexport function configure(config: Partial<TrieOHEnv>) {\n overrides = { ...overrides, ...config };\n memoizedEnv = null; // Reset memoization to apply new config\n}\n\nfunction getEnv(): TrieOHEnv {\n if (!memoizedEnv) {\n const resolved = resolveEnv();\n memoizedEnv = {\n ...resolved,\n ...overrides,\n };\n }\n return memoizedEnv;\n}\nexport const env: TrieOHEnv = {\n get PROJECT_ID() {\n return getEnv().PROJECT_ID;\n },\n get API_KEY() {\n return getEnv().API_KEY;\n },\n get BASE_URL() {\n return getEnv().BASE_URL;\n },\n};\n","export function joinUrl(base: string, path: string): string {\n if (path.startsWith(\"http\")) return path;\n \n const cleanBase = base.replace(/\\/$/, \"\");\n const cleanPath = path.replace(/^\\//, \"\");\n \n return `${cleanBase}/${cleanPath}`;\n}\n","import type { Api } from \"../core/api\";\n\ninterface TokenClaims {\n sub: {\n id: string;\n email: string;\n session_id: string;\n user_agent: string;\n user_ip: string;\n };\n iss: string;\n exp: number;\n iat: number;\n jti: string;\n}\n\nexport interface AuthTokenClaims {\n access: TokenClaims;\n refresh_expire_date: number;\n}\n\nconst ACCESS_EXPIRY_KEY = \"trieoh_access_expiry\";\nconst REFRESH_EXPIRY_KEY = \"trieoh_refresh_expiry\";\n\n// Stored only in memory\nlet memoryClaims: AuthTokenClaims | null = null;\n\nexport function saveTokenClaims(claims: AuthTokenClaims): void {\n memoryClaims = claims;\n localStorage.setItem(REFRESH_EXPIRY_KEY, String(claims.refresh_expire_date));\n localStorage.setItem(ACCESS_EXPIRY_KEY, String(claims.access.exp));\n console.log(\"[TRIEOH SDK] Token claims saved\");\n}\n\nexport function getTokenClaims(): AuthTokenClaims | null {\n return memoryClaims;\n}\n\nexport function isTokenExpiringSoon(thresholdSeconds: number = 30): boolean {\n try {\n const expiryStr = localStorage.getItem(ACCESS_EXPIRY_KEY);\n if (!expiryStr) return true;\n\n const accessExpiryTimestamp = parseInt(expiryStr, 10);\n const now = Math.floor(Date.now() / 1000);\n const timeUntilExpiry = accessExpiryTimestamp - now;\n \n return timeUntilExpiry <= thresholdSeconds;\n } catch (e) {\n console.warn(\"[TRIEOH SDK] Error reading access expiry date:\", e);\n return true;\n }\n}\n\nexport function isRefreshSessionExpired(): boolean {\n try {\n const expiryStr = localStorage.getItem(REFRESH_EXPIRY_KEY);\n if (!expiryStr) return true;\n\n const refreshExpiryTimestamp = parseInt(expiryStr, 10);\n const now = Math.floor(Date.now() / 1000);\n \n return refreshExpiryTimestamp <= now;\n } catch (e) {\n console.warn(\"[TRIEOH SDK] Error reading refresh expiry date:\", e);\n return true;\n }\n}\n\nexport function isAuthenticated(): boolean {\n const claims = getTokenClaims();\n if (!claims) return false;\n const now = Math.floor(Date.now() / 1000);\n return claims.access.exp > now;\n}\n\nexport function clearAuthTokens(): void {\n memoryClaims = null;\n localStorage.removeItem(ACCESS_EXPIRY_KEY);\n localStorage.removeItem(REFRESH_EXPIRY_KEY);\n console.log(\"[TRIEOH SDK] Auth tokens and claims cleared\");\n}\n\nexport function getUserInfo() {\n const claims = getTokenClaims();\n if (!claims) return null;\n \n return claims.access.sub\n}\n\nexport const fetchAndSaveClaims = async (apiInstance: Api) => {\n try {\n const res = await apiInstance.get<AuthTokenClaims>(\"/sessions/me\",\n { requiresAuth: true }\n );\n \n if (res.success) {\n saveTokenClaims(res.data);\n return res;\n }\n throw new Error(res.message || \"Failed to fetch session claims\");\n } catch (error) {\n console.warn(\"[TRIEOH SDK] fetch claims failed (network/server)\", error);\n throw error;\n }\n};","import { joinUrl } from \"../utils/url-utils\";\nimport {\n clearAuthTokens,\n isRefreshSessionExpired,\n isTokenExpiringSoon,\n saveTokenClaims,\n type AuthTokenClaims\n} from \"../utils/token-utils\";\nimport { env } from \"./env\";\n\n\nexport interface RequestOptions extends RequestInit {\n requiresAuth?: boolean;\n skipRefresh?: boolean;\n}\n\ninterface InterceptorConfig {\n baseURL?: string;\n authBaseURL?: string;\n onTokenRefreshed?: (claims: AuthTokenClaims) => void;\n onRefreshFailed?: (error: Error) => void;\n}\n\nexport class AuthInterceptor {\n private baseURL: string;\n private authBaseURL: string;\n private isRefreshing = false;\n private refreshPromise: Promise<void> | null = null;\n private onTokenRefreshed?: (claims: AuthTokenClaims) => void;\n private onRefreshFailed?: (error: Error) => void;\n\n constructor(config?: InterceptorConfig) {\n this.authBaseURL = config?.authBaseURL || env.BASE_URL;\n this.baseURL = config?.baseURL || this.authBaseURL;\n\n this.onTokenRefreshed = config?.onTokenRefreshed;\n this.onRefreshFailed = config?.onRefreshFailed;\n }\n\n private async fetchClaimsAndSave(): Promise<AuthTokenClaims> {\n const response = await fetch(joinUrl(this.authBaseURL, \"/sessions/me\"), {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" },\n credentials: \"include\",\n });\n\n const resJson = await response.json();\n\n if (resJson.code !== 200 || !resJson.data) {\n clearAuthTokens();\n throw new Error(resJson.message || \"Failed to fetch session claims after refresh\");\n }\n \n const claims = resJson.data as AuthTokenClaims;\n saveTokenClaims(claims);\n return claims;\n }\n\n private async refreshToken(): Promise<void> {\n if (this.isRefreshing && this.refreshPromise) return this.refreshPromise;\n \n this.isRefreshing = true;\n this.refreshPromise = (async () => {\n let claims: AuthTokenClaims;\n try {\n const response = await fetch(joinUrl(this.authBaseURL, \"/auth/refresh\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n credentials: \"include\",\n });\n\n const data = await response.json();\n\n if (data.code !== 200) {\n if (data.code !== 503) clearAuthTokens();\n throw new Error(data.message || \"Failed to refresh token\");\n }\n\n claims = await this.fetchClaimsAndSave();\n this.onTokenRefreshed?.(claims);\n console.log(\"[TRIEOH SDK] Token refreshed successfully\");\n } catch (error) {\n console.warn(\"[TRIEOH SDK] Failed to refresh token:\", error);\n clearAuthTokens();\n this.onRefreshFailed?.(error as Error);\n throw error;\n } finally {\n this.isRefreshing = false;\n this.refreshPromise = null;\n }\n })();\n\n return this.refreshPromise;\n }\n\n async beforeRequest(): Promise<void> {\n if(isRefreshSessionExpired()) {\n clearAuthTokens();\n return;\n }\n \n if (isTokenExpiringSoon(30)) {\n console.log(\"[TRIEOH SDK] Token expiring soon, refreshing...\");\n try {\n await this.refreshToken();\n } catch (error) {\n console.warn(\"[TRIEOH SDK] Refresh interceptor failed:\", error);\n }\n }\n }\n\n async fetch(url: string, options?: RequestOptions): Promise<Response> {\n const shouldAuth = options?.requiresAuth !== false;\n const shouldRefresh = !options?.skipRefresh;\n\n if (shouldAuth && shouldRefresh) await this.beforeRequest();\n\n const finalUrl = joinUrl(this.baseURL, url);\n\n return fetch(finalUrl, {\n ...options,\n credentials: \"include\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n }\n}\n\nexport const createAuthInterceptor = (config?: InterceptorConfig) => {\n return new AuthInterceptor(config);\n};\n\nexport const createAuthenticatedFetch = (config?: InterceptorConfig) => {\n const interceptor = new AuthInterceptor(config);\n \n return async (url: string, options?: RequestOptions): Promise<Response> => {\n return interceptor.fetch(url, options);\n };\n};","import { env } from \"./env\";\nimport { AuthInterceptor, type RequestOptions } from \"./interceptor\";\n\n/**\n * Base structure shared by all API responses.\n */\nexport interface BaseResponse {\n module: string;\n message: string;\n timestamp: string;\n code: number;\n}\n\n/**\n * Standardized API Response. \n * Use 'success' to narrow down to the data or error details.\n */\nexport type ApiResponse<T> = \n | (BaseResponse & { success: true; data: T })\n | (BaseResponse & { \n success: false; \n error_id: string; \n trace?: string[]; \n });\n\n/**\n * Internal type for parsing the raw response from the server.\n */\ntype RawApiResponse<T> = BaseResponse & { \n data?: T; \n error_id?: string; \n trace?: string[] \n};\n\n/**\n * Custom error class for API failures.\n * Provides access to the full standardized response.\n */\nexport class ApiError extends Error {\n code: number;\n trace?: string[];\n response: ApiResponse<unknown>;\n\n constructor(response: ApiResponse<unknown>) {\n super(response.message);\n this.name = \"ApiError\";\n this.code = response.code;\n this.trace = !response.success ? response.trace : [];\n this.response = response;\n }\n}\n\nexport class Api {\n private baseURL: string;\n private authInterceptor: AuthInterceptor;\n\n constructor(baseURL?: string, authBaseURL?: string) {\n this.baseURL = baseURL || env.BASE_URL;\n this.authInterceptor = new AuthInterceptor({ \n baseURL: this.baseURL,\n authBaseURL: authBaseURL\n });\n }\n\n private get headers() {\n return { \"Content-Type\": \"application/json\" };\n }\n\n async request<T = unknown>(path: string, options?: RequestOptions): Promise<ApiResponse<T>> {\n try {\n const response = await this.authInterceptor.fetch(path, {\n ...options,\n headers: { ...this.headers, ...(options?.headers ?? {}) },\n });\n\n const raw: RawApiResponse<T> = await response.json().catch(() => ({\n module: \"Client\",\n message: response.statusText || \"Unknown error\",\n timestamp: new Date().toISOString(),\n code: response.status,\n error_id: \"CLIENT_PARSE_ERROR\",\n trace: [\"Failed to parse API response as JSON\"],\n }));\n\n if (!response.ok) {\n return {\n success: false,\n module: raw.module || \"Unknown\",\n message: raw.message || response.statusText || \"An unknown error occurred\",\n timestamp: raw.timestamp || new Date().toISOString(),\n code: raw.code || response.status,\n error_id: raw.error_id || \"UNKNOWN_ERROR\",\n trace: raw.trace,\n };\n }\n\n return {\n success: true,\n module: raw.module,\n message: raw.message,\n timestamp: raw.timestamp,\n code: raw.code,\n data: raw.data as T,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"A network or unknown error occurred.\";\n return {\n success: false,\n module: \"Network\",\n message: errorMessage,\n timestamp: new Date().toISOString(),\n code: 503,\n error_id: \"CLIENT_NETWORK_ERROR\",\n trace: error instanceof Error ? [error.stack || errorMessage] : [errorMessage],\n };\n }\n }\n\n get<T = unknown>(path: string, options?: RequestOptions) {\n return this.request<T>(path, { ...options, method: \"GET\" });\n }\n\n post<T = unknown>(path: string, body?: unknown, options?: RequestOptions) {\n return this.request<T>(path, {\n ...options,\n method: \"POST\",\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n put<T = unknown>(path: string, body?: unknown, options?: RequestOptions) {\n return this.request<T>(path, {\n ...options,\n method: \"PUT\",\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n patch<T = unknown>(path: string, body?: unknown, options?: RequestOptions) {\n return this.request<T>(path, {\n ...options,\n method: \"PATCH\",\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n delete<T = unknown>(path: string, body?: unknown, options?: RequestOptions) {\n return this.request<T>(path, { \n ...options, \n method: \"DELETE\", \n body: body ? JSON.stringify(body) : undefined \n });\n }\n}\n\n/**\n * Creates a fetcher object with all HTTP methods returning standardized ApiResponse.\n * \n * @param config - Optional configuration for the fetcher (baseURL, authBaseURL, etc.)\n * @returns An object with get, post, put, patch, delete, and request methods.\n */\nexport const createFetcher = (config?: { baseURL?: string; authBaseURL?: string }) => {\n const api = new Api(config?.baseURL, config?.authBaseURL);\n\n return {\n request: api.request.bind(api),\n get: api.get.bind(api),\n post: api.post.bind(api),\n put: api.put.bind(api),\n patch: api.patch.bind(api),\n delete: api.delete.bind(api),\n };\n};\n\n/**\n * Creates a simple fetcher function that returns data directly or throws an ApiError on failure.\n * Ideal for Query libraries like TanStack Query.\n * \n * @param config - Optional configuration for the fetcher (baseURL, authBaseURL, etc.)\n * @returns A single fetcher function that returns a Promise of TData.\n */\nexport const createQueryFetcher = (config?: { baseURL?: string; authBaseURL?: string }) => {\n const api = new Api(config?.baseURL, config?.authBaseURL);\n\n return async <TData>(path: string, init?: RequestOptions): Promise<TData> => {\n const response = await api.request<TData>(path, init);\n if (!response.success) throw new ApiError(response);\n return response.data;\n };\n};\n","import { env } from \"../core/env\";\n\nexport const validateProjectKey = () => {\n if (!env.PROJECT_ID || env.PROJECT_ID.trim() === \"\") {\n throw new Error(\n \"[TRIEOH SDK] Project ID is missing. Please set PUBLIC_TRIEOH_AUTH_PROJECT_ID, NEXT_PUBLIC_TRIEOH_AUTH_PROJECT_ID or VITE_TRIEOH_AUTH_PROJECT_ID.\"\n );\n }\n};\n\nexport const validateApiKey = () => {\n if (!env.API_KEY || env.API_KEY.trim() === \"\") {\n throw new Error(\n \"[TRIEOH SDK] Private API Key is missing. This operation requires TRIEOH_AUTH_API_KEY to be set in a server-side environment.\"\n );\n }\n};\n","import type { ProjectFieldDefinitionResultI, FieldValue } from \"../types/fields-types\";\nimport type { SessionI } from \"../types/sessions-types\";\nimport { clearAuthTokens, fetchAndSaveClaims, getUserInfo } from \"../utils/token-utils\";\nimport { validateApiKey, validateProjectKey } from \"../utils/env-validator\";\nimport type { Api } from \"./api\";\nimport { env } from \"./env\";\n\nexport const createAuthService = (apiInstance: Api) => ({\n login: async (email: string, password: string) => {\n const options = { requiresAuth: false };\n if (env.PROJECT_ID) {\n validateProjectKey();\n const url = `/projects/${env.PROJECT_ID}/login`;\n const res = await apiInstance.post<{is_up_to_date: boolean}>(\n url,\n { email, password },\n options\n );\n if(res.success) await fetchAndSaveClaims(apiInstance);\n return res;\n }\n\n const res = await apiInstance.post<{is_up_to_date: boolean}>(\n \"/auth/login\", \n { email, password }, \n options\n );\n if(res.success) await fetchAndSaveClaims(apiInstance);\n return res;\n },\n\n register: (email: string, password: string, flow_id?: string, custom: Record<string, FieldValue> = {}) => {\n const options = { requiresAuth: false };\n if (env.PROJECT_ID) {\n validateProjectKey();\n \n const params = new URLSearchParams(); \n if(flow_id) {\n params.append(\"flow_id\", flow_id);\n params.append(\"schema_type\", \"context\");\n params.append(\"version\", \"1\");\n }\n const bodyData = {...{email, password}, ...flow_id && { custom_fields: custom } };\n const paramsUrl = params.toString() ? `?${params.toString()}` : \"\";\n const url = `/projects/${env.PROJECT_ID}/register${paramsUrl}`;\n return apiInstance.post<string>(url, bodyData, options);\n }\n\n return apiInstance.post<string>(\"/auth/register\", { email, password }, options);\n }, \n \n logout: async () => {\n const res = await apiInstance.post<string>(\"/auth/logout\");\n if(res.success) clearAuthTokens();\n return res;\n },\n\n refresh: async () => {\n const res = await apiInstance.post<{is_up_to_date: boolean}>(\n \"/auth/refresh\",\n undefined,\n { skipRefresh: true }\n );\n if(res.success) await fetchAndSaveClaims(apiInstance);\n return res;\n },\n\n sessions: async () => {\n return apiInstance.get<SessionI[]>(\"/sessions\");\n },\n\n revokeASession: async (id: string) => {\n return apiInstance.delete<string>(`/sessions/${id}`);\n },\n\n revokeSessions: async (revokeAll: boolean = false) => {\n const path = revokeAll ? \"/sessions\" : \"/sessions/others\"\n return apiInstance.delete<string>(path);\n },\n\n refreshProfileInfo: async () => fetchAndSaveClaims(apiInstance),\n\n profile: () => getUserInfo(),\n\n getProfileUpgradeForms: async () => {\n validateProjectKey();\n const url = `/projects/${env.PROJECT_ID}/upgrade-form`;\n return apiInstance.get<ProjectFieldDefinitionResultI>(url);\n },\n\n updateProfile: async (custom: Record<string, FieldValue>) => {\n validateProjectKey();\n const url = `/projects/${env.PROJECT_ID}/metadata`;\n return apiInstance.post<string>(url, { custom_fields: custom });\n },\n\n sendForgotPassword: async (email: string) => {\n const options = { requiresAuth: false };\n if (env.PROJECT_ID) {\n validateProjectKey();\n return apiInstance.post<string>(\n \"/auth/forgot-password\",\n {email, project_id: env.PROJECT_ID}, \n options\n );\n }\n return apiInstance.post<string>(\"/auth/forgot-password\", {email}, options);\n },\n\n resetPassword: async (token: string, new_password: string) => {\n return apiInstance.post<string>(\n `/auth/reset-password?token=${token}`,\n {new_password}, \n { requiresAuth: false }\n );\n },\n\n resendVerifyEmail: async () => {\n return apiInstance.post<string>(\"/auth/verify/resend\");\n },\n\n verifyEmail: async () => {\n return apiInstance.get<string>(\n \"/auth/verify\",\n { requiresAuth: false }\n );\n },\n\n addSubContext: async (user_id: string, data: Record<string, unknown>) => {\n validateProjectKey();\n return apiInstance.post<void>(\n `/projects/${env.PROJECT_ID}/sub-context`,\n { data, user_id }\n );\n },\n\n removeSubContext: async (user_id: string, keys: string[]) => {\n validateProjectKey();\n return apiInstance.delete<void>(\n `/projects/${env.PROJECT_ID}/sub-context`,\n { keys, user_id }\n );\n },\n\n});\n\nexport const createServerAuthService = (apiInstance: Api) => ({\n getProjectLatestRegisterFields: async (flow_id: string) => {\n validateProjectKey();\n validateApiKey();\n\n let url = `/projects/${env.PROJECT_ID}/schemas/lookup/latest`\n const params = new URLSearchParams();\n params.append(\"flow_id\", flow_id);\n params.append(\"schema_type\", \"context\");\n url += `?${params.toString()}`;\n\n return apiInstance.get<ProjectFieldDefinitionResultI>(\n url,\n {\n headers: {\n \"Authorization\": `Bearer ${env.API_KEY}`,\n \"Content-Type\": \"application/json\"\n }\n }\n );\n },\n\n getProjectRegisterFields: async (flow_id: string) => {\n validateProjectKey();\n validateApiKey();\n\n const version = 1;\n let url = `/projects/${env.PROJECT_ID}/schemas/lookup/v${version}`\n const params = new URLSearchParams();\n params.append(\"flow_id\", flow_id);\n params.append(\"schema_type\", \"context\");\n url += `?${params.toString()}`;\n\n return apiInstance.get<ProjectFieldDefinitionResultI>(\n url,\n {\n headers: {\n \"Authorization\": `Bearer ${env.API_KEY}`,\n \"Content-Type\": \"application/json\"\n }\n }\n );\n },\n\n assignRoleByNameToUser: async (user_id: string, role_name: string, scope_id: string | null) => {\n validateProjectKey();\n validateApiKey();\n\n const url = `/projects/${env.PROJECT_ID}/identities/${user_id}/roles/by-name`\n\n return apiInstance.post<void>(\n url,\n { role_name, scope_id },\n {\n headers: {\n \"Authorization\": `Bearer ${env.API_KEY}`,\n \"Content-Type\": \"application/json\"\n }\n }\n );\n },\n\n removeRoleByNameFromUser: async (user_id: string, role_name: string, scope_id: string | null) => {\n validateProjectKey();\n validateApiKey();\n\n const url = `/projects/${env.PROJECT_ID}/identities/${user_id}/roles/by-name`\n\n return apiInstance.delete<void>(\n url,\n { role_name, scope_id },\n {\n headers: {\n \"Authorization\": `Bearer ${env.API_KEY}`,\n \"Content-Type\": \"application/json\"\n }\n }\n );\n },\n});\n","import { Api } from \"./core/api\";\nimport { createServerAuthService } from \"./core/services\";\n\n/**\n * Creates a new server-side auth service instance with a custom base URL.\n */\nexport const createServerAuth = (baseURL?: string) => createServerAuthService(new Api(baseURL));"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/env.ts","../../src/utils/url-utils.ts","../../src/store/auth-store.ts","../../src/utils/token-utils.ts","../../src/core/interceptor.ts","../../src/core/api.ts","../../src/utils/env-validator.ts","../../src/core/services.ts","../../src/server.ts"],"names":["resolveEnv","isServer","viteEnv","safeProcessEnv","resolvedProjectId","resolvedApiKey","memoizedEnv","overrides","getEnv","env","joinUrl","base","path","cleanBase","cleanPath","_state","_listeners","notify","l","authStore","cb","partial","ACCESS_EXPIRY_KEY","REFRESH_EXPIRY_KEY","IS_UP_TO_DATE_KEY","COOKIE_OPTIONS","setCookie","name","value","expires","expiry","removeCookie","saveTokenClaims","claims","refreshExpiry","accessExpiry","isTokenExpiringSoon","thresholdSeconds","expiryStr","accessExpiryTimestamp","now","thresholdMs","isRefreshSessionExpired","refreshExpiryTimestamp","clearAuthTokens","AuthInterceptor","config","is_up_to_date","resJson","access_token","refresh_token","res","expiresDate","data","error","url","options","shouldAuth","shouldRefresh","finalUrl","Api","baseURL","authBaseURL","onTokenRefreshed","response","raw","errorMessage","body","validateProjectKey","validateApiKey","createServerAuthService","apiInstance","flow_id","params","user_id","role_name","scope_id","createServerAuth"],"mappings":"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","file":"server.js","sourcesContent":["export interface TrieOHEnv {\n PROJECT_ID: string;\n API_KEY: string;\n BASE_URL: string;\n}\n\nexport function resolveEnv(): TrieOHEnv {\n const isServer = typeof window === \"undefined\";\n\n const viteEnv = (\n typeof import.meta !== \"undefined\" && import.meta.env\n ? import.meta.env\n : {}\n ) as Partial<ImportMetaEnv>;\n\n const safeProcessEnv: NodeJS.ProcessEnv = \n typeof process !== \"undefined\" ? process.env : {};\n\n const resolvedProjectId =\n viteEnv.VITE_TRIEOH_AUTH_PROJECT_ID ||\n safeProcessEnv.NEXT_PUBLIC_TRIEOH_AUTH_PROJECT_ID ||\n safeProcessEnv.PUBLIC_TRIEOH_AUTH_PROJECT_ID ||\n \"\";\n\n const resolvedApiKey = isServer\n ? (safeProcessEnv.TRIEOH_AUTH_API_KEY || \"\")\n : \"\";\n\n return {\n PROJECT_ID: resolvedProjectId,\n API_KEY: resolvedApiKey,\n BASE_URL: \"https://api.default.com\",\n };\n}\nlet memoizedEnv: TrieOHEnv | null = null;\nlet overrides: Partial<TrieOHEnv> = {};\n\n/**\n * Configure the SDK manually. This will override any environment variables.\n */\nexport function configure(config: Partial<TrieOHEnv>) {\n overrides = { ...overrides, ...config };\n memoizedEnv = null; // Reset memoization to apply new config\n}\n\nfunction getEnv(): TrieOHEnv {\n if (!memoizedEnv) {\n const resolved = resolveEnv();\n memoizedEnv = {\n ...resolved,\n ...overrides,\n };\n }\n return memoizedEnv;\n}\nexport const env: TrieOHEnv = {\n get PROJECT_ID() {\n return getEnv().PROJECT_ID;\n },\n get API_KEY() {\n return getEnv().API_KEY;\n },\n get BASE_URL() {\n return getEnv().BASE_URL;\n },\n};\n","export function joinUrl(base: string, path: string): string {\n if (path.startsWith(\"http\")) return path;\n \n const cleanBase = base.replace(/\\/$/, \"\");\n const cleanPath = path.replace(/^\\//, \"\");\n \n return `${cleanBase}/${cleanPath}`;\n}\n","// ---- Auth Store ----\ntype AuthState = {\n isAuthenticated: boolean;\n isUpToDate: boolean;\n};\n\nlet _state: AuthState = { isAuthenticated: false, isUpToDate: false };\nconst _listeners = new Set<() => void>();\n\nconst notify = () => _listeners.forEach(l => l());\n\nexport const authStore = {\n subscribe: (cb: () => void) => {\n _listeners.add(cb);\n return () => _listeners.delete(cb);\n },\n getSnapshot: () => _state,\n getServerSnapshot: () => _state,\n set: (partial: Partial<AuthState>) => {\n _state = { ..._state, ...partial };\n notify();\n },\n reset: () => {\n _state = { isAuthenticated: false, isUpToDate: false };\n notify();\n },\n};\n","import type { Api } from \"../core/api\";\nimport { authStore } from \"../store/auth-store\";\n\nexport interface TokenClaims {\n sub: {\n id: string;\n email: string;\n session_id: string;\n user_agent: string;\n user_ip: string;\n project_id: string | null;\n verified_at: string | null;\n is_verified: boolean;\n user_type: \"client\" | \"project\";\n metadata: Record<string, unknown> | null;\n };\n iss: string;\n exp: number;\n iat: number;\n jti: string;\n}\n\nexport interface AuthTokenClaims {\n access_data: TokenClaims;\n refresh_expiry_date: string | number;\n is_up_to_date?: boolean;\n}\n\nconst ACCESS_EXPIRY_KEY = \"trieoh_access_expiry\";\nconst REFRESH_EXPIRY_KEY = \"trieoh_refresh_expiry\";\nconst IS_UP_TO_DATE_KEY = \"trieoh_is_up_to_date\";\n\n// Cookie configuration constants\nconst COOKIE_OPTIONS = \"path=/; secure; samesite=none\";\n\nexport function setCookie(name: string, value: string, expires?: string): void {\n if (typeof window === \"undefined\") return;\n const expiry = expires ? `; expires=${expires}` : \"\";\n document.cookie = `${name}=${value}; ${COOKIE_OPTIONS}${expiry}`;\n}\n\nexport function removeCookie(name: string): void {\n setCookie(name, \"\", \"Thu, 01 Jan 1970 00:00:00 GMT\");\n}\n\n// Stored only in memory\nlet memoryClaims: AuthTokenClaims | null = null;\n\nexport function saveTokenClaims(claims: AuthTokenClaims): void {\n memoryClaims = claims;\n\n const refreshExpiry = new Date(claims.refresh_expiry_date).getTime();\n const accessExpiry = claims.access_data.exp * 1000;\n\n if (isNaN(refreshExpiry)) {\n console.error(\"[TRIEOH SDK] Invalid refresh_expiry_date received:\", claims.refresh_expiry_date);\n } else localStorage.setItem(REFRESH_EXPIRY_KEY, String(refreshExpiry));\n\n if (isNaN(accessExpiry)) {\n console.error(\"[TRIEOH SDK] Invalid access expiry received:\", claims.access_data.exp);\n } else localStorage.setItem(ACCESS_EXPIRY_KEY, String(accessExpiry));\n\n if (claims.is_up_to_date !== undefined) {\n localStorage.setItem(IS_UP_TO_DATE_KEY, String(claims.is_up_to_date));\n }\n\n console.log(\"[TRIEOH SDK] Token claims saved\");\n}\n\nexport function getTokenClaims(): AuthTokenClaims | null {\n if (memoryClaims) return memoryClaims;\n return null;\n}\n\nexport function isUpToDate(): boolean {\n if (memoryClaims?.is_up_to_date !== undefined) return memoryClaims.is_up_to_date;\n const stored = localStorage.getItem(IS_UP_TO_DATE_KEY);\n return stored === \"true\";\n}\n\nexport function isTokenExpiringSoon(thresholdSeconds: number = 30): boolean {\n try {\n const expiryStr = localStorage.getItem(ACCESS_EXPIRY_KEY);\n if (!expiryStr) return true;\n\n const accessExpiryTimestamp = parseInt(expiryStr, 10);\n if (isNaN(accessExpiryTimestamp)) return true;\n\n const now = Date.now();\n const thresholdMs = thresholdSeconds * 1000;\n\n return (accessExpiryTimestamp - now) <= thresholdMs;\n } catch (e) {\n console.warn(\"[TRIEOH SDK] Error reading access expiry date:\", e);\n return true;\n }\n}\n\nexport function isRefreshSessionExpired(thresholdSeconds: number = 10): boolean {\n try {\n const expiryStr = localStorage.getItem(REFRESH_EXPIRY_KEY);\n if (!expiryStr) return true;\n\n const refreshExpiryTimestamp = parseInt(expiryStr, 10);\n if (isNaN(refreshExpiryTimestamp)) return true;\n\n const now = Date.now();\n const thresholdMs = thresholdSeconds * 1000;\n\n return (refreshExpiryTimestamp - now) <= thresholdMs;\n } catch (e) {\n console.warn(\"[TRIEOH SDK] Error reading refresh expiry date:\", e);\n return true;\n }\n}\n\nexport function isAuthenticated(): boolean {\n const expiryStr = localStorage.getItem(ACCESS_EXPIRY_KEY);\n if (!expiryStr) return false;\n const accessExpiryTimestamp = parseInt(expiryStr, 10);\n return accessExpiryTimestamp > Date.now();\n}\n\nexport function clearAuthTokens(): void {\n memoryClaims = null;\n localStorage.removeItem(ACCESS_EXPIRY_KEY);\n localStorage.removeItem(REFRESH_EXPIRY_KEY);\n localStorage.removeItem(IS_UP_TO_DATE_KEY);\n\n removeCookie(\"svc_session\");\n removeCookie(\"refresh_token\");\n\n authStore.reset();\n\n console.log(\"[TRIEOH SDK] Auth tokens and claims cleared\");\n}\n\nexport function getUserInfo() {\n const claims = getTokenClaims();\n if (!claims) return null;\n\n return claims.access_data.sub\n}\n\nexport const fetchAndSaveClaims = async (\n apiInstance: Api,\n is_up_to_date?: boolean,\n skipRefresh?: boolean\n) => {\n try {\n const res = await apiInstance.get<AuthTokenClaims>(\"/sessions/me\",\n { requiresAuth: true, skipRefresh }\n );\n\n if (res.success) {\n const claims = { ...res.data, is_up_to_date: is_up_to_date ?? isUpToDate() };\n saveTokenClaims(claims);\n return { ...res, data: claims };\n }\n throw new Error(res.message || \"Failed to fetch session claims\");\n } catch (error) {\n console.warn(\"[TRIEOH SDK] fetch claims failed (network/server)\", error);\n throw error;\n }\n};\n\nexport const exchangeAndSaveClaims = async (\n apiInstance: Api,\n access_token: string,\n refresh_token: string,\n is_up_to_date: boolean\n) => {\n const res = await apiInstance.post<{ service_session_id: string, expires_at: string }>(\n \"/auth/exchange\",\n undefined,\n {\n requiresAuth: false,\n headers: {\n \"Authorization\": `Bearer ${access_token}`,\n },\n }\n );\n\n if (res.success) {\n const expiresDate = new Date(res.data.expires_at).toUTCString();\n setCookie(\"svc_session\", res.data.service_session_id, expiresDate);\n\n const claimsRes = await fetchAndSaveClaims(apiInstance, is_up_to_date, true);\n\n const refreshExpiry = new Date(claimsRes.data.refresh_expiry_date).toUTCString();\n setCookie(\"refresh_token\", refresh_token, refreshExpiry);\n\n return claimsRes;\n }\n\n throw new Error(res.message || \"Failed to exchange tokens\");\n};","import { joinUrl } from \"../utils/url-utils\";\nimport {\n clearAuthTokens,\n isRefreshSessionExpired,\n isTokenExpiringSoon,\n saveTokenClaims,\n setCookie,\n type AuthTokenClaims\n} from \"../utils/token-utils\";\nimport { env } from \"./env\";\n\n\nexport interface RequestOptions extends RequestInit {\n requiresAuth?: boolean;\n skipRefresh?: boolean;\n}\n\ninterface InterceptorConfig {\n baseURL?: string;\n authBaseURL?: string;\n onTokenRefreshed?: (claims: AuthTokenClaims) => void;\n onRefreshFailed?: (error: Error) => void;\n}\n\nexport class AuthInterceptor {\n private baseURL: string;\n private authBaseURL: string;\n private isRefreshing = false;\n private refreshPromise: Promise<void> | null = null;\n private onTokenRefreshed?: (claims: AuthTokenClaims) => void;\n private onRefreshFailed?: (error: Error) => void;\n\n constructor(config?: InterceptorConfig) {\n this.authBaseURL = config?.authBaseURL || env.BASE_URL;\n this.baseURL = config?.baseURL || this.authBaseURL;\n\n this.onTokenRefreshed = config?.onTokenRefreshed;\n this.onRefreshFailed = config?.onRefreshFailed;\n }\n\n private async fetchClaimsAndSave(is_up_to_date?: boolean): Promise<AuthTokenClaims> {\n const response = await fetch(joinUrl(this.authBaseURL, \"/sessions/me\"), {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" },\n credentials: \"include\",\n });\n\n const resJson = await response.json();\n\n if (resJson.code !== 200 || !resJson.data) {\n clearAuthTokens();\n throw new Error(resJson.message || \"Failed to fetch session claims after refresh\");\n }\n\n const claims = { ...resJson.data, is_up_to_date } as AuthTokenClaims;\n saveTokenClaims(claims);\n return claims;\n }\n\n private async exchange(access_token: string, refresh_token: string, is_up_to_date: boolean): Promise<AuthTokenClaims> {\n const response = await fetch(joinUrl(this.authBaseURL, \"/auth/exchange\"), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Authorization\": `Bearer ${access_token}`,\n },\n credentials: \"include\",\n });\n\n const res = await response.json();\n\n if (res.code !== 200) {\n clearAuthTokens();\n throw new Error(res.message || \"Failed to exchange tokens for session\");\n }\n\n const expiresDate = new Date(res.data.expires_at).toUTCString();\n setCookie(\"svc_session\", res.data.service_session_id, expiresDate);\n\n const claims = await this.fetchClaimsAndSave(is_up_to_date);\n\n const refreshExpiry = new Date(claims.refresh_expiry_date).toUTCString();\n setCookie(\"refresh_token\", refresh_token, refreshExpiry);\n\n return claims;\n }\n\n private async refreshToken(): Promise<void> {\n if (this.isRefreshing && this.refreshPromise) return this.refreshPromise;\n\n this.isRefreshing = true;\n this.refreshPromise = (async () => {\n try {\n const response = await fetch(joinUrl(this.authBaseURL, \"/auth/refresh\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n credentials: \"include\",\n });\n\n const data = await response.json();\n\n if (data.code !== 200) {\n if (data.code !== 503) clearAuthTokens();\n throw new Error(data.message || \"Failed to refresh token\");\n }\n\n const { access_token, refresh_token, is_up_to_date } = data.data;\n\n const claims = await this.exchange(access_token, refresh_token, is_up_to_date);\n\n this.onTokenRefreshed?.(claims);\n console.log(\"[TRIEOH SDK] Token refreshed successfully\");\n } catch (error) {\n console.warn(\"[TRIEOH SDK] Failed to refresh token:\", error);\n clearAuthTokens();\n this.onRefreshFailed?.(error as Error);\n throw error;\n } finally {\n this.isRefreshing = false;\n this.refreshPromise = null;\n }\n })();\n\n return this.refreshPromise;\n }\n\n async beforeRequest(): Promise<void> {\n if (isRefreshSessionExpired()) {\n clearAuthTokens();\n return;\n }\n\n if (isTokenExpiringSoon(30)) {\n console.log(\"[TRIEOH SDK] Token expiring soon, refreshing...\");\n try {\n await this.refreshToken();\n } catch (error) {\n console.warn(\"[TRIEOH SDK] Refresh interceptor failed:\", error);\n }\n }\n }\n\n async fetch(url: string, options?: RequestOptions): Promise<Response> {\n const shouldAuth = options?.requiresAuth !== false;\n const shouldRefresh = !options?.skipRefresh;\n\n if (shouldAuth && shouldRefresh) await this.beforeRequest();\n\n const finalUrl = joinUrl(this.baseURL, url);\n\n return fetch(finalUrl, {\n ...options,\n credentials: \"include\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n });\n }\n}\n\nexport const createAuthInterceptor = (config?: InterceptorConfig) => {\n return new AuthInterceptor(config);\n};\n\nexport const createAuthenticatedFetch = (config?: InterceptorConfig) => {\n const interceptor = new AuthInterceptor(config);\n\n return async (url: string, options?: RequestOptions): Promise<Response> => {\n return interceptor.fetch(url, options);\n };\n};","import { env } from \"./env\";\nimport { AuthInterceptor, type RequestOptions } from \"./interceptor\";\nimport type { AuthTokenClaims } from \"../utils/token-utils\";\n\n/**\n * Base structure shared by all API responses.\n */\nexport interface BaseResponse {\n module: string;\n message: string;\n timestamp: string;\n code: number;\n}\n\n/**\n * Standardized API Response. \n * Use 'success' to narrow down to the data or error details.\n */\nexport type ApiResponse<T> = \n | (BaseResponse & { success: true; data: T })\n | (BaseResponse & { \n success: false; \n error_id: string; \n trace?: string[]; \n });\n\n/**\n * Internal type for parsing the raw response from the server.\n */\ntype RawApiResponse<T> = BaseResponse & { \n data?: T; \n error_id?: string; \n trace?: string[] \n};\n\n/**\n * Custom error class for API failures.\n * Provides access to the full standardized response.\n */\nexport class ApiError extends Error {\n code: number;\n trace?: string[];\n response: ApiResponse<unknown>;\n\n constructor(response: ApiResponse<unknown>) {\n super(response.message);\n this.name = \"ApiError\";\n this.code = response.code;\n this.trace = !response.success ? response.trace : [];\n this.response = response;\n }\n}\n\nexport class Api {\n private baseURL: string;\n private authInterceptor: AuthInterceptor;\n\n constructor(baseURL?: string, authBaseURL?: string, onTokenRefreshed?: (claims: AuthTokenClaims) => void) {\n this.baseURL = baseURL || env.BASE_URL;\n this.authInterceptor = new AuthInterceptor({ \n baseURL: this.baseURL,\n authBaseURL: authBaseURL,\n onTokenRefreshed\n });\n }\n\n private get headers() {\n return { \"Content-Type\": \"application/json\" };\n }\n\n async request<T = unknown>(path: string, options?: RequestOptions): Promise<ApiResponse<T>> {\n try {\n const response = await this.authInterceptor.fetch(path, {\n ...options,\n headers: { ...this.headers, ...(options?.headers ?? {}) },\n });\n\n const raw: RawApiResponse<T> = await response.json().catch(() => ({\n module: \"Client\",\n message: response.statusText || \"Unknown error\",\n timestamp: new Date().toISOString(),\n code: response.status,\n error_id: \"CLIENT_PARSE_ERROR\",\n trace: [\"Failed to parse API response as JSON\"],\n }));\n\n if (!response.ok) {\n return {\n success: false,\n module: raw.module || \"Unknown\",\n message: raw.message || response.statusText || \"An unknown error occurred\",\n timestamp: raw.timestamp || new Date().toISOString(),\n code: raw.code || response.status,\n error_id: raw.error_id || \"UNKNOWN_ERROR\",\n trace: raw.trace,\n };\n }\n\n return {\n success: true,\n module: raw.module,\n message: raw.message,\n timestamp: raw.timestamp,\n code: raw.code,\n data: raw.data as T,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"A network or unknown error occurred.\";\n return {\n success: false,\n module: \"Network\",\n message: errorMessage,\n timestamp: new Date().toISOString(),\n code: 503,\n error_id: \"CLIENT_NETWORK_ERROR\",\n trace: error instanceof Error ? [error.stack || errorMessage] : [errorMessage],\n };\n }\n }\n\n get<T = unknown>(path: string, options?: RequestOptions) {\n return this.request<T>(path, { ...options, method: \"GET\" });\n }\n\n post<T = unknown>(path: string, body?: unknown, options?: RequestOptions) {\n return this.request<T>(path, {\n ...options,\n method: \"POST\",\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n put<T = unknown>(path: string, body?: unknown, options?: RequestOptions) {\n return this.request<T>(path, {\n ...options,\n method: \"PUT\",\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n patch<T = unknown>(path: string, body?: unknown, options?: RequestOptions) {\n return this.request<T>(path, {\n ...options,\n method: \"PATCH\",\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n delete<T = unknown>(path: string, body?: unknown, options?: RequestOptions) {\n return this.request<T>(path, { \n ...options, \n method: \"DELETE\", \n body: body ? JSON.stringify(body) : undefined \n });\n }\n}\n\n/**\n * Creates a fetcher object with all HTTP methods returning standardized ApiResponse.\n * \n * @param config - Optional configuration for the fetcher (baseURL, authBaseURL, etc.)\n * @returns An object with get, post, put, patch, delete, and request methods.\n */\nexport const createFetcher = (config?: { baseURL?: string; authBaseURL?: string }) => {\n const api = new Api(config?.baseURL, config?.authBaseURL);\n\n return {\n request: api.request.bind(api),\n get: api.get.bind(api),\n post: api.post.bind(api),\n put: api.put.bind(api),\n patch: api.patch.bind(api),\n delete: api.delete.bind(api),\n };\n};\n\n/**\n * Creates a simple fetcher function that returns data directly or throws an ApiError on failure.\n * Ideal for Query libraries like TanStack Query.\n * \n * @param config - Optional configuration for the fetcher (baseURL, authBaseURL, etc.)\n * @returns A single fetcher function that returns a Promise of TData.\n */\nexport const createQueryFetcher = (config?: { baseURL?: string; authBaseURL?: string }) => {\n const api = new Api(config?.baseURL, config?.authBaseURL);\n\n return async <TData>(path: string, init?: RequestOptions): Promise<TData> => {\n const response = await api.request<TData>(path, init);\n if (!response.success) throw new ApiError(response);\n return response.data;\n };\n};\n","import { env } from \"../core/env\";\n\nexport const validateProjectKey = () => {\n if (!env.PROJECT_ID || env.PROJECT_ID.trim() === \"\") {\n throw new Error(\n \"[TRIEOH SDK] Project ID is missing. Please set PUBLIC_TRIEOH_AUTH_PROJECT_ID, NEXT_PUBLIC_TRIEOH_AUTH_PROJECT_ID or VITE_TRIEOH_AUTH_PROJECT_ID.\"\n );\n }\n};\n\nexport const validateApiKey = () => {\n if (!env.API_KEY || env.API_KEY.trim() === \"\") {\n throw new Error(\n \"[TRIEOH SDK] Private API Key is missing. This operation requires TRIEOH_AUTH_API_KEY to be set in a server-side environment.\"\n );\n }\n};\n","import type { ProjectFieldDefinitionResultI, FieldValue } from \"../types/fields-types\";\nimport type { SessionI } from \"../types/sessions-types\";\nimport {\n clearAuthTokens,\n exchangeAndSaveClaims,\n fetchAndSaveClaims,\n getUserInfo,\n isUpToDate,\n setCookie\n} from \"../utils/token-utils\";\nimport { validateApiKey, validateProjectKey } from \"../utils/env-validator\";\nimport type { Api, ApiResponse } from \"./api\";\nimport { env } from \"./env\";\n\nexport interface AuthTokens {\n access_token: string;\n refresh_token: string;\n is_up_to_date: boolean;\n}\n\nexport const createAuthService = (apiInstance: Api) => ({\n login: async (email: string, password: string) => {\n const options = { requiresAuth: false };\n let res: ApiResponse<AuthTokens>;\n\n if (env.PROJECT_ID) {\n validateProjectKey();\n const url = `/projects/${env.PROJECT_ID}/login`;\n res = await apiInstance.post<AuthTokens>(\n url,\n { email, password },\n options\n );\n } else {\n res = await apiInstance.post<AuthTokens>(\n \"/auth/login\",\n { email, password },\n options\n );\n }\n\n if (res.success) {\n try {\n const claims = await exchangeAndSaveClaims(\n apiInstance,\n res.data.access_token,\n res.data.refresh_token,\n res.data.is_up_to_date\n );\n return res;\n } catch (error) {\n console.error(\"[TRIEOH SDK] Exchange failed during login:\", error);\n clearAuthTokens();\n return {\n success: false,\n code: 500,\n message: error instanceof Error ? error.message : \"Authentication failed during exchange\"\n } as ApiResponse<AuthTokens>;\n }\n }\n\n return res;\n },\n\n register: (email: string, password: string, flow_id?: string, custom: Record<string, FieldValue> = {}) => {\n const options = { requiresAuth: false };\n if (env.PROJECT_ID) {\n validateProjectKey();\n\n const params = new URLSearchParams();\n if (flow_id) {\n params.append(\"flow_id\", flow_id);\n params.append(\"schema_type\", \"context\");\n params.append(\"version\", \"1\");\n }\n const bodyData = { ...{ email, password }, ...flow_id && { custom_fields: custom } };\n const paramsUrl = params.toString() ? `?${params.toString()}` : \"\";\n const url = `/projects/${env.PROJECT_ID}/register${paramsUrl}`;\n return apiInstance.post<string>(url, bodyData, options);\n }\n\n return apiInstance.post<string>(\"/auth/register\", { email, password }, options);\n },\n\n logout: async () => {\n const res = await apiInstance.post<string>(\"/auth/logout\");\n if (res.success) clearAuthTokens();\n return res;\n },\n\n refresh: async () => {\n const res = await apiInstance.post<AuthTokens>(\n \"/auth/refresh\",\n undefined,\n { skipRefresh: true }\n );\n\n if (res.success) {\n try {\n await exchangeAndSaveClaims(\n apiInstance,\n res.data.access_token,\n res.data.refresh_token,\n res.data.is_up_to_date\n );\n return res;\n } catch (error) {\n console.error(\"[TRIEOH SDK] Exchange failed during refresh:\", error);\n clearAuthTokens();\n return {\n success: false,\n code: 500,\n message: error instanceof Error ? error.message : \"Refresh failed during exchange\"\n } as ApiResponse<AuthTokens>;\n }\n }\n\n return res;\n },\n\n exchange: async (access_token: string) => {\n const res = await apiInstance.post<{ service_session_id: string, expires_at: string }>(\n \"/auth/exchange\",\n undefined,\n {\n requiresAuth: false,\n headers: {\n \"Authorization\": `Bearer ${access_token}`,\n }\n }\n );\n if (res.success) {\n const expiresDate = new Date(res.data.expires_at).toUTCString();\n setCookie(\"svc_session\", res.data.service_session_id, expiresDate);\n await fetchAndSaveClaims(apiInstance, undefined, true);\n }\n return res;\n },\n\n sessions: async () => {\n return apiInstance.get<SessionI[]>(\"/sessions\");\n },\n\n revokeASession: async (id: string) => {\n return apiInstance.delete<string>(`/sessions/${id}`);\n },\n\n revokeSessions: async (revokeAll: boolean = false) => {\n const path = revokeAll ? \"/sessions\" : \"/sessions/others\"\n return apiInstance.delete<string>(path);\n },\n\n refreshProfileInfo: async () => fetchAndSaveClaims(apiInstance),\n\n profile: () => getUserInfo(),\n\n isUpToDate: () => isUpToDate(),\n\n getProfileUpgradeForms: async () => {\n validateProjectKey();\n const url = `/projects/${env.PROJECT_ID}/upgrade-form`;\n return apiInstance.get<ProjectFieldDefinitionResultI>(url);\n },\n\n updateProfile: async (custom: Record<string, FieldValue>) => {\n validateProjectKey();\n const url = `/projects/${env.PROJECT_ID}/metadata`;\n return apiInstance.post<string>(url, { custom_fields: custom });\n },\n\n sendForgotPassword: async (email: string) => {\n const options = { requiresAuth: false };\n if (env.PROJECT_ID) {\n validateProjectKey();\n return apiInstance.post<string>(\n \"/auth/forgot-password\",\n { email, project_id: env.PROJECT_ID },\n options\n );\n }\n return apiInstance.post<string>(\"/auth/forgot-password\", { email }, options);\n },\n\n resetPassword: async (token: string, new_password: string) => {\n return apiInstance.post<string>(\n `/auth/reset-password?token=${token}`,\n { new_password },\n { requiresAuth: false }\n );\n },\n\n resendVerifyEmail: async () => {\n return apiInstance.post<string>(\"/auth/verify/resend\");\n },\n\n verifyEmail: async () => {\n return apiInstance.get<string>(\n \"/auth/verify\",\n { requiresAuth: false }\n );\n },\n\n addSubContext: async (user_id: string, data: Record<string, unknown>) => {\n validateProjectKey();\n return apiInstance.post<void>(\n `/projects/${env.PROJECT_ID}/sub-context`,\n { data, user_id }\n );\n },\n\n removeSubContext: async (user_id: string, keys: string[]) => {\n validateProjectKey();\n return apiInstance.delete<void>(\n `/projects/${env.PROJECT_ID}/sub-context`,\n { keys, user_id }\n );\n },\n\n\n});\n\nexport const createServerAuthService = (apiInstance: Api) => ({\n getProjectLatestRegisterFields: async (flow_id: string) => {\n validateProjectKey();\n validateApiKey();\n\n let url = `/projects/${env.PROJECT_ID}/schemas/lookup/latest`\n const params = new URLSearchParams();\n params.append(\"flow_id\", flow_id);\n params.append(\"schema_type\", \"context\");\n url += `?${params.toString()}`;\n\n return apiInstance.get<ProjectFieldDefinitionResultI>(\n url,\n {\n headers: {\n \"Authorization\": `Bearer ${env.API_KEY}`,\n \"Content-Type\": \"application/json\"\n }\n }\n );\n },\n\n getProjectRegisterFields: async (flow_id: string) => {\n validateProjectKey();\n validateApiKey();\n\n const version = 1;\n let url = `/projects/${env.PROJECT_ID}/schemas/lookup/v${version}`\n const params = new URLSearchParams();\n params.append(\"flow_id\", flow_id);\n params.append(\"schema_type\", \"context\");\n url += `?${params.toString()}`;\n\n return apiInstance.get<ProjectFieldDefinitionResultI>(\n url,\n {\n headers: {\n \"Authorization\": `Bearer ${env.API_KEY}`,\n \"Content-Type\": \"application/json\"\n }\n }\n );\n },\n\n assignRoleByNameToUser: async (user_id: string, role_name: string, scope_id: string | null) => {\n validateProjectKey();\n validateApiKey();\n\n const url = `/projects/${env.PROJECT_ID}/identities/${user_id}/roles/by-name`\n\n return apiInstance.post<void>(\n url,\n { role_name, scope_id },\n {\n headers: {\n \"Authorization\": `Bearer ${env.API_KEY}`,\n \"Content-Type\": \"application/json\"\n }\n }\n );\n },\n\n removeRoleByNameFromUser: async (user_id: string, role_name: string, scope_id: string | null) => {\n validateProjectKey();\n validateApiKey();\n\n const url = `/projects/${env.PROJECT_ID}/identities/${user_id}/roles/by-name`\n\n return apiInstance.delete<void>(\n url,\n { role_name, scope_id },\n {\n headers: {\n \"Authorization\": `Bearer ${env.API_KEY}`,\n \"Content-Type\": \"application/json\"\n }\n }\n );\n },\n});\n","import { Api } from \"./core/api\";\nimport { createServerAuthService } from \"./core/services\";\n\n/**\n * Creates a new server-side auth service instance with a custom base URL.\n */\nexport const createServerAuth = (baseURL?: string) => createServerAuthService(new Api(baseURL));"]}
|