flysoft-react-ui 0.3.0 → 0.3.1
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/contexts/AuthContext.d.ts.map +1 -1
- package/dist/contexts/AuthContext.js +108 -14
- package/dist/docs/AuthDocs.tsx/AuthDocs.d.ts +11 -0
- package/dist/docs/AuthDocs.tsx/AuthDocs.d.ts.map +1 -1
- package/dist/docs/AuthDocs.tsx/AuthDocs.js +14 -33
- package/dist/docs/AuthDocs.tsx/AuthDocsContent.d.ts.map +1 -1
- package/dist/docs/AuthDocs.tsx/AuthDocsContent.js +11 -3
- package/dist/docs/AuthDocs.tsx/mockAuthService.d.ts +24 -0
- package/dist/docs/AuthDocs.tsx/mockAuthService.d.ts.map +1 -0
- package/dist/docs/AuthDocs.tsx/mockAuthService.js +78 -0
- package/dist/docs/DocsMenu.d.ts.map +1 -1
- package/dist/docs/DocsMenu.js +1 -1
- package/dist/docs/DocsRouter.d.ts.map +1 -1
- package/dist/docs/DocsRouter.js +2 -1
- package/dist/index.css +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../src/contexts/AuthContext.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,wBAAwB;IACvC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACtC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,0CAMtB,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../src/contexts/AuthContext.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,wBAAwB;IACvC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACtC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,0CAMtB,CAAC;AAiEH,UAAU,iBAAiB;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC9E,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAClE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAmHpD,CAAC"}
|
|
@@ -19,36 +19,111 @@ const storeAuth = (auth) => {
|
|
|
19
19
|
const removeStoredAuth = () => {
|
|
20
20
|
localStorage.removeItem("auth");
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Verifica si un token ha expirado basándose en el string expires en formato ISO 8601
|
|
24
|
+
* @param expires - String de fecha en formato ISO 8601
|
|
25
|
+
* @returns true si el token ha expirado o si el formato es inválido, false si está vigente
|
|
26
|
+
*/
|
|
27
|
+
const isTokenExpired = (expires) => {
|
|
28
|
+
if (!expires) {
|
|
29
|
+
return true; // Si no hay fecha de expiración, consideramos que está expirado
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
// Validar formato ISO 8601 básico (debe poder ser parseado por Date)
|
|
33
|
+
const expirationDate = new Date(expires);
|
|
34
|
+
// Verificar que la fecha sea válida
|
|
35
|
+
if (isNaN(expirationDate.getTime())) {
|
|
36
|
+
console.warn("Formato de fecha de expiración inválido:", expires);
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
// Comparar con la fecha actual (agregamos un margen de 1 minuto para evitar problemas de precisión)
|
|
40
|
+
const now = new Date();
|
|
41
|
+
const oneMinuteInMs = 60 * 1000;
|
|
42
|
+
return expirationDate.getTime() <= now.getTime() + oneMinuteInMs;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error("Error al verificar expiración del token:", error);
|
|
46
|
+
return true; // En caso de error, considerar como expirado por seguridad
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Valida que un usuario tenga un token vigente
|
|
51
|
+
* @param user - Objeto de usuario a validar
|
|
52
|
+
* @returns true si el usuario tiene un token válido y vigente, false en caso contrario
|
|
53
|
+
*/
|
|
54
|
+
const isUserTokenValid = (user) => {
|
|
55
|
+
if (!user || !user.id) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
if (!user.token) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
return !isTokenExpired(user.token.expires);
|
|
62
|
+
};
|
|
22
63
|
export const AuthProvider = ({ children, getToken, getUserData, removeToken, }) => {
|
|
23
64
|
const [user, setUser] = useState(null);
|
|
24
65
|
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
25
66
|
const [isLoading, setIsLoading] = useState(false);
|
|
26
67
|
useEffect(() => {
|
|
27
68
|
const auth = initAuth();
|
|
28
|
-
|
|
69
|
+
// Verificar que el usuario tenga un token válido y vigente
|
|
70
|
+
if (isUserTokenValid(auth)) {
|
|
29
71
|
setUser(auth);
|
|
30
72
|
setIsAuthenticated(true);
|
|
31
73
|
}
|
|
32
74
|
else {
|
|
75
|
+
// Si el token está expirado o es inválido, limpiar el almacenamiento
|
|
76
|
+
if (auth.id && isTokenExpired(auth.token?.expires)) {
|
|
77
|
+
removeStoredAuth();
|
|
78
|
+
}
|
|
79
|
+
setUser(null);
|
|
33
80
|
setIsAuthenticated(false);
|
|
34
81
|
}
|
|
35
82
|
}, []);
|
|
36
83
|
const login = async (username, password) => {
|
|
37
84
|
setIsLoading(true);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
85
|
+
try {
|
|
86
|
+
const token = await getToken(username, password);
|
|
87
|
+
if (token.accessToken) {
|
|
88
|
+
// Verificar que el token recibido no esté expirado antes de continuar
|
|
89
|
+
if (isTokenExpired(token.expires)) {
|
|
90
|
+
console.warn("El token recibido ya está expirado");
|
|
91
|
+
setUser(null);
|
|
92
|
+
setIsAuthenticated(false);
|
|
93
|
+
setIsLoading(false);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const { id, name, aditionalData } = await getUserData(token.accessToken);
|
|
97
|
+
const userData = {
|
|
98
|
+
id,
|
|
99
|
+
name,
|
|
100
|
+
aditionalData,
|
|
101
|
+
token,
|
|
102
|
+
};
|
|
103
|
+
// Validar nuevamente antes de establecer el estado
|
|
104
|
+
if (isUserTokenValid(userData)) {
|
|
105
|
+
setUser(userData);
|
|
106
|
+
storeAuth(userData);
|
|
107
|
+
setIsAuthenticated(true);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
setUser(null);
|
|
111
|
+
setIsAuthenticated(false);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
setUser(null);
|
|
116
|
+
setIsAuthenticated(false);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.error("Error durante el login:", error);
|
|
121
|
+
setUser(null);
|
|
122
|
+
setIsAuthenticated(false);
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
setIsLoading(false);
|
|
50
126
|
}
|
|
51
|
-
setIsLoading(false);
|
|
52
127
|
};
|
|
53
128
|
const logout = async () => {
|
|
54
129
|
removeStoredAuth();
|
|
@@ -58,5 +133,24 @@ export const AuthProvider = ({ children, getToken, getUserData, removeToken, })
|
|
|
58
133
|
}
|
|
59
134
|
setIsAuthenticated(false);
|
|
60
135
|
};
|
|
136
|
+
// Validar el token periódicamente o cuando cambia el usuario
|
|
137
|
+
// Esto asegura que si el token expira durante la sesión, se actualice el estado
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
if (user && user.token?.expires) {
|
|
140
|
+
const checkTokenExpiration = () => {
|
|
141
|
+
if (isTokenExpired(user.token?.expires)) {
|
|
142
|
+
// Token expirado, cerrar sesión
|
|
143
|
+
removeStoredAuth();
|
|
144
|
+
setUser(null);
|
|
145
|
+
setIsAuthenticated(false);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
// Verificar inmediatamente
|
|
149
|
+
checkTokenExpiration();
|
|
150
|
+
// Verificar cada minuto para detectar expiraciones
|
|
151
|
+
const interval = setInterval(checkTokenExpiration, 60000);
|
|
152
|
+
return () => clearInterval(interval);
|
|
153
|
+
}
|
|
154
|
+
}, [user]);
|
|
61
155
|
return (_jsx(AuthContext.Provider, { value: { user, isAuthenticated, isLoading, login, logout }, children: children }));
|
|
62
156
|
};
|
|
@@ -1,2 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Componente de Documentación del AuthContext
|
|
3
|
+
*
|
|
4
|
+
* Este componente muestra cómo usar el AuthContext con un servicio mock
|
|
5
|
+
* para propósitos de documentación y desarrollo.
|
|
6
|
+
*
|
|
7
|
+
* El servicio mock simula las tres operaciones principales:
|
|
8
|
+
* - getToken: Obtiene un token de acceso
|
|
9
|
+
* - getUserData: Obtiene los datos del usuario autenticado
|
|
10
|
+
* - removeToken: Revoca/invalida un token (opcional)
|
|
11
|
+
*/
|
|
1
12
|
export declare const AuthDocs: () => import("react/jsx-runtime").JSX.Element;
|
|
2
13
|
//# sourceMappingURL=AuthDocs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthDocs.d.ts","sourceRoot":"","sources":["../../../src/docs/AuthDocs.tsx/AuthDocs.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AuthDocs.d.ts","sourceRoot":"","sources":["../../../src/docs/AuthDocs.tsx/AuthDocs.tsx"],"names":[],"mappings":"AAQA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,+CAUpB,CAAC"}
|
|
@@ -1,37 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { AuthProvider
|
|
3
|
-
import { apiClient } from "../../services/apiClient";
|
|
2
|
+
import { AuthProvider } from "../../contexts/AuthContext";
|
|
4
3
|
import { AuthDocsContent } from "./AuthDocsContent";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
refreshToken: refresh_token,
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
const getUserData = async (token) => {
|
|
21
|
-
const { id, name } = await apiClient.get({
|
|
22
|
-
url: "https://devmanager.osocna.com.ar/backend/api/users/userdata",
|
|
23
|
-
headers: {
|
|
24
|
-
Authorization: `Bearer ${token}`,
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
return {
|
|
28
|
-
id,
|
|
29
|
-
name,
|
|
30
|
-
aditionalData: {
|
|
31
|
-
role: "admin",
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
};
|
|
4
|
+
import { mockGetToken, mockGetUserData, mockRemoveToken, } from "./mockAuthService";
|
|
5
|
+
/**
|
|
6
|
+
* Componente de Documentación del AuthContext
|
|
7
|
+
*
|
|
8
|
+
* Este componente muestra cómo usar el AuthContext con un servicio mock
|
|
9
|
+
* para propósitos de documentación y desarrollo.
|
|
10
|
+
*
|
|
11
|
+
* El servicio mock simula las tres operaciones principales:
|
|
12
|
+
* - getToken: Obtiene un token de acceso
|
|
13
|
+
* - getUserData: Obtiene los datos del usuario autenticado
|
|
14
|
+
* - removeToken: Revoca/invalida un token (opcional)
|
|
15
|
+
*/
|
|
35
16
|
export const AuthDocs = () => {
|
|
36
|
-
return (_jsx(AuthProvider, { getToken:
|
|
17
|
+
return (_jsx(AuthProvider, { getToken: mockGetToken, getUserData: mockGetUserData, removeToken: mockRemoveToken, children: _jsx(AuthDocsContent, {}) }));
|
|
37
18
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthDocsContent.d.ts","sourceRoot":"","sources":["../../../src/docs/AuthDocs.tsx/AuthDocsContent.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,+
|
|
1
|
+
{"version":3,"file":"AuthDocsContent.d.ts","sourceRoot":"","sources":["../../../src/docs/AuthDocs.tsx/AuthDocsContent.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,+CAmW3B,CAAC"}
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useContext } from "react";
|
|
3
3
|
import { AuthContext } from "../../contexts/AuthContext";
|
|
4
|
-
import { Button } from "../../components";
|
|
4
|
+
import { Button, Card, DataField, Badge } from "../../components";
|
|
5
5
|
export const AuthDocsContent = () => {
|
|
6
6
|
const { login, isAuthenticated, isLoading, user, logout } = useContext(AuthContext);
|
|
7
7
|
const handleLogin = async () => {
|
|
8
|
-
await login("
|
|
8
|
+
await login("usuario@ejemplo.com", "password123");
|
|
9
9
|
};
|
|
10
10
|
const handleLogout = () => {
|
|
11
11
|
logout();
|
|
12
12
|
};
|
|
13
|
-
|
|
13
|
+
// Sección de documentación de interfaces (siempre visible)
|
|
14
|
+
const InterfacesDocumentation = () => (_jsx("div", { className: "space-y-4 mb-6", children: _jsx(Card, { title: "Interfaces de TypeScript", subtitle: "Estructuras de datos utilizadas por el AuthContext", children: _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2 mb-3", children: [_jsx(Badge, { variant: "primary", icon: "fa-code", size: "sm", children: "Interface" }), _jsx("code", { className: "text-sm font-mono text-[var(--color-primary)] font-semibold", children: "AuthTokenInterface" })] }), _jsx("p", { className: "text-sm text-[var(--color-text-secondary)] mb-3", children: "Define la estructura de los datos del token de autenticaci\u00F3n devueltos por el servicio de autenticaci\u00F3n." }), _jsx("div", { className: "bg-[var(--color-bg-secondary)] rounded-lg p-4 border border-[var(--color-border-default)]", children: _jsxs("div", { className: "space-y-2", children: [_jsx(DataField, { label: "accessToken", value: _jsx("span", { className: "text-xs font-mono", children: "string | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Token de acceso utilizado para autenticar las solicitudes HTTP." }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "tokenType", value: _jsx("span", { className: "text-xs font-mono", children: "string | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Tipo de token (generalmente \"Bearer\")." })] }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "expires", value: _jsx("span", { className: "text-xs font-mono", children: "string | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Fecha de expiraci\u00F3n del token en formato ISO 8601." })] }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "refreshToken", value: _jsx("span", { className: "text-xs font-mono", children: "string | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Token de actualizaci\u00F3n utilizado para obtener un nuevo token de acceso cuando el actual expira." })] })] }) })] }), _jsxs("div", { className: "pt-4 border-t border-[var(--color-border-default)]", children: [_jsxs("div", { className: "flex items-center gap-2 mb-3", children: [_jsx(Badge, { variant: "primary", icon: "fa-code", size: "sm", children: "Interface" }), _jsx("code", { className: "text-sm font-mono text-[var(--color-primary)] font-semibold", children: "AuthContextUserInterface" })] }), _jsx("p", { className: "text-sm text-[var(--color-text-secondary)] mb-3", children: "Define la estructura de los datos del usuario autenticado que se almacenan en el contexto." }), _jsx("div", { className: "bg-[var(--color-bg-secondary)] rounded-lg p-4 border border-[var(--color-border-default)]", children: _jsxs("div", { className: "space-y-2", children: [_jsx(DataField, { label: "id", value: _jsx("span", { className: "text-xs font-mono", children: "number | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Identificador \u00FAnico del usuario." }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "name", value: _jsx("span", { className: "text-xs font-mono", children: "string | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Nombre del usuario." })] }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "aditionalData", value: _jsx("span", { className: "text-xs font-mono", children: "any | undefined" }) }), _jsx("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: "Objeto que puede contener datos adicionales del usuario (roles, permisos, email, etc.). Es flexible y puede adaptarse a las necesidades espec\u00EDficas de cada aplicaci\u00F3n." })] }), _jsxs("div", { className: "pt-2 border-t border-[var(--color-border-default)]", children: [_jsx(DataField, { label: "token", value: _jsx("span", { className: "text-xs font-mono", children: "AuthTokenInterface | undefined" }) }), _jsxs("p", { className: "text-xs text-[var(--color-text-secondary)] ml-2", children: ["Objeto de token que contiene el", " ", _jsx("code", { className: "text-xs bg-white/50 px-1 rounded", children: "AuthTokenInterface" }), " ", "con la informaci\u00F3n de autenticaci\u00F3n."] })] })] }) })] })] }) }) }));
|
|
15
|
+
if (isLoading) {
|
|
16
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { children: _jsx("div", { className: "flex items-center justify-center py-8", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("i", { className: "fa fa-spinner fa-spin text-[var(--color-primary)] text-xl" }), _jsx("span", { className: "text-[var(--color-text-secondary)]", children: "Iniciando sesi\u00F3n..." })] }) }) })] }));
|
|
17
|
+
}
|
|
18
|
+
if (isAuthenticated && user) {
|
|
19
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { title: "Sesi\u00F3n Activa", subtitle: "Informaci\u00F3n del usuario autenticado", headerActions: _jsx(Badge, { variant: "success", icon: "fa-check-circle", iconPosition: "left", children: "Autenticado" }), children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(DataField, { label: "ID de Usuario", value: user.id }), _jsx(DataField, { label: "Nombre", value: user.name || "No disponible" })] }), user.aditionalData && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[var(--color-border-default)]", children: [_jsx("h4", { className: "text-sm font-semibold text-[var(--color-text-primary)] mb-3", children: "Datos Adicionales" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [user.aditionalData.role && (_jsx(DataField, { label: "Rol", value: _jsx(Badge, { variant: "primary", icon: "fa-user-shield", children: user.aditionalData.role }) })), user.aditionalData.email && (_jsx(DataField, { label: "Email", value: user.aditionalData.email })), user.aditionalData.createdAt && (_jsx(DataField, { label: "Fecha de Creaci\u00F3n", value: new Date(user.aditionalData.createdAt).toLocaleString() })), user.aditionalData.permissions && (_jsx(DataField, { label: "Permisos", value: _jsx("div", { className: "flex flex-wrap gap-2", children: user.aditionalData.permissions.map((permission, index) => (_jsx(Badge, { variant: "info", size: "sm", icon: "fa-key", children: permission }, index))) }) }))] })] })), user.token && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[var(--color-border-default)]", children: [_jsx("h4", { className: "text-sm font-semibold text-[var(--color-text-primary)] mb-3", children: "Informaci\u00F3n del Token" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(DataField, { label: "Tipo de Token", value: _jsx(Badge, { variant: "secondary", icon: "fa-tag", children: user.token.tokenType || "Bearer" }) }), user.token.expires && (_jsx(DataField, { label: "Expira", value: new Date(user.token.expires).toLocaleString() })), user.token.accessToken && (_jsx(DataField, { label: "Access Token", value: _jsxs("code", { className: "text-xs bg-[var(--color-bg-secondary)] px-2 py-1 rounded break-all", children: [user.token.accessToken.substring(0, 30), "..."] }) }))] })] })), _jsx("div", { className: "mt-6 pt-4 border-t border-[var(--color-border-default)]", children: _jsx(Button, { variant: "outline", icon: "fa-sign-out-alt", iconPosition: "left", onClick: handleLogout, className: "w-full md:w-auto", children: "Cerrar Sesi\u00F3n" }) })] }) })] }));
|
|
20
|
+
}
|
|
21
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsx(InterfacesDocumentation, {}), _jsx(Card, { title: "Autenticaci\u00F3n", subtitle: "Inicia sesi\u00F3n para ver el AuthContext en acci\u00F3n", children: _jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "bg-[var(--color-info-light)] border border-[var(--color-info)] rounded-lg p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("i", { className: "fa fa-info-circle text-[var(--color-info)] mt-1" }), _jsx("div", { className: "flex-1", children: _jsxs("p", { className: "text-sm text-[var(--color-text-primary)]", children: ["Esta es una demostraci\u00F3n del", " ", _jsx("code", { className: "text-xs bg-white/50 px-1 rounded", children: "AuthContext" }), " ", "usando un servicio mock. Haz clic en el bot\u00F3n para simular un inicio de sesi\u00F3n."] }) })] }) }), _jsx("div", { className: "flex justify-center pt-4", children: _jsx(Button, { variant: "primary", size: "lg", icon: "fa-sign-in-alt", iconPosition: "left", onClick: handleLogin, children: "Iniciar Sesi\u00F3n" }) })] }) })] }));
|
|
14
22
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AuthTokenInterface, AuthContextUserInterface } from "../../contexts/AuthContext";
|
|
2
|
+
/**
|
|
3
|
+
* Mock de getToken - Obtiene un token de acceso
|
|
4
|
+
*
|
|
5
|
+
* @param username - Nombre de usuario o email
|
|
6
|
+
* @param password - Contraseña del usuario
|
|
7
|
+
* @returns Promise con los datos del token
|
|
8
|
+
*/
|
|
9
|
+
export declare const mockGetToken: (username: string, password: string) => Promise<AuthTokenInterface>;
|
|
10
|
+
/**
|
|
11
|
+
* Mock de getUserData - Obtiene los datos del usuario autenticado
|
|
12
|
+
*
|
|
13
|
+
* @param token - Token de acceso
|
|
14
|
+
* @returns Promise con los datos del usuario
|
|
15
|
+
*/
|
|
16
|
+
export declare const mockGetUserData: (token: string) => Promise<AuthContextUserInterface>;
|
|
17
|
+
/**
|
|
18
|
+
* Mock de removeToken - Revoca/invalida un token
|
|
19
|
+
*
|
|
20
|
+
* @param token - Token a revocar
|
|
21
|
+
* @returns Promise que se resuelve cuando el token es revocado
|
|
22
|
+
*/
|
|
23
|
+
export declare const mockRemoveToken: (token: string) => Promise<void>;
|
|
24
|
+
//# sourceMappingURL=mockAuthService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockAuthService.d.ts","sourceRoot":"","sources":["../../../src/docs/AuthDocs.tsx/mockAuthService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,4BAA4B,CAAC;AAgBpC;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,OAAO,CAAC,kBAAkB,CAqB5B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,OAAO,MAAM,KACZ,OAAO,CAAC,wBAAwB,CAoBlC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAWjE,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Servicio Mock para Autenticación
|
|
3
|
+
*
|
|
4
|
+
* Este servicio simula las llamadas a la API de autenticación
|
|
5
|
+
* para propósitos de documentación y desarrollo.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Simula un delay de red para hacer más realista el mock
|
|
9
|
+
*/
|
|
10
|
+
const simulateNetworkDelay = (ms = 800) => {
|
|
11
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Mock de getToken - Obtiene un token de acceso
|
|
15
|
+
*
|
|
16
|
+
* @param username - Nombre de usuario o email
|
|
17
|
+
* @param password - Contraseña del usuario
|
|
18
|
+
* @returns Promise con los datos del token
|
|
19
|
+
*/
|
|
20
|
+
export const mockGetToken = async (username, password) => {
|
|
21
|
+
await simulateNetworkDelay();
|
|
22
|
+
// Validación básica de credenciales
|
|
23
|
+
if (!username || !password) {
|
|
24
|
+
throw new Error("Username y password son requeridos");
|
|
25
|
+
}
|
|
26
|
+
// Simular token JWT
|
|
27
|
+
const tokenData = {
|
|
28
|
+
accessToken: `mock_access_token_${Date.now()}_${Math.random()
|
|
29
|
+
.toString(36)
|
|
30
|
+
.substring(7)}`,
|
|
31
|
+
tokenType: "Bearer",
|
|
32
|
+
expires: new Date(Date.now() + 3600000).toISOString(), // 1 hora
|
|
33
|
+
refreshToken: `mock_refresh_token_${Date.now()}_${Math.random()
|
|
34
|
+
.toString(36)
|
|
35
|
+
.substring(7)}`,
|
|
36
|
+
};
|
|
37
|
+
return tokenData;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Mock de getUserData - Obtiene los datos del usuario autenticado
|
|
41
|
+
*
|
|
42
|
+
* @param token - Token de acceso
|
|
43
|
+
* @returns Promise con los datos del usuario
|
|
44
|
+
*/
|
|
45
|
+
export const mockGetUserData = async (token) => {
|
|
46
|
+
await simulateNetworkDelay();
|
|
47
|
+
if (!token) {
|
|
48
|
+
throw new Error("Token es requerido");
|
|
49
|
+
}
|
|
50
|
+
// Simular datos de usuario
|
|
51
|
+
const userData = {
|
|
52
|
+
id: 123,
|
|
53
|
+
name: "Usuario de Prueba",
|
|
54
|
+
aditionalData: {
|
|
55
|
+
role: "admin",
|
|
56
|
+
email: "usuario@ejemplo.com",
|
|
57
|
+
createdAt: new Date().toISOString(),
|
|
58
|
+
permissions: ["read", "write", "delete"],
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
return userData;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Mock de removeToken - Revoca/invalida un token
|
|
65
|
+
*
|
|
66
|
+
* @param token - Token a revocar
|
|
67
|
+
* @returns Promise que se resuelve cuando el token es revocado
|
|
68
|
+
*/
|
|
69
|
+
export const mockRemoveToken = async (token) => {
|
|
70
|
+
await simulateNetworkDelay();
|
|
71
|
+
if (!token) {
|
|
72
|
+
throw new Error("Token es requerido");
|
|
73
|
+
}
|
|
74
|
+
// Simular revocación del token
|
|
75
|
+
// En una implementación real, aquí se haría una llamada al servidor
|
|
76
|
+
// para invalidar el token
|
|
77
|
+
console.log(`Token revocado: ${token.substring(0, 20)}...`);
|
|
78
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocsMenu.d.ts","sourceRoot":"","sources":["../../src/docs/DocsMenu.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,+
|
|
1
|
+
{"version":3,"file":"DocsMenu.d.ts","sourceRoot":"","sources":["../../src/docs/DocsMenu.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,+CA4BpB,CAAC"}
|
package/dist/docs/DocsMenu.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Link } from "react-router-dom";
|
|
3
3
|
export const DocsMenu = () => {
|
|
4
|
-
return (_jsx(_Fragment, { children: _jsxs("ul", { children: [_jsx("li", { children: _jsx(Link, { to: "/docs/button", children: "Button" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/badge", children: "Badge" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/card", children: "Card" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/input", children: "Input" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/theme", children: "ThemeSwitcher" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/datafield", children: "DataField" }) })] }) }));
|
|
4
|
+
return (_jsx(_Fragment, { children: _jsxs("ul", { children: [_jsx("li", { children: _jsx(Link, { to: "/docs/button", children: "Button" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/badge", children: "Badge" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/card", children: "Card" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/input", children: "Input" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/theme", children: "ThemeSwitcher" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/datafield", children: "DataField" }) }), _jsx("li", { children: _jsx(Link, { to: "/docs/auth", children: "AuthContext" }) })] }) }));
|
|
5
5
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocsRouter.d.ts","sourceRoot":"","sources":["../../src/docs/DocsRouter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"DocsRouter.d.ts","sourceRoot":"","sources":["../../src/docs/DocsRouter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAa9B,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
package/dist/docs/DocsRouter.js
CHANGED
|
@@ -7,7 +7,8 @@ import InputDocs from "./InputDocs";
|
|
|
7
7
|
import ThemeSwitcherDocs from "./ThemeSwitcherDocs";
|
|
8
8
|
import BadgeDocs from "./BadgeDocs";
|
|
9
9
|
import DataFieldDocs from "./DataFieldDocs";
|
|
10
|
+
import { AuthDocs } from "./AuthDocs.tsx/AuthDocs";
|
|
10
11
|
export const DocsRouter = () => {
|
|
11
|
-
return (_jsxs(Routes, { children: [_jsx(Route, { path: "", element: _jsx(Navigate, { to: "button", replace: true }) }), _jsx(Route, { path: "button", element: _jsx(ButtonDocs, {}) }), _jsx(Route, { path: "badge", element: _jsx(BadgeDocs, {}) }), _jsx(Route, { path: "card", element: _jsx(CardDocs, {}) }), _jsx(Route, { path: "input", element: _jsx(InputDocs, {}) }), _jsx(Route, { path: "theme", element: _jsx(ThemeSwitcherDocs, {}) }), _jsx(Route, { path: "datafield", element: _jsx(DataFieldDocs, {}) })] }));
|
|
12
|
+
return (_jsxs(Routes, { children: [_jsx(Route, { path: "", element: _jsx(Navigate, { to: "button", replace: true }) }), _jsx(Route, { path: "button", element: _jsx(ButtonDocs, {}) }), _jsx(Route, { path: "badge", element: _jsx(BadgeDocs, {}) }), _jsx(Route, { path: "card", element: _jsx(CardDocs, {}) }), _jsx(Route, { path: "input", element: _jsx(InputDocs, {}) }), _jsx(Route, { path: "theme", element: _jsx(ThemeSwitcherDocs, {}) }), _jsx(Route, { path: "datafield", element: _jsx(DataFieldDocs, {}) }), _jsx(Route, { path: "auth", element: _jsx(AuthDocs, {}) })] }));
|
|
12
13
|
};
|
|
13
14
|
export default DocsRouter;
|