@riligar/auth-react 1.22.0 → 1.24.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 +39 -104
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +39 -104
- package/dist/index.js.map +1 -1
- package/package.json +1 -5
package/dist/index.js
CHANGED
|
@@ -8,7 +8,6 @@ var reactRouterDom = require('react-router-dom');
|
|
|
8
8
|
var core = require('@mantine/core');
|
|
9
9
|
var form = require('@mantine/form');
|
|
10
10
|
var iconsReact = require('@tabler/icons-react');
|
|
11
|
-
var notifications = require('@mantine/notifications');
|
|
12
11
|
|
|
13
12
|
// Config - API Base URL fixa para o serviço de autenticação
|
|
14
13
|
let API_BASE = 'https://manager.myauth.click';
|
|
@@ -752,32 +751,39 @@ const useAuthStore = zustand.create((set, get) => ({
|
|
|
752
751
|
if (isAuthenticated()) {
|
|
753
752
|
const token = window.localStorage.getItem('auth:token');
|
|
754
753
|
if (token) {
|
|
755
|
-
//
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
754
|
+
// Usa o decoder oficial do SDK que é mais seguro
|
|
755
|
+
const payload = decodeJWT(token);
|
|
756
|
+
|
|
757
|
+
// Se não for um JWT ou não tiver expiração, não fazemos refresh em background
|
|
758
|
+
// O backend cuidará da expiração da sessão opaca via 401 nas requisições normais
|
|
759
|
+
if (!payload || !payload.exp) return;
|
|
760
760
|
const now = Date.now() / 1000;
|
|
761
761
|
const timeUntilExpiry = payload.exp - now;
|
|
762
762
|
|
|
763
|
-
// Se o token expira em menos de 5 minutos,
|
|
763
|
+
// Se o token expira em menos de 5 minutos, tenta o refresh
|
|
764
764
|
if (timeUntilExpiry < 300) {
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
765
|
+
try {
|
|
766
|
+
await refreshToken();
|
|
767
|
+
const user = getCurrentUser();
|
|
768
|
+
set({
|
|
769
|
+
user
|
|
770
|
+
});
|
|
771
|
+
} catch (refreshErr) {
|
|
772
|
+
console.warn('[AuthStore] Falha ao renovar token:', refreshErr);
|
|
773
|
+
// Só desloga se for um erro de autenticação explícito (401)
|
|
774
|
+
if (refreshErr.res?.status === 401) {
|
|
775
|
+
set({
|
|
776
|
+
user: null
|
|
777
|
+
});
|
|
778
|
+
window.localStorage.removeItem('auth:token');
|
|
779
|
+
}
|
|
780
|
+
}
|
|
771
781
|
}
|
|
772
782
|
}
|
|
773
783
|
}
|
|
774
784
|
} catch (error) {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
set({
|
|
778
|
-
user: null
|
|
779
|
-
});
|
|
780
|
-
window.localStorage.removeItem('auth:token');
|
|
785
|
+
// Erros de processamento interno não devem deslogar o usuário
|
|
786
|
+
console.error('[AuthStore] Erro no ciclo de refresh automático:', error);
|
|
781
787
|
}
|
|
782
788
|
}, 4 * 60 * 1000); // Verifica a cada 4 minutos
|
|
783
789
|
|
|
@@ -2068,6 +2074,8 @@ function UserProfile({
|
|
|
2068
2074
|
onProfileUpdate,
|
|
2069
2075
|
onPasswordChange,
|
|
2070
2076
|
onEmailChange,
|
|
2077
|
+
onSessionRevoked,
|
|
2078
|
+
onOtherSessionsRevoked,
|
|
2071
2079
|
onError,
|
|
2072
2080
|
// Features toggle
|
|
2073
2081
|
showAvatar = true,
|
|
@@ -2154,7 +2162,9 @@ function UserProfile({
|
|
|
2154
2162
|
if (isCurrentSession) {
|
|
2155
2163
|
try {
|
|
2156
2164
|
await revokeSession(sessionId);
|
|
2165
|
+
onSessionRevoked?.(sessionId);
|
|
2157
2166
|
} catch (error) {
|
|
2167
|
+
onError?.(error);
|
|
2158
2168
|
// Even if it fails, we're revoking our own session, so just logout
|
|
2159
2169
|
// The server already revoked our session
|
|
2160
2170
|
}
|
|
@@ -2168,11 +2178,7 @@ function UserProfile({
|
|
|
2168
2178
|
// Revoking another session
|
|
2169
2179
|
try {
|
|
2170
2180
|
await revokeSession(sessionId);
|
|
2171
|
-
|
|
2172
|
-
title: labels.successTitle || 'Sucesso',
|
|
2173
|
-
message: labels.sessionRevoked || 'Sessão encerrada com sucesso',
|
|
2174
|
-
color: 'green'
|
|
2175
|
-
});
|
|
2181
|
+
onSessionRevoked?.(sessionId);
|
|
2176
2182
|
} catch (error) {
|
|
2177
2183
|
// Check for 401 error (our SDK uses error.res, axios uses error.response)
|
|
2178
2184
|
const status = error.res?.status || error.response?.status;
|
|
@@ -2183,28 +2189,14 @@ function UserProfile({
|
|
|
2183
2189
|
if (variant === 'modal') onClose?.();
|
|
2184
2190
|
return;
|
|
2185
2191
|
}
|
|
2186
|
-
notifications.notifications.show({
|
|
2187
|
-
title: labels.errorTitle || 'Erro',
|
|
2188
|
-
message: error.message || labels.sessionRevokeFailed || 'Falha ao encerrar sessão',
|
|
2189
|
-
color: 'red'
|
|
2190
|
-
});
|
|
2191
2192
|
onError?.(error);
|
|
2192
2193
|
}
|
|
2193
2194
|
};
|
|
2194
2195
|
const handleRevokeOtherSessions = async () => {
|
|
2195
2196
|
try {
|
|
2196
2197
|
await revokeOtherSessions();
|
|
2197
|
-
|
|
2198
|
-
title: labels.successTitle || 'Sucesso',
|
|
2199
|
-
message: labels.otherSessionsRevoked || 'Todas as outras sessões foram encerradas',
|
|
2200
|
-
color: 'green'
|
|
2201
|
-
});
|
|
2198
|
+
onOtherSessionsRevoked?.();
|
|
2202
2199
|
} catch (error) {
|
|
2203
|
-
notifications.notifications.show({
|
|
2204
|
-
title: labels.errorTitle || 'Erro',
|
|
2205
|
-
message: error.message || labels.otherSessionsRevokeFailed || 'Falha ao encerrar sessões',
|
|
2206
|
-
color: 'red'
|
|
2207
|
-
});
|
|
2208
2200
|
onError?.(error);
|
|
2209
2201
|
}
|
|
2210
2202
|
};
|
|
@@ -2265,21 +2257,13 @@ function UserProfile({
|
|
|
2265
2257
|
|
|
2266
2258
|
// Validate file type
|
|
2267
2259
|
if (!file.type.startsWith('image/')) {
|
|
2268
|
-
|
|
2269
|
-
title: labels.errorTitle || 'Erro',
|
|
2270
|
-
message: labels.avatarInvalidType || 'Por favor, selecione uma imagem válida',
|
|
2271
|
-
color: 'red'
|
|
2272
|
-
});
|
|
2260
|
+
onError?.(new Error(labels.avatarInvalidType || 'Por favor, selecione uma imagem válida'));
|
|
2273
2261
|
return;
|
|
2274
2262
|
}
|
|
2275
2263
|
|
|
2276
2264
|
// Validate file size
|
|
2277
2265
|
if (file.size > maxAvatarSize) {
|
|
2278
|
-
|
|
2279
|
-
title: labels.errorTitle || 'Erro',
|
|
2280
|
-
message: labels.avatarTooLarge || `Imagem muito grande. Máximo ${Math.round(maxAvatarSize / 1024)}KB.`,
|
|
2281
|
-
color: 'red'
|
|
2282
|
-
});
|
|
2266
|
+
onError?.(new Error(labels.avatarTooLarge || `Imagem muito grande. Máximo ${Math.round(maxAvatarSize / 1024)}KB.`));
|
|
2283
2267
|
return;
|
|
2284
2268
|
}
|
|
2285
2269
|
setAvatarFile(file);
|
|
@@ -2318,40 +2302,20 @@ function UserProfile({
|
|
|
2318
2302
|
const handleChangePassword = async values => {
|
|
2319
2303
|
try {
|
|
2320
2304
|
await changePassword(values.currentPassword, values.newPassword);
|
|
2321
|
-
notifications.notifications.show({
|
|
2322
|
-
title: labels.successTitle || 'Sucesso',
|
|
2323
|
-
message: labels.passwordChanged || 'Senha alterada com sucesso',
|
|
2324
|
-
color: 'green'
|
|
2325
|
-
});
|
|
2326
2305
|
passwordForm.reset();
|
|
2327
2306
|
setEditingSection(null);
|
|
2328
2307
|
onPasswordChange?.();
|
|
2329
2308
|
} catch (error) {
|
|
2330
|
-
notifications.notifications.show({
|
|
2331
|
-
title: labels.errorTitle || 'Erro',
|
|
2332
|
-
message: error.message || labels.passwordChangeFailed || 'Falha ao alterar senha',
|
|
2333
|
-
color: 'red'
|
|
2334
|
-
});
|
|
2335
2309
|
onError?.(error);
|
|
2336
2310
|
}
|
|
2337
2311
|
};
|
|
2338
2312
|
const handleChangeEmail = async values => {
|
|
2339
2313
|
try {
|
|
2340
2314
|
await changeEmail(values.newEmail);
|
|
2341
|
-
notifications.notifications.show({
|
|
2342
|
-
title: labels.successTitle || 'Sucesso',
|
|
2343
|
-
message: labels.emailVerificationSent || 'Verifique seu novo email para confirmar a alteração',
|
|
2344
|
-
color: 'green'
|
|
2345
|
-
});
|
|
2346
2315
|
emailForm.reset();
|
|
2347
2316
|
setEditingSection(null);
|
|
2348
2317
|
onEmailChange?.(values.newEmail);
|
|
2349
2318
|
} catch (error) {
|
|
2350
|
-
notifications.notifications.show({
|
|
2351
|
-
title: labels.errorTitle || 'Erro',
|
|
2352
|
-
message: error.message || labels.emailChangeFailed || 'Falha ao alterar email',
|
|
2353
|
-
color: 'red'
|
|
2354
|
-
});
|
|
2355
2319
|
onError?.(error);
|
|
2356
2320
|
}
|
|
2357
2321
|
};
|
|
@@ -2360,43 +2324,29 @@ function UserProfile({
|
|
|
2360
2324
|
await updateProfile({
|
|
2361
2325
|
name: values.name
|
|
2362
2326
|
});
|
|
2363
|
-
notifications.notifications.show({
|
|
2364
|
-
title: labels.successTitle || 'Sucesso',
|
|
2365
|
-
message: labels.nameUpdated || 'Nome atualizado com sucesso',
|
|
2366
|
-
color: 'green'
|
|
2367
|
-
});
|
|
2368
2327
|
nameForm.reset();
|
|
2369
2328
|
setEditingSection(null);
|
|
2370
2329
|
onProfileUpdate?.({
|
|
2371
2330
|
name: values.name
|
|
2372
2331
|
});
|
|
2373
2332
|
} catch (error) {
|
|
2374
|
-
notifications.notifications.show({
|
|
2375
|
-
title: labels.errorTitle || 'Erro',
|
|
2376
|
-
message: error.message || labels.nameUpdateFailed || 'Falha ao atualizar nome',
|
|
2377
|
-
color: 'red'
|
|
2378
|
-
});
|
|
2379
2333
|
onError?.(error);
|
|
2380
2334
|
}
|
|
2381
2335
|
};
|
|
2382
2336
|
const handleChangeAvatar = async () => {
|
|
2383
2337
|
if (!avatarPreview) {
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2338
|
+
// Optionally handle this validation error via callback or just return?
|
|
2339
|
+
// Since it's a validation error before async call, we might want to expose it too?
|
|
2340
|
+
// The original code used notifications. Let's send to onError for consistency or just return if it's UI state.
|
|
2341
|
+
// Actually, for validation within the component, maybe we can just let it be silent or use form error if applicable?
|
|
2342
|
+
// But this is outside form context. Let's use onError with a custom error object.
|
|
2343
|
+
onError?.(new Error(labels.avatarRequired || 'Selecione uma imagem'));
|
|
2389
2344
|
return;
|
|
2390
2345
|
}
|
|
2391
2346
|
try {
|
|
2392
2347
|
await updateProfile({
|
|
2393
2348
|
image: avatarPreview
|
|
2394
2349
|
});
|
|
2395
|
-
notifications.notifications.show({
|
|
2396
|
-
title: labels.successTitle || 'Sucesso',
|
|
2397
|
-
message: labels.avatarUpdated || 'Foto de perfil atualizada com sucesso',
|
|
2398
|
-
color: 'green'
|
|
2399
|
-
});
|
|
2400
2350
|
setAvatarPreview(null);
|
|
2401
2351
|
setAvatarFile(null);
|
|
2402
2352
|
setEditingSection(null);
|
|
@@ -2404,11 +2354,6 @@ function UserProfile({
|
|
|
2404
2354
|
image: avatarPreview
|
|
2405
2355
|
});
|
|
2406
2356
|
} catch (error) {
|
|
2407
|
-
notifications.notifications.show({
|
|
2408
|
-
title: labels.errorTitle || 'Erro',
|
|
2409
|
-
message: error.message || labels.avatarUpdateFailed || 'Falha ao atualizar foto',
|
|
2410
|
-
color: 'red'
|
|
2411
|
-
});
|
|
2412
2357
|
onError?.(error);
|
|
2413
2358
|
}
|
|
2414
2359
|
};
|
|
@@ -2417,11 +2362,6 @@ function UserProfile({
|
|
|
2417
2362
|
await updateProfile({
|
|
2418
2363
|
image: ''
|
|
2419
2364
|
});
|
|
2420
|
-
notifications.notifications.show({
|
|
2421
|
-
title: labels.successTitle || 'Sucesso',
|
|
2422
|
-
message: labels.avatarRemoved || 'Foto de perfil removida',
|
|
2423
|
-
color: 'green'
|
|
2424
|
-
});
|
|
2425
2365
|
setAvatarPreview(null);
|
|
2426
2366
|
setAvatarFile(null);
|
|
2427
2367
|
setEditingSection(null);
|
|
@@ -2429,11 +2369,6 @@ function UserProfile({
|
|
|
2429
2369
|
image: ''
|
|
2430
2370
|
});
|
|
2431
2371
|
} catch (error) {
|
|
2432
|
-
notifications.notifications.show({
|
|
2433
|
-
title: labels.errorTitle || 'Erro',
|
|
2434
|
-
message: error.message || labels.avatarRemoveFailed || 'Falha ao remover foto',
|
|
2435
|
-
color: 'red'
|
|
2436
|
-
});
|
|
2437
2372
|
onError?.(error);
|
|
2438
2373
|
}
|
|
2439
2374
|
};
|