dauth-context-react 5.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,14 +4,18 @@ import {
4
4
  ISessionResponse,
5
5
  IUpdateUserResponse,
6
6
  IDeleteAccountResponse,
7
- IProfileRedirectResponse,
8
7
  } from './interfaces/dauth.api.responses';
9
8
 
10
9
  function getCsrfToken(): string {
11
10
  const match = document.cookie.match(
12
11
  /(?:^|;\s*)(?:__Host-csrf|csrf-token)=([^;]*)/
13
12
  );
14
- return match?.[1] ?? '';
13
+ if (!match?.[1]) return '';
14
+ try {
15
+ return decodeURIComponent(match[1]);
16
+ } catch {
17
+ return match[1];
18
+ }
15
19
  }
16
20
 
17
21
  export async function exchangeCodeAPI(
@@ -81,18 +85,3 @@ export async function deleteAccountAPI(
81
85
  const data = await response.json();
82
86
  return { response, data };
83
87
  }
84
-
85
- export async function profileRedirectAPI(
86
- basePath: string
87
- ): Promise<IProfileRedirectResponse> {
88
- const response = await fetch(
89
- `${basePath}/profile-redirect`,
90
- {
91
- method: 'GET',
92
- headers: { 'X-CSRF-Token': getCsrfToken() },
93
- credentials: 'include',
94
- }
95
- );
96
- const data = await response.json();
97
- return { response, data };
98
- }
@@ -33,10 +33,3 @@ export interface IDeleteAccountResponse {
33
33
  message: string;
34
34
  };
35
35
  }
36
-
37
- export interface IProfileRedirectResponse {
38
- response: Response;
39
- data: {
40
- redirectUrl: string;
41
- };
42
- }
@@ -9,14 +9,17 @@ export function setDauthUrl(url: string | undefined) {
9
9
  function checkIsLocalhost(): boolean {
10
10
  if (typeof window === 'undefined') return false;
11
11
  const hostname = window.location.hostname;
12
- return Boolean(
12
+ return (
13
13
  hostname === 'localhost' ||
14
14
  hostname === '[::1]' ||
15
- hostname.match(
16
- /(192)\.(168)\.(1)\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/gm
15
+ /^127(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
16
+ hostname
17
17
  ) ||
18
- hostname.match(
19
- /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
18
+ /^192\.168(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){2}$/.test(
19
+ hostname
20
+ ) ||
21
+ /^10(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
22
+ hostname
20
23
  )
21
24
  );
22
25
  }
package/src/index.tsx CHANGED
@@ -16,9 +16,19 @@ import type {
16
16
  IDauthProviderProps,
17
17
  IDauthAuthMethods,
18
18
  IDauthUser,
19
+ IFormField,
20
+ IModalTheme,
21
+ DauthProfileModalProps,
19
22
  } from './interfaces';
20
23
 
21
- export type { IDauthProviderProps, IDauthAuthMethods };
24
+ export { DauthProfileModal } from './DauthProfileModal';
25
+ export type {
26
+ IDauthProviderProps,
27
+ IDauthAuthMethods,
28
+ IFormField,
29
+ IModalTheme,
30
+ DauthProfileModalProps,
31
+ };
22
32
 
23
33
  const defaultOnError = (error: Error) => console.error(error);
24
34
 
@@ -33,10 +43,7 @@ export const DauthProvider: React.FC<IDauthProviderProps> = (
33
43
  env,
34
44
  dauthUrl,
35
45
  } = props;
36
- const [dauthState, dispatch] = useReducer(
37
- userReducer,
38
- initialDauthState
39
- );
46
+ const [dauthState, dispatch] = useReducer(userReducer, initialDauthState);
40
47
 
41
48
  // Configure custom dauth URL before any API calls
42
49
  useEffect(() => {
@@ -66,16 +73,11 @@ export const DauthProvider: React.FC<IDauthProviderProps> = (
66
73
 
67
74
  const loginWithRedirect = useCallback(() => {
68
75
  const base = `${getClientBasePath()}/${domainName}/${routes.signin}`;
69
- const url = env
70
- ? `${base}?env=${encodeURIComponent(env)}`
71
- : base;
76
+ const url = env ? `${base}?env=${encodeURIComponent(env)}` : base;
72
77
  return window.location.replace(url);
73
78
  }, [domainName, env]);
74
79
 
75
- const logout = useCallback(
76
- () => action.logoutAction(ctx),
77
- [ctx]
78
- );
80
+ const logout = useCallback(() => action.logoutAction(ctx), [ctx]);
79
81
 
80
82
  const updateUser = useCallback(
81
83
  async (fields: Partial<IDauthUser>) => {
@@ -108,11 +110,6 @@ export const DauthProvider: React.FC<IDauthProviderProps> = (
108
110
  [ctx]
109
111
  );
110
112
 
111
- const updateUserWithRedirect = useCallback(
112
- () => action.updateUserWithRedirectAction(ctx),
113
- [ctx]
114
- );
115
-
116
113
  const deleteAccount = useCallback(
117
114
  () => action.deleteAccountAction(ctx),
118
115
  [ctx]
@@ -124,17 +121,9 @@ export const DauthProvider: React.FC<IDauthProviderProps> = (
124
121
  loginWithRedirect,
125
122
  logout,
126
123
  updateUser,
127
- updateUserWithRedirect,
128
124
  deleteAccount,
129
125
  }),
130
- [
131
- dauthState,
132
- loginWithRedirect,
133
- logout,
134
- updateUser,
135
- updateUserWithRedirect,
136
- deleteAccount,
137
- ]
126
+ [dauthState, loginWithRedirect, logout, updateUser, deleteAccount]
138
127
  );
139
128
 
140
129
  return (
@@ -13,7 +13,6 @@ const initialDauthState: IDauthState = {
13
13
  loginWithRedirect: () => {},
14
14
  logout: () => {},
15
15
  updateUser: () => Promise.resolve(false),
16
- updateUserWithRedirect: () => {},
17
16
  deleteAccount: () => Promise.resolve(false),
18
17
  };
19
18
 
package/src/interfaces.ts CHANGED
@@ -31,12 +31,29 @@ export interface IDauthAuthMethods {
31
31
  passkey: boolean;
32
32
  }
33
33
 
34
+ export interface IFormField {
35
+ field: string;
36
+ required: boolean;
37
+ }
38
+
39
+ export interface IModalTheme {
40
+ accent?: string;
41
+ accentHover?: string;
42
+ surface?: string;
43
+ surfaceHover?: string;
44
+ textPrimary?: string;
45
+ textSecondary?: string;
46
+ border?: string;
47
+ }
48
+
34
49
  export interface IDauthDomainState {
35
50
  name: string;
36
51
  environments?: IDauthDomainEnvironment[];
37
52
  loginRedirect: string;
38
53
  allowedOrigins: string[];
39
54
  authMethods?: IDauthAuthMethods;
55
+ formFields?: IFormField[];
56
+ modalTheme?: IModalTheme;
40
57
  }
41
58
 
42
59
  export interface IDauthState {
@@ -47,19 +64,19 @@ export interface IDauthState {
47
64
  loginWithRedirect: () => void;
48
65
  logout: () => void;
49
66
  updateUser: (fields: Partial<IDauthUser>) => Promise<boolean>;
50
- updateUserWithRedirect: () => void;
51
67
  deleteAccount: () => Promise<boolean>;
52
68
  }
53
69
 
70
+ export interface DauthProfileModalProps {
71
+ open: boolean;
72
+ onClose: () => void;
73
+ }
74
+
54
75
  export interface IActionStatus {
55
76
  type: TStatusTypes;
56
77
  message: string;
57
78
  }
58
- export type TStatusTypes =
59
- | 'success'
60
- | 'error'
61
- | 'info'
62
- | 'warning';
79
+ export type TStatusTypes = 'success' | 'error' | 'info' | 'warning';
63
80
 
64
81
  export interface IDauthProviderProps {
65
82
  domainName: string;
@@ -4,7 +4,6 @@ import {
4
4
  logoutAPI,
5
5
  updateUserAPI,
6
6
  deleteAccountAPI,
7
- profileRedirectAPI,
8
7
  } from '../api/dauth.api';
9
8
  import { IDauthDomainState, IDauthUser } from '../interfaces';
10
9
  import * as DauthTypes from './dauth.types';
@@ -15,10 +14,7 @@ export interface ActionContext {
15
14
  onError: (error: Error) => void;
16
15
  }
17
16
 
18
- export async function exchangeCodeAction(
19
- ctx: ActionContext,
20
- code: string
21
- ) {
17
+ export async function exchangeCodeAction(ctx: ActionContext, code: string) {
22
18
  const { dispatch, authProxyPath, onError } = ctx;
23
19
  dispatch({
24
20
  type: DauthTypes.SET_IS_LOADING,
@@ -26,11 +22,7 @@ export async function exchangeCodeAction(
26
22
  });
27
23
  try {
28
24
  // Clean URL immediately (before any fetch)
29
- window.history.replaceState(
30
- {},
31
- document.title,
32
- window.location.pathname
33
- );
25
+ window.history.replaceState({}, document.title, window.location.pathname);
34
26
  const result = await exchangeCodeAPI(authProxyPath, code);
35
27
  if (result.response.status === 200) {
36
28
  dispatch({
@@ -45,9 +37,7 @@ export async function exchangeCodeAction(
45
37
  }
46
38
  resetUser(dispatch);
47
39
  } catch (error) {
48
- onError(
49
- error instanceof Error ? error : new Error(String(error))
50
- );
40
+ onError(error instanceof Error ? error : new Error(String(error)));
51
41
  resetUser(dispatch);
52
42
  } finally {
53
43
  dispatch({
@@ -79,9 +69,7 @@ export async function autoLoginAction(ctx: ActionContext) {
79
69
  // No session — not authenticated (not an error)
80
70
  resetUser(dispatch);
81
71
  } catch (error) {
82
- onError(
83
- error instanceof Error ? error : new Error(String(error))
84
- );
72
+ onError(error instanceof Error ? error : new Error(String(error)));
85
73
  resetUser(dispatch);
86
74
  } finally {
87
75
  dispatch({
@@ -106,9 +94,7 @@ export async function logoutAction(ctx: ActionContext) {
106
94
  type: DauthTypes.LOGIN,
107
95
  payload: {
108
96
  user: {
109
- language:
110
- window.document.documentElement.getAttribute('lang') ||
111
- 'es',
97
+ language: window.document.documentElement.getAttribute('lang') || 'es',
112
98
  },
113
99
  domain: {},
114
100
  isAuthenticated: false,
@@ -126,10 +112,7 @@ export async function updateUserAction(
126
112
  ): Promise<boolean> {
127
113
  const { dispatch, authProxyPath, onError } = ctx;
128
114
  if (user.language) {
129
- window.document.documentElement.setAttribute(
130
- 'lang',
131
- user.language
132
- );
115
+ window.document.documentElement.setAttribute('lang', user.language);
133
116
  }
134
117
  try {
135
118
  const result = await updateUserAPI(authProxyPath, user);
@@ -140,45 +123,14 @@ export async function updateUserAction(
140
123
  });
141
124
  return true;
142
125
  }
143
- onError(
144
- new Error('Update user error: ' + result.data.message)
145
- );
126
+ onError(new Error('Update user error: ' + result.data.message));
146
127
  return false;
147
128
  } catch (error) {
148
- onError(
149
- error instanceof Error
150
- ? error
151
- : new Error('Update user error')
152
- );
129
+ onError(error instanceof Error ? error : new Error('Update user error'));
153
130
  return false;
154
131
  }
155
132
  }
156
133
 
157
- export async function updateUserWithRedirectAction(
158
- ctx: ActionContext
159
- ) {
160
- const { authProxyPath, onError } = ctx;
161
- try {
162
- const result = await profileRedirectAPI(authProxyPath);
163
- if (
164
- result.response.status === 200 &&
165
- result.data.redirectUrl
166
- ) {
167
- window.location.replace(result.data.redirectUrl);
168
- return;
169
- }
170
- onError(
171
- new Error('Could not generate profile redirect')
172
- );
173
- } catch (error) {
174
- onError(
175
- error instanceof Error
176
- ? error
177
- : new Error('Profile redirect error')
178
- );
179
- }
180
- }
181
-
182
134
  export async function deleteAccountAction(
183
135
  ctx: ActionContext
184
136
  ): Promise<boolean> {
@@ -191,11 +143,7 @@ export async function deleteAccountAction(
191
143
  }
192
144
  return false;
193
145
  } catch (error) {
194
- onError(
195
- error instanceof Error
196
- ? error
197
- : new Error('Delete account error')
198
- );
146
+ onError(error instanceof Error ? error : new Error('Delete account error'));
199
147
  return false;
200
148
  }
201
149
  }