dauth-context-react 4.0.4 → 5.0.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx","../src/initialDauthState.ts","../src/reducer/dauth.types.ts","../src/reducer/dauth.reducer.ts","../src/api/utils/config.ts","../src/api/dauth.api.ts","../src/reducer/dauth.actions.ts","../src/constants.ts","../src/api/utils/routes.ts"],"sourcesContent":["import React, {\n useReducer,\n useMemo,\n useEffect,\n useCallback,\n createContext,\n useContext,\n useRef,\n} from 'react';\nimport initialDauthState from './initialDauthState';\nimport userReducer from './reducer/dauth.reducer';\nimport * as action from './reducer/dauth.actions';\nimport { getClientBasePath, setDauthUrl } from './api/utils/config';\nimport { TOKEN_LS, REFRESH_TOKEN_LS, AUTH_CODE_PARAM } from './constants';\nimport { routes } from './api/utils/routes';\nimport type {\n IDauthProviderProps,\n IDauthStorageKeys,\n IDauthUser,\n IDauthAuthMethods,\n} from './interfaces';\nimport { SET_IS_LOADING } from './reducer/dauth.types';\n\nexport type { IDauthProviderProps, IDauthAuthMethods };\n\nconst defaultOnError = (error: Error) => console.error(error);\n\nexport const DauthProvider: React.FC<IDauthProviderProps> = (\n props: IDauthProviderProps\n) => {\n const { domainName, children, storageKey, onError, env, dauthUrl } = props;\n const [dauthState, dispatch] = useReducer(userReducer, initialDauthState);\n const refreshTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Configure custom dauth URL before any API calls\n useEffect(() => {\n setDauthUrl(dauthUrl);\n }, [dauthUrl]);\n\n const storageKeys: IDauthStorageKeys = useMemo(\n () => ({\n accessToken: storageKey?.accessToken ?? TOKEN_LS,\n refreshToken: storageKey?.refreshToken ?? REFRESH_TOKEN_LS,\n }),\n [storageKey?.accessToken, storageKey?.refreshToken]\n );\n\n const handleError = useCallback(\n (error: Error) => (onError ?? defaultOnError)(error),\n [onError]\n );\n\n // Build action context\n const ctx = useMemo(\n () => ({ dispatch, domainName, storageKeys, onError: handleError }),\n [domainName, storageKeys, handleError]\n );\n\n // Schedule next proactive refresh based on access token expiry\n const scheduleRefresh = useCallback(() => {\n if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);\n const token = localStorage.getItem(storageKeys.accessToken);\n if (!token) return;\n try {\n const payloadB64 = token.split('.')[1];\n if (!payloadB64) return;\n const payload = JSON.parse(atob(payloadB64));\n const expiresIn = (payload.exp || 0) * 1000 - Date.now();\n // Refresh 5 minutes before expiry, minimum 10 seconds\n const refreshIn = Math.max(expiresIn - 5 * 60 * 1000, 10_000);\n refreshTimerRef.current = setTimeout(async () => {\n await action.refreshSessionAction(ctx);\n scheduleRefresh();\n }, refreshIn);\n } catch (_) {\n // If decode fails, retry in 5 minutes\n refreshTimerRef.current = setTimeout(\n async () => {\n await action.refreshSessionAction(ctx);\n scheduleRefresh();\n },\n 5 * 60 * 1000\n );\n }\n }, [ctx, storageKeys.accessToken]);\n\n // Catch login redirect — exchange authorization code for tokens\n useEffect(() => {\n (async () => {\n const queryString = window.location.search;\n if (!queryString) return;\n const urlParams = new URLSearchParams(queryString);\n const code = urlParams.get(AUTH_CODE_PARAM);\n if (code && !dauthState.isAuthenticated) {\n return action.exchangeCodeAction({ ...ctx, code });\n }\n })();\n }, []);\n\n // Auto Login\n useEffect(() => {\n (async () => {\n // Skip if code exchange is in progress — that effect handles isLoading\n const urlParams = new URLSearchParams(window.location.search);\n if (urlParams.get(AUTH_CODE_PARAM)) return;\n\n const refreshToken = localStorage.getItem(storageKeys.refreshToken);\n if (refreshToken && !dauthState.isAuthenticated) {\n return action.setAutoLoginAction(ctx);\n } else {\n return dispatch({\n type: SET_IS_LOADING,\n payload: { isLoading: false },\n });\n }\n })();\n }, []);\n\n // Schedule proactive refresh when authenticated\n useEffect(() => {\n if (dauthState.isAuthenticated) {\n scheduleRefresh();\n }\n return () => {\n if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);\n };\n }, [dauthState.isAuthenticated, scheduleRefresh]);\n\n const loginWithRedirect = useCallback(() => {\n const base = `${getClientBasePath()}/${domainName}/${routes.signin}`;\n const url = env ? `${base}?env=${encodeURIComponent(env)}` : base;\n return window.location.replace(url);\n }, [domainName, env]);\n\n const logout = useCallback(() => {\n if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);\n return action.setLogoutAction({\n dispatch,\n domainName,\n storageKeys,\n });\n }, [domainName, storageKeys]);\n\n const getAccessToken = useCallback(async () => {\n const token = await action.getAccessTokenAction(ctx);\n return token as string;\n }, [ctx]);\n\n const updateUser = useCallback(\n async (fields: Partial<IDauthUser>) => {\n const token_ls = localStorage.getItem(storageKeys.accessToken);\n const {\n name,\n lastname,\n nickname,\n telPrefix,\n telSuffix,\n language,\n avatar,\n birthDate,\n country,\n metadata,\n } = fields;\n const user = {\n name,\n lastname,\n nickname,\n telPrefix,\n telSuffix,\n language,\n avatar,\n birthDate,\n country,\n metadata,\n } as Partial<IDauthUser>;\n return (await action.setUpdateUserAction({\n ...ctx,\n user,\n token: token_ls,\n })) as boolean;\n },\n [ctx, storageKeys.accessToken]\n );\n\n const updateUserWithRedirect = useCallback(() => {\n const token_ls = localStorage.getItem(storageKeys.accessToken);\n if (!token_ls) return;\n return window.location.replace(\n `${getClientBasePath()}/${domainName}/${routes.updateUser}/${token_ls}`\n );\n }, [domainName, storageKeys.accessToken]);\n\n const deleteAccount = useCallback(async () => {\n const token_ls = localStorage.getItem(storageKeys.accessToken);\n if (!token_ls) return false;\n if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);\n return (await action.deleteAccountAction({\n ...ctx,\n token: token_ls,\n })) as boolean;\n }, [ctx, storageKeys.accessToken]);\n\n const memoProvider = useMemo(\n () => ({\n ...dauthState,\n loginWithRedirect,\n logout,\n getAccessToken,\n updateUser,\n updateUserWithRedirect,\n deleteAccount,\n }),\n [\n dauthState,\n loginWithRedirect,\n logout,\n getAccessToken,\n updateUser,\n updateUserWithRedirect,\n deleteAccount,\n ]\n );\n\n return (\n <DauthContext.Provider value={memoProvider}>\n {children}\n </DauthContext.Provider>\n );\n};\n\nconst DauthContext = createContext(initialDauthState);\n\nexport const useDauth = () => {\n const context = useContext(DauthContext);\n if (!context) {\n throw new Error('useDauth must be used inside DauthProvider');\n }\n return context;\n};\n","import { IDauthDomainState, IDauthState, IDauthUser } from './interfaces';\n\nconst initialDauthState: IDauthState = {\n user: {\n language:\n (typeof window !== 'undefined'\n ? window.document.documentElement.getAttribute('lang')\n : null) || 'es',\n } as IDauthUser,\n domain: {} as IDauthDomainState,\n isLoading: true,\n isAuthenticated: false,\n loginWithRedirect: () => {},\n logout: () => {},\n getAccessToken: () => Promise.resolve(''),\n updateUser: () => Promise.resolve(false),\n updateUserWithRedirect: () => {},\n deleteAccount: () => Promise.resolve(false),\n};\n\nexport default initialDauthState;\n","export const LOGIN = 'LOGIN';\nexport const SET_IS_LOADING = 'SET_IS_LOADING';\nexport const UPDATE_USER = 'UPDATE_USER';\n","import { IDauthState } from '../interfaces';\nimport * as DauthTypes from './dauth.types';\n\nexport default function userReducer(state: IDauthState, action: any) {\n const { type, payload } = action;\n\n switch (type) {\n case DauthTypes.LOGIN: {\n const login: IDauthState = {\n ...state,\n user: payload.user,\n domain: payload.domain,\n isAuthenticated: payload.isAuthenticated,\n };\n return login;\n }\n\n case DauthTypes.SET_IS_LOADING: {\n const isLoading: IDauthState = {\n ...state,\n isLoading: payload.isLoading,\n };\n return isLoading;\n }\n\n case DauthTypes.UPDATE_USER: {\n const updateUser: IDauthState = {\n ...state,\n user: {\n ...state.user,\n ...payload,\n },\n };\n return updateUser;\n }\n\n default:\n return state;\n }\n}\n","export const apiVersion = 'v1';\nexport const serverDomain = 'dauth.ovh';\n\nlet _dauthUrl: string | undefined;\n\nexport function setDauthUrl(url: string | undefined) {\n _dauthUrl = url?.replace(/\\/+$/, '');\n}\n\nfunction checkIsLocalhost(): boolean {\n if (typeof window === 'undefined') return false;\n const hostname = window.location.hostname;\n return Boolean(\n hostname === 'localhost' ||\n hostname === '[::1]' ||\n hostname.match(\n /(192)\\.(168)\\.(1)\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/gm\n ) ||\n hostname.match(/^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)\n );\n}\n\nexport function getServerBasePath() {\n if (_dauthUrl) return `${_dauthUrl}/api/${apiVersion}`;\n const isLocalhost = checkIsLocalhost();\n const serverPort = 4012;\n const serverLocalUrl = `${window.location.protocol}//${window.location.hostname}:${serverPort}/api/${apiVersion}`;\n const serverProdUrl = `https://${serverDomain}/api/${apiVersion}`;\n return isLocalhost ? serverLocalUrl : serverProdUrl;\n}\n\nexport function getClientBasePath() {\n if (_dauthUrl) return _dauthUrl;\n const isLocalhost = checkIsLocalhost();\n const clientPort = 5185;\n const clientLocalUrl = `${window.location.protocol}//${window.location.hostname}:${clientPort}`;\n const clientProdUrl = `https://${serverDomain}`;\n return isLocalhost ? clientLocalUrl : clientProdUrl;\n}\n","import { getServerBasePath } from './utils/config';\nimport { IDauthUser } from '../interfaces';\nimport {\n IdeleteAccountAPIResponse,\n IExchangeCodeAPIResponse,\n IgetUserAPIResponse,\n IrefreshTokenAPIResponse,\n IupdateUserAPIResponse,\n} from './interfaces/dauth.api.responses';\n\nexport const getUserAPI = async (\n domainName: string,\n token: string\n): Promise<IgetUserAPIResponse> => {\n const params = {\n method: 'GET',\n headers: {\n Authorization: token,\n 'Content-Type': 'application/json',\n },\n };\n const response = await fetch(\n `${getServerBasePath()}/app/${domainName}/user`,\n params\n );\n const data = await response.json();\n return { response, data };\n};\n\nexport const updateUserAPI = async (\n domainName: string,\n user: Partial<IDauthUser>,\n token: string\n): Promise<IupdateUserAPIResponse> => {\n const params = {\n method: 'PATCH',\n headers: {\n Authorization: token,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(user),\n };\n const response = await fetch(\n `${getServerBasePath()}/app/${domainName}/user`,\n params\n );\n const data = await response.json();\n return { response, data };\n};\n\nexport const refreshTokenAPI = async (\n domainName: string,\n refreshToken: string\n): Promise<IrefreshTokenAPIResponse> => {\n const params = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ refreshToken }),\n };\n const response = await fetch(\n `${getServerBasePath()}/app/${domainName}/refresh-token`,\n params\n );\n const data = await response.json();\n return { response, data };\n};\n\nexport const deleteAccountAPI = async (\n domainName: string,\n token: string\n): Promise<IdeleteAccountAPIResponse> => {\n const params = {\n method: 'DELETE',\n headers: {\n Authorization: token,\n 'Content-Type': 'application/json',\n },\n };\n const response = await fetch(\n `${getServerBasePath()}/app/${domainName}/user`,\n params\n );\n const data = await response.json();\n return { response, data };\n};\n\nexport const exchangeCodeAPI = async (\n domainName: string,\n code: string\n): Promise<IExchangeCodeAPIResponse> => {\n const params = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ code }),\n };\n const response = await fetch(\n `${getServerBasePath()}/app/${domainName}/exchange-code`,\n params\n );\n const data = await response.json();\n return { response, data };\n};\n\nexport const logoutAPI = async (\n domainName: string,\n refreshToken: string\n): Promise<{ response: Response }> => {\n const params = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ refreshToken }),\n };\n const response = await fetch(\n `${getServerBasePath()}/app/${domainName}/logout`,\n params\n );\n return { response };\n};\n","import {\n deleteAccountAPI,\n exchangeCodeAPI,\n getUserAPI,\n logoutAPI,\n refreshTokenAPI,\n updateUserAPI,\n} from '../api/dauth.api';\nimport {\n IDauthDomainState,\n IDauthStorageKeys,\n IDauthUser,\n} from '../interfaces';\nimport * as DauthTypes from './dauth.types';\n\nexport interface ActionContext {\n dispatch: React.Dispatch<any>;\n domainName: string;\n storageKeys: IDauthStorageKeys;\n onError: (error: Error) => void;\n}\n\ntype TExchangeCodeAction = ActionContext & { code: string };\nexport async function exchangeCodeAction({\n dispatch,\n code,\n domainName,\n storageKeys,\n onError,\n}: TExchangeCodeAction) {\n dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: true },\n });\n try {\n // Clean URL immediately (before any fetch)\n window.history.replaceState({}, document.title, window.location.pathname);\n const exchangeResult = await exchangeCodeAPI(domainName, code);\n if (exchangeResult.response.status !== 200) {\n return resetUser(dispatch, storageKeys);\n }\n const { accessToken, refreshToken } = exchangeResult.data;\n localStorage.setItem(storageKeys.accessToken, accessToken);\n localStorage.setItem(storageKeys.refreshToken, refreshToken);\n const getUserFetch = await getUserAPI(domainName, accessToken);\n if (getUserFetch.response.status === 200) {\n dispatch({\n type: DauthTypes.LOGIN,\n payload: {\n user: getUserFetch.data.user,\n domain: getUserFetch.data.domain,\n isAuthenticated: true,\n },\n });\n return;\n }\n return resetUser(dispatch, storageKeys);\n } catch (error) {\n onError(error instanceof Error ? error : new Error(String(error)));\n return resetUser(dispatch, storageKeys);\n } finally {\n dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: false },\n });\n }\n}\n\nexport async function setAutoLoginAction({\n dispatch,\n domainName,\n storageKeys,\n onError,\n}: ActionContext) {\n dispatch({ type: DauthTypes.SET_IS_LOADING, payload: { isLoading: true } });\n const storedRefreshToken = localStorage.getItem(storageKeys.refreshToken);\n if (!storedRefreshToken) {\n dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: false },\n });\n return resetUser(dispatch, storageKeys);\n }\n try {\n const refreshResult = await refreshTokenAPI(domainName, storedRefreshToken);\n if (refreshResult.response.status === 200) {\n const newAccessToken = refreshResult.data.accessToken;\n const newRefreshToken = refreshResult.data.refreshToken;\n localStorage.setItem(storageKeys.accessToken, newAccessToken);\n localStorage.setItem(storageKeys.refreshToken, newRefreshToken);\n const getUserFetch = await getUserAPI(domainName, newAccessToken);\n if (getUserFetch.response.status === 200) {\n dispatch({\n type: DauthTypes.LOGIN,\n payload: {\n user: getUserFetch.data.user,\n domain: getUserFetch.data.domain,\n isAuthenticated: true,\n },\n });\n return;\n }\n }\n // Refresh failed — session expired\n resetUser(dispatch, storageKeys);\n } catch (error) {\n onError(error instanceof Error ? error : new Error(String(error)));\n resetUser(dispatch, storageKeys);\n } finally {\n dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: false },\n });\n }\n}\n\nexport async function setLogoutAction({\n dispatch,\n domainName,\n storageKeys,\n}: Omit<ActionContext, 'onError'>) {\n const storedRefreshToken = localStorage.getItem(storageKeys.refreshToken);\n if (storedRefreshToken && domainName) {\n try {\n await logoutAPI(domainName, storedRefreshToken);\n } catch (_) {\n // Best-effort server-side logout\n }\n }\n dispatch({ type: DauthTypes.SET_IS_LOADING, payload: { isLoading: true } });\n dispatch({\n type: DauthTypes.LOGIN,\n payload: {\n user: {\n language: window.document.documentElement.getAttribute('lang') || 'es',\n },\n domain: {},\n isAuthenticated: false,\n },\n });\n localStorage.removeItem(storageKeys.accessToken);\n localStorage.removeItem(storageKeys.refreshToken);\n return dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: false },\n });\n}\n\nexport async function refreshSessionAction({\n dispatch,\n domainName,\n storageKeys,\n onError,\n}: ActionContext) {\n const storedRefreshToken = localStorage.getItem(storageKeys.refreshToken);\n if (!storedRefreshToken) {\n return resetUser(dispatch, storageKeys);\n }\n try {\n const refreshResult = await refreshTokenAPI(domainName, storedRefreshToken);\n if (refreshResult.response.status === 200) {\n localStorage.setItem(\n storageKeys.accessToken,\n refreshResult.data.accessToken\n );\n localStorage.setItem(\n storageKeys.refreshToken,\n refreshResult.data.refreshToken\n );\n return;\n }\n // Refresh failed — revoked or expired\n resetUser(dispatch, storageKeys);\n } catch (error) {\n onError(error instanceof Error ? error : new Error(String(error)));\n resetUser(dispatch, storageKeys);\n }\n}\n\ntype TSetUpdateAction = ActionContext & {\n user: Partial<IDauthUser>;\n token: string | null;\n};\nexport async function setUpdateUserAction({\n dispatch,\n domainName,\n user,\n token,\n onError,\n}: TSetUpdateAction) {\n if (user.language) {\n window.document.documentElement.setAttribute('lang', user.language);\n }\n if (!token) {\n dispatch({\n type: DauthTypes.UPDATE_USER,\n payload: user,\n });\n return false;\n }\n try {\n const getUserFetch = await updateUserAPI(domainName, user, token);\n if (getUserFetch.response.status === 200) {\n dispatch({\n type: DauthTypes.UPDATE_USER,\n payload: getUserFetch.data.user,\n });\n return true;\n } else {\n onError(new Error('Update user error: ' + getUserFetch.data.message));\n return false;\n }\n } catch (error) {\n onError(error instanceof Error ? error : new Error('Update user error'));\n return false;\n }\n}\n\nexport async function getAccessTokenAction({\n dispatch,\n domainName,\n storageKeys,\n onError,\n}: ActionContext) {\n const token_ls = localStorage.getItem(storageKeys.accessToken);\n if (!token_ls) return 'token-not-found';\n // Decode JWT to check expiry (without verification — that's the server's job)\n try {\n const payloadB64 = token_ls.split('.')[1];\n if (payloadB64) {\n const payload = JSON.parse(atob(payloadB64));\n const expiresIn = (payload.exp || 0) * 1000 - Date.now();\n // If token expires in less than 5 minutes, refresh proactively\n if (expiresIn < 5 * 60 * 1000) {\n await refreshSessionAction({\n dispatch,\n domainName,\n storageKeys,\n onError,\n });\n const refreshedToken = localStorage.getItem(storageKeys.accessToken);\n return refreshedToken || 'token-not-found';\n }\n }\n } catch (_) {\n // If decode fails, return stored token and let server validate\n }\n return token_ls;\n}\n\nexport async function deleteAccountAction({\n dispatch,\n domainName,\n storageKeys,\n onError,\n token,\n}: ActionContext & { token: string }) {\n try {\n const result = await deleteAccountAPI(domainName, token);\n if (result.response.status === 200) {\n resetUser(dispatch, storageKeys);\n return true;\n }\n return false;\n } catch (error) {\n onError(error instanceof Error ? error : new Error('Delete account error'));\n return false;\n }\n}\n\n///////////////////////////////////////////\n//////////////////////////////////////////\nexport const resetUser = (\n dispatch: React.Dispatch<any>,\n storageKeys: IDauthStorageKeys\n) => {\n localStorage.removeItem(storageKeys.accessToken);\n localStorage.removeItem(storageKeys.refreshToken);\n return dispatch({\n type: DauthTypes.LOGIN,\n payload: {\n user: {} as IDauthUser,\n domain: {} as IDauthDomainState,\n isAuthenticated: false,\n },\n });\n};\n","export const TOKEN_LS = 'dauth_state';\nexport const REFRESH_TOKEN_LS = 'dauth_refresh_token';\nexport const AUTH_CODE_PARAM = 'code';\n","export const routes = {\n signin: 'signin',\n updateUser: 'update-user',\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.tsx","../src/initialDauthState.ts","../src/reducer/dauth.types.ts","../src/reducer/dauth.reducer.ts","../src/api/dauth.api.ts","../src/reducer/dauth.actions.ts","../src/api/utils/config.ts","../src/constants.ts","../src/api/utils/routes.ts"],"sourcesContent":["import React, {\n useReducer,\n useMemo,\n useEffect,\n useCallback,\n createContext,\n useContext,\n} from 'react';\nimport initialDauthState from './initialDauthState';\nimport userReducer from './reducer/dauth.reducer';\nimport * as action from './reducer/dauth.actions';\nimport { getClientBasePath, setDauthUrl } from './api/utils/config';\nimport { AUTH_CODE_PARAM } from './constants';\nimport { routes } from './api/utils/routes';\nimport type {\n IDauthProviderProps,\n IDauthAuthMethods,\n IDauthUser,\n} from './interfaces';\n\nexport type { IDauthProviderProps, IDauthAuthMethods };\n\nconst defaultOnError = (error: Error) => console.error(error);\n\nexport const DauthProvider: React.FC<IDauthProviderProps> = (\n props: IDauthProviderProps\n) => {\n const {\n domainName,\n children,\n authProxyPath = '/api/auth',\n onError,\n env,\n dauthUrl,\n } = props;\n const [dauthState, dispatch] = useReducer(\n userReducer,\n initialDauthState\n );\n\n // Configure custom dauth URL before any API calls\n useEffect(() => {\n setDauthUrl(dauthUrl);\n }, [dauthUrl]);\n\n const handleError = useCallback(\n (error: Error) => (onError ?? defaultOnError)(error),\n [onError]\n );\n\n const ctx = useMemo(\n () => ({ dispatch, authProxyPath, onError: handleError }),\n [authProxyPath, handleError]\n );\n\n // On mount: exchange code or auto-login via session cookie\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const code = params.get(AUTH_CODE_PARAM);\n if (code) {\n action.exchangeCodeAction(ctx, code);\n } else {\n action.autoLoginAction(ctx);\n }\n }, []);\n\n const loginWithRedirect = useCallback(() => {\n const base = `${getClientBasePath()}/${domainName}/${routes.signin}`;\n const url = env\n ? `${base}?env=${encodeURIComponent(env)}`\n : base;\n return window.location.replace(url);\n }, [domainName, env]);\n\n const logout = useCallback(\n () => action.logoutAction(ctx),\n [ctx]\n );\n\n const updateUser = useCallback(\n async (fields: Partial<IDauthUser>) => {\n const {\n name,\n lastname,\n nickname,\n telPrefix,\n telSuffix,\n language,\n avatar,\n birthDate,\n country,\n metadata,\n } = fields;\n const user = {\n name,\n lastname,\n nickname,\n telPrefix,\n telSuffix,\n language,\n avatar,\n birthDate,\n country,\n metadata,\n } as Partial<IDauthUser>;\n return action.updateUserAction(ctx, user);\n },\n [ctx]\n );\n\n const updateUserWithRedirect = useCallback(\n () => action.updateUserWithRedirectAction(ctx),\n [ctx]\n );\n\n const deleteAccount = useCallback(\n () => action.deleteAccountAction(ctx),\n [ctx]\n );\n\n const memoProvider = useMemo(\n () => ({\n ...dauthState,\n loginWithRedirect,\n logout,\n updateUser,\n updateUserWithRedirect,\n deleteAccount,\n }),\n [\n dauthState,\n loginWithRedirect,\n logout,\n updateUser,\n updateUserWithRedirect,\n deleteAccount,\n ]\n );\n\n return (\n <DauthContext.Provider value={memoProvider}>\n {children}\n </DauthContext.Provider>\n );\n};\n\nconst DauthContext = createContext(initialDauthState);\n\nexport const useDauth = () => {\n const context = useContext(DauthContext);\n if (!context) {\n throw new Error('useDauth must be used inside DauthProvider');\n }\n return context;\n};\n","import { IDauthDomainState, IDauthState, IDauthUser } from './interfaces';\n\nconst initialDauthState: IDauthState = {\n user: {\n language:\n (typeof window !== 'undefined'\n ? window.document.documentElement.getAttribute('lang')\n : null) || 'es',\n } as IDauthUser,\n domain: {} as IDauthDomainState,\n isLoading: true,\n isAuthenticated: false,\n loginWithRedirect: () => {},\n logout: () => {},\n updateUser: () => Promise.resolve(false),\n updateUserWithRedirect: () => {},\n deleteAccount: () => Promise.resolve(false),\n};\n\nexport default initialDauthState;\n","export const LOGIN = 'LOGIN';\nexport const SET_IS_LOADING = 'SET_IS_LOADING';\nexport const UPDATE_USER = 'UPDATE_USER';\n","import { IDauthState } from '../interfaces';\nimport * as DauthTypes from './dauth.types';\n\nexport default function userReducer(state: IDauthState, action: any) {\n const { type, payload } = action;\n\n switch (type) {\n case DauthTypes.LOGIN: {\n const login: IDauthState = {\n ...state,\n user: payload.user,\n domain: payload.domain,\n isAuthenticated: payload.isAuthenticated,\n };\n return login;\n }\n\n case DauthTypes.SET_IS_LOADING: {\n const isLoading: IDauthState = {\n ...state,\n isLoading: payload.isLoading,\n };\n return isLoading;\n }\n\n case DauthTypes.UPDATE_USER: {\n const updateUser: IDauthState = {\n ...state,\n user: {\n ...state.user,\n ...payload,\n },\n };\n return updateUser;\n }\n\n default:\n return state;\n }\n}\n","import { IDauthUser } from '../interfaces';\nimport {\n IExchangeCodeResponse,\n ISessionResponse,\n IUpdateUserResponse,\n IDeleteAccountResponse,\n IProfileRedirectResponse,\n} from './interfaces/dauth.api.responses';\n\nfunction getCsrfToken(): string {\n const match = document.cookie.match(\n /(?:^|;\\s*)(?:__Host-csrf|csrf-token)=([^;]*)/\n );\n return match?.[1] ?? '';\n}\n\nexport async function exchangeCodeAPI(\n basePath: string,\n code: string\n): Promise<IExchangeCodeResponse> {\n const response = await fetch(`${basePath}/exchange-code`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n credentials: 'include',\n body: JSON.stringify({ code }),\n });\n const data = await response.json();\n return { response, data };\n}\n\nexport async function getSessionAPI(\n basePath: string\n): Promise<ISessionResponse> {\n const response = await fetch(`${basePath}/session`, {\n method: 'GET',\n credentials: 'include',\n });\n const data = await response.json();\n return { response, data };\n}\n\nexport async function logoutAPI(\n basePath: string\n): Promise<{ response: Response }> {\n const response = await fetch(`${basePath}/logout`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': getCsrfToken(),\n },\n credentials: 'include',\n });\n return { response };\n}\n\nexport async function updateUserAPI(\n basePath: string,\n user: Partial<IDauthUser>\n): Promise<IUpdateUserResponse> {\n const response = await fetch(`${basePath}/user`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': getCsrfToken(),\n },\n credentials: 'include',\n body: JSON.stringify(user),\n });\n const data = await response.json();\n return { response, data };\n}\n\nexport async function deleteAccountAPI(\n basePath: string\n): Promise<IDeleteAccountResponse> {\n const response = await fetch(`${basePath}/user`, {\n method: 'DELETE',\n headers: { 'X-CSRF-Token': getCsrfToken() },\n credentials: 'include',\n });\n const data = await response.json();\n return { response, data };\n}\n\nexport async function profileRedirectAPI(\n basePath: string\n): Promise<IProfileRedirectResponse> {\n const response = await fetch(\n `${basePath}/profile-redirect`,\n {\n method: 'GET',\n headers: { 'X-CSRF-Token': getCsrfToken() },\n credentials: 'include',\n }\n );\n const data = await response.json();\n return { response, data };\n}\n","import {\n exchangeCodeAPI,\n getSessionAPI,\n logoutAPI,\n updateUserAPI,\n deleteAccountAPI,\n profileRedirectAPI,\n} from '../api/dauth.api';\nimport { IDauthDomainState, IDauthUser } from '../interfaces';\nimport * as DauthTypes from './dauth.types';\n\nexport interface ActionContext {\n dispatch: React.Dispatch<any>;\n authProxyPath: string;\n onError: (error: Error) => void;\n}\n\nexport async function exchangeCodeAction(\n ctx: ActionContext,\n code: string\n) {\n const { dispatch, authProxyPath, onError } = ctx;\n dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: true },\n });\n try {\n // Clean URL immediately (before any fetch)\n window.history.replaceState(\n {},\n document.title,\n window.location.pathname\n );\n const result = await exchangeCodeAPI(authProxyPath, code);\n if (result.response.status === 200) {\n dispatch({\n type: DauthTypes.LOGIN,\n payload: {\n user: result.data.user,\n domain: result.data.domain,\n isAuthenticated: true,\n },\n });\n return;\n }\n resetUser(dispatch);\n } catch (error) {\n onError(\n error instanceof Error ? error : new Error(String(error))\n );\n resetUser(dispatch);\n } finally {\n dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: false },\n });\n }\n}\n\nexport async function autoLoginAction(ctx: ActionContext) {\n const { dispatch, authProxyPath, onError } = ctx;\n dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: true },\n });\n try {\n const result = await getSessionAPI(authProxyPath);\n if (result.response.status === 200) {\n dispatch({\n type: DauthTypes.LOGIN,\n payload: {\n user: result.data.user,\n domain: result.data.domain,\n isAuthenticated: true,\n },\n });\n return;\n }\n // No session — not authenticated (not an error)\n resetUser(dispatch);\n } catch (error) {\n onError(\n error instanceof Error ? error : new Error(String(error))\n );\n resetUser(dispatch);\n } finally {\n dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: false },\n });\n }\n}\n\nexport async function logoutAction(ctx: ActionContext) {\n const { dispatch, authProxyPath } = ctx;\n try {\n await logoutAPI(authProxyPath);\n } catch {\n // Best-effort server-side logout\n }\n dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: true },\n });\n dispatch({\n type: DauthTypes.LOGIN,\n payload: {\n user: {\n language:\n window.document.documentElement.getAttribute('lang') ||\n 'es',\n },\n domain: {},\n isAuthenticated: false,\n },\n });\n dispatch({\n type: DauthTypes.SET_IS_LOADING,\n payload: { isLoading: false },\n });\n}\n\nexport async function updateUserAction(\n ctx: ActionContext,\n user: Partial<IDauthUser>\n): Promise<boolean> {\n const { dispatch, authProxyPath, onError } = ctx;\n if (user.language) {\n window.document.documentElement.setAttribute(\n 'lang',\n user.language\n );\n }\n try {\n const result = await updateUserAPI(authProxyPath, user);\n if (result.response.status === 200) {\n dispatch({\n type: DauthTypes.UPDATE_USER,\n payload: result.data.user,\n });\n return true;\n }\n onError(\n new Error('Update user error: ' + result.data.message)\n );\n return false;\n } catch (error) {\n onError(\n error instanceof Error\n ? error\n : new Error('Update user error')\n );\n return false;\n }\n}\n\nexport async function updateUserWithRedirectAction(\n ctx: ActionContext\n) {\n const { authProxyPath, onError } = ctx;\n try {\n const result = await profileRedirectAPI(authProxyPath);\n if (\n result.response.status === 200 &&\n result.data.redirectUrl\n ) {\n window.location.replace(result.data.redirectUrl);\n return;\n }\n onError(\n new Error('Could not generate profile redirect')\n );\n } catch (error) {\n onError(\n error instanceof Error\n ? error\n : new Error('Profile redirect error')\n );\n }\n}\n\nexport async function deleteAccountAction(\n ctx: ActionContext\n): Promise<boolean> {\n const { dispatch, authProxyPath, onError } = ctx;\n try {\n const result = await deleteAccountAPI(authProxyPath);\n if (result.response.status === 200) {\n resetUser(dispatch);\n return true;\n }\n return false;\n } catch (error) {\n onError(\n error instanceof Error\n ? error\n : new Error('Delete account error')\n );\n return false;\n }\n}\n\nexport const resetUser = (dispatch: React.Dispatch<any>) => {\n return dispatch({\n type: DauthTypes.LOGIN,\n payload: {\n user: {} as IDauthUser,\n domain: {} as IDauthDomainState,\n isAuthenticated: false,\n },\n });\n};\n","export const serverDomain = 'dauth.ovh';\n\nlet _dauthUrl: string | undefined;\n\nexport function setDauthUrl(url: string | undefined) {\n _dauthUrl = url?.replace(/\\/+$/, '');\n}\n\nfunction checkIsLocalhost(): boolean {\n if (typeof window === 'undefined') return false;\n const hostname = window.location.hostname;\n return Boolean(\n hostname === 'localhost' ||\n hostname === '[::1]' ||\n hostname.match(\n /(192)\\.(168)\\.(1)\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/gm\n ) ||\n hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n );\n}\n\nexport function getClientBasePath() {\n if (_dauthUrl) return _dauthUrl;\n const isLocalhost = checkIsLocalhost();\n const clientPort = 5185;\n const clientLocalUrl = `${window.location.protocol}//${window.location.hostname}:${clientPort}`;\n const clientProdUrl = `https://${serverDomain}`;\n return isLocalhost ? clientLocalUrl : clientProdUrl;\n}\n","export const AUTH_CODE_PARAM = 'code';\n","export const routes = {\n signin: 'signin',\n};\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACLP,IAAM,oBAAiC;AAAA,EACrC,MAAM;AAAA,IACJ,WACG,OAAO,WAAW,cACf,OAAO,SAAS,gBAAgB,aAAa,MAAM,IACnD,SAAS;AAAA,EACjB;AAAA,EACA,QAAQ,CAAC;AAAA,EACT,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,mBAAmB,MAAM;AAAA,EAAC;AAAA,EAC1B,QAAQ,MAAM;AAAA,EAAC;AAAA,EACf,YAAY,MAAM,QAAQ,QAAQ,KAAK;AAAA,EACvC,wBAAwB,MAAM;AAAA,EAAC;AAAA,EAC/B,eAAe,MAAM,QAAQ,QAAQ,KAAK;AAC5C;AAEA,IAAO,4BAAQ;;;ACnBR,IAAM,QAAQ;AACd,IAAM,iBAAiB;AACvB,IAAM,cAAc;;;ACCZ,SAAR,YAA6B,OAAoB,QAAa;AACnE,QAAM,EAAE,MAAM,QAAQ,IAAI;AAE1B,UAAQ,MAAM;AAAA,IACZ,KAAgB,OAAO;AACrB,YAAM,QAAqB;AAAA,QACzB,GAAG;AAAA,QACH,MAAM,QAAQ;AAAA,QACd,QAAQ,QAAQ;AAAA,QAChB,iBAAiB,QAAQ;AAAA,MAC3B;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAgB,gBAAgB;AAC9B,YAAM,YAAyB;AAAA,QAC7B,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,MACrB;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAgB,aAAa;AAC3B,YAAM,aAA0B;AAAA,QAC9B,GAAG;AAAA,QACH,MAAM;AAAA,UACJ,GAAG,MAAM;AAAA,UACT,GAAG;AAAA,QACL;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IAEA;AACE,aAAO;AAAA,EACX;AACF;;;AC9BA,SAAS,eAAuB;AAC9B,QAAM,QAAQ,SAAS,OAAO;AAAA,IAC5B;AAAA,EACF;AACA,SAAO,QAAQ,CAAC,KAAK;AACvB;AAEA,eAAsB,gBACpB,UACA,MACgC;AAChC,QAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IACxD,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,aAAa;AAAA,IACb,MAAM,KAAK,UAAU,EAAE,KAAK,CAAC;AAAA,EAC/B,CAAC;AACD,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,SAAO,EAAE,UAAU,KAAK;AAC1B;AAEA,eAAsB,cACpB,UAC2B;AAC3B,QAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,YAAY;AAAA,IAClD,QAAQ;AAAA,IACR,aAAa;AAAA,EACf,CAAC;AACD,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,SAAO,EAAE,UAAU,KAAK;AAC1B;AAEA,eAAsB,UACpB,UACiC;AACjC,QAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,WAAW;AAAA,IACjD,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,gBAAgB,aAAa;AAAA,IAC/B;AAAA,IACA,aAAa;AAAA,EACf,CAAC;AACD,SAAO,EAAE,SAAS;AACpB;AAEA,eAAsB,cACpB,UACA,MAC8B;AAC9B,QAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,SAAS;AAAA,IAC/C,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,gBAAgB,aAAa;AAAA,IAC/B;AAAA,IACA,aAAa;AAAA,IACb,MAAM,KAAK,UAAU,IAAI;AAAA,EAC3B,CAAC;AACD,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,SAAO,EAAE,UAAU,KAAK;AAC1B;AAEA,eAAsB,iBACpB,UACiC;AACjC,QAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,SAAS;AAAA,IAC/C,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,aAAa,EAAE;AAAA,IAC1C,aAAa;AAAA,EACf,CAAC;AACD,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,SAAO,EAAE,UAAU,KAAK;AAC1B;AAEA,eAAsB,mBACpB,UACmC;AACnC,QAAM,WAAW,MAAM;AAAA,IACrB,GAAG,QAAQ;AAAA,IACX;AAAA,MACE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,aAAa,EAAE;AAAA,MAC1C,aAAa;AAAA,IACf;AAAA,EACF;AACA,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,SAAO,EAAE,UAAU,KAAK;AAC1B;;;AChFA,eAAsB,mBACpB,KACA,MACA;AACA,QAAM,EAAE,UAAU,eAAe,QAAQ,IAAI;AAC7C,WAAS;AAAA,IACP,MAAiB;AAAA,IACjB,SAAS,EAAE,WAAW,KAAK;AAAA,EAC7B,CAAC;AACD,MAAI;AAEF,WAAO,QAAQ;AAAA,MACb,CAAC;AAAA,MACD,SAAS;AAAA,MACT,OAAO,SAAS;AAAA,IAClB;AACA,UAAM,SAAS,MAAM,gBAAgB,eAAe,IAAI;AACxD,QAAI,OAAO,SAAS,WAAW,KAAK;AAClC,eAAS;AAAA,QACP,MAAiB;AAAA,QACjB,SAAS;AAAA,UACP,MAAM,OAAO,KAAK;AAAA,UAClB,QAAQ,OAAO,KAAK;AAAA,UACpB,iBAAiB;AAAA,QACnB;AAAA,MACF,CAAC;AACD;AAAA,IACF;AACA,cAAU,QAAQ;AAAA,EACpB,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,IAC1D;AACA,cAAU,QAAQ;AAAA,EACpB,UAAE;AACA,aAAS;AAAA,MACP,MAAiB;AAAA,MACjB,SAAS,EAAE,WAAW,MAAM;AAAA,IAC9B,CAAC;AAAA,EACH;AACF;AAEA,eAAsB,gBAAgB,KAAoB;AACxD,QAAM,EAAE,UAAU,eAAe,QAAQ,IAAI;AAC7C,WAAS;AAAA,IACP,MAAiB;AAAA,IACjB,SAAS,EAAE,WAAW,KAAK;AAAA,EAC7B,CAAC;AACD,MAAI;AACF,UAAM,SAAS,MAAM,cAAc,aAAa;AAChD,QAAI,OAAO,SAAS,WAAW,KAAK;AAClC,eAAS;AAAA,QACP,MAAiB;AAAA,QACjB,SAAS;AAAA,UACP,MAAM,OAAO,KAAK;AAAA,UAClB,QAAQ,OAAO,KAAK;AAAA,UACpB,iBAAiB;AAAA,QACnB;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,cAAU,QAAQ;AAAA,EACpB,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,IAC1D;AACA,cAAU,QAAQ;AAAA,EACpB,UAAE;AACA,aAAS;AAAA,MACP,MAAiB;AAAA,MACjB,SAAS,EAAE,WAAW,MAAM;AAAA,IAC9B,CAAC;AAAA,EACH;AACF;AAEA,eAAsB,aAAa,KAAoB;AACrD,QAAM,EAAE,UAAU,cAAc,IAAI;AACpC,MAAI;AACF,UAAM,UAAU,aAAa;AAAA,EAC/B,QAAQ;AAAA,EAER;AACA,WAAS;AAAA,IACP,MAAiB;AAAA,IACjB,SAAS,EAAE,WAAW,KAAK;AAAA,EAC7B,CAAC;AACD,WAAS;AAAA,IACP,MAAiB;AAAA,IACjB,SAAS;AAAA,MACP,MAAM;AAAA,QACJ,UACE,OAAO,SAAS,gBAAgB,aAAa,MAAM,KACnD;AAAA,MACJ;AAAA,MACA,QAAQ,CAAC;AAAA,MACT,iBAAiB;AAAA,IACnB;AAAA,EACF,CAAC;AACD,WAAS;AAAA,IACP,MAAiB;AAAA,IACjB,SAAS,EAAE,WAAW,MAAM;AAAA,EAC9B,CAAC;AACH;AAEA,eAAsB,iBACpB,KACA,MACkB;AAClB,QAAM,EAAE,UAAU,eAAe,QAAQ,IAAI;AAC7C,MAAI,KAAK,UAAU;AACjB,WAAO,SAAS,gBAAgB;AAAA,MAC9B;AAAA,MACA,KAAK;AAAA,IACP;AAAA,EACF;AACA,MAAI;AACF,UAAM,SAAS,MAAM,cAAc,eAAe,IAAI;AACtD,QAAI,OAAO,SAAS,WAAW,KAAK;AAClC,eAAS;AAAA,QACP,MAAiB;AAAA,QACjB,SAAS,OAAO,KAAK;AAAA,MACvB,CAAC;AACD,aAAO;AAAA,IACT;AACA;AAAA,MACE,IAAI,MAAM,wBAAwB,OAAO,KAAK,OAAO;AAAA,IACvD;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QACb,QACA,IAAI,MAAM,mBAAmB;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,6BACpB,KACA;AACA,QAAM,EAAE,eAAe,QAAQ,IAAI;AACnC,MAAI;AACF,UAAM,SAAS,MAAM,mBAAmB,aAAa;AACrD,QACE,OAAO,SAAS,WAAW,OAC3B,OAAO,KAAK,aACZ;AACA,aAAO,SAAS,QAAQ,OAAO,KAAK,WAAW;AAC/C;AAAA,IACF;AACA;AAAA,MACE,IAAI,MAAM,qCAAqC;AAAA,IACjD;AAAA,EACF,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QACb,QACA,IAAI,MAAM,wBAAwB;AAAA,IACxC;AAAA,EACF;AACF;AAEA,eAAsB,oBACpB,KACkB;AAClB,QAAM,EAAE,UAAU,eAAe,QAAQ,IAAI;AAC7C,MAAI;AACF,UAAM,SAAS,MAAM,iBAAiB,aAAa;AACnD,QAAI,OAAO,SAAS,WAAW,KAAK;AAClC,gBAAU,QAAQ;AAClB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QACb,QACA,IAAI,MAAM,sBAAsB;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AACF;AAEO,IAAM,YAAY,CAAC,aAAkC;AAC1D,SAAO,SAAS;AAAA,IACd,MAAiB;AAAA,IACjB,SAAS;AAAA,MACP,MAAM,CAAC;AAAA,MACP,QAAQ,CAAC;AAAA,MACT,iBAAiB;AAAA,IACnB;AAAA,EACF,CAAC;AACH;;;ACnNO,IAAM,eAAe;AAE5B,IAAI;AAEG,SAAS,YAAY,KAAyB;AACnD,cAAY,KAAK,QAAQ,QAAQ,EAAE;AACrC;AAEA,SAAS,mBAA4B;AACnC,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,WAAW,OAAO,SAAS;AACjC,SAAO;AAAA,IACL,aAAa,eACb,aAAa,WACb,SAAS;AAAA,MACP;AAAA,IACF,KACA,SAAS;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,oBAAoB;AAClC,MAAI,UAAW,QAAO;AACtB,QAAM,cAAc,iBAAiB;AACrC,QAAM,aAAa;AACnB,QAAM,iBAAiB,GAAG,OAAO,SAAS,QAAQ,KAAK,OAAO,SAAS,QAAQ,IAAI,UAAU;AAC7F,QAAM,gBAAgB,WAAW,YAAY;AAC7C,SAAO,cAAc,iBAAiB;AACxC;;;AC9BO,IAAM,kBAAkB;;;ACAxB,IAAM,SAAS;AAAA,EACpB,QAAQ;AACV;;;AR0II;AAtHJ,IAAM,iBAAiB,CAAC,UAAiB,QAAQ,MAAM,KAAK;AAErD,IAAM,gBAA+C,CAC1D,UACG;AACH,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,CAAC,YAAY,QAAQ,IAAI;AAAA,IAC7B;AAAA,IACA;AAAA,EACF;AAGA,YAAU,MAAM;AACd,gBAAY,QAAQ;AAAA,EACtB,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,cAAc;AAAA,IAClB,CAAC,WAAkB,WAAW,gBAAgB,KAAK;AAAA,IACnD,CAAC,OAAO;AAAA,EACV;AAEA,QAAM,MAAM;AAAA,IACV,OAAO,EAAE,UAAU,eAAe,SAAS,YAAY;AAAA,IACvD,CAAC,eAAe,WAAW;AAAA,EAC7B;AAGA,YAAU,MAAM;AACd,UAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,MAAM;AACzD,UAAM,OAAO,OAAO,IAAI,eAAe;AACvC,QAAI,MAAM;AACR,MAAO,mBAAmB,KAAK,IAAI;AAAA,IACrC,OAAO;AACL,MAAO,gBAAgB,GAAG;AAAA,IAC5B;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB,YAAY,MAAM;AAC1C,UAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,UAAU,IAAI,OAAO,MAAM;AAClE,UAAM,MAAM,MACR,GAAG,IAAI,QAAQ,mBAAmB,GAAG,CAAC,KACtC;AACJ,WAAO,OAAO,SAAS,QAAQ,GAAG;AAAA,EACpC,GAAG,CAAC,YAAY,GAAG,CAAC;AAEpB,QAAM,SAAS;AAAA,IACb,MAAa,aAAa,GAAG;AAAA,IAC7B,CAAC,GAAG;AAAA,EACN;AAEA,QAAM,aAAa;AAAA,IACjB,OAAO,WAAgC;AACrC,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,IAAI;AACJ,YAAM,OAAO;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAc,iBAAiB,KAAK,IAAI;AAAA,IAC1C;AAAA,IACA,CAAC,GAAG;AAAA,EACN;AAEA,QAAM,yBAAyB;AAAA,IAC7B,MAAa,6BAA6B,GAAG;AAAA,IAC7C,CAAC,GAAG;AAAA,EACN;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAa,oBAAoB,GAAG;AAAA,IACpC,CAAC,GAAG;AAAA,EACN;AAEA,QAAM,eAAe;AAAA,IACnB,OAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SACE,oBAAC,aAAa,UAAb,EAAsB,OAAO,cAC3B,UACH;AAEJ;AAEA,IAAM,eAAe,cAAc,yBAAiB;AAE7C,IAAM,WAAW,MAAM;AAC5B,QAAM,UAAU,WAAW,YAAY;AACvC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,SAAO;AACT;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dauth-context-react",
3
- "version": "4.0.4",
3
+ "version": "5.0.0",
4
4
  "license": "MIT",
5
5
  "author": "David T. Pizarro Frick",
6
6
  "main": "dist/index.js",
@@ -1,118 +1,98 @@
1
- import { getServerBasePath } from './utils/config';
2
1
  import { IDauthUser } from '../interfaces';
3
2
  import {
4
- IdeleteAccountAPIResponse,
5
- IExchangeCodeAPIResponse,
6
- IgetUserAPIResponse,
7
- IrefreshTokenAPIResponse,
8
- IupdateUserAPIResponse,
3
+ IExchangeCodeResponse,
4
+ ISessionResponse,
5
+ IUpdateUserResponse,
6
+ IDeleteAccountResponse,
7
+ IProfileRedirectResponse,
9
8
  } from './interfaces/dauth.api.responses';
10
9
 
11
- export const getUserAPI = async (
12
- domainName: string,
13
- token: string
14
- ): Promise<IgetUserAPIResponse> => {
15
- const params = {
10
+ function getCsrfToken(): string {
11
+ const match = document.cookie.match(
12
+ /(?:^|;\s*)(?:__Host-csrf|csrf-token)=([^;]*)/
13
+ );
14
+ return match?.[1] ?? '';
15
+ }
16
+
17
+ export async function exchangeCodeAPI(
18
+ basePath: string,
19
+ code: string
20
+ ): Promise<IExchangeCodeResponse> {
21
+ const response = await fetch(`${basePath}/exchange-code`, {
22
+ method: 'POST',
23
+ headers: { 'Content-Type': 'application/json' },
24
+ credentials: 'include',
25
+ body: JSON.stringify({ code }),
26
+ });
27
+ const data = await response.json();
28
+ return { response, data };
29
+ }
30
+
31
+ export async function getSessionAPI(
32
+ basePath: string
33
+ ): Promise<ISessionResponse> {
34
+ const response = await fetch(`${basePath}/session`, {
16
35
  method: 'GET',
36
+ credentials: 'include',
37
+ });
38
+ const data = await response.json();
39
+ return { response, data };
40
+ }
41
+
42
+ export async function logoutAPI(
43
+ basePath: string
44
+ ): Promise<{ response: Response }> {
45
+ const response = await fetch(`${basePath}/logout`, {
46
+ method: 'POST',
17
47
  headers: {
18
- Authorization: token,
19
48
  'Content-Type': 'application/json',
49
+ 'X-CSRF-Token': getCsrfToken(),
20
50
  },
21
- };
22
- const response = await fetch(
23
- `${getServerBasePath()}/app/${domainName}/user`,
24
- params
25
- );
26
- const data = await response.json();
27
- return { response, data };
28
- };
51
+ credentials: 'include',
52
+ });
53
+ return { response };
54
+ }
29
55
 
30
- export const updateUserAPI = async (
31
- domainName: string,
32
- user: Partial<IDauthUser>,
33
- token: string
34
- ): Promise<IupdateUserAPIResponse> => {
35
- const params = {
56
+ export async function updateUserAPI(
57
+ basePath: string,
58
+ user: Partial<IDauthUser>
59
+ ): Promise<IUpdateUserResponse> {
60
+ const response = await fetch(`${basePath}/user`, {
36
61
  method: 'PATCH',
37
62
  headers: {
38
- Authorization: token,
39
63
  'Content-Type': 'application/json',
64
+ 'X-CSRF-Token': getCsrfToken(),
40
65
  },
66
+ credentials: 'include',
41
67
  body: JSON.stringify(user),
42
- };
43
- const response = await fetch(
44
- `${getServerBasePath()}/app/${domainName}/user`,
45
- params
46
- );
47
- const data = await response.json();
48
- return { response, data };
49
- };
50
-
51
- export const refreshTokenAPI = async (
52
- domainName: string,
53
- refreshToken: string
54
- ): Promise<IrefreshTokenAPIResponse> => {
55
- const params = {
56
- method: 'POST',
57
- headers: { 'Content-Type': 'application/json' },
58
- body: JSON.stringify({ refreshToken }),
59
- };
60
- const response = await fetch(
61
- `${getServerBasePath()}/app/${domainName}/refresh-token`,
62
- params
63
- );
68
+ });
64
69
  const data = await response.json();
65
70
  return { response, data };
66
- };
71
+ }
67
72
 
68
- export const deleteAccountAPI = async (
69
- domainName: string,
70
- token: string
71
- ): Promise<IdeleteAccountAPIResponse> => {
72
- const params = {
73
+ export async function deleteAccountAPI(
74
+ basePath: string
75
+ ): Promise<IDeleteAccountResponse> {
76
+ const response = await fetch(`${basePath}/user`, {
73
77
  method: 'DELETE',
74
- headers: {
75
- Authorization: token,
76
- 'Content-Type': 'application/json',
77
- },
78
- };
79
- const response = await fetch(
80
- `${getServerBasePath()}/app/${domainName}/user`,
81
- params
82
- );
78
+ headers: { 'X-CSRF-Token': getCsrfToken() },
79
+ credentials: 'include',
80
+ });
83
81
  const data = await response.json();
84
82
  return { response, data };
85
- };
83
+ }
86
84
 
87
- export const exchangeCodeAPI = async (
88
- domainName: string,
89
- code: string
90
- ): Promise<IExchangeCodeAPIResponse> => {
91
- const params = {
92
- method: 'POST',
93
- headers: { 'Content-Type': 'application/json' },
94
- body: JSON.stringify({ code }),
95
- };
85
+ export async function profileRedirectAPI(
86
+ basePath: string
87
+ ): Promise<IProfileRedirectResponse> {
96
88
  const response = await fetch(
97
- `${getServerBasePath()}/app/${domainName}/exchange-code`,
98
- params
89
+ `${basePath}/profile-redirect`,
90
+ {
91
+ method: 'GET',
92
+ headers: { 'X-CSRF-Token': getCsrfToken() },
93
+ credentials: 'include',
94
+ }
99
95
  );
100
96
  const data = await response.json();
101
97
  return { response, data };
102
- };
103
-
104
- export const logoutAPI = async (
105
- domainName: string,
106
- refreshToken: string
107
- ): Promise<{ response: Response }> => {
108
- const params = {
109
- method: 'POST',
110
- headers: { 'Content-Type': 'application/json' },
111
- body: JSON.stringify({ refreshToken }),
112
- };
113
- const response = await fetch(
114
- `${getServerBasePath()}/app/${domainName}/logout`,
115
- params
116
- );
117
- return { response };
118
- };
98
+ }
@@ -1,23 +1,23 @@
1
1
  import { IDauthDomainState, IDauthUser } from '../../interfaces';
2
2
 
3
- export interface IdeleteAccountAPIResponse {
3
+ export interface IExchangeCodeResponse {
4
4
  response: Response;
5
5
  data: {
6
- status: string;
7
- message: string;
6
+ user: IDauthUser;
7
+ domain: IDauthDomainState;
8
+ isNewUser: boolean;
8
9
  };
9
10
  }
10
11
 
11
- export interface IgetUserAPIResponse {
12
+ export interface ISessionResponse {
12
13
  response: Response;
13
14
  data: {
14
- status: string;
15
15
  user: IDauthUser;
16
16
  domain: IDauthDomainState;
17
17
  };
18
18
  }
19
19
 
20
- export interface IupdateUserAPIResponse {
20
+ export interface IUpdateUserResponse {
21
21
  response: Response;
22
22
  data: {
23
23
  status: string;
@@ -26,19 +26,17 @@ export interface IupdateUserAPIResponse {
26
26
  };
27
27
  }
28
28
 
29
- export interface IrefreshTokenAPIResponse {
29
+ export interface IDeleteAccountResponse {
30
30
  response: Response;
31
31
  data: {
32
- accessToken: string;
33
- refreshToken: string;
32
+ status: string;
33
+ message: string;
34
34
  };
35
35
  }
36
36
 
37
- export interface IExchangeCodeAPIResponse {
37
+ export interface IProfileRedirectResponse {
38
38
  response: Response;
39
39
  data: {
40
- accessToken: string;
41
- refreshToken: string;
42
- isNewUser?: boolean;
40
+ redirectUrl: string;
43
41
  };
44
42
  }
@@ -1,4 +1,3 @@
1
- export const apiVersion = 'v1';
2
1
  export const serverDomain = 'dauth.ovh';
3
2
 
4
3
  let _dauthUrl: string | undefined;
@@ -16,19 +15,12 @@ function checkIsLocalhost(): boolean {
16
15
  hostname.match(
17
16
  /(192)\.(168)\.(1)\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/gm
18
17
  ) ||
19
- hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
18
+ hostname.match(
19
+ /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20
+ )
20
21
  );
21
22
  }
22
23
 
23
- export function getServerBasePath() {
24
- if (_dauthUrl) return `${_dauthUrl}/api/${apiVersion}`;
25
- const isLocalhost = checkIsLocalhost();
26
- const serverPort = 4012;
27
- const serverLocalUrl = `${window.location.protocol}//${window.location.hostname}:${serverPort}/api/${apiVersion}`;
28
- const serverProdUrl = `https://${serverDomain}/api/${apiVersion}`;
29
- return isLocalhost ? serverLocalUrl : serverProdUrl;
30
- }
31
-
32
24
  export function getClientBasePath() {
33
25
  if (_dauthUrl) return _dauthUrl;
34
26
  const isLocalhost = checkIsLocalhost();
@@ -1,4 +1,3 @@
1
1
  export const routes = {
2
2
  signin: 'signin',
3
- updateUser: 'update-user',
4
3
  };
package/src/constants.ts CHANGED
@@ -1,3 +1 @@
1
- export const TOKEN_LS = 'dauth_state';
2
- export const REFRESH_TOKEN_LS = 'dauth_refresh_token';
3
1
  export const AUTH_CODE_PARAM = 'code';