@riligar/auth-react 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +1333 -507
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1358 -510
- package/dist/index.js.map +1 -1
- package/package.json +37 -7
package/dist/index.js
CHANGED
|
@@ -1,16 +1,47 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React$1 = require('react');
|
|
4
4
|
var reactRouterDom = require('react-router-dom');
|
|
5
|
+
var core = require('@mantine/core');
|
|
6
|
+
var form = require('@mantine/form');
|
|
7
|
+
var iconsReact = require('@tabler/icons-react');
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
10
|
+
// Config - pode ser sobrescrita pelo AuthProvider
|
|
11
|
+
// Tenta detectar ambiente Vite, mas falha graciosamente se não existir
|
|
12
|
+
const getEnvVar = key => {
|
|
13
|
+
try {
|
|
14
|
+
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) }) !== 'undefined' && undefined && undefined[key]) {
|
|
15
|
+
return undefined[key];
|
|
16
|
+
}
|
|
17
|
+
} catch (e) {
|
|
18
|
+
// ignore
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
22
|
+
let API_BASE = (typeof window !== 'undefined' && window?.location ? getEnvVar('VITE_API_BASE') : null) || 'http://localhost:3000';
|
|
23
|
+
let API_KEY = null;
|
|
24
|
+
|
|
25
|
+
// Permite configurar a API base e key externamente (chamado pelo AuthProvider)
|
|
26
|
+
function configure({
|
|
27
|
+
apiUrl,
|
|
28
|
+
apiKey
|
|
29
|
+
}) {
|
|
30
|
+
if (apiUrl) API_BASE = apiUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
31
|
+
if (apiKey) API_KEY = apiKey;
|
|
32
|
+
}
|
|
8
33
|
|
|
9
34
|
// helper fetch pré-configurado
|
|
10
35
|
async function api(route, opts = {}) {
|
|
36
|
+
// Garante que a rota comece com /
|
|
37
|
+
const cleanRoute = route.startsWith('/') ? route : `/${route}`;
|
|
38
|
+
|
|
39
|
+
// Constrói URL completa (API_BASE já teve trailing slash removido no configure)
|
|
40
|
+
const url = `${API_BASE}${cleanRoute}`;
|
|
11
41
|
const token = getStoredToken();
|
|
12
42
|
const headers = {
|
|
13
|
-
|
|
43
|
+
'Content-Type': 'application/json',
|
|
44
|
+
Accept: 'application/json',
|
|
14
45
|
...opts.headers
|
|
15
46
|
};
|
|
16
47
|
|
|
@@ -18,7 +49,12 @@ async function api(route, opts = {}) {
|
|
|
18
49
|
if (token) {
|
|
19
50
|
headers.Authorization = `Bearer ${token}`;
|
|
20
51
|
}
|
|
21
|
-
|
|
52
|
+
|
|
53
|
+
// Adiciona API Key se configurada
|
|
54
|
+
if (API_KEY) {
|
|
55
|
+
headers['X-API-Key'] = API_KEY;
|
|
56
|
+
}
|
|
57
|
+
const res = await fetch(url, {
|
|
22
58
|
headers,
|
|
23
59
|
...opts
|
|
24
60
|
});
|
|
@@ -45,14 +81,38 @@ function setStoredToken(token) {
|
|
|
45
81
|
window.localStorage.removeItem('auth:token');
|
|
46
82
|
}
|
|
47
83
|
}
|
|
84
|
+
// Helper para processar resposta de autenticação e salvar token
|
|
85
|
+
function handleAuthResponse(result) {
|
|
86
|
+
// Tenta encontrar o token em vários lugares possíveis
|
|
87
|
+
const token = result.token || result.session?.token || result.session?.sessionToken;
|
|
88
|
+
console.log('[AuthSDK] Handling Auth Response:', {
|
|
89
|
+
hasToken: !!result.token,
|
|
90
|
+
hasSessionToken: !!result.session?.token,
|
|
91
|
+
hasSessionSessionToken: !!result.session?.sessionToken,
|
|
92
|
+
extractedToken: token
|
|
93
|
+
});
|
|
94
|
+
if (token) {
|
|
95
|
+
console.log('[AuthSDK] Saving token to storage');
|
|
96
|
+
setStoredToken(token);
|
|
97
|
+
} else {
|
|
98
|
+
console.warn('[AuthSDK] No token found in response', result);
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
48
102
|
|
|
49
103
|
// Decodifica JWT (apenas payload, sem verificação de assinatura)
|
|
50
104
|
function decodeJWT(token) {
|
|
51
105
|
try {
|
|
52
106
|
const parts = token.split('.');
|
|
53
107
|
if (parts.length !== 3) return null;
|
|
54
|
-
|
|
55
|
-
|
|
108
|
+
|
|
109
|
+
// Safe base64 decode
|
|
110
|
+
const base64Url = parts[1];
|
|
111
|
+
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
112
|
+
|
|
113
|
+
// Verifica ambiente para decodificar
|
|
114
|
+
const jsonPayload = typeof window !== 'undefined' ? window.atob(base64) : Buffer.from(base64, 'base64').toString();
|
|
115
|
+
return JSON.parse(jsonPayload);
|
|
56
116
|
} catch {
|
|
57
117
|
return null;
|
|
58
118
|
}
|
|
@@ -61,14 +121,33 @@ function decodeJWT(token) {
|
|
|
61
121
|
// Verifica se o token está expirado
|
|
62
122
|
function isTokenExpired(token) {
|
|
63
123
|
const payload = decodeJWT(token);
|
|
64
|
-
|
|
65
|
-
|
|
124
|
+
|
|
125
|
+
// Se não for um JWT válido (payload null), assumimos que é um token opaco (session token)
|
|
126
|
+
// Nesse caso, deixamos o servidor validar via 401
|
|
127
|
+
if (!payload) return false;
|
|
128
|
+
if (!payload.exp) return false;
|
|
129
|
+
const now = Date.now();
|
|
130
|
+
const exp = payload.exp * 1000;
|
|
131
|
+
const isExpired = now >= exp;
|
|
132
|
+
if (isExpired) {
|
|
133
|
+
console.log('[AuthSDK] Token expired:', {
|
|
134
|
+
now,
|
|
135
|
+
exp,
|
|
136
|
+
diff: exp - now
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return isExpired;
|
|
66
140
|
}
|
|
67
141
|
|
|
68
142
|
// Verifica se o usuário está autenticado
|
|
69
143
|
function isAuthenticated() {
|
|
70
144
|
const token = getStoredToken();
|
|
71
|
-
|
|
145
|
+
const valid = token && !isTokenExpired(token);
|
|
146
|
+
console.log('[AuthSDK] isAuthenticated check:', {
|
|
147
|
+
hasToken: !!token,
|
|
148
|
+
valid
|
|
149
|
+
});
|
|
150
|
+
return valid;
|
|
72
151
|
}
|
|
73
152
|
|
|
74
153
|
// Obtém dados do usuário do token
|
|
@@ -84,37 +163,32 @@ function getCurrentUser() {
|
|
|
84
163
|
} : null;
|
|
85
164
|
}
|
|
86
165
|
|
|
87
|
-
/*--- métodos de autenticação-------------------*/
|
|
88
|
-
const signUp = async (email, password) => {
|
|
89
|
-
const result = await api(
|
|
90
|
-
method:
|
|
166
|
+
/*--- métodos de autenticação -------------------*/
|
|
167
|
+
const signUp = async (email, password, name = '') => {
|
|
168
|
+
const result = await api('/auth/sign-up/email', {
|
|
169
|
+
method: 'POST',
|
|
91
170
|
body: JSON.stringify({
|
|
92
171
|
email,
|
|
93
|
-
password
|
|
172
|
+
password,
|
|
173
|
+
name
|
|
94
174
|
})
|
|
95
175
|
});
|
|
96
|
-
|
|
97
|
-
setStoredToken(result.token);
|
|
98
|
-
}
|
|
99
|
-
return result;
|
|
176
|
+
return handleAuthResponse(result);
|
|
100
177
|
};
|
|
101
178
|
const signIn = async (email, password) => {
|
|
102
|
-
const result = await api(
|
|
103
|
-
method:
|
|
179
|
+
const result = await api('/auth/sign-in/email', {
|
|
180
|
+
method: 'POST',
|
|
104
181
|
body: JSON.stringify({
|
|
105
182
|
email,
|
|
106
183
|
password
|
|
107
184
|
})
|
|
108
185
|
});
|
|
109
|
-
|
|
110
|
-
setStoredToken(result.token);
|
|
111
|
-
}
|
|
112
|
-
return result;
|
|
186
|
+
return handleAuthResponse(result);
|
|
113
187
|
};
|
|
114
188
|
const signOut = async () => {
|
|
115
189
|
try {
|
|
116
|
-
await api(
|
|
117
|
-
method:
|
|
190
|
+
await api('/auth/sign-out', {
|
|
191
|
+
method: 'POST'
|
|
118
192
|
});
|
|
119
193
|
} catch {
|
|
120
194
|
// Ignora erros de logout no servidor
|
|
@@ -124,23 +198,77 @@ const signOut = async () => {
|
|
|
124
198
|
};
|
|
125
199
|
const refreshToken = async () => {
|
|
126
200
|
try {
|
|
127
|
-
const result = await api(
|
|
128
|
-
method:
|
|
201
|
+
const result = await api('/auth/refresh', {
|
|
202
|
+
method: 'POST'
|
|
129
203
|
});
|
|
130
|
-
|
|
131
|
-
setStoredToken(result.token);
|
|
132
|
-
return result;
|
|
133
|
-
}
|
|
204
|
+
return handleAuthResponse(result);
|
|
134
205
|
} catch (error) {
|
|
135
206
|
setStoredToken(null);
|
|
136
207
|
throw error;
|
|
137
208
|
}
|
|
138
209
|
};
|
|
139
210
|
|
|
140
|
-
|
|
211
|
+
/*--- Magic Link ---------------------------------*/
|
|
212
|
+
const sendMagicLink = async (email, callbackURL) => {
|
|
213
|
+
const callback = callbackURL || (typeof window !== 'undefined' ? `${window.location.origin}/auth/magic-link/verify` : '/auth/magic-link/verify');
|
|
214
|
+
return await api('/auth/sign-in/magic-link', {
|
|
215
|
+
method: 'POST',
|
|
216
|
+
body: JSON.stringify({
|
|
217
|
+
email,
|
|
218
|
+
callbackURL: callback
|
|
219
|
+
})
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
const verifyMagicLink = async token => {
|
|
223
|
+
const result = await api(`/auth/magic-link/verify?token=${encodeURIComponent(token)}`);
|
|
224
|
+
return handleAuthResponse(result);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/*--- Password Reset -----------------------------*/
|
|
228
|
+
const forgotPassword = async (email, redirectTo) => {
|
|
229
|
+
const redirect = redirectTo || (typeof window !== 'undefined' ? `${window.location.origin}/auth/reset-password` : '/auth/reset-password');
|
|
230
|
+
return await api('/auth/forget-password', {
|
|
231
|
+
method: 'POST',
|
|
232
|
+
body: JSON.stringify({
|
|
233
|
+
email,
|
|
234
|
+
redirectTo: redirect
|
|
235
|
+
})
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
const resetPassword = async (token, newPassword) => {
|
|
239
|
+
return await api('/auth/reset-password', {
|
|
240
|
+
method: 'POST',
|
|
241
|
+
body: JSON.stringify({
|
|
242
|
+
token,
|
|
243
|
+
newPassword
|
|
244
|
+
})
|
|
245
|
+
});
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
/*--- Email Verification -------------------------*/
|
|
249
|
+
const verifyEmail = async token => {
|
|
250
|
+
const result = await api(`/auth/verify-email?token=${encodeURIComponent(token)}`);
|
|
251
|
+
return handleAuthResponse(result);
|
|
252
|
+
};
|
|
253
|
+
const resendVerification = async (email, callbackURL) => {
|
|
254
|
+
const callback = callbackURL || (typeof window !== 'undefined' ? `${window.location.origin}/auth/verify-email` : '/auth/verify-email');
|
|
255
|
+
return await api('/auth/send-verification-email', {
|
|
256
|
+
method: 'POST',
|
|
257
|
+
body: JSON.stringify({
|
|
258
|
+
email,
|
|
259
|
+
callbackURL: callback
|
|
260
|
+
})
|
|
261
|
+
});
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
/*--- Session ------------------------------------*/
|
|
265
|
+
const getSession = async () => {
|
|
266
|
+
return await api('/auth/session');
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
/* Social login redirect (ex.: Google) -----------*/
|
|
141
270
|
function socialRedirect(provider, redirectTo = typeof window !== 'undefined' ? window.location.href : '/') {
|
|
142
271
|
if (typeof window === 'undefined') return;
|
|
143
|
-
// Melhor pegar a URL de redirect dada pelo back-end, mas isso já funciona:
|
|
144
272
|
window.location = `${API_BASE}/auth/sign-in/${provider}?redirect=${encodeURIComponent(redirectTo)}`;
|
|
145
273
|
}
|
|
146
274
|
|
|
@@ -161,479 +289,84 @@ const createStoreImpl = (createState) => {
|
|
|
161
289
|
listeners.add(listener);
|
|
162
290
|
return () => listeners.delete(listener);
|
|
163
291
|
};
|
|
164
|
-
const
|
|
165
|
-
if ((undefined ? undefined.MODE : void 0) !== "production") {
|
|
166
|
-
console.warn(
|
|
167
|
-
"[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
listeners.clear();
|
|
171
|
-
};
|
|
172
|
-
const api = { setState, getState, getInitialState, subscribe, destroy };
|
|
292
|
+
const api = { setState, getState, getInitialState, subscribe };
|
|
173
293
|
const initialState = state = createState(setState, getState, api);
|
|
174
294
|
return api;
|
|
175
295
|
};
|
|
176
|
-
const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
|
|
177
|
-
|
|
178
|
-
function getDefaultExportFromCjs (x) {
|
|
179
|
-
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
var withSelector = {exports: {}};
|
|
183
|
-
|
|
184
|
-
var withSelector_production = {};
|
|
185
|
-
|
|
186
|
-
var shim = {exports: {}};
|
|
187
|
-
|
|
188
|
-
var useSyncExternalStoreShim_production = {};
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* @license React
|
|
192
|
-
* use-sync-external-store-shim.production.js
|
|
193
|
-
*
|
|
194
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
195
|
-
*
|
|
196
|
-
* This source code is licensed under the MIT license found in the
|
|
197
|
-
* LICENSE file in the root directory of this source tree.
|
|
198
|
-
*/
|
|
199
|
-
|
|
200
|
-
var hasRequiredUseSyncExternalStoreShim_production;
|
|
201
|
-
|
|
202
|
-
function requireUseSyncExternalStoreShim_production () {
|
|
203
|
-
if (hasRequiredUseSyncExternalStoreShim_production) return useSyncExternalStoreShim_production;
|
|
204
|
-
hasRequiredUseSyncExternalStoreShim_production = 1;
|
|
205
|
-
var React = require$$0;
|
|
206
|
-
function is(x, y) {
|
|
207
|
-
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
|
208
|
-
}
|
|
209
|
-
var objectIs = "function" === typeof Object.is ? Object.is : is,
|
|
210
|
-
useState = React.useState,
|
|
211
|
-
useEffect = React.useEffect,
|
|
212
|
-
useLayoutEffect = React.useLayoutEffect,
|
|
213
|
-
useDebugValue = React.useDebugValue;
|
|
214
|
-
function useSyncExternalStore$2(subscribe, getSnapshot) {
|
|
215
|
-
var value = getSnapshot(),
|
|
216
|
-
_useState = useState({ inst: { value: value, getSnapshot: getSnapshot } }),
|
|
217
|
-
inst = _useState[0].inst,
|
|
218
|
-
forceUpdate = _useState[1];
|
|
219
|
-
useLayoutEffect(
|
|
220
|
-
function () {
|
|
221
|
-
inst.value = value;
|
|
222
|
-
inst.getSnapshot = getSnapshot;
|
|
223
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
224
|
-
},
|
|
225
|
-
[subscribe, value, getSnapshot]
|
|
226
|
-
);
|
|
227
|
-
useEffect(
|
|
228
|
-
function () {
|
|
229
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
230
|
-
return subscribe(function () {
|
|
231
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
232
|
-
});
|
|
233
|
-
},
|
|
234
|
-
[subscribe]
|
|
235
|
-
);
|
|
236
|
-
useDebugValue(value);
|
|
237
|
-
return value;
|
|
238
|
-
}
|
|
239
|
-
function checkIfSnapshotChanged(inst) {
|
|
240
|
-
var latestGetSnapshot = inst.getSnapshot;
|
|
241
|
-
inst = inst.value;
|
|
242
|
-
try {
|
|
243
|
-
var nextValue = latestGetSnapshot();
|
|
244
|
-
return !objectIs(inst, nextValue);
|
|
245
|
-
} catch (error) {
|
|
246
|
-
return true;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
function useSyncExternalStore$1(subscribe, getSnapshot) {
|
|
250
|
-
return getSnapshot();
|
|
251
|
-
}
|
|
252
|
-
var shim =
|
|
253
|
-
"undefined" === typeof window ||
|
|
254
|
-
"undefined" === typeof window.document ||
|
|
255
|
-
"undefined" === typeof window.document.createElement
|
|
256
|
-
? useSyncExternalStore$1
|
|
257
|
-
: useSyncExternalStore$2;
|
|
258
|
-
useSyncExternalStoreShim_production.useSyncExternalStore =
|
|
259
|
-
void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim;
|
|
260
|
-
return useSyncExternalStoreShim_production;
|
|
261
|
-
}
|
|
296
|
+
const createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);
|
|
262
297
|
|
|
263
|
-
var useSyncExternalStoreShim_development = {};
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* @license React
|
|
267
|
-
* use-sync-external-store-shim.development.js
|
|
268
|
-
*
|
|
269
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
270
|
-
*
|
|
271
|
-
* This source code is licensed under the MIT license found in the
|
|
272
|
-
* LICENSE file in the root directory of this source tree.
|
|
273
|
-
*/
|
|
274
|
-
|
|
275
|
-
var hasRequiredUseSyncExternalStoreShim_development;
|
|
276
|
-
|
|
277
|
-
function requireUseSyncExternalStoreShim_development () {
|
|
278
|
-
if (hasRequiredUseSyncExternalStoreShim_development) return useSyncExternalStoreShim_development;
|
|
279
|
-
hasRequiredUseSyncExternalStoreShim_development = 1;
|
|
280
|
-
"production" !== process.env.NODE_ENV &&
|
|
281
|
-
(function () {
|
|
282
|
-
function is(x, y) {
|
|
283
|
-
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
|
284
|
-
}
|
|
285
|
-
function useSyncExternalStore$2(subscribe, getSnapshot) {
|
|
286
|
-
didWarnOld18Alpha ||
|
|
287
|
-
void 0 === React.startTransition ||
|
|
288
|
-
((didWarnOld18Alpha = true),
|
|
289
|
-
console.error(
|
|
290
|
-
"You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."
|
|
291
|
-
));
|
|
292
|
-
var value = getSnapshot();
|
|
293
|
-
if (!didWarnUncachedGetSnapshot) {
|
|
294
|
-
var cachedValue = getSnapshot();
|
|
295
|
-
objectIs(value, cachedValue) ||
|
|
296
|
-
(console.error(
|
|
297
|
-
"The result of getSnapshot should be cached to avoid an infinite loop"
|
|
298
|
-
),
|
|
299
|
-
(didWarnUncachedGetSnapshot = true));
|
|
300
|
-
}
|
|
301
|
-
cachedValue = useState({
|
|
302
|
-
inst: { value: value, getSnapshot: getSnapshot }
|
|
303
|
-
});
|
|
304
|
-
var inst = cachedValue[0].inst,
|
|
305
|
-
forceUpdate = cachedValue[1];
|
|
306
|
-
useLayoutEffect(
|
|
307
|
-
function () {
|
|
308
|
-
inst.value = value;
|
|
309
|
-
inst.getSnapshot = getSnapshot;
|
|
310
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
311
|
-
},
|
|
312
|
-
[subscribe, value, getSnapshot]
|
|
313
|
-
);
|
|
314
|
-
useEffect(
|
|
315
|
-
function () {
|
|
316
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
317
|
-
return subscribe(function () {
|
|
318
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
319
|
-
});
|
|
320
|
-
},
|
|
321
|
-
[subscribe]
|
|
322
|
-
);
|
|
323
|
-
useDebugValue(value);
|
|
324
|
-
return value;
|
|
325
|
-
}
|
|
326
|
-
function checkIfSnapshotChanged(inst) {
|
|
327
|
-
var latestGetSnapshot = inst.getSnapshot;
|
|
328
|
-
inst = inst.value;
|
|
329
|
-
try {
|
|
330
|
-
var nextValue = latestGetSnapshot();
|
|
331
|
-
return !objectIs(inst, nextValue);
|
|
332
|
-
} catch (error) {
|
|
333
|
-
return true;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
function useSyncExternalStore$1(subscribe, getSnapshot) {
|
|
337
|
-
return getSnapshot();
|
|
338
|
-
}
|
|
339
|
-
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
|
|
340
|
-
"function" ===
|
|
341
|
-
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&
|
|
342
|
-
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
343
|
-
var React = require$$0,
|
|
344
|
-
objectIs = "function" === typeof Object.is ? Object.is : is,
|
|
345
|
-
useState = React.useState,
|
|
346
|
-
useEffect = React.useEffect,
|
|
347
|
-
useLayoutEffect = React.useLayoutEffect,
|
|
348
|
-
useDebugValue = React.useDebugValue,
|
|
349
|
-
didWarnOld18Alpha = false,
|
|
350
|
-
didWarnUncachedGetSnapshot = false,
|
|
351
|
-
shim =
|
|
352
|
-
"undefined" === typeof window ||
|
|
353
|
-
"undefined" === typeof window.document ||
|
|
354
|
-
"undefined" === typeof window.document.createElement
|
|
355
|
-
? useSyncExternalStore$1
|
|
356
|
-
: useSyncExternalStore$2;
|
|
357
|
-
useSyncExternalStoreShim_development.useSyncExternalStore =
|
|
358
|
-
void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim;
|
|
359
|
-
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
|
|
360
|
-
"function" ===
|
|
361
|
-
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
|
|
362
|
-
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
363
|
-
})();
|
|
364
|
-
return useSyncExternalStoreShim_development;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
var hasRequiredShim;
|
|
368
|
-
|
|
369
|
-
function requireShim () {
|
|
370
|
-
if (hasRequiredShim) return shim.exports;
|
|
371
|
-
hasRequiredShim = 1;
|
|
372
|
-
|
|
373
|
-
if (process.env.NODE_ENV === 'production') {
|
|
374
|
-
shim.exports = requireUseSyncExternalStoreShim_production();
|
|
375
|
-
} else {
|
|
376
|
-
shim.exports = requireUseSyncExternalStoreShim_development();
|
|
377
|
-
}
|
|
378
|
-
return shim.exports;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* @license React
|
|
383
|
-
* use-sync-external-store-shim/with-selector.production.js
|
|
384
|
-
*
|
|
385
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
386
|
-
*
|
|
387
|
-
* This source code is licensed under the MIT license found in the
|
|
388
|
-
* LICENSE file in the root directory of this source tree.
|
|
389
|
-
*/
|
|
390
|
-
|
|
391
|
-
var hasRequiredWithSelector_production;
|
|
392
|
-
|
|
393
|
-
function requireWithSelector_production () {
|
|
394
|
-
if (hasRequiredWithSelector_production) return withSelector_production;
|
|
395
|
-
hasRequiredWithSelector_production = 1;
|
|
396
|
-
var React = require$$0,
|
|
397
|
-
shim = requireShim();
|
|
398
|
-
function is(x, y) {
|
|
399
|
-
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
|
400
|
-
}
|
|
401
|
-
var objectIs = "function" === typeof Object.is ? Object.is : is,
|
|
402
|
-
useSyncExternalStore = shim.useSyncExternalStore,
|
|
403
|
-
useRef = React.useRef,
|
|
404
|
-
useEffect = React.useEffect,
|
|
405
|
-
useMemo = React.useMemo,
|
|
406
|
-
useDebugValue = React.useDebugValue;
|
|
407
|
-
withSelector_production.useSyncExternalStoreWithSelector = function (
|
|
408
|
-
subscribe,
|
|
409
|
-
getSnapshot,
|
|
410
|
-
getServerSnapshot,
|
|
411
|
-
selector,
|
|
412
|
-
isEqual
|
|
413
|
-
) {
|
|
414
|
-
var instRef = useRef(null);
|
|
415
|
-
if (null === instRef.current) {
|
|
416
|
-
var inst = { hasValue: false, value: null };
|
|
417
|
-
instRef.current = inst;
|
|
418
|
-
} else inst = instRef.current;
|
|
419
|
-
instRef = useMemo(
|
|
420
|
-
function () {
|
|
421
|
-
function memoizedSelector(nextSnapshot) {
|
|
422
|
-
if (!hasMemo) {
|
|
423
|
-
hasMemo = true;
|
|
424
|
-
memoizedSnapshot = nextSnapshot;
|
|
425
|
-
nextSnapshot = selector(nextSnapshot);
|
|
426
|
-
if (void 0 !== isEqual && inst.hasValue) {
|
|
427
|
-
var currentSelection = inst.value;
|
|
428
|
-
if (isEqual(currentSelection, nextSnapshot))
|
|
429
|
-
return (memoizedSelection = currentSelection);
|
|
430
|
-
}
|
|
431
|
-
return (memoizedSelection = nextSnapshot);
|
|
432
|
-
}
|
|
433
|
-
currentSelection = memoizedSelection;
|
|
434
|
-
if (objectIs(memoizedSnapshot, nextSnapshot)) return currentSelection;
|
|
435
|
-
var nextSelection = selector(nextSnapshot);
|
|
436
|
-
if (void 0 !== isEqual && isEqual(currentSelection, nextSelection))
|
|
437
|
-
return (memoizedSnapshot = nextSnapshot), currentSelection;
|
|
438
|
-
memoizedSnapshot = nextSnapshot;
|
|
439
|
-
return (memoizedSelection = nextSelection);
|
|
440
|
-
}
|
|
441
|
-
var hasMemo = false,
|
|
442
|
-
memoizedSnapshot,
|
|
443
|
-
memoizedSelection,
|
|
444
|
-
maybeGetServerSnapshot =
|
|
445
|
-
void 0 === getServerSnapshot ? null : getServerSnapshot;
|
|
446
|
-
return [
|
|
447
|
-
function () {
|
|
448
|
-
return memoizedSelector(getSnapshot());
|
|
449
|
-
},
|
|
450
|
-
null === maybeGetServerSnapshot
|
|
451
|
-
? void 0
|
|
452
|
-
: function () {
|
|
453
|
-
return memoizedSelector(maybeGetServerSnapshot());
|
|
454
|
-
}
|
|
455
|
-
];
|
|
456
|
-
},
|
|
457
|
-
[getSnapshot, getServerSnapshot, selector, isEqual]
|
|
458
|
-
);
|
|
459
|
-
var value = useSyncExternalStore(subscribe, instRef[0], instRef[1]);
|
|
460
|
-
useEffect(
|
|
461
|
-
function () {
|
|
462
|
-
inst.hasValue = true;
|
|
463
|
-
inst.value = value;
|
|
464
|
-
},
|
|
465
|
-
[value]
|
|
466
|
-
);
|
|
467
|
-
useDebugValue(value);
|
|
468
|
-
return value;
|
|
469
|
-
};
|
|
470
|
-
return withSelector_production;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
var withSelector_development = {};
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* @license React
|
|
477
|
-
* use-sync-external-store-shim/with-selector.development.js
|
|
478
|
-
*
|
|
479
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
480
|
-
*
|
|
481
|
-
* This source code is licensed under the MIT license found in the
|
|
482
|
-
* LICENSE file in the root directory of this source tree.
|
|
483
|
-
*/
|
|
484
|
-
|
|
485
|
-
var hasRequiredWithSelector_development;
|
|
486
|
-
|
|
487
|
-
function requireWithSelector_development () {
|
|
488
|
-
if (hasRequiredWithSelector_development) return withSelector_development;
|
|
489
|
-
hasRequiredWithSelector_development = 1;
|
|
490
|
-
"production" !== process.env.NODE_ENV &&
|
|
491
|
-
(function () {
|
|
492
|
-
function is(x, y) {
|
|
493
|
-
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
|
494
|
-
}
|
|
495
|
-
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
|
|
496
|
-
"function" ===
|
|
497
|
-
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&
|
|
498
|
-
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
499
|
-
var React = require$$0,
|
|
500
|
-
shim = requireShim(),
|
|
501
|
-
objectIs = "function" === typeof Object.is ? Object.is : is,
|
|
502
|
-
useSyncExternalStore = shim.useSyncExternalStore,
|
|
503
|
-
useRef = React.useRef,
|
|
504
|
-
useEffect = React.useEffect,
|
|
505
|
-
useMemo = React.useMemo,
|
|
506
|
-
useDebugValue = React.useDebugValue;
|
|
507
|
-
withSelector_development.useSyncExternalStoreWithSelector = function (
|
|
508
|
-
subscribe,
|
|
509
|
-
getSnapshot,
|
|
510
|
-
getServerSnapshot,
|
|
511
|
-
selector,
|
|
512
|
-
isEqual
|
|
513
|
-
) {
|
|
514
|
-
var instRef = useRef(null);
|
|
515
|
-
if (null === instRef.current) {
|
|
516
|
-
var inst = { hasValue: false, value: null };
|
|
517
|
-
instRef.current = inst;
|
|
518
|
-
} else inst = instRef.current;
|
|
519
|
-
instRef = useMemo(
|
|
520
|
-
function () {
|
|
521
|
-
function memoizedSelector(nextSnapshot) {
|
|
522
|
-
if (!hasMemo) {
|
|
523
|
-
hasMemo = true;
|
|
524
|
-
memoizedSnapshot = nextSnapshot;
|
|
525
|
-
nextSnapshot = selector(nextSnapshot);
|
|
526
|
-
if (void 0 !== isEqual && inst.hasValue) {
|
|
527
|
-
var currentSelection = inst.value;
|
|
528
|
-
if (isEqual(currentSelection, nextSnapshot))
|
|
529
|
-
return (memoizedSelection = currentSelection);
|
|
530
|
-
}
|
|
531
|
-
return (memoizedSelection = nextSnapshot);
|
|
532
|
-
}
|
|
533
|
-
currentSelection = memoizedSelection;
|
|
534
|
-
if (objectIs(memoizedSnapshot, nextSnapshot))
|
|
535
|
-
return currentSelection;
|
|
536
|
-
var nextSelection = selector(nextSnapshot);
|
|
537
|
-
if (void 0 !== isEqual && isEqual(currentSelection, nextSelection))
|
|
538
|
-
return (memoizedSnapshot = nextSnapshot), currentSelection;
|
|
539
|
-
memoizedSnapshot = nextSnapshot;
|
|
540
|
-
return (memoizedSelection = nextSelection);
|
|
541
|
-
}
|
|
542
|
-
var hasMemo = false,
|
|
543
|
-
memoizedSnapshot,
|
|
544
|
-
memoizedSelection,
|
|
545
|
-
maybeGetServerSnapshot =
|
|
546
|
-
void 0 === getServerSnapshot ? null : getServerSnapshot;
|
|
547
|
-
return [
|
|
548
|
-
function () {
|
|
549
|
-
return memoizedSelector(getSnapshot());
|
|
550
|
-
},
|
|
551
|
-
null === maybeGetServerSnapshot
|
|
552
|
-
? void 0
|
|
553
|
-
: function () {
|
|
554
|
-
return memoizedSelector(maybeGetServerSnapshot());
|
|
555
|
-
}
|
|
556
|
-
];
|
|
557
|
-
},
|
|
558
|
-
[getSnapshot, getServerSnapshot, selector, isEqual]
|
|
559
|
-
);
|
|
560
|
-
var value = useSyncExternalStore(subscribe, instRef[0], instRef[1]);
|
|
561
|
-
useEffect(
|
|
562
|
-
function () {
|
|
563
|
-
inst.hasValue = true;
|
|
564
|
-
inst.value = value;
|
|
565
|
-
},
|
|
566
|
-
[value]
|
|
567
|
-
);
|
|
568
|
-
useDebugValue(value);
|
|
569
|
-
return value;
|
|
570
|
-
};
|
|
571
|
-
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
|
|
572
|
-
"function" ===
|
|
573
|
-
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
|
|
574
|
-
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
575
|
-
})();
|
|
576
|
-
return withSelector_development;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
if (process.env.NODE_ENV === 'production') {
|
|
580
|
-
withSelector.exports = requireWithSelector_production();
|
|
581
|
-
} else {
|
|
582
|
-
withSelector.exports = requireWithSelector_development();
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
var withSelectorExports = withSelector.exports;
|
|
586
|
-
var useSyncExternalStoreExports = /*@__PURE__*/getDefaultExportFromCjs(withSelectorExports);
|
|
587
|
-
|
|
588
|
-
const { useDebugValue } = require$$0;
|
|
589
|
-
const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports;
|
|
590
|
-
let didWarnAboutEqualityFn = false;
|
|
591
298
|
const identity = (arg) => arg;
|
|
592
|
-
function useStore(api, selector = identity
|
|
593
|
-
|
|
594
|
-
console.warn(
|
|
595
|
-
"[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"
|
|
596
|
-
);
|
|
597
|
-
didWarnAboutEqualityFn = true;
|
|
598
|
-
}
|
|
599
|
-
const slice = useSyncExternalStoreWithSelector(
|
|
299
|
+
function useStore(api, selector = identity) {
|
|
300
|
+
const slice = React$1.useSyncExternalStore(
|
|
600
301
|
api.subscribe,
|
|
601
|
-
api.getState,
|
|
602
|
-
|
|
603
|
-
selector,
|
|
604
|
-
equalityFn
|
|
302
|
+
React$1.useCallback(() => selector(api.getState()), [api, selector]),
|
|
303
|
+
React$1.useCallback(() => selector(api.getInitialState()), [api, selector])
|
|
605
304
|
);
|
|
606
|
-
useDebugValue(slice);
|
|
305
|
+
React$1.useDebugValue(slice);
|
|
607
306
|
return slice;
|
|
608
307
|
}
|
|
609
308
|
const createImpl = (createState) => {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
"[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`."
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
|
-
const api = typeof createState === "function" ? createStore(createState) : createState;
|
|
616
|
-
const useBoundStore = (selector, equalityFn) => useStore(api, selector, equalityFn);
|
|
309
|
+
const api = createStore(createState);
|
|
310
|
+
const useBoundStore = (selector) => useStore(api, selector);
|
|
617
311
|
Object.assign(useBoundStore, api);
|
|
618
312
|
return useBoundStore;
|
|
619
313
|
};
|
|
620
|
-
const create = (createState) => createState ? createImpl(createState) : createImpl;
|
|
314
|
+
const create = ((createState) => createState ? createImpl(createState) : createImpl);
|
|
621
315
|
|
|
622
316
|
// Estado: { user, loading, error }
|
|
623
317
|
const useAuthStore = create((set, get) => ({
|
|
624
318
|
user: null,
|
|
625
319
|
loading: true,
|
|
626
320
|
error: null,
|
|
321
|
+
// Loading states granulares
|
|
322
|
+
loadingStates: {
|
|
323
|
+
signIn: false,
|
|
324
|
+
signUp: false,
|
|
325
|
+
signOut: false,
|
|
326
|
+
magicLink: false,
|
|
327
|
+
verifyMagicLink: false,
|
|
328
|
+
resetPassword: false,
|
|
329
|
+
verifyEmail: false,
|
|
330
|
+
resendVerification: false
|
|
331
|
+
},
|
|
332
|
+
// Helper para atualizar loading states
|
|
333
|
+
setLoading: (key, value) => set(state => ({
|
|
334
|
+
loadingStates: {
|
|
335
|
+
...state.loadingStates,
|
|
336
|
+
[key]: value
|
|
337
|
+
}
|
|
338
|
+
})),
|
|
627
339
|
/* Init ao montar o Provider */
|
|
628
340
|
init: async () => {
|
|
629
341
|
try {
|
|
630
|
-
// Verifica se há um token válido
|
|
342
|
+
// Verifica se há um token válido
|
|
631
343
|
if (isAuthenticated()) {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
344
|
+
// Tenta extrair usuário do token (JWT)
|
|
345
|
+
let user = getCurrentUser();
|
|
346
|
+
|
|
347
|
+
// Se o token for opaco (não-JWT), getCurrentUser retorna null.
|
|
348
|
+
// Precisamos buscar a sessão no servidor.
|
|
349
|
+
if (!user) {
|
|
350
|
+
try {
|
|
351
|
+
const session = await getSession();
|
|
352
|
+
if (session?.user) {
|
|
353
|
+
user = session.user;
|
|
354
|
+
}
|
|
355
|
+
} catch (sessionError) {
|
|
356
|
+
console.warn('[AuthStore] Failed to fetch session:', sessionError);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if (user) {
|
|
360
|
+
set({
|
|
361
|
+
user,
|
|
362
|
+
loading: false
|
|
363
|
+
});
|
|
364
|
+
} else {
|
|
365
|
+
set({
|
|
366
|
+
user: null,
|
|
367
|
+
loading: false
|
|
368
|
+
});
|
|
369
|
+
}
|
|
637
370
|
} else {
|
|
638
371
|
set({
|
|
639
372
|
user: null,
|
|
@@ -648,57 +381,237 @@ const useAuthStore = create((set, get) => ({
|
|
|
648
381
|
});
|
|
649
382
|
}
|
|
650
383
|
},
|
|
651
|
-
/* Ações */
|
|
652
|
-
signUp: async (email, password) => {
|
|
384
|
+
/* Ações de Autenticação */
|
|
385
|
+
signUp: async (email, password, name) => {
|
|
386
|
+
const {
|
|
387
|
+
setLoading
|
|
388
|
+
} = get();
|
|
389
|
+
setLoading('signUp', true);
|
|
653
390
|
set({
|
|
654
|
-
loading: true,
|
|
655
391
|
error: null
|
|
656
392
|
});
|
|
657
393
|
try {
|
|
658
|
-
const result = await signUp(email, password);
|
|
394
|
+
const result = await signUp(email, password, name);
|
|
659
395
|
const user = getCurrentUser();
|
|
660
396
|
set({
|
|
661
397
|
user,
|
|
662
398
|
loading: false
|
|
663
399
|
});
|
|
400
|
+
setLoading('signUp', false);
|
|
664
401
|
return result;
|
|
665
402
|
} catch (err) {
|
|
666
403
|
set({
|
|
667
|
-
error: err
|
|
668
|
-
loading: false
|
|
404
|
+
error: err
|
|
669
405
|
});
|
|
406
|
+
setLoading('signUp', false);
|
|
670
407
|
throw err;
|
|
671
408
|
}
|
|
672
409
|
},
|
|
673
410
|
signIn: async (email, password) => {
|
|
411
|
+
const {
|
|
412
|
+
setLoading
|
|
413
|
+
} = get();
|
|
414
|
+
setLoading('signIn', true);
|
|
674
415
|
set({
|
|
675
|
-
loading: true,
|
|
676
416
|
error: null
|
|
677
417
|
});
|
|
678
418
|
try {
|
|
679
419
|
const result = await signIn(email, password);
|
|
680
|
-
|
|
420
|
+
|
|
421
|
+
// Tenta obter usuário do token (se JWT)
|
|
422
|
+
let user = getCurrentUser();
|
|
423
|
+
|
|
424
|
+
// Se não encontrou no token (sessão opaca), busca do servidor
|
|
425
|
+
if (!user) {
|
|
426
|
+
const session = await getSession();
|
|
427
|
+
if (session?.user) user = session.user;
|
|
428
|
+
}
|
|
681
429
|
set({
|
|
682
430
|
user,
|
|
683
431
|
loading: false
|
|
684
432
|
});
|
|
433
|
+
setLoading('signIn', false);
|
|
685
434
|
return result;
|
|
686
435
|
} catch (err) {
|
|
687
436
|
set({
|
|
688
|
-
error: err
|
|
689
|
-
loading: false
|
|
437
|
+
error: err
|
|
690
438
|
});
|
|
439
|
+
setLoading('signIn', false);
|
|
691
440
|
throw err;
|
|
692
441
|
}
|
|
693
442
|
},
|
|
694
443
|
signOut: async () => {
|
|
695
|
-
|
|
444
|
+
const {
|
|
445
|
+
setLoading
|
|
446
|
+
} = get();
|
|
447
|
+
setLoading('signOut', true);
|
|
448
|
+
try {
|
|
449
|
+
await signOut();
|
|
450
|
+
set({
|
|
451
|
+
user: null
|
|
452
|
+
});
|
|
453
|
+
// Sincronizar logout entre abas
|
|
454
|
+
if (typeof window !== 'undefined') {
|
|
455
|
+
window.localStorage.setItem('auth:logout', Date.now());
|
|
456
|
+
}
|
|
457
|
+
} finally {
|
|
458
|
+
setLoading('signOut', false);
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
/* Magic Link */
|
|
462
|
+
sendMagicLink: async (email, callbackURL) => {
|
|
463
|
+
const {
|
|
464
|
+
setLoading
|
|
465
|
+
} = get();
|
|
466
|
+
setLoading('magicLink', true);
|
|
696
467
|
set({
|
|
697
|
-
|
|
468
|
+
error: null
|
|
698
469
|
});
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
470
|
+
try {
|
|
471
|
+
const result = await sendMagicLink(email, callbackURL);
|
|
472
|
+
setLoading('magicLink', false);
|
|
473
|
+
return result;
|
|
474
|
+
} catch (err) {
|
|
475
|
+
set({
|
|
476
|
+
error: err
|
|
477
|
+
});
|
|
478
|
+
setLoading('magicLink', false);
|
|
479
|
+
throw err;
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
verifyMagicLink: async token => {
|
|
483
|
+
const {
|
|
484
|
+
setLoading
|
|
485
|
+
} = get();
|
|
486
|
+
setLoading('verifyMagicLink', true);
|
|
487
|
+
set({
|
|
488
|
+
error: null
|
|
489
|
+
});
|
|
490
|
+
try {
|
|
491
|
+
const result = await verifyMagicLink(token);
|
|
492
|
+
let user = result.user;
|
|
493
|
+
|
|
494
|
+
// Se não veio no resultado, tenta pegar do token ou do servidor
|
|
495
|
+
if (!user) {
|
|
496
|
+
user = getCurrentUser();
|
|
497
|
+
if (!user) {
|
|
498
|
+
const session = await getSession();
|
|
499
|
+
if (session?.user) user = session.user;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
if (user) {
|
|
503
|
+
set({
|
|
504
|
+
user,
|
|
505
|
+
loading: false
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
setLoading('verifyMagicLink', false);
|
|
509
|
+
return result;
|
|
510
|
+
} catch (err) {
|
|
511
|
+
set({
|
|
512
|
+
error: err
|
|
513
|
+
});
|
|
514
|
+
setLoading('verifyMagicLink', false);
|
|
515
|
+
throw err;
|
|
516
|
+
}
|
|
517
|
+
},
|
|
518
|
+
/* Password Reset */
|
|
519
|
+
forgotPassword: async (email, redirectTo) => {
|
|
520
|
+
const {
|
|
521
|
+
setLoading
|
|
522
|
+
} = get();
|
|
523
|
+
setLoading('resetPassword', true);
|
|
524
|
+
set({
|
|
525
|
+
error: null
|
|
526
|
+
});
|
|
527
|
+
try {
|
|
528
|
+
const result = await forgotPassword(email, redirectTo);
|
|
529
|
+
setLoading('resetPassword', false);
|
|
530
|
+
return result;
|
|
531
|
+
} catch (err) {
|
|
532
|
+
set({
|
|
533
|
+
error: err
|
|
534
|
+
});
|
|
535
|
+
setLoading('resetPassword', false);
|
|
536
|
+
throw err;
|
|
537
|
+
}
|
|
538
|
+
},
|
|
539
|
+
resetPassword: async (token, newPassword) => {
|
|
540
|
+
const {
|
|
541
|
+
setLoading
|
|
542
|
+
} = get();
|
|
543
|
+
setLoading('resetPassword', true);
|
|
544
|
+
set({
|
|
545
|
+
error: null
|
|
546
|
+
});
|
|
547
|
+
try {
|
|
548
|
+
const result = await resetPassword(token, newPassword);
|
|
549
|
+
setLoading('resetPassword', false);
|
|
550
|
+
return result;
|
|
551
|
+
} catch (err) {
|
|
552
|
+
set({
|
|
553
|
+
error: err
|
|
554
|
+
});
|
|
555
|
+
setLoading('resetPassword', false);
|
|
556
|
+
throw err;
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
/* Email Verification */
|
|
560
|
+
verifyEmail: async token => {
|
|
561
|
+
const {
|
|
562
|
+
setLoading
|
|
563
|
+
} = get();
|
|
564
|
+
setLoading('verifyEmail', true);
|
|
565
|
+
set({
|
|
566
|
+
error: null
|
|
567
|
+
});
|
|
568
|
+
try {
|
|
569
|
+
const result = await verifyEmail(token);
|
|
570
|
+
if (result.user) {
|
|
571
|
+
set({
|
|
572
|
+
user: result.user,
|
|
573
|
+
loading: false
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
setLoading('verifyEmail', false);
|
|
577
|
+
return result;
|
|
578
|
+
} catch (err) {
|
|
579
|
+
set({
|
|
580
|
+
error: err
|
|
581
|
+
});
|
|
582
|
+
setLoading('verifyEmail', false);
|
|
583
|
+
throw err;
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
resendVerification: async (email, callbackURL) => {
|
|
587
|
+
const {
|
|
588
|
+
setLoading
|
|
589
|
+
} = get();
|
|
590
|
+
setLoading('resendVerification', true);
|
|
591
|
+
set({
|
|
592
|
+
error: null
|
|
593
|
+
});
|
|
594
|
+
try {
|
|
595
|
+
const result = await resendVerification(email, callbackURL);
|
|
596
|
+
setLoading('resendVerification', false);
|
|
597
|
+
return result;
|
|
598
|
+
} catch (err) {
|
|
599
|
+
set({
|
|
600
|
+
error: err
|
|
601
|
+
});
|
|
602
|
+
setLoading('resendVerification', false);
|
|
603
|
+
throw err;
|
|
604
|
+
}
|
|
605
|
+
},
|
|
606
|
+
/* Session */
|
|
607
|
+
getSession: async () => {
|
|
608
|
+
try {
|
|
609
|
+
return await getSession();
|
|
610
|
+
} catch (err) {
|
|
611
|
+
set({
|
|
612
|
+
error: err
|
|
613
|
+
});
|
|
614
|
+
throw err;
|
|
702
615
|
}
|
|
703
616
|
},
|
|
704
617
|
/* Refresh do token em background */
|
|
@@ -711,7 +624,10 @@ const useAuthStore = create((set, get) => ({
|
|
|
711
624
|
const token = window.localStorage.getItem('auth:token');
|
|
712
625
|
if (token) {
|
|
713
626
|
// Decodifica o token para verificar tempo de expiração
|
|
714
|
-
const
|
|
627
|
+
const base64Url = token.split('.')[1];
|
|
628
|
+
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
629
|
+
const jsonPayload = window.atob(base64);
|
|
630
|
+
const payload = JSON.parse(jsonPayload);
|
|
715
631
|
const now = Date.now() / 1000;
|
|
716
632
|
const timeUntilExpiry = payload.exp - now;
|
|
717
633
|
|
|
@@ -752,24 +668,110 @@ const useAuthStore = create((set, get) => ({
|
|
|
752
668
|
return false;
|
|
753
669
|
}
|
|
754
670
|
return true;
|
|
755
|
-
}
|
|
671
|
+
},
|
|
672
|
+
/* Atualizar usuário manualmente */
|
|
673
|
+
setUser: user => set({
|
|
674
|
+
user
|
|
675
|
+
})
|
|
756
676
|
}));
|
|
757
677
|
|
|
758
|
-
const
|
|
678
|
+
const isIterable = (obj) => Symbol.iterator in obj;
|
|
679
|
+
const hasIterableEntries = (value) => (
|
|
680
|
+
// HACK: avoid checking entries type
|
|
681
|
+
"entries" in value
|
|
682
|
+
);
|
|
683
|
+
const compareEntries = (valueA, valueB) => {
|
|
684
|
+
const mapA = valueA instanceof Map ? valueA : new Map(valueA.entries());
|
|
685
|
+
const mapB = valueB instanceof Map ? valueB : new Map(valueB.entries());
|
|
686
|
+
if (mapA.size !== mapB.size) {
|
|
687
|
+
return false;
|
|
688
|
+
}
|
|
689
|
+
for (const [key, value] of mapA) {
|
|
690
|
+
if (!mapB.has(key) || !Object.is(value, mapB.get(key))) {
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
return true;
|
|
695
|
+
};
|
|
696
|
+
const compareIterables = (valueA, valueB) => {
|
|
697
|
+
const iteratorA = valueA[Symbol.iterator]();
|
|
698
|
+
const iteratorB = valueB[Symbol.iterator]();
|
|
699
|
+
let nextA = iteratorA.next();
|
|
700
|
+
let nextB = iteratorB.next();
|
|
701
|
+
while (!nextA.done && !nextB.done) {
|
|
702
|
+
if (!Object.is(nextA.value, nextB.value)) {
|
|
703
|
+
return false;
|
|
704
|
+
}
|
|
705
|
+
nextA = iteratorA.next();
|
|
706
|
+
nextB = iteratorB.next();
|
|
707
|
+
}
|
|
708
|
+
return !!nextA.done && !!nextB.done;
|
|
709
|
+
};
|
|
710
|
+
function shallow(valueA, valueB) {
|
|
711
|
+
if (Object.is(valueA, valueB)) {
|
|
712
|
+
return true;
|
|
713
|
+
}
|
|
714
|
+
if (typeof valueA !== "object" || valueA === null || typeof valueB !== "object" || valueB === null) {
|
|
715
|
+
return false;
|
|
716
|
+
}
|
|
717
|
+
if (Object.getPrototypeOf(valueA) !== Object.getPrototypeOf(valueB)) {
|
|
718
|
+
return false;
|
|
719
|
+
}
|
|
720
|
+
if (isIterable(valueA) && isIterable(valueB)) {
|
|
721
|
+
if (hasIterableEntries(valueA) && hasIterableEntries(valueB)) {
|
|
722
|
+
return compareEntries(valueA, valueB);
|
|
723
|
+
}
|
|
724
|
+
return compareIterables(valueA, valueB);
|
|
725
|
+
}
|
|
726
|
+
return compareEntries(
|
|
727
|
+
{ entries: () => Object.entries(valueA) },
|
|
728
|
+
{ entries: () => Object.entries(valueB) }
|
|
729
|
+
);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
function useShallow(selector) {
|
|
733
|
+
const prev = React$1.useRef(void 0);
|
|
734
|
+
return (state) => {
|
|
735
|
+
const next = selector(state);
|
|
736
|
+
return shallow(prev.current, next) ? prev.current : prev.current = next;
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
const AuthContext = /*#__PURE__*/React$1.createContext(); // só para ter o Provider em JSX
|
|
759
741
|
|
|
760
742
|
function AuthProvider({
|
|
761
|
-
children
|
|
743
|
+
children,
|
|
744
|
+
apiUrl,
|
|
745
|
+
// URL base da API (OBRIGATÓRIA)
|
|
746
|
+
apiKey,
|
|
747
|
+
// API Key para header X-API-Key (OBRIGATÓRIA)
|
|
748
|
+
onError // Callback de erro global
|
|
762
749
|
}) {
|
|
750
|
+
// Validação de props obrigatórias
|
|
751
|
+
if (!apiKey) {
|
|
752
|
+
throw new Error('[@riligar/auth-react] apiKey é obrigatória no AuthProvider. ' + 'Obtenha sua API Key no dashboard em https://dashboard.myauth.click');
|
|
753
|
+
}
|
|
754
|
+
if (!apiUrl) {
|
|
755
|
+
throw new Error('[@riligar/auth-react] apiUrl é obrigatória no AuthProvider. ' + 'Use a URL do seu servidor de autenticação.');
|
|
756
|
+
}
|
|
763
757
|
const init = useAuthStore(s => s.init);
|
|
764
758
|
const startRefresh = useAuthStore(s => s.startRefresh);
|
|
765
759
|
const checkTokenValidity = useAuthStore(s => s.checkTokenValidity);
|
|
766
|
-
|
|
760
|
+
|
|
761
|
+
// Configura SDK com apiUrl e apiKey
|
|
762
|
+
React$1.useEffect(() => {
|
|
763
|
+
configure({
|
|
764
|
+
apiUrl,
|
|
765
|
+
apiKey
|
|
766
|
+
});
|
|
767
|
+
}, [apiUrl, apiKey]);
|
|
768
|
+
React$1.useEffect(() => {
|
|
767
769
|
init();
|
|
768
770
|
startRefresh();
|
|
769
771
|
}, [init, startRefresh]);
|
|
770
772
|
|
|
771
773
|
// Sincronização entre abas - escuta logout e mudanças no token
|
|
772
|
-
|
|
774
|
+
React$1.useEffect(() => {
|
|
773
775
|
if (typeof window === 'undefined') return;
|
|
774
776
|
const handleStorageChange = event => {
|
|
775
777
|
if (event.key === 'auth:logout') {
|
|
@@ -785,7 +787,7 @@ function AuthProvider({
|
|
|
785
787
|
}, [checkTokenValidity]);
|
|
786
788
|
|
|
787
789
|
// Verifica validade do token periodicamente
|
|
788
|
-
|
|
790
|
+
React$1.useEffect(() => {
|
|
789
791
|
if (typeof window === 'undefined') return;
|
|
790
792
|
const interval = setInterval(() => {
|
|
791
793
|
checkTokenValidity();
|
|
@@ -793,23 +795,66 @@ function AuthProvider({
|
|
|
793
795
|
|
|
794
796
|
return () => clearInterval(interval);
|
|
795
797
|
}, [checkTokenValidity]);
|
|
798
|
+
|
|
799
|
+
// Contexto com onError callback
|
|
800
|
+
const contextValue = React$1.useMemo(() => ({
|
|
801
|
+
onError
|
|
802
|
+
}), [onError]);
|
|
796
803
|
return /*#__PURE__*/React.createElement(AuthContext.Provider, {
|
|
797
|
-
value:
|
|
804
|
+
value: contextValue
|
|
798
805
|
}, children);
|
|
799
806
|
}
|
|
800
807
|
|
|
801
808
|
/* Hooks "facade" que a app vai usar */
|
|
802
|
-
const useAuth = () => useAuthStore(s => ({
|
|
809
|
+
const useAuth = () => useAuthStore(useShallow(s => ({
|
|
803
810
|
user: s.user,
|
|
804
811
|
loading: s.loading,
|
|
805
812
|
error: s.error,
|
|
806
813
|
isAuthenticated: s.user !== null
|
|
807
|
-
}));
|
|
814
|
+
})));
|
|
815
|
+
|
|
816
|
+
// Auth Actions
|
|
808
817
|
const useSignIn = () => useAuthStore(s => s.signIn);
|
|
809
818
|
const useSignUp = () => useAuthStore(s => s.signUp);
|
|
810
819
|
const useSignOut = () => useAuthStore(s => s.signOut);
|
|
811
820
|
const useCheckToken = () => useAuthStore(s => s.checkTokenValidity);
|
|
812
821
|
|
|
822
|
+
// Magic Link Hook
|
|
823
|
+
const useMagicLink = () => useAuthStore(useShallow(s => ({
|
|
824
|
+
sendMagicLink: s.sendMagicLink,
|
|
825
|
+
verifyMagicLink: s.verifyMagicLink,
|
|
826
|
+
loading: s.loadingStates.magicLink,
|
|
827
|
+
verifying: s.loadingStates.verifyMagicLink,
|
|
828
|
+
error: s.error
|
|
829
|
+
})));
|
|
830
|
+
|
|
831
|
+
// Password Reset Hook
|
|
832
|
+
const usePasswordReset = () => useAuthStore(useShallow(s => ({
|
|
833
|
+
forgotPassword: s.forgotPassword,
|
|
834
|
+
resetPassword: s.resetPassword,
|
|
835
|
+
loading: s.loadingStates.resetPassword,
|
|
836
|
+
error: s.error
|
|
837
|
+
})));
|
|
838
|
+
|
|
839
|
+
// Email Verification Hook
|
|
840
|
+
const useEmailVerification = () => useAuthStore(useShallow(s => ({
|
|
841
|
+
verifyEmail: s.verifyEmail,
|
|
842
|
+
resendVerification: s.resendVerification,
|
|
843
|
+
loading: s.loadingStates.verifyEmail,
|
|
844
|
+
resending: s.loadingStates.resendVerification,
|
|
845
|
+
error: s.error
|
|
846
|
+
})));
|
|
847
|
+
|
|
848
|
+
// Session Hook
|
|
849
|
+
const useSession = () => useAuthStore(useShallow(s => ({
|
|
850
|
+
getSession: s.getSession,
|
|
851
|
+
user: s.user,
|
|
852
|
+
setUser: s.setUser
|
|
853
|
+
})));
|
|
854
|
+
|
|
855
|
+
// Loading States Hook
|
|
856
|
+
const useAuthLoading = () => useAuthStore(s => s.loadingStates);
|
|
857
|
+
|
|
813
858
|
function ProtectedRoute({
|
|
814
859
|
fallback = /*#__PURE__*/React.createElement("p", null, "\u231B Carregando..."),
|
|
815
860
|
redirectTo = "/login"
|
|
@@ -826,19 +871,822 @@ function ProtectedRoute({
|
|
|
826
871
|
return /*#__PURE__*/React.createElement(reactRouterDom.Outlet, null);
|
|
827
872
|
}
|
|
828
873
|
|
|
874
|
+
function _extends() {
|
|
875
|
+
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
876
|
+
for (var e = 1; e < arguments.length; e++) {
|
|
877
|
+
var t = arguments[e];
|
|
878
|
+
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
|
|
879
|
+
}
|
|
880
|
+
return n;
|
|
881
|
+
}, _extends.apply(null, arguments);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Container wrapper para componentes de autenticação
|
|
886
|
+
* Usa Mantine Paper com estilo consistente
|
|
887
|
+
*/
|
|
888
|
+
function AuthCard({
|
|
889
|
+
children,
|
|
890
|
+
title,
|
|
891
|
+
subtitle,
|
|
892
|
+
logo,
|
|
893
|
+
logoHeight = 32,
|
|
894
|
+
width = 350,
|
|
895
|
+
...props
|
|
896
|
+
}) {
|
|
897
|
+
return /*#__PURE__*/React.createElement(core.Paper, _extends({
|
|
898
|
+
withBorder: true,
|
|
899
|
+
shadow: "md",
|
|
900
|
+
p: 24,
|
|
901
|
+
w: width,
|
|
902
|
+
radius: "md"
|
|
903
|
+
}, props), /*#__PURE__*/React.createElement(core.Stack, {
|
|
904
|
+
gap: "sm"
|
|
905
|
+
}, (logo || title || subtitle) && /*#__PURE__*/React.createElement(core.Stack, {
|
|
906
|
+
gap: "xs"
|
|
907
|
+
}, logo && /*#__PURE__*/React.createElement(core.Image, {
|
|
908
|
+
src: logo,
|
|
909
|
+
alt: "Auth",
|
|
910
|
+
h: logoHeight,
|
|
911
|
+
fit: "contain"
|
|
912
|
+
}), title && /*#__PURE__*/React.createElement(core.Title, {
|
|
913
|
+
order: 3
|
|
914
|
+
}, title), subtitle && /*#__PURE__*/React.createElement(core.Text, {
|
|
915
|
+
size: "sm",
|
|
916
|
+
c: "dimmed"
|
|
917
|
+
}, subtitle)), children));
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
var img = "data:image/webp;base64,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";
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* Formulário de Sign In completo com Mantine
|
|
924
|
+
* Suporta email/password, magic link, social login
|
|
925
|
+
*/
|
|
926
|
+
function SignInForm({
|
|
927
|
+
// Configuração
|
|
928
|
+
logo = img,
|
|
929
|
+
title = 'Entrar',
|
|
930
|
+
subtitle = 'Acesse sua conta para continuar',
|
|
931
|
+
// Features
|
|
932
|
+
showMagicLink = true,
|
|
933
|
+
showForgotPassword = true,
|
|
934
|
+
showSocialLogin = false,
|
|
935
|
+
showSignUpLink = true,
|
|
936
|
+
// Links
|
|
937
|
+
signUpUrl = '/auth/signup',
|
|
938
|
+
// Callbacks
|
|
939
|
+
onSuccess,
|
|
940
|
+
onError,
|
|
941
|
+
onMagicLinkSent,
|
|
942
|
+
onForgotPasswordSent,
|
|
943
|
+
onSocialLogin,
|
|
944
|
+
// Custom labels
|
|
945
|
+
labels = {},
|
|
946
|
+
...cardProps
|
|
947
|
+
}) {
|
|
948
|
+
const signIn = useAuthStore(s => s.signIn);
|
|
949
|
+
const sendMagicLink = useAuthStore(s => s.sendMagicLink);
|
|
950
|
+
const forgotPassword = useAuthStore(s => s.forgotPassword);
|
|
951
|
+
const loadingSignIn = useAuthStore(s => s.loadingStates.signIn);
|
|
952
|
+
const loadingMagicLink = useAuthStore(s => s.loadingStates.magicLink);
|
|
953
|
+
const loadingResetPassword = useAuthStore(s => s.loadingStates.resetPassword);
|
|
954
|
+
const form$1 = form.useForm({
|
|
955
|
+
initialValues: {
|
|
956
|
+
email: '',
|
|
957
|
+
password: ''
|
|
958
|
+
},
|
|
959
|
+
validate: {
|
|
960
|
+
email: value => /^\S+@\S+$/.test(value) ? null : labels.invalidEmail || 'Email inválido',
|
|
961
|
+
password: value => value.length < 6 ? labels.passwordTooShort || 'A senha deve ter pelo menos 6 caracteres' : null
|
|
962
|
+
}
|
|
963
|
+
});
|
|
964
|
+
const handleSubmit = async values => {
|
|
965
|
+
try {
|
|
966
|
+
const result = await signIn(values.email, values.password);
|
|
967
|
+
onSuccess?.(result);
|
|
968
|
+
} catch (error) {
|
|
969
|
+
onError?.(error);
|
|
970
|
+
}
|
|
971
|
+
};
|
|
972
|
+
const handleMagicLink = async () => {
|
|
973
|
+
if (!form$1.values.email) {
|
|
974
|
+
form$1.setFieldError('email', labels.emailRequired || 'Email obrigatório');
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
try {
|
|
978
|
+
await sendMagicLink(form$1.values.email);
|
|
979
|
+
onMagicLinkSent?.(form$1.values.email);
|
|
980
|
+
} catch (error) {
|
|
981
|
+
onError?.(error);
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
const handleForgotPassword = async () => {
|
|
985
|
+
if (!form$1.values.email) {
|
|
986
|
+
form$1.setFieldError('email', labels.emailRequired || 'Email obrigatório');
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
try {
|
|
990
|
+
await forgotPassword(form$1.values.email);
|
|
991
|
+
onForgotPasswordSent?.(form$1.values.email);
|
|
992
|
+
} catch (error) {
|
|
993
|
+
onError?.(error);
|
|
994
|
+
}
|
|
995
|
+
};
|
|
996
|
+
const isLoading = loadingSignIn || loadingMagicLink || loadingResetPassword;
|
|
997
|
+
return /*#__PURE__*/React.createElement(AuthCard, _extends({
|
|
998
|
+
logo: logo,
|
|
999
|
+
title: title,
|
|
1000
|
+
subtitle: subtitle
|
|
1001
|
+
}, cardProps), /*#__PURE__*/React.createElement("form", {
|
|
1002
|
+
onSubmit: form$1.onSubmit(handleSubmit)
|
|
1003
|
+
}, /*#__PURE__*/React.createElement(core.Stack, {
|
|
1004
|
+
gap: "sm"
|
|
1005
|
+
}, /*#__PURE__*/React.createElement(core.TextInput, _extends({
|
|
1006
|
+
label: labels.email || 'Email',
|
|
1007
|
+
placeholder: labels.emailPlaceholder || 'seu@email.com',
|
|
1008
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconMail, {
|
|
1009
|
+
size: 16
|
|
1010
|
+
})
|
|
1011
|
+
}, form$1.getInputProps('email'), {
|
|
1012
|
+
disabled: isLoading
|
|
1013
|
+
})), /*#__PURE__*/React.createElement(core.PasswordInput, _extends({
|
|
1014
|
+
label: labels.password || 'Senha',
|
|
1015
|
+
placeholder: labels.passwordPlaceholder || 'Sua senha',
|
|
1016
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconLock, {
|
|
1017
|
+
size: 16
|
|
1018
|
+
})
|
|
1019
|
+
}, form$1.getInputProps('password'), {
|
|
1020
|
+
disabled: isLoading
|
|
1021
|
+
})), showForgotPassword && /*#__PURE__*/React.createElement(core.Anchor, {
|
|
1022
|
+
size: "sm",
|
|
1023
|
+
ta: "right",
|
|
1024
|
+
onClick: handleForgotPassword,
|
|
1025
|
+
style: {
|
|
1026
|
+
cursor: 'pointer'
|
|
1027
|
+
},
|
|
1028
|
+
c: loadingResetPassword ? 'dimmed' : 'blue'
|
|
1029
|
+
}, loadingResetPassword ? labels.sendingReset || 'Enviando...' : labels.forgotPassword || 'Esqueceu a senha?'), /*#__PURE__*/React.createElement(core.Button, {
|
|
1030
|
+
type: "submit",
|
|
1031
|
+
fullWidth: true,
|
|
1032
|
+
loading: loadingSignIn,
|
|
1033
|
+
rightSection: /*#__PURE__*/React.createElement(iconsReact.IconArrowRight, {
|
|
1034
|
+
size: 16
|
|
1035
|
+
})
|
|
1036
|
+
}, labels.signInButton || 'Entrar'))), showMagicLink && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(core.Divider, {
|
|
1037
|
+
label: labels.orContinueWith || 'Ou continue com'
|
|
1038
|
+
}), /*#__PURE__*/React.createElement(core.Button, {
|
|
1039
|
+
variant: "light",
|
|
1040
|
+
fullWidth: true,
|
|
1041
|
+
loading: loadingMagicLink,
|
|
1042
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconMail, {
|
|
1043
|
+
size: 16
|
|
1044
|
+
}),
|
|
1045
|
+
onClick: handleMagicLink,
|
|
1046
|
+
disabled: isLoading || !form$1.values.email
|
|
1047
|
+
}, labels.magicLinkButton || 'Enviar Link Mágico')), showSocialLogin && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(core.Divider, null), /*#__PURE__*/React.createElement(core.Group, {
|
|
1048
|
+
grow: true
|
|
1049
|
+
}, /*#__PURE__*/React.createElement(core.Button, {
|
|
1050
|
+
variant: "light",
|
|
1051
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconBrandGoogle, {
|
|
1052
|
+
size: 16
|
|
1053
|
+
}),
|
|
1054
|
+
onClick: () => onSocialLogin?.('google'),
|
|
1055
|
+
disabled: isLoading
|
|
1056
|
+
}, "Google"), /*#__PURE__*/React.createElement(core.Button, {
|
|
1057
|
+
variant: "light",
|
|
1058
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconBrandGithub, {
|
|
1059
|
+
size: 16
|
|
1060
|
+
}),
|
|
1061
|
+
onClick: () => onSocialLogin?.('github'),
|
|
1062
|
+
disabled: isLoading
|
|
1063
|
+
}, "GitHub"))), showSignUpLink && /*#__PURE__*/React.createElement(core.Center, null, /*#__PURE__*/React.createElement(core.Text, {
|
|
1064
|
+
size: "sm",
|
|
1065
|
+
c: "dimmed"
|
|
1066
|
+
}, labels.noAccount || 'Não tem uma conta?', " ", /*#__PURE__*/React.createElement(core.Anchor, {
|
|
1067
|
+
href: signUpUrl
|
|
1068
|
+
}, labels.createAccount || 'Criar conta'))));
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* Formulário de Sign Up com Mantine
|
|
1073
|
+
*/
|
|
1074
|
+
function SignUpForm({
|
|
1075
|
+
// Configuração
|
|
1076
|
+
logo = img,
|
|
1077
|
+
title = 'Criar Conta',
|
|
1078
|
+
subtitle = 'Preencha os dados para se cadastrar',
|
|
1079
|
+
// Features
|
|
1080
|
+
requireName = true,
|
|
1081
|
+
showSignInLink = true,
|
|
1082
|
+
showSocialLogin = false,
|
|
1083
|
+
// Links
|
|
1084
|
+
signInUrl = '/auth/signin',
|
|
1085
|
+
// Callbacks
|
|
1086
|
+
onSuccess,
|
|
1087
|
+
onError,
|
|
1088
|
+
onSocialLogin,
|
|
1089
|
+
// Custom labels
|
|
1090
|
+
labels = {},
|
|
1091
|
+
...cardProps
|
|
1092
|
+
}) {
|
|
1093
|
+
const signUp = useAuthStore(s => s.signUp);
|
|
1094
|
+
const loading = useAuthStore(s => s.loadingStates.signUp);
|
|
1095
|
+
const form$1 = form.useForm({
|
|
1096
|
+
initialValues: {
|
|
1097
|
+
name: '',
|
|
1098
|
+
email: '',
|
|
1099
|
+
password: '',
|
|
1100
|
+
confirmPassword: ''
|
|
1101
|
+
},
|
|
1102
|
+
validate: {
|
|
1103
|
+
name: value => requireName && !value ? labels.nameRequired || 'Nome obrigatório' : null,
|
|
1104
|
+
email: value => /^\S+@\S+$/.test(value) ? null : labels.invalidEmail || 'Email inválido',
|
|
1105
|
+
password: value => value.length < 6 ? labels.passwordTooShort || 'A senha deve ter pelo menos 6 caracteres' : null,
|
|
1106
|
+
confirmPassword: (value, values) => value !== values.password ? labels.passwordMismatch || 'As senhas não coincidem' : null
|
|
1107
|
+
}
|
|
1108
|
+
});
|
|
1109
|
+
const handleSubmit = async values => {
|
|
1110
|
+
try {
|
|
1111
|
+
const result = await signUp(values.email, values.password, values.name);
|
|
1112
|
+
onSuccess?.(result);
|
|
1113
|
+
} catch (error) {
|
|
1114
|
+
onError?.(error);
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1117
|
+
return /*#__PURE__*/React.createElement(AuthCard, _extends({
|
|
1118
|
+
logo: logo,
|
|
1119
|
+
title: title,
|
|
1120
|
+
subtitle: subtitle
|
|
1121
|
+
}, cardProps), /*#__PURE__*/React.createElement("form", {
|
|
1122
|
+
onSubmit: form$1.onSubmit(handleSubmit)
|
|
1123
|
+
}, /*#__PURE__*/React.createElement(core.Stack, {
|
|
1124
|
+
gap: "sm"
|
|
1125
|
+
}, requireName && /*#__PURE__*/React.createElement(core.TextInput, _extends({
|
|
1126
|
+
label: labels.name || 'Nome',
|
|
1127
|
+
placeholder: labels.namePlaceholder || 'Seu nome',
|
|
1128
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconUser, {
|
|
1129
|
+
size: 16
|
|
1130
|
+
})
|
|
1131
|
+
}, form$1.getInputProps('name'), {
|
|
1132
|
+
disabled: loading
|
|
1133
|
+
})), /*#__PURE__*/React.createElement(core.TextInput, _extends({
|
|
1134
|
+
label: labels.email || 'Email',
|
|
1135
|
+
placeholder: labels.emailPlaceholder || 'seu@email.com',
|
|
1136
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconMail, {
|
|
1137
|
+
size: 16
|
|
1138
|
+
})
|
|
1139
|
+
}, form$1.getInputProps('email'), {
|
|
1140
|
+
disabled: loading
|
|
1141
|
+
})), /*#__PURE__*/React.createElement(core.PasswordInput, _extends({
|
|
1142
|
+
label: labels.password || 'Senha',
|
|
1143
|
+
placeholder: labels.passwordPlaceholder || 'Crie uma senha',
|
|
1144
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconLock, {
|
|
1145
|
+
size: 16
|
|
1146
|
+
})
|
|
1147
|
+
}, form$1.getInputProps('password'), {
|
|
1148
|
+
disabled: loading
|
|
1149
|
+
})), /*#__PURE__*/React.createElement(core.PasswordInput, _extends({
|
|
1150
|
+
label: labels.confirmPassword || 'Confirmar Senha',
|
|
1151
|
+
placeholder: labels.confirmPasswordPlaceholder || 'Repita a senha',
|
|
1152
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconLock, {
|
|
1153
|
+
size: 16
|
|
1154
|
+
})
|
|
1155
|
+
}, form$1.getInputProps('confirmPassword'), {
|
|
1156
|
+
disabled: loading
|
|
1157
|
+
})), /*#__PURE__*/React.createElement(core.Button, {
|
|
1158
|
+
type: "submit",
|
|
1159
|
+
fullWidth: true,
|
|
1160
|
+
loading: loading,
|
|
1161
|
+
rightSection: /*#__PURE__*/React.createElement(iconsReact.IconArrowRight, {
|
|
1162
|
+
size: 16
|
|
1163
|
+
})
|
|
1164
|
+
}, labels.signUpButton || 'Criar Conta'))), showSocialLogin && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(core.Divider, {
|
|
1165
|
+
label: labels.orContinueWith || 'Ou continue com'
|
|
1166
|
+
}), /*#__PURE__*/React.createElement(core.Group, {
|
|
1167
|
+
grow: true
|
|
1168
|
+
}, /*#__PURE__*/React.createElement(core.Button, {
|
|
1169
|
+
variant: "light",
|
|
1170
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconBrandGoogle, {
|
|
1171
|
+
size: 16
|
|
1172
|
+
}),
|
|
1173
|
+
onClick: () => onSocialLogin?.('google'),
|
|
1174
|
+
disabled: loading
|
|
1175
|
+
}, "Google"), /*#__PURE__*/React.createElement(core.Button, {
|
|
1176
|
+
variant: "light",
|
|
1177
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconBrandGithub, {
|
|
1178
|
+
size: 16
|
|
1179
|
+
}),
|
|
1180
|
+
onClick: () => onSocialLogin?.('github'),
|
|
1181
|
+
disabled: loading
|
|
1182
|
+
}, "GitHub"))), showSignInLink && /*#__PURE__*/React.createElement(core.Center, null, /*#__PURE__*/React.createElement(core.Text, {
|
|
1183
|
+
size: "sm",
|
|
1184
|
+
c: "dimmed"
|
|
1185
|
+
}, labels.hasAccount || 'Já tem uma conta?', " ", /*#__PURE__*/React.createElement(core.Anchor, {
|
|
1186
|
+
href: signInUrl
|
|
1187
|
+
}, labels.signIn || 'Entrar'))));
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
/**
|
|
1191
|
+
* Formulário para envio de Magic Link
|
|
1192
|
+
*/
|
|
1193
|
+
function MagicLinkForm({
|
|
1194
|
+
// Configuração
|
|
1195
|
+
logo = img,
|
|
1196
|
+
title = 'Login sem Senha',
|
|
1197
|
+
subtitle = 'Receba um link de acesso no seu email',
|
|
1198
|
+
// Features
|
|
1199
|
+
showSignInLink = true,
|
|
1200
|
+
// Links
|
|
1201
|
+
signInUrl = '/auth/signin',
|
|
1202
|
+
// Callbacks
|
|
1203
|
+
onSent,
|
|
1204
|
+
onError,
|
|
1205
|
+
// Custom labels
|
|
1206
|
+
labels = {},
|
|
1207
|
+
...cardProps
|
|
1208
|
+
}) {
|
|
1209
|
+
const sendMagicLink = useAuthStore(s => s.sendMagicLink);
|
|
1210
|
+
const loading = useAuthStore(s => s.loadingStates.magicLink);
|
|
1211
|
+
const form$1 = form.useForm({
|
|
1212
|
+
initialValues: {
|
|
1213
|
+
email: ''
|
|
1214
|
+
},
|
|
1215
|
+
validate: {
|
|
1216
|
+
email: value => /^\S+@\S+$/.test(value) ? null : labels.invalidEmail || 'Email inválido'
|
|
1217
|
+
}
|
|
1218
|
+
});
|
|
1219
|
+
const handleSubmit = async values => {
|
|
1220
|
+
try {
|
|
1221
|
+
await sendMagicLink(values.email);
|
|
1222
|
+
onSent?.(values.email);
|
|
1223
|
+
} catch (error) {
|
|
1224
|
+
onError?.(error);
|
|
1225
|
+
}
|
|
1226
|
+
};
|
|
1227
|
+
return /*#__PURE__*/React.createElement(AuthCard, _extends({
|
|
1228
|
+
logo: logo,
|
|
1229
|
+
title: title,
|
|
1230
|
+
subtitle: subtitle
|
|
1231
|
+
}, cardProps), /*#__PURE__*/React.createElement("form", {
|
|
1232
|
+
onSubmit: form$1.onSubmit(handleSubmit)
|
|
1233
|
+
}, /*#__PURE__*/React.createElement(core.Stack, {
|
|
1234
|
+
gap: "sm"
|
|
1235
|
+
}, /*#__PURE__*/React.createElement(core.TextInput, _extends({
|
|
1236
|
+
label: labels.email || 'Email',
|
|
1237
|
+
placeholder: labels.emailPlaceholder || 'seu@email.com',
|
|
1238
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconMail, {
|
|
1239
|
+
size: 16
|
|
1240
|
+
})
|
|
1241
|
+
}, form$1.getInputProps('email'), {
|
|
1242
|
+
disabled: loading
|
|
1243
|
+
})), /*#__PURE__*/React.createElement(core.Button, {
|
|
1244
|
+
type: "submit",
|
|
1245
|
+
fullWidth: true,
|
|
1246
|
+
loading: loading,
|
|
1247
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconSend, {
|
|
1248
|
+
size: 16
|
|
1249
|
+
})
|
|
1250
|
+
}, labels.sendButton || 'Enviar Link Mágico'))), showSignInLink && /*#__PURE__*/React.createElement(core.Center, null, /*#__PURE__*/React.createElement(core.Text, {
|
|
1251
|
+
size: "sm",
|
|
1252
|
+
c: "dimmed"
|
|
1253
|
+
}, labels.backTo || 'Voltar para', " ", /*#__PURE__*/React.createElement(core.Anchor, {
|
|
1254
|
+
href: signInUrl
|
|
1255
|
+
}, labels.signIn || 'login com senha'))));
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
/**
|
|
1259
|
+
* Componente de verificação de Magic Link
|
|
1260
|
+
* Extrai token da URL e verifica automaticamente
|
|
1261
|
+
*/
|
|
1262
|
+
function MagicLinkVerify({
|
|
1263
|
+
// Configuração
|
|
1264
|
+
logo = img,
|
|
1265
|
+
// Token pode ser passado diretamente ou extraído da URL
|
|
1266
|
+
token: propToken,
|
|
1267
|
+
// Callbacks
|
|
1268
|
+
onSuccess,
|
|
1269
|
+
onError,
|
|
1270
|
+
// Redirect após sucesso/erro
|
|
1271
|
+
redirectTo,
|
|
1272
|
+
redirectDelay = 2000,
|
|
1273
|
+
// Custom labels
|
|
1274
|
+
labels = {},
|
|
1275
|
+
...cardProps
|
|
1276
|
+
}) {
|
|
1277
|
+
const [status, setStatus] = React$1.useState('verifying'); // verifying, success, error
|
|
1278
|
+
const [errorMessage, setErrorMessage] = React$1.useState('');
|
|
1279
|
+
const verifyMagicLink = useAuthStore(s => s.verifyMagicLink);
|
|
1280
|
+
React$1.useEffect(() => {
|
|
1281
|
+
const verify = async () => {
|
|
1282
|
+
// Pega token da prop ou da URL
|
|
1283
|
+
let token = propToken;
|
|
1284
|
+
if (!token && typeof window !== 'undefined') {
|
|
1285
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
1286
|
+
token = urlParams.get('token');
|
|
1287
|
+
}
|
|
1288
|
+
if (!token) {
|
|
1289
|
+
setStatus('error');
|
|
1290
|
+
setErrorMessage(labels.noToken || 'Token não encontrado na URL');
|
|
1291
|
+
onError?.(new Error('No token'));
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
try {
|
|
1295
|
+
const result = await verifyMagicLink(token);
|
|
1296
|
+
setStatus('success');
|
|
1297
|
+
onSuccess?.(result);
|
|
1298
|
+
if (redirectTo) {
|
|
1299
|
+
setTimeout(() => {
|
|
1300
|
+
window.location.href = redirectTo;
|
|
1301
|
+
}, redirectDelay);
|
|
1302
|
+
}
|
|
1303
|
+
} catch (error) {
|
|
1304
|
+
setStatus('error');
|
|
1305
|
+
setErrorMessage(error.message || labels.verificationFailed || 'Verificação falhou');
|
|
1306
|
+
onError?.(error);
|
|
1307
|
+
}
|
|
1308
|
+
};
|
|
1309
|
+
verify();
|
|
1310
|
+
}, [propToken, verifyMagicLink, onSuccess, onError, redirectTo, redirectDelay, labels]);
|
|
1311
|
+
return /*#__PURE__*/React.createElement(AuthCard, _extends({
|
|
1312
|
+
logo: logo
|
|
1313
|
+
}, cardProps), status === 'verifying' && /*#__PURE__*/React.createElement(core.Stack, {
|
|
1314
|
+
align: "center",
|
|
1315
|
+
gap: "sm"
|
|
1316
|
+
}, /*#__PURE__*/React.createElement(core.Loader, {
|
|
1317
|
+
size: "lg"
|
|
1318
|
+
}), /*#__PURE__*/React.createElement(core.Title, {
|
|
1319
|
+
order: 4
|
|
1320
|
+
}, labels.verifying || 'Verificando Link Mágico'), /*#__PURE__*/React.createElement(core.Text, {
|
|
1321
|
+
size: "sm",
|
|
1322
|
+
c: "dimmed",
|
|
1323
|
+
ta: "center"
|
|
1324
|
+
}, labels.pleaseWait || 'Aguarde enquanto autenticamos você...')), status === 'success' && /*#__PURE__*/React.createElement(core.Stack, {
|
|
1325
|
+
align: "center",
|
|
1326
|
+
gap: "sm"
|
|
1327
|
+
}, /*#__PURE__*/React.createElement(iconsReact.IconCheck, {
|
|
1328
|
+
size: 48,
|
|
1329
|
+
color: "var(--mantine-color-green-6)"
|
|
1330
|
+
}), /*#__PURE__*/React.createElement(core.Title, {
|
|
1331
|
+
order: 4
|
|
1332
|
+
}, labels.success || 'Autenticado com Sucesso!'), /*#__PURE__*/React.createElement(core.Text, {
|
|
1333
|
+
size: "sm",
|
|
1334
|
+
c: "dimmed",
|
|
1335
|
+
ta: "center"
|
|
1336
|
+
}, redirectTo ? labels.redirecting || 'Redirecionando...' : labels.authenticated || 'Você está autenticado.')), status === 'error' && /*#__PURE__*/React.createElement(core.Stack, {
|
|
1337
|
+
align: "center",
|
|
1338
|
+
gap: "sm"
|
|
1339
|
+
}, /*#__PURE__*/React.createElement(iconsReact.IconX, {
|
|
1340
|
+
size: 48,
|
|
1341
|
+
color: "var(--mantine-color-red-6)"
|
|
1342
|
+
}), /*#__PURE__*/React.createElement(core.Title, {
|
|
1343
|
+
order: 4
|
|
1344
|
+
}, labels.failed || 'Falha na Autenticação'), /*#__PURE__*/React.createElement(core.Text, {
|
|
1345
|
+
size: "sm",
|
|
1346
|
+
c: "dimmed",
|
|
1347
|
+
ta: "center"
|
|
1348
|
+
}, errorMessage || labels.invalidLink || 'O link é inválido ou expirou.')));
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
/**
|
|
1352
|
+
* Formulário para solicitar reset de senha
|
|
1353
|
+
*/
|
|
1354
|
+
function ForgotPasswordForm({
|
|
1355
|
+
// Configuração
|
|
1356
|
+
logo = img,
|
|
1357
|
+
title = 'Recuperar Senha',
|
|
1358
|
+
subtitle = 'Enviaremos um link para redefinir sua senha',
|
|
1359
|
+
// Features
|
|
1360
|
+
showSignInLink = true,
|
|
1361
|
+
// Links
|
|
1362
|
+
signInUrl = '/auth/signin',
|
|
1363
|
+
// Callbacks
|
|
1364
|
+
onSent,
|
|
1365
|
+
onError,
|
|
1366
|
+
// Custom labels
|
|
1367
|
+
labels = {},
|
|
1368
|
+
...cardProps
|
|
1369
|
+
}) {
|
|
1370
|
+
const forgotPassword = useAuthStore(s => s.forgotPassword);
|
|
1371
|
+
const loading = useAuthStore(s => s.loadingStates.resetPassword);
|
|
1372
|
+
const form$1 = form.useForm({
|
|
1373
|
+
initialValues: {
|
|
1374
|
+
email: ''
|
|
1375
|
+
},
|
|
1376
|
+
validate: {
|
|
1377
|
+
email: value => /^\S+@\S+$/.test(value) ? null : labels.invalidEmail || 'Email inválido'
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1380
|
+
const handleSubmit = async values => {
|
|
1381
|
+
try {
|
|
1382
|
+
await forgotPassword(values.email);
|
|
1383
|
+
onSent?.(values.email);
|
|
1384
|
+
} catch (error) {
|
|
1385
|
+
onError?.(error);
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
return /*#__PURE__*/React.createElement(AuthCard, _extends({
|
|
1389
|
+
logo: logo,
|
|
1390
|
+
title: title,
|
|
1391
|
+
subtitle: subtitle
|
|
1392
|
+
}, cardProps), /*#__PURE__*/React.createElement("form", {
|
|
1393
|
+
onSubmit: form$1.onSubmit(handleSubmit)
|
|
1394
|
+
}, /*#__PURE__*/React.createElement(core.Stack, {
|
|
1395
|
+
gap: "sm"
|
|
1396
|
+
}, /*#__PURE__*/React.createElement(core.TextInput, _extends({
|
|
1397
|
+
label: labels.email || 'Email',
|
|
1398
|
+
placeholder: labels.emailPlaceholder || 'seu@email.com',
|
|
1399
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconMail, {
|
|
1400
|
+
size: 16
|
|
1401
|
+
})
|
|
1402
|
+
}, form$1.getInputProps('email'), {
|
|
1403
|
+
disabled: loading
|
|
1404
|
+
})), /*#__PURE__*/React.createElement(core.Button, {
|
|
1405
|
+
type: "submit",
|
|
1406
|
+
fullWidth: true,
|
|
1407
|
+
loading: loading,
|
|
1408
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconSend, {
|
|
1409
|
+
size: 16
|
|
1410
|
+
})
|
|
1411
|
+
}, labels.sendButton || 'Enviar Link de Recuperação'))), showSignInLink && /*#__PURE__*/React.createElement(core.Center, null, /*#__PURE__*/React.createElement(core.Text, {
|
|
1412
|
+
size: "sm",
|
|
1413
|
+
c: "dimmed"
|
|
1414
|
+
}, labels.rememberedPassword || 'Lembrou a senha?', " ", /*#__PURE__*/React.createElement(core.Anchor, {
|
|
1415
|
+
href: signInUrl
|
|
1416
|
+
}, labels.signIn || 'Entrar'))));
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
/**
|
|
1420
|
+
* Formulário para redefinir senha com token
|
|
1421
|
+
*/
|
|
1422
|
+
function ResetPasswordForm({
|
|
1423
|
+
// Configuração
|
|
1424
|
+
logo = img,
|
|
1425
|
+
title = 'Nova Senha',
|
|
1426
|
+
subtitle = 'Crie uma nova senha para sua conta',
|
|
1427
|
+
// Token pode ser passado diretamente ou extraído da URL
|
|
1428
|
+
token: propToken,
|
|
1429
|
+
// Callbacks
|
|
1430
|
+
onSuccess,
|
|
1431
|
+
onError,
|
|
1432
|
+
// Redirect após sucesso
|
|
1433
|
+
signInUrl = '/auth/signin',
|
|
1434
|
+
// Custom labels
|
|
1435
|
+
labels = {},
|
|
1436
|
+
...cardProps
|
|
1437
|
+
}) {
|
|
1438
|
+
const [token, setToken] = React$1.useState(propToken || '');
|
|
1439
|
+
const [success, setSuccess] = React$1.useState(false);
|
|
1440
|
+
const resetPassword = useAuthStore(s => s.resetPassword);
|
|
1441
|
+
const loading = useAuthStore(s => s.loadingStates.resetPassword);
|
|
1442
|
+
|
|
1443
|
+
// Extrai token da URL se não foi passado como prop
|
|
1444
|
+
React$1.useEffect(() => {
|
|
1445
|
+
if (!propToken && typeof window !== 'undefined') {
|
|
1446
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
1447
|
+
const urlToken = urlParams.get('token');
|
|
1448
|
+
if (urlToken) setToken(urlToken);
|
|
1449
|
+
}
|
|
1450
|
+
}, [propToken]);
|
|
1451
|
+
const form$1 = form.useForm({
|
|
1452
|
+
initialValues: {
|
|
1453
|
+
password: '',
|
|
1454
|
+
confirmPassword: ''
|
|
1455
|
+
},
|
|
1456
|
+
validate: {
|
|
1457
|
+
password: value => value.length < 6 ? labels.passwordTooShort || 'A senha deve ter pelo menos 6 caracteres' : null,
|
|
1458
|
+
confirmPassword: (value, values) => value !== values.password ? labels.passwordMismatch || 'As senhas não coincidem' : null
|
|
1459
|
+
}
|
|
1460
|
+
});
|
|
1461
|
+
const handleSubmit = async values => {
|
|
1462
|
+
if (!token) {
|
|
1463
|
+
onError?.(new Error('Token não encontrado'));
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
try {
|
|
1467
|
+
await resetPassword(token, values.password);
|
|
1468
|
+
setSuccess(true);
|
|
1469
|
+
onSuccess?.();
|
|
1470
|
+
} catch (error) {
|
|
1471
|
+
onError?.(error);
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
if (success) {
|
|
1475
|
+
return /*#__PURE__*/React.createElement(AuthCard, _extends({
|
|
1476
|
+
logo: logo
|
|
1477
|
+
}, cardProps), /*#__PURE__*/React.createElement(core.Stack, {
|
|
1478
|
+
align: "center",
|
|
1479
|
+
gap: "sm"
|
|
1480
|
+
}, /*#__PURE__*/React.createElement(iconsReact.IconCheck, {
|
|
1481
|
+
size: 48,
|
|
1482
|
+
color: "var(--mantine-color-green-6)"
|
|
1483
|
+
}), /*#__PURE__*/React.createElement(core.Title, {
|
|
1484
|
+
order: 4
|
|
1485
|
+
}, labels.successTitle || 'Senha Redefinida!'), /*#__PURE__*/React.createElement(core.Text, {
|
|
1486
|
+
size: "sm",
|
|
1487
|
+
c: "dimmed",
|
|
1488
|
+
ta: "center"
|
|
1489
|
+
}, labels.successMessage || 'Sua senha foi alterada com sucesso.'), /*#__PURE__*/React.createElement(core.Button, {
|
|
1490
|
+
component: "a",
|
|
1491
|
+
href: signInUrl,
|
|
1492
|
+
fullWidth: true
|
|
1493
|
+
}, labels.goToSignIn || 'Ir para Login')));
|
|
1494
|
+
}
|
|
1495
|
+
if (!token) {
|
|
1496
|
+
return /*#__PURE__*/React.createElement(AuthCard, _extends({
|
|
1497
|
+
logo: logo
|
|
1498
|
+
}, cardProps), /*#__PURE__*/React.createElement(core.Stack, {
|
|
1499
|
+
align: "center",
|
|
1500
|
+
gap: "sm"
|
|
1501
|
+
}, /*#__PURE__*/React.createElement(core.Text, {
|
|
1502
|
+
c: "red"
|
|
1503
|
+
}, labels.noToken || 'Token não encontrado na URL'), /*#__PURE__*/React.createElement(core.Button, {
|
|
1504
|
+
component: "a",
|
|
1505
|
+
href: signInUrl,
|
|
1506
|
+
variant: "light",
|
|
1507
|
+
fullWidth: true
|
|
1508
|
+
}, labels.goToSignIn || 'Voltar para Login')));
|
|
1509
|
+
}
|
|
1510
|
+
return /*#__PURE__*/React.createElement(AuthCard, _extends({
|
|
1511
|
+
logo: logo,
|
|
1512
|
+
title: title,
|
|
1513
|
+
subtitle: subtitle
|
|
1514
|
+
}, cardProps), /*#__PURE__*/React.createElement("form", {
|
|
1515
|
+
onSubmit: form$1.onSubmit(handleSubmit)
|
|
1516
|
+
}, /*#__PURE__*/React.createElement(core.Stack, {
|
|
1517
|
+
gap: "sm"
|
|
1518
|
+
}, /*#__PURE__*/React.createElement(core.PasswordInput, _extends({
|
|
1519
|
+
label: labels.newPassword || 'Nova Senha',
|
|
1520
|
+
placeholder: labels.newPasswordPlaceholder || 'Crie uma nova senha',
|
|
1521
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconLock, {
|
|
1522
|
+
size: 16
|
|
1523
|
+
})
|
|
1524
|
+
}, form$1.getInputProps('password'), {
|
|
1525
|
+
disabled: loading
|
|
1526
|
+
})), /*#__PURE__*/React.createElement(core.PasswordInput, _extends({
|
|
1527
|
+
label: labels.confirmPassword || 'Confirmar Senha',
|
|
1528
|
+
placeholder: labels.confirmPasswordPlaceholder || 'Repita a nova senha',
|
|
1529
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconLock, {
|
|
1530
|
+
size: 16
|
|
1531
|
+
})
|
|
1532
|
+
}, form$1.getInputProps('confirmPassword'), {
|
|
1533
|
+
disabled: loading
|
|
1534
|
+
})), /*#__PURE__*/React.createElement(core.Button, {
|
|
1535
|
+
type: "submit",
|
|
1536
|
+
fullWidth: true,
|
|
1537
|
+
loading: loading
|
|
1538
|
+
}, labels.resetButton || 'Redefinir Senha'))));
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
/**
|
|
1542
|
+
* Card de verificação de email
|
|
1543
|
+
* Verifica token automaticamente e permite reenvio
|
|
1544
|
+
*/
|
|
1545
|
+
function VerifyEmailCard({
|
|
1546
|
+
// Configuração
|
|
1547
|
+
logo = img,
|
|
1548
|
+
// Token pode ser passado diretamente ou extraído da URL
|
|
1549
|
+
token: propToken,
|
|
1550
|
+
// Email para reenvio (opcional)
|
|
1551
|
+
email,
|
|
1552
|
+
// Callbacks
|
|
1553
|
+
onSuccess,
|
|
1554
|
+
onError,
|
|
1555
|
+
onResent,
|
|
1556
|
+
// Redirect após sucesso
|
|
1557
|
+
redirectTo,
|
|
1558
|
+
redirectDelay = 2000,
|
|
1559
|
+
// Custom labels
|
|
1560
|
+
labels = {},
|
|
1561
|
+
...cardProps
|
|
1562
|
+
}) {
|
|
1563
|
+
const [status, setStatus] = React$1.useState('verifying'); // verifying, success, error
|
|
1564
|
+
const [errorMessage, setErrorMessage] = React$1.useState('');
|
|
1565
|
+
const verifyEmail = useAuthStore(s => s.verifyEmail);
|
|
1566
|
+
const resendVerification = useAuthStore(s => s.resendVerification);
|
|
1567
|
+
const loadingResend = useAuthStore(s => s.loadingStates.resendVerification);
|
|
1568
|
+
React$1.useEffect(() => {
|
|
1569
|
+
const verify = async () => {
|
|
1570
|
+
// Pega token da prop ou da URL
|
|
1571
|
+
let token = propToken;
|
|
1572
|
+
if (!token && typeof window !== 'undefined') {
|
|
1573
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
1574
|
+
token = urlParams.get('token');
|
|
1575
|
+
}
|
|
1576
|
+
if (!token) {
|
|
1577
|
+
setStatus('error');
|
|
1578
|
+
setErrorMessage(labels.noToken || 'Token não encontrado na URL');
|
|
1579
|
+
onError?.(new Error('No token'));
|
|
1580
|
+
return;
|
|
1581
|
+
}
|
|
1582
|
+
try {
|
|
1583
|
+
const result = await verifyEmail(token);
|
|
1584
|
+
setStatus('success');
|
|
1585
|
+
onSuccess?.(result);
|
|
1586
|
+
if (redirectTo) {
|
|
1587
|
+
setTimeout(() => {
|
|
1588
|
+
window.location.href = redirectTo;
|
|
1589
|
+
}, redirectDelay);
|
|
1590
|
+
}
|
|
1591
|
+
} catch (error) {
|
|
1592
|
+
setStatus('error');
|
|
1593
|
+
setErrorMessage(error.message || labels.verificationFailed || 'Verificação falhou');
|
|
1594
|
+
onError?.(error);
|
|
1595
|
+
}
|
|
1596
|
+
};
|
|
1597
|
+
verify();
|
|
1598
|
+
}, [propToken, verifyEmail, onSuccess, onError, redirectTo, redirectDelay, labels]);
|
|
1599
|
+
const handleResend = async () => {
|
|
1600
|
+
if (!email) return;
|
|
1601
|
+
try {
|
|
1602
|
+
await resendVerification(email);
|
|
1603
|
+
onResent?.(email);
|
|
1604
|
+
} catch (error) {
|
|
1605
|
+
onError?.(error);
|
|
1606
|
+
}
|
|
1607
|
+
};
|
|
1608
|
+
return /*#__PURE__*/React.createElement(AuthCard, _extends({
|
|
1609
|
+
logo: logo
|
|
1610
|
+
}, cardProps), status === 'verifying' && /*#__PURE__*/React.createElement(core.Stack, {
|
|
1611
|
+
align: "center",
|
|
1612
|
+
gap: "sm"
|
|
1613
|
+
}, /*#__PURE__*/React.createElement(core.Loader, {
|
|
1614
|
+
size: "lg"
|
|
1615
|
+
}), /*#__PURE__*/React.createElement(core.Title, {
|
|
1616
|
+
order: 4
|
|
1617
|
+
}, labels.verifying || 'Verificando Email'), /*#__PURE__*/React.createElement(core.Text, {
|
|
1618
|
+
size: "sm",
|
|
1619
|
+
c: "dimmed",
|
|
1620
|
+
ta: "center"
|
|
1621
|
+
}, labels.pleaseWait || 'Aguarde enquanto verificamos seu email...')), status === 'success' && /*#__PURE__*/React.createElement(core.Stack, {
|
|
1622
|
+
align: "center",
|
|
1623
|
+
gap: "sm"
|
|
1624
|
+
}, /*#__PURE__*/React.createElement(iconsReact.IconCheck, {
|
|
1625
|
+
size: 48,
|
|
1626
|
+
color: "var(--mantine-color-green-6)"
|
|
1627
|
+
}), /*#__PURE__*/React.createElement(core.Title, {
|
|
1628
|
+
order: 4
|
|
1629
|
+
}, labels.success || 'Email Verificado!'), /*#__PURE__*/React.createElement(core.Text, {
|
|
1630
|
+
size: "sm",
|
|
1631
|
+
c: "dimmed",
|
|
1632
|
+
ta: "center"
|
|
1633
|
+
}, redirectTo ? labels.redirecting || 'Redirecionando...' : labels.verified || 'Seu email foi verificado com sucesso.')), status === 'error' && /*#__PURE__*/React.createElement(core.Stack, {
|
|
1634
|
+
align: "center",
|
|
1635
|
+
gap: "sm"
|
|
1636
|
+
}, /*#__PURE__*/React.createElement(iconsReact.IconX, {
|
|
1637
|
+
size: 48,
|
|
1638
|
+
color: "var(--mantine-color-red-6)"
|
|
1639
|
+
}), /*#__PURE__*/React.createElement(core.Title, {
|
|
1640
|
+
order: 4
|
|
1641
|
+
}, labels.failed || 'Verificação Falhou'), /*#__PURE__*/React.createElement(core.Text, {
|
|
1642
|
+
size: "sm",
|
|
1643
|
+
c: "dimmed",
|
|
1644
|
+
ta: "center"
|
|
1645
|
+
}, errorMessage || labels.invalidToken || 'O link é inválido ou expirou.'), email && /*#__PURE__*/React.createElement(core.Button, {
|
|
1646
|
+
variant: "light",
|
|
1647
|
+
leftSection: /*#__PURE__*/React.createElement(iconsReact.IconRefresh, {
|
|
1648
|
+
size: 16
|
|
1649
|
+
}),
|
|
1650
|
+
onClick: handleResend,
|
|
1651
|
+
loading: loadingResend,
|
|
1652
|
+
fullWidth: true
|
|
1653
|
+
}, labels.resend || 'Reenviar Email de Verificação')));
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
exports.AuthCard = AuthCard;
|
|
829
1657
|
exports.AuthProvider = AuthProvider;
|
|
1658
|
+
exports.ForgotPasswordForm = ForgotPasswordForm;
|
|
1659
|
+
exports.MagicLinkForm = MagicLinkForm;
|
|
1660
|
+
exports.MagicLinkVerify = MagicLinkVerify;
|
|
830
1661
|
exports.ProtectedRoute = ProtectedRoute;
|
|
1662
|
+
exports.ResetPasswordForm = ResetPasswordForm;
|
|
1663
|
+
exports.SignInForm = SignInForm;
|
|
1664
|
+
exports.SignUpForm = SignUpForm;
|
|
1665
|
+
exports.VerifyEmailCard = VerifyEmailCard;
|
|
1666
|
+
exports.configure = configure;
|
|
1667
|
+
exports.forgotPassword = forgotPassword;
|
|
831
1668
|
exports.getCurrentUser = getCurrentUser;
|
|
1669
|
+
exports.getSession = getSession;
|
|
832
1670
|
exports.isAuthenticated = isAuthenticated;
|
|
833
1671
|
exports.refreshToken = refreshToken;
|
|
1672
|
+
exports.resendVerification = resendVerification;
|
|
1673
|
+
exports.resetPassword = resetPassword;
|
|
1674
|
+
exports.sendMagicLink = sendMagicLink;
|
|
834
1675
|
exports.signIn = signIn;
|
|
835
1676
|
exports.signOut = signOut;
|
|
836
1677
|
exports.signUp = signUp;
|
|
837
1678
|
exports.socialRedirect = socialRedirect;
|
|
838
1679
|
exports.useAuth = useAuth;
|
|
1680
|
+
exports.useAuthLoading = useAuthLoading;
|
|
839
1681
|
exports.useAuthStore = useAuthStore;
|
|
840
1682
|
exports.useCheckToken = useCheckToken;
|
|
1683
|
+
exports.useEmailVerification = useEmailVerification;
|
|
1684
|
+
exports.useMagicLink = useMagicLink;
|
|
1685
|
+
exports.usePasswordReset = usePasswordReset;
|
|
1686
|
+
exports.useSession = useSession;
|
|
841
1687
|
exports.useSignIn = useSignIn;
|
|
842
1688
|
exports.useSignOut = useSignOut;
|
|
843
1689
|
exports.useSignUp = useSignUp;
|
|
1690
|
+
exports.verifyEmail = verifyEmail;
|
|
1691
|
+
exports.verifyMagicLink = verifyMagicLink;
|
|
844
1692
|
//# sourceMappingURL=index.js.map
|