@riligar/auth-react 1.16.0 → 1.18.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 +68 -49
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +68 -49
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -22,14 +22,17 @@ const getEnvVar = key => {
|
|
|
22
22
|
};
|
|
23
23
|
let API_BASE = (typeof window !== 'undefined' && window?.location ? getEnvVar('VITE_API_BASE') : null) || 'http://localhost:3000';
|
|
24
24
|
let API_KEY = null;
|
|
25
|
+
let INTERNAL_MODE = false; // Modo interno: não exige API Key (para aplicações same-domain)
|
|
25
26
|
|
|
26
|
-
// Permite configurar a API base e
|
|
27
|
+
// Permite configurar a API base, key e modo interno externamente (chamado pelo AuthProvider)
|
|
27
28
|
function configure({
|
|
28
29
|
apiUrl,
|
|
29
|
-
apiKey
|
|
30
|
+
apiKey,
|
|
31
|
+
internal = false
|
|
30
32
|
}) {
|
|
31
33
|
if (apiUrl) API_BASE = apiUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
32
34
|
if (apiKey) API_KEY = apiKey;
|
|
35
|
+
INTERNAL_MODE = internal;
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
// helper fetch pré-configurado
|
|
@@ -51,12 +54,14 @@ async function api(route, opts = {}) {
|
|
|
51
54
|
headers.Authorization = `Bearer ${token}`;
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
// Adiciona API Key se configurada
|
|
55
|
-
if (API_KEY) {
|
|
57
|
+
// Adiciona API Key se configurada e não estiver em modo interno
|
|
58
|
+
if (API_KEY && !INTERNAL_MODE) {
|
|
56
59
|
headers['X-API-Key'] = API_KEY;
|
|
57
60
|
}
|
|
58
61
|
const res = await fetch(url, {
|
|
59
62
|
headers,
|
|
63
|
+
credentials: 'include',
|
|
64
|
+
// Required for sending session cookies
|
|
60
65
|
...opts
|
|
61
66
|
});
|
|
62
67
|
|
|
@@ -387,46 +392,33 @@ const useAuthStore = create((set, get) => ({
|
|
|
387
392
|
try {
|
|
388
393
|
// Buscar application info primeiro (não bloqueia o init)
|
|
389
394
|
fetchApplicationInfo();
|
|
395
|
+
let user = null;
|
|
390
396
|
|
|
391
|
-
//
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
// Precisamos buscar a sessão no servidor.
|
|
398
|
-
if (!user) {
|
|
399
|
-
try {
|
|
400
|
-
const sessionData = await getSession();
|
|
401
|
-
if (sessionData?.user) {
|
|
402
|
-
user = sessionData.user;
|
|
403
|
-
}
|
|
404
|
-
if (sessionData?.session) {
|
|
405
|
-
set({
|
|
406
|
-
currentSession: sessionData.session
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
} catch (sessionError) {
|
|
410
|
-
console.warn('[AuthStore] Failed to fetch session:', sessionError);
|
|
411
|
-
}
|
|
397
|
+
// PRIMEIRO: Tenta buscar sessão do servidor (funciona com cookies)
|
|
398
|
+
// Isso é essencial para Better Auth que usa session cookies
|
|
399
|
+
try {
|
|
400
|
+
const sessionData = await getSession();
|
|
401
|
+
if (sessionData?.user) {
|
|
402
|
+
user = sessionData.user;
|
|
412
403
|
}
|
|
413
|
-
if (
|
|
414
|
-
set({
|
|
415
|
-
user,
|
|
416
|
-
loading: false
|
|
417
|
-
});
|
|
418
|
-
} else {
|
|
404
|
+
if (sessionData?.session) {
|
|
419
405
|
set({
|
|
420
|
-
|
|
421
|
-
loading: false
|
|
406
|
+
currentSession: sessionData.session
|
|
422
407
|
});
|
|
423
408
|
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
loading: false
|
|
428
|
-
});
|
|
409
|
+
} catch (sessionError) {
|
|
410
|
+
// Se falhar (401), continua para verificar localStorage token
|
|
411
|
+
console.log('[AuthStore] Server session not found, checking local token');
|
|
429
412
|
}
|
|
413
|
+
|
|
414
|
+
// SEGUNDO: Se não encontrou sessão via cookies, verifica localStorage token (JWT)
|
|
415
|
+
if (!user && isAuthenticated()) {
|
|
416
|
+
user = getCurrentUser();
|
|
417
|
+
}
|
|
418
|
+
set({
|
|
419
|
+
user,
|
|
420
|
+
loading: false
|
|
421
|
+
});
|
|
430
422
|
} catch (error) {
|
|
431
423
|
console.error('Erro na inicialização:', error);
|
|
432
424
|
set({
|
|
@@ -704,19 +696,41 @@ const useAuthStore = create((set, get) => ({
|
|
|
704
696
|
throw err;
|
|
705
697
|
}
|
|
706
698
|
},
|
|
707
|
-
revokeSession: async
|
|
699
|
+
revokeSession: async sessionId => {
|
|
708
700
|
const {
|
|
709
701
|
setLoading,
|
|
710
|
-
|
|
702
|
+
currentSession,
|
|
703
|
+
sessions,
|
|
704
|
+
signOut
|
|
711
705
|
} = get();
|
|
712
706
|
setLoading('revokeSession', true);
|
|
713
707
|
set({
|
|
714
708
|
error: null
|
|
715
709
|
});
|
|
716
710
|
try {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
711
|
+
console.log('[AuthStore] Revoking session:', {
|
|
712
|
+
targetId: sessionId,
|
|
713
|
+
currentId: currentSession?.id,
|
|
714
|
+
totalSessions: sessions.length
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
// Detect if current session OR last remaining session
|
|
718
|
+
const isCurrent = sessionId === currentSession?.id;
|
|
719
|
+
const isLast = sessions.length === 1 && sessions[0].id === sessionId;
|
|
720
|
+
|
|
721
|
+
// Se for a sessão atual ou a última, faz logout normal
|
|
722
|
+
if (isCurrent || isLast) {
|
|
723
|
+
console.log('[AuthStore] Revoking current/last session -> Executing signOut');
|
|
724
|
+
await signOut();
|
|
725
|
+
// signOut já limpa loading states e erros no finally, mas
|
|
726
|
+
// como estamos dentro do fluxo deste método, garantimos:
|
|
727
|
+
setLoading('revokeSession', false);
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
await revokeSession(sessionId);
|
|
731
|
+
|
|
732
|
+
// NÃO atualiza a lista automaticamente - se for a sessão atual,
|
|
733
|
+
// listSessions() vai falhar com 401. O componente decide se quer atualizar.
|
|
720
734
|
setLoading('revokeSession', false);
|
|
721
735
|
} catch (err) {
|
|
722
736
|
set({
|
|
@@ -884,11 +898,14 @@ function AuthProvider({
|
|
|
884
898
|
apiUrl,
|
|
885
899
|
// URL base da API (OBRIGATÓRIA)
|
|
886
900
|
apiKey,
|
|
887
|
-
// API Key para header X-API-Key (
|
|
901
|
+
// API Key para header X-API-Key (obrigatória exceto em modo internal)
|
|
902
|
+
internal = false,
|
|
903
|
+
// Modo interno: não exige API Key (para aplicações same-domain como dashboard)
|
|
888
904
|
onError // Callback de erro global
|
|
889
905
|
}) {
|
|
890
906
|
// Validação de props obrigatórias
|
|
891
|
-
|
|
907
|
+
// apiKey só é obrigatória se não estiver em modo internal
|
|
908
|
+
if (!internal && !apiKey) {
|
|
892
909
|
throw new Error('[@riligar/auth-react] apiKey é obrigatória no AuthProvider. ' + 'Obtenha sua API Key no dashboard em https://dashboard.myauth.click');
|
|
893
910
|
}
|
|
894
911
|
if (!apiUrl) {
|
|
@@ -898,15 +915,15 @@ function AuthProvider({
|
|
|
898
915
|
const startRefresh = useAuthStore(s => s.startRefresh);
|
|
899
916
|
const checkTokenValidity = useAuthStore(s => s.checkTokenValidity);
|
|
900
917
|
|
|
901
|
-
// Configura SDK com apiUrl e
|
|
902
|
-
// Configura SDK com apiUrl e apiKey
|
|
918
|
+
// Configura SDK com apiUrl, apiKey e modo interno
|
|
903
919
|
// Usamos useMemo para garantir que a configuração ocorra ANTES dos efeitos dos componentes filhos
|
|
904
920
|
useMemo(() => {
|
|
905
921
|
configure({
|
|
906
922
|
apiUrl,
|
|
907
|
-
apiKey
|
|
923
|
+
apiKey,
|
|
924
|
+
internal
|
|
908
925
|
});
|
|
909
|
-
}, [apiUrl, apiKey]);
|
|
926
|
+
}, [apiUrl, apiKey, internal]);
|
|
910
927
|
useEffect(() => {
|
|
911
928
|
init();
|
|
912
929
|
startRefresh();
|
|
@@ -935,6 +952,8 @@ function AuthProvider({
|
|
|
935
952
|
});
|
|
936
953
|
// Dispara evento de logout para sincronizar entre abas
|
|
937
954
|
localStorage.setItem('auth:logout', Date.now());
|
|
955
|
+
// Recarrega para redirecionar - deixa o Protect/rotas decidirem para onde ir
|
|
956
|
+
window.location.reload();
|
|
938
957
|
};
|
|
939
958
|
window.addEventListener('storage', handleStorageChange);
|
|
940
959
|
window.addEventListener('auth:session-revoked', handleSessionRevoked);
|