@riligar/auth-react 1.4.0 → 1.5.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 -18
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +67 -16
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React$1, {
|
|
1
|
+
import React$1, { useMemo, useEffect, createContext, useState, useRef } from 'react';
|
|
2
2
|
import { Navigate, Outlet } from 'react-router-dom';
|
|
3
3
|
import { Paper, Stack, Image, Title, Text, TextInput, PasswordInput, Anchor, Button, Divider, Group, Center, Loader } from '@mantine/core';
|
|
4
4
|
import { useForm } from '@mantine/form';
|
|
@@ -58,10 +58,18 @@ async function api(route, opts = {}) {
|
|
|
58
58
|
|
|
59
59
|
// Converte JSON automaticamente e lança erro legível
|
|
60
60
|
const data = res.status !== 204 ? await res.json().catch(() => ({})) : null;
|
|
61
|
-
if (!res.ok)
|
|
62
|
-
res
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
if (!res.ok) {
|
|
62
|
+
let errorMessage = data?.message || data?.error || data?.detail || res.statusText;
|
|
63
|
+
|
|
64
|
+
// Se a mensagem for um objeto, tenta extrair string ou stringify
|
|
65
|
+
if (typeof errorMessage === 'object') {
|
|
66
|
+
errorMessage = errorMessage.message || JSON.stringify(errorMessage);
|
|
67
|
+
}
|
|
68
|
+
throw Object.assign(new Error(errorMessage), {
|
|
69
|
+
res,
|
|
70
|
+
data
|
|
71
|
+
});
|
|
72
|
+
}
|
|
65
73
|
return data;
|
|
66
74
|
}
|
|
67
75
|
|
|
@@ -756,7 +764,9 @@ function AuthProvider({
|
|
|
756
764
|
const checkTokenValidity = useAuthStore(s => s.checkTokenValidity);
|
|
757
765
|
|
|
758
766
|
// Configura SDK com apiUrl e apiKey
|
|
759
|
-
|
|
767
|
+
// Configura SDK com apiUrl e apiKey
|
|
768
|
+
// Usamos useMemo para garantir que a configuração ocorra ANTES dos efeitos dos componentes filhos
|
|
769
|
+
useMemo(() => {
|
|
760
770
|
configure({
|
|
761
771
|
apiUrl,
|
|
762
772
|
apiKey
|
|
@@ -1274,6 +1284,7 @@ function MagicLinkVerify({
|
|
|
1274
1284
|
const [status, setStatus] = useState('verifying'); // verifying, success, error
|
|
1275
1285
|
const [errorMessage, setErrorMessage] = useState('');
|
|
1276
1286
|
const verifyMagicLink = useAuthStore(s => s.verifyMagicLink);
|
|
1287
|
+
const verifyingTokenRef = useRef(null);
|
|
1277
1288
|
useEffect(() => {
|
|
1278
1289
|
const verify = async () => {
|
|
1279
1290
|
// Pega token da prop ou da URL
|
|
@@ -1288,6 +1299,10 @@ function MagicLinkVerify({
|
|
|
1288
1299
|
onError?.(new Error('No token'));
|
|
1289
1300
|
return;
|
|
1290
1301
|
}
|
|
1302
|
+
|
|
1303
|
+
// Evita verificar o mesmo token duas vezes (React Strict Mode ou re-renders)
|
|
1304
|
+
if (verifyingTokenRef.current === token) return;
|
|
1305
|
+
verifyingTokenRef.current = token;
|
|
1291
1306
|
try {
|
|
1292
1307
|
const result = await verifyMagicLink(token);
|
|
1293
1308
|
setStatus('success');
|
|
@@ -1304,7 +1319,8 @@ function MagicLinkVerify({
|
|
|
1304
1319
|
}
|
|
1305
1320
|
};
|
|
1306
1321
|
verify();
|
|
1307
|
-
|
|
1322
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1323
|
+
}, [propToken, redirectTo, redirectDelay]);
|
|
1308
1324
|
return /*#__PURE__*/React.createElement(AuthCard, _extends({
|
|
1309
1325
|
logo: logo
|
|
1310
1326
|
}, cardProps), status === 'verifying' && /*#__PURE__*/React.createElement(Stack, {
|
|
@@ -1559,9 +1575,13 @@ function VerifyEmailCard({
|
|
|
1559
1575
|
}) {
|
|
1560
1576
|
const [status, setStatus] = useState('verifying'); // verifying, success, error
|
|
1561
1577
|
const [errorMessage, setErrorMessage] = useState('');
|
|
1578
|
+
const [tokenEmail, setTokenEmail] = useState(null); // Novo estado para email do token
|
|
1579
|
+
|
|
1562
1580
|
const verifyEmail = useAuthStore(s => s.verifyEmail);
|
|
1563
1581
|
const resendVerification = useAuthStore(s => s.resendVerification);
|
|
1564
1582
|
const loadingResend = useAuthStore(s => s.loadingStates.resendVerification);
|
|
1583
|
+
const user = useAuthStore(s => s.user);
|
|
1584
|
+
const verifyingTokenRef = useRef(null);
|
|
1565
1585
|
useEffect(() => {
|
|
1566
1586
|
const verify = async () => {
|
|
1567
1587
|
// Pega token da prop ou da URL
|
|
@@ -1571,11 +1591,25 @@ function VerifyEmailCard({
|
|
|
1571
1591
|
token = urlParams.get('token');
|
|
1572
1592
|
}
|
|
1573
1593
|
if (!token) {
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1594
|
+
// Se já mostramos o erro de token faltando, não precisa fazer nada
|
|
1595
|
+
if (status === 'missing_token') return;
|
|
1596
|
+
setStatus('missing_token');
|
|
1577
1597
|
return;
|
|
1578
1598
|
}
|
|
1599
|
+
|
|
1600
|
+
// Tenta extrair email do token (mesmo expirado) para permitir reenvio
|
|
1601
|
+
try {
|
|
1602
|
+
const payload = decodeJWT(token);
|
|
1603
|
+
if (payload?.email) {
|
|
1604
|
+
setTokenEmail(payload.email);
|
|
1605
|
+
}
|
|
1606
|
+
} catch (e) {
|
|
1607
|
+
// ignore jwt error
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
// Evita verificar o mesmo token duas vezes (React Strict Mode ou re-renders)
|
|
1611
|
+
if (verifyingTokenRef.current === token) return;
|
|
1612
|
+
verifyingTokenRef.current = token;
|
|
1579
1613
|
try {
|
|
1580
1614
|
const result = await verifyEmail(token);
|
|
1581
1615
|
setStatus('success');
|
|
@@ -1586,18 +1620,22 @@ function VerifyEmailCard({
|
|
|
1586
1620
|
}, redirectDelay);
|
|
1587
1621
|
}
|
|
1588
1622
|
} catch (error) {
|
|
1623
|
+
// Se der erro, permitimos tentar novamente apenas se o usuário recarregar
|
|
1624
|
+
// ou se implementarmos um botão de retry que limpe o ref
|
|
1589
1625
|
setStatus('error');
|
|
1590
1626
|
setErrorMessage(error.message || labels.verificationFailed || 'Verificação falhou');
|
|
1591
1627
|
onError?.(error);
|
|
1592
1628
|
}
|
|
1593
1629
|
};
|
|
1594
1630
|
verify();
|
|
1595
|
-
|
|
1631
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1632
|
+
}, [propToken, redirectTo, redirectDelay]);
|
|
1596
1633
|
const handleResend = async () => {
|
|
1597
|
-
|
|
1634
|
+
const targetEmail = email || user?.email || tokenEmail;
|
|
1635
|
+
if (!targetEmail) return;
|
|
1598
1636
|
try {
|
|
1599
|
-
await resendVerification(
|
|
1600
|
-
onResent?.(
|
|
1637
|
+
await resendVerification(targetEmail);
|
|
1638
|
+
onResent?.(targetEmail);
|
|
1601
1639
|
} catch (error) {
|
|
1602
1640
|
onError?.(error);
|
|
1603
1641
|
}
|
|
@@ -1615,7 +1653,19 @@ function VerifyEmailCard({
|
|
|
1615
1653
|
size: "sm",
|
|
1616
1654
|
c: "dimmed",
|
|
1617
1655
|
ta: "center"
|
|
1618
|
-
}, labels.pleaseWait || 'Aguarde enquanto verificamos seu email...')), status === '
|
|
1656
|
+
}, labels.pleaseWait || 'Aguarde enquanto verificamos seu email...')), status === 'missing_token' && /*#__PURE__*/React.createElement(Stack, {
|
|
1657
|
+
align: "center",
|
|
1658
|
+
gap: "sm"
|
|
1659
|
+
}, /*#__PURE__*/React.createElement(IconMail, {
|
|
1660
|
+
size: 48,
|
|
1661
|
+
color: "var(--mantine-color-blue-6)"
|
|
1662
|
+
}), /*#__PURE__*/React.createElement(Title, {
|
|
1663
|
+
order: 4
|
|
1664
|
+
}, labels.verification || 'Verificação de Email'), /*#__PURE__*/React.createElement(Text, {
|
|
1665
|
+
size: "sm",
|
|
1666
|
+
c: "dimmed",
|
|
1667
|
+
ta: "center"
|
|
1668
|
+
}, labels.missingToken || 'Para verificar seu conta, clique no link enviado para seu email.')), status === 'success' && /*#__PURE__*/React.createElement(Stack, {
|
|
1619
1669
|
align: "center",
|
|
1620
1670
|
gap: "sm"
|
|
1621
1671
|
}, /*#__PURE__*/React.createElement(IconCheck, {
|
|
@@ -1639,7 +1689,7 @@ function VerifyEmailCard({
|
|
|
1639
1689
|
size: "sm",
|
|
1640
1690
|
c: "dimmed",
|
|
1641
1691
|
ta: "center"
|
|
1642
|
-
}, errorMessage || labels.invalidToken || 'O link é inválido ou expirou.'), email && /*#__PURE__*/React.createElement(Button, {
|
|
1692
|
+
}, errorMessage || labels.invalidToken || 'O link é inválido ou expirou.'), (email || user?.email || tokenEmail) && errorMessage?.toLowerCase().includes('expired') && /*#__PURE__*/React.createElement(Button, {
|
|
1643
1693
|
variant: "light",
|
|
1644
1694
|
leftSection: /*#__PURE__*/React.createElement(IconRefresh, {
|
|
1645
1695
|
size: 16
|
|
@@ -1647,8 +1697,8 @@ function VerifyEmailCard({
|
|
|
1647
1697
|
onClick: handleResend,
|
|
1648
1698
|
loading: loadingResend,
|
|
1649
1699
|
fullWidth: true
|
|
1650
|
-
}, labels.resend || '
|
|
1700
|
+
}, labels.resend || 'Solicitar novo link')));
|
|
1651
1701
|
}
|
|
1652
1702
|
|
|
1653
|
-
export { AuthCard, AuthProvider, ForgotPasswordForm, MagicLinkForm, MagicLinkVerify, ProtectedRoute, ResetPasswordForm, SignInForm, SignUpForm, VerifyEmailCard, configure, forgotPassword, getCurrentUser, getSession, isAuthenticated, refreshToken, resendVerification, resetPassword, sendMagicLink, signIn, signOut, signUp, socialRedirect, useAuth, useAuthLoading, useAuthStore, useCheckToken, useEmailVerification, useMagicLink, usePasswordReset, useSession, useSignIn, useSignOut, useSignUp, verifyEmail, verifyMagicLink };
|
|
1703
|
+
export { AuthCard, AuthProvider, ForgotPasswordForm, MagicLinkForm, MagicLinkVerify, ProtectedRoute, ResetPasswordForm, SignInForm, SignUpForm, VerifyEmailCard, configure, decodeJWT, forgotPassword, getCurrentUser, getSession, isAuthenticated, refreshToken, resendVerification, resetPassword, sendMagicLink, signIn, signOut, signUp, socialRedirect, useAuth, useAuthLoading, useAuthStore, useCheckToken, useEmailVerification, useMagicLink, usePasswordReset, useSession, useSignIn, useSignOut, useSignUp, verifyEmail, verifyMagicLink };
|
|
1654
1704
|
//# sourceMappingURL=index.esm.js.map
|