update user login baru dan hakakses
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
// server/api/users/current.get.ts
|
||||
// Get current logged-in user data from JWT token
|
||||
|
||||
// Helper function to decode JWT token payload
|
||||
const decodeTokenPayload = (token: string | undefined): any | null => {
|
||||
if (!token) return null;
|
||||
try {
|
||||
const parts = token.split(".");
|
||||
if (parts.length < 2) return null;
|
||||
const payloadBase64 = parts[1];
|
||||
return JSON.parse(Buffer.from(payloadBase64, "base64").toString());
|
||||
} catch (e) {
|
||||
console.error("❌ Failed to decode token payload:", e);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
console.log("🔍 Current user endpoint called");
|
||||
|
||||
const sessionCookie = getCookie(event, "user_session");
|
||||
|
||||
if (!sessionCookie) {
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
statusMessage: "No session cookie found",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const session = JSON.parse(sessionCookie);
|
||||
|
||||
const isExpired = Date.now() > session.expiresAt;
|
||||
if (isExpired) {
|
||||
deleteCookie(event, "user_session");
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
statusMessage: "Session expired",
|
||||
});
|
||||
}
|
||||
|
||||
// Decode tokens to get full user data
|
||||
const idTokenPayload = decodeTokenPayload(session.idToken);
|
||||
const accessTokenPayload = decodeTokenPayload(session.accessToken);
|
||||
|
||||
// Extract roles from different sources
|
||||
const realmRoles = accessTokenPayload?.realm_access?.roles ||
|
||||
idTokenPayload?.realm_access?.roles ||
|
||||
[];
|
||||
|
||||
const accountRoles = accessTokenPayload?.resource_access?.account?.roles ||
|
||||
idTokenPayload?.resource_access?.account?.roles ||
|
||||
[];
|
||||
|
||||
// Extract resource roles (from all resources in resource_access)
|
||||
const resourceRoles: string[] = [];
|
||||
if (accessTokenPayload?.resource_access) {
|
||||
Object.keys(accessTokenPayload.resource_access).forEach(resourceName => {
|
||||
if (resourceName !== 'account') { // Exclude account, already handled
|
||||
const resourceRolesArray = accessTokenPayload.resource_access[resourceName]?.roles || [];
|
||||
resourceRoles.push(...resourceRolesArray.map((role: string) => `${resourceName}:${role}`));
|
||||
}
|
||||
});
|
||||
}
|
||||
if (idTokenPayload?.resource_access) {
|
||||
Object.keys(idTokenPayload.resource_access).forEach(resourceName => {
|
||||
if (resourceName !== 'account') { // Exclude account, already handled
|
||||
const resourceRolesArray = idTokenPayload.resource_access[resourceName]?.roles || [];
|
||||
resourceRoles.push(...resourceRolesArray.map((role: string) => `${resourceName}:${role}`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Legacy: Combined roles (for backward compatibility)
|
||||
const roles = [...realmRoles, ...accountRoles, ...resourceRoles];
|
||||
|
||||
// Keycloak uses 'groups_join' in access token, not 'groups'
|
||||
const groups = accessTokenPayload?.groups_join ||
|
||||
accessTokenPayload?.groups ||
|
||||
idTokenPayload?.groups_join ||
|
||||
idTokenPayload?.groups ||
|
||||
[];
|
||||
|
||||
// Determine tipeUser from groups or roles if possible
|
||||
// You can customize this mapping based on your business logic
|
||||
let tipeUser = '';
|
||||
if (Array.isArray(groups) && groups.length > 0) {
|
||||
// Extract tipeUser from groups path (e.g., "/Instalasi STIM/Devops/Superadmin" -> "Superadmin")
|
||||
const lastGroup = groups[groups.length - 1];
|
||||
if (typeof lastGroup === 'string') {
|
||||
const parts = lastGroup.split('/').filter(Boolean);
|
||||
if (parts.length > 0) {
|
||||
tipeUser = parts[parts.length - 1]; // Get last part of path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build user data object
|
||||
const userData = {
|
||||
id: idTokenPayload?.sub || session.user?.id,
|
||||
namaLengkap: idTokenPayload?.name ||
|
||||
session.user?.name ||
|
||||
`${idTokenPayload?.given_name || ''} ${idTokenPayload?.family_name || ''}`.trim() ||
|
||||
idTokenPayload?.preferred_username,
|
||||
namaUser: idTokenPayload?.preferred_username ||
|
||||
session.user?.preferred_username ||
|
||||
idTokenPayload?.email?.split('@')[0],
|
||||
email: idTokenPayload?.email || session.user?.email,
|
||||
given_name: idTokenPayload?.given_name,
|
||||
family_name: idTokenPayload?.family_name,
|
||||
roles: Array.isArray(roles) ? roles : [],
|
||||
realmRoles: Array.isArray(realmRoles) ? realmRoles : [],
|
||||
accountRoles: Array.isArray(accountRoles) ? accountRoles : [],
|
||||
resourceRoles: Array.isArray(resourceRoles) ? resourceRoles : [],
|
||||
groups: Array.isArray(groups) ? groups : [],
|
||||
tipeUser: tipeUser, // Extracted from groups or empty
|
||||
lastLogin: null, // Will be set on sync
|
||||
// Include full token payloads for reference
|
||||
idTokenPayload,
|
||||
accessTokenPayload,
|
||||
};
|
||||
|
||||
console.log("✅ Current user data extracted from JWT");
|
||||
return userData;
|
||||
} catch (parseError: any) {
|
||||
console.error("❌ Failed to parse session or extract user data:", parseError);
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
statusMessage: "Invalid session data",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user