UNPKG

ssr-keycloak

Version:

SSR compatible Keycloak authentication library for React applications

189 lines (188 loc) 5.82 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSessionFromRequest = getSessionFromRequest; exports.setSessionInResponse = setSessionInResponse; exports.clearSessionInResponse = clearSessionInResponse; exports.isSessionValid = isSessionValid; exports.refreshSession = refreshSession; exports.createNewSession = createNewSession; exports.updateSession = updateSession; exports.getUserRolesFromSession = getUserRolesFromSession; exports.hasRoleInSession = hasRoleInSession; exports.hasAnyRoleInSession = hasAnyRoleInSession; exports.hasAllRolesInSession = hasAllRolesInSession; const crypto_1 = __importDefault(require("crypto")); const SESSION_COOKIE_NAME = 'ssr_keycloak_session'; const SESSION_SECRET = process.env.KEYCLOAK_SESSION_SECRET || 'default-secret-change-in-production'; /** * Session'ı şifreler */ function encryptSession(session) { const cipher = crypto_1.default.createCipher('aes-256-cbc', SESSION_SECRET); let encrypted = cipher.update(JSON.stringify(session), 'utf8', 'hex'); encrypted += cipher.final('hex'); return encrypted; } /** * Session'ı şifresini çözer */ function decryptSession(encryptedSession) { try { const decipher = crypto_1.default.createDecipher('aes-256-cbc', SESSION_SECRET); let decrypted = decipher.update(encryptedSession, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return JSON.parse(decrypted); } catch (error) { console.error('Session decryption failed:', error); return null; } } /** * Session cookie'sini oluşturur */ function createSessionCookie(session) { const encryptedSession = encryptSession(session); return { name: SESSION_COOKIE_NAME, value: encryptedSession, expires: new Date(session.expiresAt), maxAge: Math.floor((session.expiresAt - Date.now()) / 1000), path: '/', secure: process.env.NODE_ENV === 'production', httpOnly: true, sameSite: 'lax' }; } /** * Request'ten session'ı okur */ function getSessionFromRequest(request) { const sessionCookie = request.cookies[SESSION_COOKIE_NAME]; if (!sessionCookie) { return null; } const session = decryptSession(sessionCookie); if (!session) { return null; } // Session'ın geçerli olup olmadığını kontrol et if (Date.now() >= session.expiresAt) { return null; } return session; } /** * Session'ı response'a yazar */ function setSessionInResponse(session, response) { const cookie = createSessionCookie(session); response.setCookie(cookie); } /** * Session'ı response'dan siler */ function clearSessionInResponse(response) { response.deleteCookie(SESSION_COOKIE_NAME); } /** * Session'ın geçerli olup olmadığını kontrol eder */ function isSessionValid(session) { if (!session) return false; return Date.now() < session.expiresAt; } /** * Session'ı yeniler (lastActivity günceller) */ function refreshSession(session) { return { ...session, lastActivity: Date.now() }; } /** * Yeni session oluşturur */ function createNewSession(userId, tokens, user, realm, clientId, expiresIn = 3600) { const now = Date.now(); return { sessionId: userId, // Keycloak user ID'yi session ID olarak kullan userId, tokens: { accessToken: tokens.access_token, refreshToken: tokens.refresh_token, idToken: tokens.id_token, expiresAt: now + (tokens.expires_in * 1000), refreshExpiresAt: now + (tokens.refresh_expires_in * 1000) }, user: { id: user.sub, username: user.preferred_username || user.username || '', email: user.email, firstName: user.given_name, lastName: user.family_name, fullName: user.name, roles: user.roles || [], groups: user.groups || [], emailVerified: user.email_verified || false, enabled: user.enabled !== false, realmAccess: { roles: user.realm_access?.roles || [] }, resourceAccess: user.resource_access || {} }, realm, clientId, lastActivity: now, expiresAt: now + (expiresIn * 1000) }; } /** * Session'ı günceller */ function updateSession(currentSession, updates) { return { ...currentSession, ...updates, lastActivity: Date.now() }; } /** * Session'dan kullanıcı rollerini alır */ function getUserRolesFromSession(session, resource) { if (!session) return []; if (resource) { return session.user.resourceAccess[resource]?.roles || []; } return [...session.user.realmAccess.roles, ...session.user.roles]; } /** * Session'da belirli bir rol olup olmadığını kontrol eder */ function hasRoleInSession(session, role, resource) { if (!session) return false; if (resource) { return session.user.resourceAccess[resource]?.roles?.includes(role) || false; } return session.user.realmAccess.roles.includes(role) || session.user.roles.includes(role); } /** * Session'da belirli rollerden herhangi biri olup olmadığını kontrol eder */ function hasAnyRoleInSession(session, roles, resource) { return roles.some(role => hasRoleInSession(session, role, resource)); } /** * Session'da belirli rollerin hepsinin olup olmadığını kontrol eder */ function hasAllRolesInSession(session, roles, resource) { return roles.every(role => hasRoleInSession(session, role, resource)); }