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