Auth: idUsuario login via sige_sam_v3.usuario

- Login uses idUsuario + password (plain text or SHA256)
- API types: HelpDeskUser with idUsuario, nombres, apPaterno
- Sidebar/layout: fullName from nombres + apPaterno
- pnpm-workspace.yaml: approve unrs-resolver builds
This commit is contained in:
Nurfog committed 2026-09-10 11:36:46 -03:00
1 parent 2a303c73ae
commit 72775500da
7 files changed
+45 -31

No files matched your search

+10
View File
@@ -138,6 +138,9 @@ packages:
'@emnapi/runtime@1.10.0':
resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
'@emnapi/runtime@1.11.3':
resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==}
'@emnapi/wasi-threads@1.2.1':
resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
@@ -2275,6 +2278,11 @@ snapshots:
tslib: 2.8.1
optional: true
'@emnapi/runtime@1.11.3':
dependencies:
tslib: 2.8.1
optional: true
'@emnapi/wasi-threads@1.2.1':
dependencies:
tslib: 2.8.1
@@ -2436,6 +2444,8 @@ snapshots:
optional: true
'@img/sharp-wasm32@0.35.4':
dependencies:
'@emnapi/runtime': 1.11.3
optional: true
'@img/sharp-webcontainers-wasm32@0.35.4':
+2
View File
@@ -0,0 +1,2 @@
allowBuilds:
unrs-resolver: true
+3 -2
View File
@@ -79,7 +79,8 @@ function AppShell({ children }: { children: React.ReactNode }) {
function TopNavbarUser() {
const { user } = useAuth();
const initials = user?.nombre
const fullName = user ? `${user.nombres} ${user.apPaterno}` : "Usuario";
const initials = user?.nombres
?.split(" ")
.map((n: string) => n[0])
.join("")
@@ -90,7 +91,7 @@ function TopNavbarUser() {
<div className="d-flex align-items-center gap-2">
<div className="avatar-circle">{initials}</div>
<span className="d-none d-md-inline" style={{ fontSize: "0.85rem", fontWeight: 500 }}>
{user?.nombre || "Usuario"}
{fullName}
</span>
</div>
);
+6 -6
View File
@@ -5,7 +5,7 @@ import { useRouter } from "next/navigation";
import { useAuth } from "@/lib/auth";
export default function LoginPage() {
const [rut, setRut] = useState("");
const [idUsuario, setIdUsuario] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
@@ -17,7 +17,7 @@ export default function LoginPage() {
setError("");
setLoading(true);
try {
await login(rut, password);
await login(idUsuario, password);
router.push("/");
} catch (err: any) {
setError(err.message || "Credenciales inválidas");
@@ -74,13 +74,13 @@ export default function LoginPage() {
<form onSubmit={handleSubmit}>
<div className="mb-3">
<label className="form-label">RUT</label>
<label className="form-label">Usuario</label>
<input
type="text"
className="form-control"
placeholder="12.345.678-9"
value={rut}
onChange={(e) => setRut(e.target.value)}
placeholder="Tu ID de usuario"
value={idUsuario}
onChange={(e) => setIdUsuario(e.target.value)}
required
autoFocus
/>
+4 -3
View File
@@ -14,7 +14,8 @@ export default function Sidebar() {
{ href: "/knowledge-base", icon: "bi-journal-bookmark", label: "Knowledge Base" },
];
const initials = user?.nombre
const fullName = user ? `${user.nombres} ${user.apPaterno}` : "Usuario";
const initials = user?.nombres
?.split(" ")
.map((n: string) => n[0])
.join("")
@@ -49,8 +50,8 @@ export default function Sidebar() {
<div className="sidebar-user">
<div className="avatar">{initials}</div>
<div className="sidebar-user-info">
<div className="name">{user?.nombre || "Usuario"}</div>
<div className="role">{user?.perfil || "Agente"}</div>
<div className="name">{fullName}</div>
<div className="role">{user?.tipo || "Usuario"}</div>
</div>
<button
onClick={logout}
+14 -14
View File
@@ -28,16 +28,15 @@ async function fetchApi<T>(
}
// ==================== Auth ====================
// SAM uses RUT-based auth — adapt as needed
export async function login(rut: string, password: string) {
return fetchApi<{ success: boolean; message?: string; token?: string; user?: User }>(
"/api/auth/login",
{ method: "POST", body: JSON.stringify({ rut, password }) }
export async function login(idUsuario: string, password: string) {
return fetchApi<{ success: boolean; message?: string; token?: string; user?: HelpDeskUser }>(
"/api/helpdesk/login",
{ method: "POST", body: JSON.stringify({ idUsuario, password }) }
);
}
export async function getMe() {
return fetchApi<User>("/api/auth/me");
return fetchApi<HelpDeskUser>("/api/helpdesk/me");
}
// ==================== Tickets ====================
@@ -152,15 +151,16 @@ export async function getSLAPolicies() {
}
// ==================== Types ====================
export interface User {
usuarioId: number;
nombre: string;
export interface HelpDeskUser {
idUsuario: string;
nombres: string;
apPaterno: string;
apMaterno?: string;
email: string;
perfil: string;
sedeId?: number;
telefono?: string;
tipo?: string;
activo: number;
fono?: string;
idSede?: number;
}
export interface Ticket {
@@ -196,7 +196,7 @@ export interface TicketListResult {
export interface Comment {
id: number;
ticketId: number;
userId: number;
userId: string;
userName?: string;
content: string;
isInternal: boolean;
@@ -216,7 +216,7 @@ export interface KBArticle {
content: string;
categoryId: number;
categoryName?: string;
authorId: number;
authorId: string;
authorName?: string;
isPublished: boolean;
viewCount: number;
+6 -6
View File
@@ -1,11 +1,11 @@
"use client";
import React, { createContext, useContext, useState, useEffect, useCallback } from "react";
import { getMe, login as apiLogin, type User } from "./api";
import { getMe, login as apiLogin, type HelpDeskUser } from "./api";
interface AuthContextType {
user: User | null;
login: (rut: string, password: string) => Promise<void>;
user: HelpDeskUser | null;
login: (idUsuario: string, password: string) => Promise<void>;
logout: () => void;
isAuthenticated: boolean;
isLoading: boolean;
@@ -20,7 +20,7 @@ const AuthContext = createContext<AuthContextType>({
});
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [user, setUser] = useState<HelpDeskUser | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
@@ -35,8 +35,8 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
}
}, []);
const login = useCallback(async (rut: string, password: string) => {
const result = await apiLogin(rut, password);
const login = useCallback(async (idUsuario: string, password: string) => {
const result = await apiLogin(idUsuario, password);
if (!result.success || !result.token) {
throw new Error(result.message || "Credenciales inválidas");
}