@unchainedshop/events
Version:
Event emitter abstraction layer for the Unchained Engine
201 lines (200 loc) • 7.11 kB
JavaScript
import { createLogger } from '@unchainedshop/logger';
import { EventDirector } from "../EventDirector.js";
import { OCSF_AUTH_ACTIVITY, OCSF_ACCOUNT_ACTIVITY, OCSF_API_ACTIVITY } from "./ocsf-types.js";
const logger = createLogger('unchained:audit-integration');
function extractContext(payload) {
return {
userId: payload.userId || payload.user?._id || payload.user?.id,
userName: payload.userName || payload.user?.username || payload.user?.emails?.[0]?.address,
remoteAddress: payload.remoteAddress || payload.ip,
sessionId: payload.sessionId,
};
}
const ACCOUNT_ACTION_MAP = {
'reset-password': {
activity: OCSF_ACCOUNT_ACTIVITY.PASSWORD_RESET,
message: 'Password reset requested',
},
'verify-email': { activity: OCSF_ACCOUNT_ACTIVITY.ENABLE, message: 'Email verified' },
'enroll-account': { activity: OCSF_ACCOUNT_ACTIVITY.ENABLE, message: 'Account enrolled' },
};
export function configureAuditIntegration(auditLog) {
const sub = (event, handler) => {
try {
EventDirector.subscribe(event, async ({ payload }) => {
try {
await handler(payload);
}
catch (error) {
logger.error(`Audit log error for ${event}: ${error}`);
}
});
}
catch {
}
};
sub('API_LOGIN_TOKEN_CREATED', async (p) => {
const ctx = extractContext(p);
await auditLog.logAuthentication({ activity: OCSF_AUTH_ACTIVITY.LOGON, ...ctx, success: true });
});
sub('API_LOGOUT', async (p) => {
const ctx = extractContext(p);
await auditLog.logAuthentication({ activity: OCSF_AUTH_ACTIVITY.LOGOFF, ...ctx, success: true });
});
sub('USER_CREATE', async (p) => {
const ctx = extractContext(p);
await auditLog.logAccountChange({ activity: OCSF_ACCOUNT_ACTIVITY.CREATE, ...ctx, success: true });
});
sub('USER_REMOVE', async (p) => {
const ctx = extractContext(p);
await auditLog.logAccountChange({ activity: OCSF_ACCOUNT_ACTIVITY.DELETE, ...ctx, success: true });
});
sub('USER_UPDATE_PASSWORD', async (p) => {
const ctx = extractContext(p);
await auditLog.logAccountChange({
activity: OCSF_ACCOUNT_ACTIVITY.PASSWORD_CHANGE,
...ctx,
success: true,
});
});
sub('USER_ADD_ROLES', async (p) => {
const ctx = extractContext(p);
await auditLog.logAccountChange({
activity: OCSF_ACCOUNT_ACTIVITY.ATTACH_POLICY,
...ctx,
success: true,
message: `Roles added: ${p.roles?.join(', ') || 'unknown'}`,
});
});
sub('USER_UPDATE_ROLE', async (p) => {
const ctx = extractContext(p);
await auditLog.logAccountChange({
activity: OCSF_ACCOUNT_ACTIVITY.ATTACH_POLICY,
...ctx,
success: true,
message: 'User roles updated',
});
});
sub('USER_ACCOUNT_ACTION', async (p) => {
const ctx = extractContext(p);
const mapped = ACCOUNT_ACTION_MAP[p.action] || {
activity: OCSF_ACCOUNT_ACTIVITY.OTHER,
message: 'Account action',
};
await auditLog.logAccountChange({ ...mapped, ...ctx, success: true });
});
sub('ORDER_CREATE', async (p) => {
const ctx = extractContext(p);
await auditLog.logApiActivity({
activity: OCSF_API_ACTIVITY.CREATE,
...ctx,
userId: p.order?.userId || ctx.userId,
success: true,
operation: 'createOrder',
message: `Order created: ${p.order?._id || 'unknown'}`,
});
});
sub('ORDER_CHECKOUT', async (p) => {
const ctx = extractContext(p);
await auditLog.logApiActivity({
activity: OCSF_API_ACTIVITY.CHECKOUT,
...ctx,
userId: p.order?.userId || ctx.userId,
success: true,
operation: 'checkoutOrder',
message: `Order checkout: ${p.order?._id || 'unknown'}`,
});
});
sub('ORDER_CONFIRMED', async (p) => {
const ctx = extractContext(p);
await auditLog.logApiActivity({
activity: OCSF_API_ACTIVITY.UPDATE,
...ctx,
userId: p.order?.userId || ctx.userId,
success: true,
operation: 'confirmOrder',
message: `Order confirmed: ${p.order?._id || 'unknown'}`,
});
});
sub('ORDER_FULFILLED', async (p) => {
const ctx = extractContext(p);
await auditLog.logApiActivity({
activity: OCSF_API_ACTIVITY.UPDATE,
...ctx,
userId: p.order?.userId || ctx.userId,
success: true,
operation: 'fulfillOrder',
message: `Order fulfilled: ${p.order?._id || 'unknown'}`,
});
});
sub('ORDER_REJECTED', async (p) => {
const ctx = extractContext(p);
await auditLog.logApiActivity({
activity: OCSF_API_ACTIVITY.UPDATE,
...ctx,
userId: p.order?.userId || ctx.userId,
success: false,
operation: 'rejectOrder',
message: `Order rejected: ${p.order?._id || 'unknown'}`,
});
});
sub('ORDER_ADD_PRODUCT', async (p) => {
const ctx = extractContext(p);
await auditLog.logApiActivity({
activity: OCSF_API_ACTIVITY.UPDATE,
...ctx,
success: true,
operation: 'addToCart',
message: `Product added to cart: ${p.orderPosition?.productId || 'unknown'}`,
});
});
sub('ORDER_REMOVE_CART_ITEM', async (p) => {
const ctx = extractContext(p);
await auditLog.logApiActivity({
activity: OCSF_API_ACTIVITY.DELETE,
...ctx,
success: true,
operation: 'removeFromCart',
message: 'Product removed from cart',
});
});
sub('ORDER_PAY', async (p) => {
const ctx = extractContext(p);
await auditLog.logApiActivity({
activity: OCSF_API_ACTIVITY.PAYMENT,
...ctx,
success: true,
operation: 'processPayment',
message: 'Payment processed for order',
});
});
sub('ORDER_UPDATE_PAYMENT', async (p) => {
const ctx = extractContext(p);
await auditLog.logApiActivity({
activity: OCSF_API_ACTIVITY.PAYMENT,
...ctx,
success: true,
operation: 'updatePayment',
message: 'Payment updated',
});
});
}
export const AUDITED_EVENTS = [
'API_LOGIN_TOKEN_CREATED',
'API_LOGOUT',
'USER_CREATE',
'USER_REMOVE',
'USER_UPDATE_PASSWORD',
'USER_ADD_ROLES',
'USER_UPDATE_ROLE',
'USER_ACCOUNT_ACTION',
'ORDER_CREATE',
'ORDER_CHECKOUT',
'ORDER_CONFIRMED',
'ORDER_FULFILLED',
'ORDER_REJECTED',
'ORDER_ADD_PRODUCT',
'ORDER_REMOVE_CART_ITEM',
'ORDER_PAY',
'ORDER_UPDATE_PAYMENT',
];