@fluoce/auth-react 0.1.1 → 0.2.0
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/index.cjs +317 -221
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -70
- package/dist/index.d.ts +45 -70
- package/dist/index.js +320 -225
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/README.md +0 -87
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/FluoceAuthProvider.tsx","../src/AuthContext.tsx","../src/cookies.ts","../src/apiClient.ts","../src/AuthGuard.tsx"],"sourcesContent":["export { FluoceAuthProvider } from './FluoceAuthProvider';\nexport type { FluoceAuthProviderProps } from './FluoceAuthProvider';\nexport { AuthGuard } from './AuthGuard';\nexport type { AuthGuardProps } from './AuthGuard';\nexport { useFluoceAuth } from './AuthContext';\nexport { FluoceApiClient } from './apiClient';\nexport type {\n FluoceUser,\n TokenPair,\n FluoceAuthConfig,\n FluoceAuthContextValue,\n} from './types';\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { FluoceAuthContext } from \"./AuthContext\";\nimport { FluoceApiClient } from \"./apiClient\";\nimport type { FluoceAuthConfig, FluoceUser } from \"./types\";\n\nexport interface FluoceAuthProviderProps extends FluoceAuthConfig {\n children: ReactNode;\n}\n\nexport function FluoceAuthProvider({\n children,\n ...config\n}: FluoceAuthProviderProps) {\n const clientRef = useRef<FluoceApiClient>();\n if (!clientRef.current) clientRef.current = new FluoceApiClient(config);\n const client = clientRef.current;\n\n const [user, setUser] = useState<FluoceUser | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const redirectToLogin = useCallback(() => {\n window.location.href = client.buildLoginUrl();\n }, [client]);\n\n // keep the client's failure hook pointed at the latest redirect fn\n client.onAuthFailure = redirectToLogin;\n\n const refreshUser = useCallback(async () => {\n try {\n const me = await client.getMe();\n setUser(me);\n setError(null);\n } catch (e) {\n setUser(null);\n setError(e as Error);\n }\n }, [client]);\n\n const logout = useCallback(\n async (allDevices = false) => {\n await client.logout(allDevices);\n setUser(null);\n redirectToLogin();\n },\n [client, redirectToLogin],\n );\n\n useEffect(() => {\n let cancelled = false;\n\n async function init() {\n const params = new URLSearchParams(window.location.search);\n const code = params.get(\"code\");\n\n try {\n if (code) {\n await client.exchangeCode(code);\n params.delete(\"code\");\n const query = params.toString();\n const cleanUrl =\n window.location.pathname +\n (query ? `?${query}` : \"\") +\n window.location.hash;\n window.history.replaceState({}, \"\", cleanUrl);\n }\n\n if (client.getAccessToken() || client.getRefreshToken()) {\n const me = await client.getMe();\n if (!cancelled) setUser(me);\n }\n } catch (e) {\n if (!cancelled) setError(e as Error);\n } finally {\n if (!cancelled) setLoading(false);\n }\n }\n\n init();\n return () => {\n cancelled = true;\n };\n // run once on mount only\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // const authFetch = useCallback(\n // <T,>(path: string, init?: RequestInit) => client.authFetch<T>(path, init),\n // [client],\n // );\n\n const value = useMemo(\n () => ({\n user,\n loading,\n isAuthenticated: !!user,\n error,\n refreshUser,\n logout,\n redirectToLogin,\n }),\n [user, loading, error, refreshUser, logout, redirectToLogin],\n );\n\n return (\n <FluoceAuthContext.Provider value={value}>\n {children}\n </FluoceAuthContext.Provider>\n );\n}\n","import { createContext, useContext } from \"react\";\nimport type { FluoceAuthContextValue } from \"./types\";\n\nexport const FluoceAuthContext = createContext<FluoceAuthContextValue | null>(\n null,\n);\n\nexport function useFluoceAuth(): FluoceAuthContextValue {\n const ctx = useContext(FluoceAuthContext);\n if (!ctx)\n throw new Error(\"useFluoceAuth must be used within <FluoceAuthProvider>\");\n return ctx;\n}\n","export function setCookie(name: string, value: string, days: number): void {\n const expires = new Date(Date.now() + days * 864e5).toUTCString();\n document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/; SameSite=Lax`;\n}\n\nexport function getCookie(name: string): string | null {\n const escaped = name.replace(/([.$?*|{}()[\\]\\\\/+^])/g, '\\\\$1');\n const match = document.cookie.match(new RegExp('(?:^|; )' + escaped + '=([^;]*)'));\n return match ? decodeURIComponent(match[1]) : null;\n}\n\nexport function deleteCookie(name: string): void {\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;\n}\n","import { getCookie, setCookie, deleteCookie } from \"./cookies\";\nimport type { FluoceAuthConfig, FluoceUser, TokenPair } from \"./types\";\n\ntype ResolvedConfig = Required<FluoceAuthConfig>;\n\nexport class FluoceApiClient {\n private config: ResolvedConfig;\n private refreshPromise: Promise<TokenPair | null> | null = null;\n\n /** set by the Provider — called once refresh fails and there's no session left */\n onAuthFailure: () => void = () => {};\n\n constructor(config: FluoceAuthConfig) {\n this.config = {\n accessTokenCookie: \"fluoce_access_token\",\n refreshTokenCookie: \"fluoce_refresh_token\",\n accessTokenExpiryDays: 1,\n refreshTokenExpiryDays: 30,\n ...config,\n };\n }\n\n getAccessToken(): string | null {\n return getCookie(this.config.accessTokenCookie);\n }\n\n getRefreshToken(): string | null {\n return getCookie(this.config.refreshTokenCookie);\n }\n\n setTokens(tokens: TokenPair): void {\n setCookie(\n this.config.accessTokenCookie,\n tokens.accessToken,\n this.config.accessTokenExpiryDays,\n );\n setCookie(\n this.config.refreshTokenCookie,\n tokens.refreshToken,\n this.config.refreshTokenExpiryDays,\n );\n }\n\n clearTokens(): void {\n deleteCookie(this.config.accessTokenCookie);\n deleteCookie(this.config.refreshTokenCookie);\n }\n\n buildLoginUrl(): string {\n const ref = encodeURIComponent(this.config.appUrl);\n return `${this.config.authUrl}/auth?ref=${ref}`;\n }\n\n async exchangeCode(code: string): Promise<TokenPair> {\n const res = await fetch(`${this.config.apiUrl}/exchange`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code }),\n });\n if (!res.ok) throw new Error(`exchange failed: ${res.status}`);\n const data = (await res.json()) as TokenPair;\n this.setTokens(data);\n return data;\n }\n\n async getMe(): Promise<FluoceUser> {\n return this.authFetch<FluoceUser>(\"/me\");\n }\n\n async updateMe(payload: {\n name?: string;\n photo?: string;\n }): Promise<FluoceUser> {\n return this.authFetch<FluoceUser>(\"/me\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n });\n }\n\n async refresh(): Promise<TokenPair | null> {\n // dedupe concurrent refresh calls triggered by parallel 401s\n if (this.refreshPromise) return this.refreshPromise;\n\n const refreshToken = this.getRefreshToken();\n if (!refreshToken) return null;\n\n this.refreshPromise = (async () => {\n try {\n const res = await fetch(`${this.config.apiUrl}/refresh`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${refreshToken}`,\n },\n });\n if (!res.ok) {\n this.clearTokens();\n return null;\n }\n const data = (await res.json()) as TokenPair;\n this.setTokens(data);\n return data;\n } catch {\n this.clearTokens();\n return null;\n } finally {\n this.refreshPromise = null;\n }\n })();\n\n return this.refreshPromise;\n }\n\n async logout(allDevices = false): Promise<void> {\n const refreshToken = this.getRefreshToken();\n if (refreshToken) {\n try {\n await fetch(\n `${this.config.apiUrl}${allDevices ? \"/logout/all\" : \"/logout\"}`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${refreshToken}`,\n },\n },\n );\n } catch {\n // best-effort — clear local session regardless\n }\n }\n this.clearTokens();\n }\n\n /**\n * Authenticated fetch. Attaches access token, retries once through /refresh\n * on 401, and calls onAuthFailure (-> redirect to auth frontend) if that\n * fails too. Use this for /me, /me updates, and any endpoint you add later.\n */\n async authFetch<T = unknown>(\n path: string,\n init: RequestInit = {},\n ): Promise<T> {\n const doFetch = (token: string | null) =>\n fetch(`${this.config.apiUrl}${path}`, {\n ...init,\n headers: {\n ...(init.headers || {}),\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n });\n\n let res = await doFetch(this.getAccessToken());\n\n if (res.status === 401) {\n const refreshed = await this.refresh();\n if (!refreshed) {\n this.onAuthFailure();\n throw new Error(\"unauthenticated\");\n }\n res = await doFetch(refreshed.accessToken);\n if (res.status === 401) {\n this.clearTokens();\n this.onAuthFailure();\n throw new Error(\"unauthenticated\");\n }\n }\n\n if (!res.ok) throw new Error(`request failed: ${res.status}`);\n\n return res.json() as Promise<T>;\n }\n}\n","import { useEffect, type ReactNode } from \"react\";\nimport { useFluoceAuth } from \"./AuthContext\";\n\nexport interface AuthGuardProps {\n children: ReactNode;\n /** shown while loading or right before the redirect fires */\n fallback?: ReactNode;\n}\n\nexport function AuthGuard({ children, fallback = null }: AuthGuardProps) {\n const { loading, isAuthenticated, redirectToLogin } = useFluoceAuth();\n\n useEffect(() => {\n if (!loading && !isAuthenticated) {\n redirectToLogin();\n }\n }, [loading, isAuthenticated, redirectToLogin]);\n\n if (loading || !isAuthenticated) {\n return <>{fallback}</>;\n }\n\n return <>{children}</>;\n}\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/provider/auth_provider.tsx","../src/const/api_endpoint.ts","../src/const/route.ts","../src/func/func_cookies.ts","../src/func/func_try_catch.ts","../src/api/api_service.ts","../src/context/auth_context.tsx","../src/hook/use_auth.ts","../src/guard/auth_guard.tsx"],"sourcesContent":["export { auth_provider as FluoceAuthProvider } from \"./provider/auth_provider\";\r\nexport { use_auth as useFluoceAuth } from \"./hook/use_auth\";\r\nexport { auth_guard as FluoceAuthGuard } from \"./guard/auth_guard\";\r\nexport { user_type as FluoceUserType } from \"./types/user_type\";\r\nexport { auth_provider_interface as FluoceAuthProviderType } from \"./types/auth_provider_interface\";\r\nexport { redirect_type as FluoceRedirectType } from \"./types/redirect_type\";\r\n","import {\r\n useMemo as use_memo,\r\n useState as use_state,\r\n useEffect as use_effect,\r\n} from \"react\";\r\nimport { auth_provider_interface } from \"../types/auth_provider_interface\";\r\nimport { Api_service } from \"../api/api_service\";\r\nimport { user_type } from \"../types/user_type\";\r\nimport { auth_context_interface } from \"../types/auth_context_interface\";\r\nimport { auth_context } from \"../context/auth_context\";\r\n\r\nexport const auth_provider = ({\r\n children,\r\n app_url,\r\n on_error,\r\n redirect,\r\n}: auth_provider_interface) => {\r\n const auth_api = use_memo(() => {\r\n return new Api_service({\r\n app_url,\r\n on_error,\r\n redirect,\r\n });\r\n }, [app_url, on_error, redirect]);\r\n\r\n const [user, set_user] = use_state<user_type | null>(null);\r\n\r\n const [safe_loading, set_safe_loading] = use_state(false);\r\n\r\n const [auth_flow_loading, set_auth_flow_loading] = use_state(false);\r\n\r\n const refresh = async () => {\r\n const response = await auth_api.refresh();\r\n return response?.success ?? false;\r\n };\r\n\r\n const logout = async () => {\r\n await auth_api.logout();\r\n set_user(null);\r\n return true;\r\n };\r\n\r\n const auth_flow = async ({ code }: { code: string }) => {\r\n set_auth_flow_loading(true);\r\n try {\r\n const data = await auth_api.auth_flow({\r\n code,\r\n });\r\n if (data?.success && data?.data) {\r\n set_user(data?.data);\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n } catch (error) {\r\n return false;\r\n } finally {\r\n set_auth_flow_loading(false);\r\n }\r\n };\r\n\r\n const get_safe_user = async () => {\r\n set_safe_loading(true);\r\n try {\r\n if (user) {\r\n return user;\r\n }\r\n const data = await auth_api.safe_me({});\r\n if (data?.success && data?.data) {\r\n set_user(data?.data);\r\n return data.data;\r\n } else {\r\n return null;\r\n }\r\n } catch (error) {\r\n return null;\r\n } finally {\r\n set_safe_loading(false);\r\n }\r\n };\r\n\r\n use_effect(() => {\r\n void get_safe_user();\r\n }, []);\r\n\r\n const value: auth_context_interface = {\r\n user,\r\n safe_loading,\r\n auth_flow_loading,\r\n refresh,\r\n logout,\r\n auth_flow,\r\n get_safe_user,\r\n get access_token() {\r\n return auth_api.get_access_token();\r\n },\r\n get refresh_token() {\r\n return auth_api.get_refresh_token();\r\n },\r\n };\r\n\r\n return (\r\n <auth_context.Provider value={value}>{children}</auth_context.Provider>\r\n );\r\n};\r\n","export const base_url = \"https://auth-service.fluoce.com\";\r\n\r\nexport const api_endpoint = {\r\n me: \"/me\",\r\n exchange: \"/exchange\",\r\n refresh: \"/refresh\",\r\n logout: \"/logout\",\r\n};\r\n","export const route = {\r\n fluoce_auth: (ref: string) => `https://auth.fluoce.com/auth?ref=${ref}`,\r\n};\r\n","export function func_set_cookie(\n name: string,\n value: string,\n days: number,\n): void {\n const expires = new Date(Date.now() + days * 864e5).toUTCString();\n document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/; SameSite=Lax`;\n}\n\nexport function func_get_cookie(name: string): string | null {\n const escaped = name.replace(/([.$?*|{}()[\\]\\\\/+^])/g, \"\\\\$1\");\n const match = document.cookie.match(\n new RegExp(\"(?:^|; )\" + escaped + \"=([^;]*)\"),\n );\n return match ? decodeURIComponent(match[1]) : null;\n}\n\nexport function func_delete_cookie(name: string): void {\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; SameSite=Lax`;\n}\n","export async function func_try_catch<T>({\r\n fn,\r\n onError,\r\n}: {\r\n fn: () => Promise<T>;\r\n onError?: (error: unknown) => void;\r\n}): Promise<T | null> {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n if (onError) {\r\n onError(error);\r\n return null;\r\n }\r\n if (error instanceof Error) {\r\n throw error;\r\n } else {\r\n throw new Error(String(error));\r\n }\r\n }\r\n}\r\n","import { api_endpoint, base_url } from \"../const/api_endpoint\";\r\nimport { route } from \"../const/route\";\r\nimport {\r\n func_delete_cookie,\r\n func_get_cookie,\r\n func_set_cookie,\r\n} from \"../func/func_cookies\";\r\nimport { func_try_catch } from \"../func/func_try_catch\";\r\nimport { Api_service_interface } from \"../types/api_service_interface\";\r\nimport { redirect_type } from \"../types/redirect_type\";\r\nimport {\r\n exchange_response_type,\r\n refresh_response_type,\r\n response_type,\r\n user_response_type,\r\n} from \"../types/response_types\";\r\n\r\nexport class Api_service implements Api_service_interface {\r\n private readonly base_url = base_url;\r\n private readonly api_endpoint = api_endpoint;\r\n private app_url: string;\r\n private on_error?: (error: unknown) => void;\r\n private redirect?: redirect_type = {\r\n type: \"fluoce\",\r\n };\r\n\r\n private readonly redirect_at_fluoce_auth = (error: unknown) => {\r\n console.warn(error);\r\n window.location.replace(route.fluoce_auth(this.app_url));\r\n };\r\n\r\n private readonly handle_redirect = (error?: unknown): void => {\r\n switch (this.redirect?.type) {\r\n case \"fluoce\":\r\n this.redirect_at_fluoce_auth(error);\r\n break;\r\n case \"custom\":\r\n this.redirect.redirect(error);\r\n break;\r\n case \"none\":\r\n break;\r\n }\r\n };\r\n\r\n private readonly handle_error = (error?: unknown): void => {\r\n if (this.on_error) {\r\n this.on_error(error);\r\n return;\r\n }\r\n this.handle_redirect(error);\r\n };\r\n\r\n constructor(\r\n {\r\n app_url,\r\n on_error,\r\n redirect,\r\n }: {\r\n app_url: string;\r\n on_error?: (error: unknown) => void;\r\n redirect?: redirect_type;\r\n },\r\n private readonly http: typeof fetch = fetch,\r\n ) {\r\n this.app_url = app_url;\r\n this.on_error = on_error;\r\n if (redirect) {\r\n this.redirect = redirect;\r\n }\r\n }\r\n\r\n public readonly get_access_token = (): string | null => {\r\n return func_get_cookie(\"accessToken\");\r\n };\r\n\r\n public readonly get_refresh_token = (): string | null => {\r\n return func_get_cookie(\"refreshToken\");\r\n };\r\n\r\n private readonly delete_cookie = () => {\r\n func_delete_cookie(\"accessToken\");\r\n func_delete_cookie(\"refreshToken\");\r\n };\r\n\r\n async me({ accessToken }: { accessToken?: string }) {\r\n const data = await func_try_catch<response_type<user_response_type> | null>(\r\n {\r\n fn: async () => {\r\n const res = await this.http(this.base_url + this.api_endpoint.me, {\r\n method: \"GET\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n Authorization: `Bearer ${accessToken ? accessToken : this.get_access_token()}`,\r\n },\r\n });\r\n return await res.json();\r\n },\r\n onError: (error) => {\r\n this.handle_error(error);\r\n },\r\n },\r\n );\r\n\r\n if (data?.success) {\r\n return data;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n async safe_me({ accessToken }: { accessToken?: string }) {\r\n const data = await func_try_catch<response_type<user_response_type> | null>(\r\n {\r\n fn: async () => {\r\n const res = await this.http(this.base_url + this.api_endpoint.me, {\r\n method: \"GET\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n Authorization: `Bearer ${accessToken ? accessToken : this.get_access_token()}`,\r\n },\r\n });\r\n return await res.json();\r\n },\r\n },\r\n );\r\n\r\n if (data?.success) {\r\n return data;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n async exchange({ code }: { code: string }) {\r\n const data = await func_try_catch<response_type<exchange_response_type>>({\r\n fn: async () => {\r\n const res = await this.http(\r\n this.base_url + this.api_endpoint.exchange,\r\n {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify({ code }),\r\n },\r\n );\r\n return await res.json();\r\n },\r\n onError: () => {\r\n this.handle_error();\r\n },\r\n });\r\n\r\n const refreshToken = data?.data?.refreshToken;\r\n const accessToken = data?.data?.accessToken;\r\n\r\n if (refreshToken && accessToken) {\r\n func_set_cookie(\"refreshToken\", refreshToken, 59);\r\n func_set_cookie(\"accessToken\", accessToken, 14 / (24 * 60));\r\n }\r\n\r\n if (data?.success) {\r\n return data;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n async refresh() {\r\n const data = await func_try_catch<response_type<refresh_response_type>>({\r\n fn: async () => {\r\n const res = await this.http(this.base_url + this.api_endpoint.refresh, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n Authorization: `Bearer ${this.get_refresh_token()}`,\r\n },\r\n });\r\n return await res.json();\r\n },\r\n onError: () => {\r\n this.handle_error();\r\n },\r\n });\r\n\r\n const refreshToken = data?.data?.refreshToken;\r\n const accessToken = data?.data?.accessToken;\r\n\r\n if (refreshToken && accessToken) {\r\n document.cookie = `refreshToken=${encodeURIComponent(refreshToken)}; path=/;`;\r\n document.cookie = `accessToken=${encodeURIComponent(accessToken)}; path=/;`;\r\n }\r\n\r\n if (data?.success) {\r\n return data;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n async logout() {\r\n this.delete_cookie();\r\n await func_try_catch<response_type<unknown>>({\r\n fn: async () => {\r\n const res = await this.http(this.base_url + this.api_endpoint.logout, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n Authorization: `Bearer ${this.get_refresh_token()}`,\r\n },\r\n });\r\n return await res.json();\r\n },\r\n onError: () => {\r\n this.handle_error();\r\n },\r\n });\r\n }\r\n\r\n async auth_flow({ code }: { code: string }) {\r\n const exchange_data = await this.exchange({\r\n code,\r\n });\r\n if (exchange_data?.success) {\r\n const me_data = await this.me({\r\n accessToken: exchange_data?.data?.accessToken,\r\n });\r\n return me_data;\r\n } else {\r\n return null;\r\n }\r\n }\r\n}\r\n","import { createContext as create_context } from \"react\";\r\nimport { auth_context_interface } from \"../types/auth_context_interface\";\r\n\r\nexport const auth_context = create_context<auth_context_interface | null>(null);\r\n","import { useContext as use_context } from \"react\";\r\nimport { auth_context } from \"../context/auth_context\";\r\n\r\nexport const use_auth = () => {\r\n const context = use_context(auth_context);\r\n\r\n if (!context) {\r\n throw new Error(\"use_auth must be used within an auth_provider\");\r\n }\r\n\r\n return context;\r\n};\r\n","import { use_auth } from \"../hook/use_auth\";\r\nimport { auth_guard_interface } from \"../types/auth_guard_interface\";\r\n\r\nexport const auth_guard = ({\r\n children,\r\n fallback = null,\r\n}: auth_guard_interface) => {\r\n const { user, safe_loading } = use_auth();\r\n\r\n if (safe_loading && !user) {\r\n return <>{fallback}</>;\r\n }\r\n\r\n if (!user && !safe_loading) {\r\n return null;\r\n }\r\n\r\n return <>{children}</>;\r\n};\r\n"],"mappings":"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","names":["import_react","create_context","use_memo","use_state","use_effect","import_react","use_context","import_jsx_runtime"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,82 +1,57 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
interface TokenPair {
|
|
13
|
-
accessToken: string;
|
|
14
|
-
refreshToken: string;
|
|
15
|
-
}
|
|
16
|
-
interface FluoceAuthConfig {
|
|
17
|
-
/** Auth frontend base url, e.g. "https://auth.fluoce.com" */
|
|
18
|
-
authUrl: string;
|
|
19
|
-
/** Auth backend api base url, e.g. "http://localhost:3001" */
|
|
20
|
-
apiUrl: string;
|
|
21
|
-
/**
|
|
22
|
-
* This app's own callback url, sent as `ref` and where auth.fluoce.com
|
|
23
|
-
* redirects back with `?code=`. e.g. "https://myapp.com/auth"
|
|
24
|
-
*/
|
|
25
|
-
appUrl: string;
|
|
26
|
-
accessTokenCookie?: string;
|
|
27
|
-
refreshTokenCookie?: string;
|
|
28
|
-
accessTokenExpiryDays?: number;
|
|
29
|
-
refreshTokenExpiryDays?: number;
|
|
30
|
-
}
|
|
31
|
-
interface FluoceAuthContextValue {
|
|
32
|
-
user: FluoceUser | null;
|
|
33
|
-
loading: boolean;
|
|
34
|
-
isAuthenticated: boolean;
|
|
35
|
-
error: Error | null;
|
|
36
|
-
refreshUser: () => Promise<void>;
|
|
37
|
-
logout: (allDevices?: boolean) => Promise<void>;
|
|
38
|
-
redirectToLogin: () => void;
|
|
39
|
-
}
|
|
4
|
+
type redirect_type = {
|
|
5
|
+
type: "fluoce";
|
|
6
|
+
} | {
|
|
7
|
+
type: "custom";
|
|
8
|
+
redirect: (error: unknown) => void;
|
|
9
|
+
} | {
|
|
10
|
+
type: "none";
|
|
11
|
+
};
|
|
40
12
|
|
|
41
|
-
interface
|
|
13
|
+
interface auth_provider_interface {
|
|
42
14
|
children: ReactNode;
|
|
15
|
+
app_url: string;
|
|
16
|
+
on_error?: () => void;
|
|
17
|
+
redirect?: redirect_type;
|
|
43
18
|
}
|
|
44
|
-
declare function FluoceAuthProvider({ children, ...config }: FluoceAuthProviderProps): react.JSX.Element;
|
|
45
19
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
20
|
+
declare const auth_provider: ({ children, app_url, on_error, redirect, }: auth_provider_interface) => react.JSX.Element;
|
|
21
|
+
|
|
22
|
+
type user_response_type = {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
email: string | null;
|
|
26
|
+
phone: string | null;
|
|
27
|
+
photo: string | null;
|
|
28
|
+
createdAt: Date;
|
|
29
|
+
updatedAt: Date;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type user_type = user_response_type;
|
|
33
|
+
|
|
34
|
+
interface auth_context_interface {
|
|
35
|
+
user: user_response_type | null;
|
|
36
|
+
safe_loading: boolean;
|
|
37
|
+
auth_flow_loading: boolean;
|
|
38
|
+
logout(): Promise<boolean>;
|
|
39
|
+
refresh(): Promise<boolean>;
|
|
40
|
+
auth_flow({ code }: {
|
|
41
|
+
code: string;
|
|
42
|
+
}): Promise<boolean>;
|
|
43
|
+
get_safe_user(): Promise<user_type | null>;
|
|
44
|
+
refresh_token: string | null;
|
|
45
|
+
access_token: string | null;
|
|
50
46
|
}
|
|
51
|
-
declare function AuthGuard({ children, fallback }: AuthGuardProps): react.JSX.Element;
|
|
52
47
|
|
|
53
|
-
declare
|
|
48
|
+
declare const use_auth: () => auth_context_interface;
|
|
54
49
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
/** set by the Provider — called once refresh fails and there's no session left */
|
|
59
|
-
onAuthFailure: () => void;
|
|
60
|
-
constructor(config: FluoceAuthConfig);
|
|
61
|
-
getAccessToken(): string | null;
|
|
62
|
-
getRefreshToken(): string | null;
|
|
63
|
-
setTokens(tokens: TokenPair): void;
|
|
64
|
-
clearTokens(): void;
|
|
65
|
-
buildLoginUrl(): string;
|
|
66
|
-
exchangeCode(code: string): Promise<TokenPair>;
|
|
67
|
-
getMe(): Promise<FluoceUser>;
|
|
68
|
-
updateMe(payload: {
|
|
69
|
-
name?: string;
|
|
70
|
-
photo?: string;
|
|
71
|
-
}): Promise<FluoceUser>;
|
|
72
|
-
refresh(): Promise<TokenPair | null>;
|
|
73
|
-
logout(allDevices?: boolean): Promise<void>;
|
|
74
|
-
/**
|
|
75
|
-
* Authenticated fetch. Attaches access token, retries once through /refresh
|
|
76
|
-
* on 401, and calls onAuthFailure (-> redirect to auth frontend) if that
|
|
77
|
-
* fails too. Use this for /me, /me updates, and any endpoint you add later.
|
|
78
|
-
*/
|
|
79
|
-
authFetch<T = unknown>(path: string, init?: RequestInit): Promise<T>;
|
|
50
|
+
interface auth_guard_interface {
|
|
51
|
+
children: ReactNode;
|
|
52
|
+
fallback?: ReactNode;
|
|
80
53
|
}
|
|
81
54
|
|
|
82
|
-
|
|
55
|
+
declare const auth_guard: ({ children, fallback, }: auth_guard_interface) => react.JSX.Element | null;
|
|
56
|
+
|
|
57
|
+
export { auth_guard as FluoceAuthGuard, auth_provider as FluoceAuthProvider, type auth_provider_interface as FluoceAuthProviderType, type redirect_type as FluoceRedirectType, type user_type as FluoceUserType, use_auth as useFluoceAuth };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,82 +1,57 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
interface TokenPair {
|
|
13
|
-
accessToken: string;
|
|
14
|
-
refreshToken: string;
|
|
15
|
-
}
|
|
16
|
-
interface FluoceAuthConfig {
|
|
17
|
-
/** Auth frontend base url, e.g. "https://auth.fluoce.com" */
|
|
18
|
-
authUrl: string;
|
|
19
|
-
/** Auth backend api base url, e.g. "http://localhost:3001" */
|
|
20
|
-
apiUrl: string;
|
|
21
|
-
/**
|
|
22
|
-
* This app's own callback url, sent as `ref` and where auth.fluoce.com
|
|
23
|
-
* redirects back with `?code=`. e.g. "https://myapp.com/auth"
|
|
24
|
-
*/
|
|
25
|
-
appUrl: string;
|
|
26
|
-
accessTokenCookie?: string;
|
|
27
|
-
refreshTokenCookie?: string;
|
|
28
|
-
accessTokenExpiryDays?: number;
|
|
29
|
-
refreshTokenExpiryDays?: number;
|
|
30
|
-
}
|
|
31
|
-
interface FluoceAuthContextValue {
|
|
32
|
-
user: FluoceUser | null;
|
|
33
|
-
loading: boolean;
|
|
34
|
-
isAuthenticated: boolean;
|
|
35
|
-
error: Error | null;
|
|
36
|
-
refreshUser: () => Promise<void>;
|
|
37
|
-
logout: (allDevices?: boolean) => Promise<void>;
|
|
38
|
-
redirectToLogin: () => void;
|
|
39
|
-
}
|
|
4
|
+
type redirect_type = {
|
|
5
|
+
type: "fluoce";
|
|
6
|
+
} | {
|
|
7
|
+
type: "custom";
|
|
8
|
+
redirect: (error: unknown) => void;
|
|
9
|
+
} | {
|
|
10
|
+
type: "none";
|
|
11
|
+
};
|
|
40
12
|
|
|
41
|
-
interface
|
|
13
|
+
interface auth_provider_interface {
|
|
42
14
|
children: ReactNode;
|
|
15
|
+
app_url: string;
|
|
16
|
+
on_error?: () => void;
|
|
17
|
+
redirect?: redirect_type;
|
|
43
18
|
}
|
|
44
|
-
declare function FluoceAuthProvider({ children, ...config }: FluoceAuthProviderProps): react.JSX.Element;
|
|
45
19
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
20
|
+
declare const auth_provider: ({ children, app_url, on_error, redirect, }: auth_provider_interface) => react.JSX.Element;
|
|
21
|
+
|
|
22
|
+
type user_response_type = {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
email: string | null;
|
|
26
|
+
phone: string | null;
|
|
27
|
+
photo: string | null;
|
|
28
|
+
createdAt: Date;
|
|
29
|
+
updatedAt: Date;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type user_type = user_response_type;
|
|
33
|
+
|
|
34
|
+
interface auth_context_interface {
|
|
35
|
+
user: user_response_type | null;
|
|
36
|
+
safe_loading: boolean;
|
|
37
|
+
auth_flow_loading: boolean;
|
|
38
|
+
logout(): Promise<boolean>;
|
|
39
|
+
refresh(): Promise<boolean>;
|
|
40
|
+
auth_flow({ code }: {
|
|
41
|
+
code: string;
|
|
42
|
+
}): Promise<boolean>;
|
|
43
|
+
get_safe_user(): Promise<user_type | null>;
|
|
44
|
+
refresh_token: string | null;
|
|
45
|
+
access_token: string | null;
|
|
50
46
|
}
|
|
51
|
-
declare function AuthGuard({ children, fallback }: AuthGuardProps): react.JSX.Element;
|
|
52
47
|
|
|
53
|
-
declare
|
|
48
|
+
declare const use_auth: () => auth_context_interface;
|
|
54
49
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
/** set by the Provider — called once refresh fails and there's no session left */
|
|
59
|
-
onAuthFailure: () => void;
|
|
60
|
-
constructor(config: FluoceAuthConfig);
|
|
61
|
-
getAccessToken(): string | null;
|
|
62
|
-
getRefreshToken(): string | null;
|
|
63
|
-
setTokens(tokens: TokenPair): void;
|
|
64
|
-
clearTokens(): void;
|
|
65
|
-
buildLoginUrl(): string;
|
|
66
|
-
exchangeCode(code: string): Promise<TokenPair>;
|
|
67
|
-
getMe(): Promise<FluoceUser>;
|
|
68
|
-
updateMe(payload: {
|
|
69
|
-
name?: string;
|
|
70
|
-
photo?: string;
|
|
71
|
-
}): Promise<FluoceUser>;
|
|
72
|
-
refresh(): Promise<TokenPair | null>;
|
|
73
|
-
logout(allDevices?: boolean): Promise<void>;
|
|
74
|
-
/**
|
|
75
|
-
* Authenticated fetch. Attaches access token, retries once through /refresh
|
|
76
|
-
* on 401, and calls onAuthFailure (-> redirect to auth frontend) if that
|
|
77
|
-
* fails too. Use this for /me, /me updates, and any endpoint you add later.
|
|
78
|
-
*/
|
|
79
|
-
authFetch<T = unknown>(path: string, init?: RequestInit): Promise<T>;
|
|
50
|
+
interface auth_guard_interface {
|
|
51
|
+
children: ReactNode;
|
|
52
|
+
fallback?: ReactNode;
|
|
80
53
|
}
|
|
81
54
|
|
|
82
|
-
|
|
55
|
+
declare const auth_guard: ({ children, fallback, }: auth_guard_interface) => react.JSX.Element | null;
|
|
56
|
+
|
|
57
|
+
export { auth_guard as FluoceAuthGuard, auth_provider as FluoceAuthProvider, type auth_provider_interface as FluoceAuthProviderType, type redirect_type as FluoceRedirectType, type user_type as FluoceUserType, use_auth as useFluoceAuth };
|