dauth-context-react 3.0.0 → 4.0.1
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.js +40 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +40 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/api/dauth.api.ts +18 -0
- package/src/api/interfaces/dauth.api.responses.ts +9 -0
- package/src/constants.ts +1 -0
- package/src/index.tsx +5 -10
- package/src/reducer/dauth.actions.ts +27 -16
package/dist/index.js
CHANGED
|
@@ -179,6 +179,19 @@ var deleteAccountAPI = async (domainName, token) => {
|
|
|
179
179
|
const data = await response.json();
|
|
180
180
|
return { response, data };
|
|
181
181
|
};
|
|
182
|
+
var exchangeCodeAPI = async (domainName, code) => {
|
|
183
|
+
const params = {
|
|
184
|
+
method: "POST",
|
|
185
|
+
headers: { "Content-Type": "application/json" },
|
|
186
|
+
body: JSON.stringify({ code })
|
|
187
|
+
};
|
|
188
|
+
const response = await fetch(
|
|
189
|
+
`${getServerBasePath()}/app/${domainName}/exchange-code`,
|
|
190
|
+
params
|
|
191
|
+
);
|
|
192
|
+
const data = await response.json();
|
|
193
|
+
return { response, data };
|
|
194
|
+
};
|
|
182
195
|
var logoutAPI = async (domainName, refreshToken) => {
|
|
183
196
|
const params = {
|
|
184
197
|
method: "POST",
|
|
@@ -193,17 +206,31 @@ var logoutAPI = async (domainName, refreshToken) => {
|
|
|
193
206
|
};
|
|
194
207
|
|
|
195
208
|
// src/reducer/dauth.actions.ts
|
|
196
|
-
async function
|
|
209
|
+
async function exchangeCodeAction({
|
|
197
210
|
dispatch,
|
|
198
|
-
|
|
199
|
-
refreshToken,
|
|
211
|
+
code,
|
|
200
212
|
domainName,
|
|
201
213
|
storageKeys,
|
|
202
214
|
onError
|
|
203
215
|
}) {
|
|
204
|
-
dispatch({
|
|
216
|
+
dispatch({
|
|
217
|
+
type: SET_IS_LOADING,
|
|
218
|
+
payload: { isLoading: true }
|
|
219
|
+
});
|
|
205
220
|
try {
|
|
206
|
-
|
|
221
|
+
window.history.replaceState(
|
|
222
|
+
{},
|
|
223
|
+
document.title,
|
|
224
|
+
window.location.pathname
|
|
225
|
+
);
|
|
226
|
+
const exchangeResult = await exchangeCodeAPI(domainName, code);
|
|
227
|
+
if (exchangeResult.response.status !== 200) {
|
|
228
|
+
return resetUser(dispatch, storageKeys);
|
|
229
|
+
}
|
|
230
|
+
const { accessToken, refreshToken } = exchangeResult.data;
|
|
231
|
+
localStorage.setItem(storageKeys.accessToken, accessToken);
|
|
232
|
+
localStorage.setItem(storageKeys.refreshToken, refreshToken);
|
|
233
|
+
const getUserFetch = await getUserAPI(domainName, accessToken);
|
|
207
234
|
if (getUserFetch.response.status === 200) {
|
|
208
235
|
dispatch({
|
|
209
236
|
type: LOGIN,
|
|
@@ -213,15 +240,13 @@ async function setDauthStateAction({
|
|
|
213
240
|
isAuthenticated: true
|
|
214
241
|
}
|
|
215
242
|
});
|
|
216
|
-
window.history.replaceState({}, document.title, window.location.pathname);
|
|
217
|
-
localStorage.setItem(storageKeys.accessToken, token);
|
|
218
|
-
localStorage.setItem(storageKeys.refreshToken, refreshToken);
|
|
219
243
|
return;
|
|
220
|
-
} else {
|
|
221
|
-
return resetUser(dispatch, storageKeys);
|
|
222
244
|
}
|
|
245
|
+
return resetUser(dispatch, storageKeys);
|
|
223
246
|
} catch (error) {
|
|
224
|
-
onError(
|
|
247
|
+
onError(
|
|
248
|
+
error instanceof Error ? error : new Error(String(error))
|
|
249
|
+
);
|
|
225
250
|
return resetUser(dispatch, storageKeys);
|
|
226
251
|
} finally {
|
|
227
252
|
dispatch({
|
|
@@ -432,6 +457,7 @@ var resetUser = (dispatch, storageKeys) => {
|
|
|
432
457
|
// src/constants.ts
|
|
433
458
|
var TOKEN_LS = "dauth_state";
|
|
434
459
|
var REFRESH_TOKEN_LS = "dauth_refresh_token";
|
|
460
|
+
var AUTH_CODE_PARAM = "code";
|
|
435
461
|
|
|
436
462
|
// src/api/utils/routes.ts
|
|
437
463
|
var routes = {
|
|
@@ -493,14 +519,9 @@ var DauthProvider = (props) => {
|
|
|
493
519
|
const queryString = window.location.search;
|
|
494
520
|
if (!queryString) return;
|
|
495
521
|
const urlParams = new URLSearchParams(queryString);
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
return setDauthStateAction({
|
|
500
|
-
...ctx,
|
|
501
|
-
token: token_url,
|
|
502
|
-
refreshToken: refresh_url
|
|
503
|
-
});
|
|
522
|
+
const code = urlParams.get(AUTH_CODE_PARAM);
|
|
523
|
+
if (code && !dauthState.isAuthenticated) {
|
|
524
|
+
return exchangeCodeAction({ ...ctx, code });
|
|
504
525
|
}
|
|
505
526
|
})();
|
|
506
527
|
}, []);
|
package/dist/index.js.map
CHANGED
|
@@ -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 } 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\n useEffect(() => {\n (async () => {\n const queryString = window.location.search;\n if (!queryString) return;\n const urlParams = new URLSearchParams(queryString);\n const token_url = urlParams.get(storageKeys.accessToken);\n const refresh_url = urlParams.get(storageKeys.refreshToken);\n if (token_url && refresh_url && !dauthState.isAuthenticated) {\n return action.setDauthStateAction({\n ...ctx,\n token: token_url,\n refreshToken: refresh_url,\n });\n }\n })();\n }, []);\n\n // Auto Login\n useEffect(() => {\n (async () => {\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 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 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 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 TSetDauthStateAction = ActionContext & {\n token: string;\n refreshToken: string;\n};\nexport async function setDauthStateAction({\n dispatch,\n token,\n refreshToken,\n domainName,\n storageKeys,\n onError,\n}: TSetDauthStateAction) {\n dispatch({ type: DauthTypes.SET_IS_LOADING, payload: { isLoading: true } });\n try {\n const getUserFetch = await getUserAPI(domainName, token);\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 window.history.replaceState({}, document.title, window.location.pathname);\n localStorage.setItem(storageKeys.accessToken, token);\n localStorage.setItem(storageKeys.refreshToken, refreshToken);\n return;\n } else {\n return resetUser(dispatch, storageKeys);\n }\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';\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/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 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(\n {},\n document.title,\n window.location.pathname\n );\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(\n error instanceof Error ? error : new Error(String(error))\n );\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":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -162,6 +162,19 @@ var deleteAccountAPI = async (domainName, token) => {
|
|
|
162
162
|
const data = await response.json();
|
|
163
163
|
return { response, data };
|
|
164
164
|
};
|
|
165
|
+
var exchangeCodeAPI = async (domainName, code) => {
|
|
166
|
+
const params = {
|
|
167
|
+
method: "POST",
|
|
168
|
+
headers: { "Content-Type": "application/json" },
|
|
169
|
+
body: JSON.stringify({ code })
|
|
170
|
+
};
|
|
171
|
+
const response = await fetch(
|
|
172
|
+
`${getServerBasePath()}/app/${domainName}/exchange-code`,
|
|
173
|
+
params
|
|
174
|
+
);
|
|
175
|
+
const data = await response.json();
|
|
176
|
+
return { response, data };
|
|
177
|
+
};
|
|
165
178
|
var logoutAPI = async (domainName, refreshToken) => {
|
|
166
179
|
const params = {
|
|
167
180
|
method: "POST",
|
|
@@ -176,17 +189,31 @@ var logoutAPI = async (domainName, refreshToken) => {
|
|
|
176
189
|
};
|
|
177
190
|
|
|
178
191
|
// src/reducer/dauth.actions.ts
|
|
179
|
-
async function
|
|
192
|
+
async function exchangeCodeAction({
|
|
180
193
|
dispatch,
|
|
181
|
-
|
|
182
|
-
refreshToken,
|
|
194
|
+
code,
|
|
183
195
|
domainName,
|
|
184
196
|
storageKeys,
|
|
185
197
|
onError
|
|
186
198
|
}) {
|
|
187
|
-
dispatch({
|
|
199
|
+
dispatch({
|
|
200
|
+
type: SET_IS_LOADING,
|
|
201
|
+
payload: { isLoading: true }
|
|
202
|
+
});
|
|
188
203
|
try {
|
|
189
|
-
|
|
204
|
+
window.history.replaceState(
|
|
205
|
+
{},
|
|
206
|
+
document.title,
|
|
207
|
+
window.location.pathname
|
|
208
|
+
);
|
|
209
|
+
const exchangeResult = await exchangeCodeAPI(domainName, code);
|
|
210
|
+
if (exchangeResult.response.status !== 200) {
|
|
211
|
+
return resetUser(dispatch, storageKeys);
|
|
212
|
+
}
|
|
213
|
+
const { accessToken, refreshToken } = exchangeResult.data;
|
|
214
|
+
localStorage.setItem(storageKeys.accessToken, accessToken);
|
|
215
|
+
localStorage.setItem(storageKeys.refreshToken, refreshToken);
|
|
216
|
+
const getUserFetch = await getUserAPI(domainName, accessToken);
|
|
190
217
|
if (getUserFetch.response.status === 200) {
|
|
191
218
|
dispatch({
|
|
192
219
|
type: LOGIN,
|
|
@@ -196,15 +223,13 @@ async function setDauthStateAction({
|
|
|
196
223
|
isAuthenticated: true
|
|
197
224
|
}
|
|
198
225
|
});
|
|
199
|
-
window.history.replaceState({}, document.title, window.location.pathname);
|
|
200
|
-
localStorage.setItem(storageKeys.accessToken, token);
|
|
201
|
-
localStorage.setItem(storageKeys.refreshToken, refreshToken);
|
|
202
226
|
return;
|
|
203
|
-
} else {
|
|
204
|
-
return resetUser(dispatch, storageKeys);
|
|
205
227
|
}
|
|
228
|
+
return resetUser(dispatch, storageKeys);
|
|
206
229
|
} catch (error) {
|
|
207
|
-
onError(
|
|
230
|
+
onError(
|
|
231
|
+
error instanceof Error ? error : new Error(String(error))
|
|
232
|
+
);
|
|
208
233
|
return resetUser(dispatch, storageKeys);
|
|
209
234
|
} finally {
|
|
210
235
|
dispatch({
|
|
@@ -415,6 +440,7 @@ var resetUser = (dispatch, storageKeys) => {
|
|
|
415
440
|
// src/constants.ts
|
|
416
441
|
var TOKEN_LS = "dauth_state";
|
|
417
442
|
var REFRESH_TOKEN_LS = "dauth_refresh_token";
|
|
443
|
+
var AUTH_CODE_PARAM = "code";
|
|
418
444
|
|
|
419
445
|
// src/api/utils/routes.ts
|
|
420
446
|
var routes = {
|
|
@@ -476,14 +502,9 @@ var DauthProvider = (props) => {
|
|
|
476
502
|
const queryString = window.location.search;
|
|
477
503
|
if (!queryString) return;
|
|
478
504
|
const urlParams = new URLSearchParams(queryString);
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
return setDauthStateAction({
|
|
483
|
-
...ctx,
|
|
484
|
-
token: token_url,
|
|
485
|
-
refreshToken: refresh_url
|
|
486
|
-
});
|
|
505
|
+
const code = urlParams.get(AUTH_CODE_PARAM);
|
|
506
|
+
if (code && !dauthState.isAuthenticated) {
|
|
507
|
+
return exchangeCodeAction({ ...ctx, code });
|
|
487
508
|
}
|
|
488
509
|
})();
|
|
489
510
|
}, []);
|
package/dist/index.mjs.map
CHANGED
|
@@ -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 } 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\n useEffect(() => {\n (async () => {\n const queryString = window.location.search;\n if (!queryString) return;\n const urlParams = new URLSearchParams(queryString);\n const token_url = urlParams.get(storageKeys.accessToken);\n const refresh_url = urlParams.get(storageKeys.refreshToken);\n if (token_url && refresh_url && !dauthState.isAuthenticated) {\n return action.setDauthStateAction({\n ...ctx,\n token: token_url,\n refreshToken: refresh_url,\n });\n }\n })();\n }, []);\n\n // Auto Login\n useEffect(() => {\n (async () => {\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 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 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 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 TSetDauthStateAction = ActionContext & {\n token: string;\n refreshToken: string;\n};\nexport async function setDauthStateAction({\n dispatch,\n token,\n refreshToken,\n domainName,\n storageKeys,\n onError,\n}: TSetDauthStateAction) {\n dispatch({ type: DauthTypes.SET_IS_LOADING, payload: { isLoading: true } });\n try {\n const getUserFetch = await getUserAPI(domainName, token);\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 window.history.replaceState({}, document.title, window.location.pathname);\n localStorage.setItem(storageKeys.accessToken, token);\n localStorage.setItem(storageKeys.refreshToken, refreshToken);\n return;\n } else {\n return resetUser(dispatch, storageKeys);\n }\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';\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/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 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(\n {},\n document.title,\n window.location.pathname\n );\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(\n error instanceof Error ? error : new Error(String(error))\n );\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":[]}
|
package/package.json
CHANGED
package/src/api/dauth.api.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { getServerBasePath } from './utils/config';
|
|
|
2
2
|
import { IDauthUser } from '../interfaces';
|
|
3
3
|
import {
|
|
4
4
|
IdeleteAccountAPIResponse,
|
|
5
|
+
IExchangeCodeAPIResponse,
|
|
5
6
|
IgetUserAPIResponse,
|
|
6
7
|
IrefreshTokenAPIResponse,
|
|
7
8
|
IupdateUserAPIResponse,
|
|
@@ -83,6 +84,23 @@ export const deleteAccountAPI = async (
|
|
|
83
84
|
return { response, data };
|
|
84
85
|
};
|
|
85
86
|
|
|
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
|
+
};
|
|
96
|
+
const response = await fetch(
|
|
97
|
+
`${getServerBasePath()}/app/${domainName}/exchange-code`,
|
|
98
|
+
params
|
|
99
|
+
);
|
|
100
|
+
const data = await response.json();
|
|
101
|
+
return { response, data };
|
|
102
|
+
};
|
|
103
|
+
|
|
86
104
|
export const logoutAPI = async (
|
|
87
105
|
domainName: string,
|
|
88
106
|
refreshToken: string
|
package/src/constants.ts
CHANGED
package/src/index.tsx
CHANGED
|
@@ -11,7 +11,7 @@ import initialDauthState from './initialDauthState';
|
|
|
11
11
|
import userReducer from './reducer/dauth.reducer';
|
|
12
12
|
import * as action from './reducer/dauth.actions';
|
|
13
13
|
import { getClientBasePath, setDauthUrl } from './api/utils/config';
|
|
14
|
-
import { TOKEN_LS, REFRESH_TOKEN_LS } from './constants';
|
|
14
|
+
import { TOKEN_LS, REFRESH_TOKEN_LS, AUTH_CODE_PARAM } from './constants';
|
|
15
15
|
import { routes } from './api/utils/routes';
|
|
16
16
|
import type {
|
|
17
17
|
IDauthProviderProps,
|
|
@@ -84,20 +84,15 @@ export const DauthProvider: React.FC<IDauthProviderProps> = (
|
|
|
84
84
|
}
|
|
85
85
|
}, [ctx, storageKeys.accessToken]);
|
|
86
86
|
|
|
87
|
-
// Catch login redirect
|
|
87
|
+
// Catch login redirect — exchange authorization code for tokens
|
|
88
88
|
useEffect(() => {
|
|
89
89
|
(async () => {
|
|
90
90
|
const queryString = window.location.search;
|
|
91
91
|
if (!queryString) return;
|
|
92
92
|
const urlParams = new URLSearchParams(queryString);
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return action.setDauthStateAction({
|
|
97
|
-
...ctx,
|
|
98
|
-
token: token_url,
|
|
99
|
-
refreshToken: refresh_url,
|
|
100
|
-
});
|
|
93
|
+
const code = urlParams.get(AUTH_CODE_PARAM);
|
|
94
|
+
if (code && !dauthState.isAuthenticated) {
|
|
95
|
+
return action.exchangeCodeAction({ ...ctx, code });
|
|
101
96
|
}
|
|
102
97
|
})();
|
|
103
98
|
}, []);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deleteAccountAPI,
|
|
3
|
+
exchangeCodeAPI,
|
|
3
4
|
getUserAPI,
|
|
4
5
|
logoutAPI,
|
|
5
6
|
refreshTokenAPI,
|
|
@@ -19,21 +20,33 @@ export interface ActionContext {
|
|
|
19
20
|
onError: (error: Error) => void;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
type
|
|
23
|
-
|
|
24
|
-
refreshToken: string;
|
|
25
|
-
};
|
|
26
|
-
export async function setDauthStateAction({
|
|
23
|
+
type TExchangeCodeAction = ActionContext & { code: string };
|
|
24
|
+
export async function exchangeCodeAction({
|
|
27
25
|
dispatch,
|
|
28
|
-
|
|
29
|
-
refreshToken,
|
|
26
|
+
code,
|
|
30
27
|
domainName,
|
|
31
28
|
storageKeys,
|
|
32
29
|
onError,
|
|
33
|
-
}:
|
|
34
|
-
dispatch({
|
|
30
|
+
}: TExchangeCodeAction) {
|
|
31
|
+
dispatch({
|
|
32
|
+
type: DauthTypes.SET_IS_LOADING,
|
|
33
|
+
payload: { isLoading: true },
|
|
34
|
+
});
|
|
35
35
|
try {
|
|
36
|
-
|
|
36
|
+
// Clean URL immediately (before any fetch)
|
|
37
|
+
window.history.replaceState(
|
|
38
|
+
{},
|
|
39
|
+
document.title,
|
|
40
|
+
window.location.pathname
|
|
41
|
+
);
|
|
42
|
+
const exchangeResult = await exchangeCodeAPI(domainName, code);
|
|
43
|
+
if (exchangeResult.response.status !== 200) {
|
|
44
|
+
return resetUser(dispatch, storageKeys);
|
|
45
|
+
}
|
|
46
|
+
const { accessToken, refreshToken } = exchangeResult.data;
|
|
47
|
+
localStorage.setItem(storageKeys.accessToken, accessToken);
|
|
48
|
+
localStorage.setItem(storageKeys.refreshToken, refreshToken);
|
|
49
|
+
const getUserFetch = await getUserAPI(domainName, accessToken);
|
|
37
50
|
if (getUserFetch.response.status === 200) {
|
|
38
51
|
dispatch({
|
|
39
52
|
type: DauthTypes.LOGIN,
|
|
@@ -43,15 +56,13 @@ export async function setDauthStateAction({
|
|
|
43
56
|
isAuthenticated: true,
|
|
44
57
|
},
|
|
45
58
|
});
|
|
46
|
-
window.history.replaceState({}, document.title, window.location.pathname);
|
|
47
|
-
localStorage.setItem(storageKeys.accessToken, token);
|
|
48
|
-
localStorage.setItem(storageKeys.refreshToken, refreshToken);
|
|
49
59
|
return;
|
|
50
|
-
} else {
|
|
51
|
-
return resetUser(dispatch, storageKeys);
|
|
52
60
|
}
|
|
61
|
+
return resetUser(dispatch, storageKeys);
|
|
53
62
|
} catch (error) {
|
|
54
|
-
onError(
|
|
63
|
+
onError(
|
|
64
|
+
error instanceof Error ? error : new Error(String(error))
|
|
65
|
+
);
|
|
55
66
|
return resetUser(dispatch, storageKeys);
|
|
56
67
|
} finally {
|
|
57
68
|
dispatch({
|