From 09ac5c8df5a49d5638f66a8efe5d1ea3587a5a4f Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Thu, 13 Nov 2025 21:27:32 -0300 Subject: [PATCH 1/4] Add user login and select organization audit logs --- .../ee/services/audit-log/audit-log-types.ts | 31 ++++++- .../src/services/auth/auth-login-service.ts | 82 +++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index f91692a14..2dc683b58 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -365,6 +365,8 @@ export enum EventType { LOAD_PROJECT_KMS_BACKUP = "load-project-kms-backup", ORG_ADMIN_ACCESS_PROJECT = "org-admin-accessed-project", ORG_ADMIN_BYPASS_SSO = "org-admin-bypassed-sso", + USER_LOGIN = "user-login", + USER_SELECT_ORGANIZATION = "user-select-organization", CREATE_CERTIFICATE_TEMPLATE = "create-certificate-template", UPDATE_CERTIFICATE_TEMPLATE = "update-certificate-template", DELETE_CERTIFICATE_TEMPLATE = "delete-certificate-template", @@ -2657,6 +2659,31 @@ interface OrgAdminBypassSSOEvent { metadata: Record; // no metadata yet } +interface UserLoginEvent { + type: EventType.USER_LOGIN; + metadata: { + email: string; + userAgent: string; + ipAddress: string; + authMethod: string; + organizationId?: string; + organizationName?: string; + authProvider?: string; + }; +} + +interface UserSelectOrganizationEvent { + type: EventType.USER_SELECT_ORGANIZATION; + metadata: { + email: string; + userAgent: string; + ipAddress: string; + organizationId: string; + organizationName: string; + authMethod: string; + }; +} + interface CreateCertificateTemplateEstConfig { type: EventType.CREATE_CERTIFICATE_TEMPLATE_EST_CONFIG; metadata: { @@ -4535,4 +4562,6 @@ export type Event = | UpdateCertificateRenewalConfigEvent | DisableCertificateRenewalConfigEvent | AutomatedRenewCertificate - | AutomatedRenewCertificateFailed; + | AutomatedRenewCertificateFailed + | UserLoginEvent + | UserSelectOrganizationEvent; diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index b9c759703..1c06dcb96 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -454,6 +454,32 @@ export const authLoginServiceFactory = ({ }); } + if (organizationId) { + await auditLogService.createAuditLog({ + orgId: organizationId, + ipAddress: ip, + userAgent, + userAgentType: getUserAgentType(userAgent), + actor: { + type: ActorType.USER, + metadata: { + email: userEnc.email, + userId: userEnc.userId, + username: userEnc.username + } + }, + event: { + type: EventType.USER_LOGIN, + metadata: { + email, + userAgent, + ipAddress: ip, + authMethod + } + } + }); + } + return { tokens: { accessToken: token.access, @@ -646,6 +672,32 @@ export const authLoginServiceFactory = ({ } } + await auditLogService.createAuditLog({ + orgId: organizationId, + ipAddress, + userAgent, + userAgentType: getUserAgentType(userAgent), + actor: { + type: ActorType.USER, + metadata: { + email: user.email, + userId: user.id, + username: user.username + } + }, + event: { + type: EventType.USER_SELECT_ORGANIZATION, + metadata: { + email: user.email || "", + userAgent, + ipAddress, + organizationId, + organizationName: selectedOrg.name, + authMethod: decodedToken.authMethod + } + } + }); + return { ...tokens, user, @@ -1039,6 +1091,36 @@ export const authLoginServiceFactory = ({ organizationId }); + if (organizationId) { + await auditLogService.createAuditLog({ + orgId: organizationId, + ipAddress: ip, + userAgent, + userAgentType: getUserAgentType(userAgent), + actor: { + type: ActorType.USER, + metadata: { + email: userEnc.email, + userId: userEnc.userId, + username: userEnc.username + } + }, + event: { + type: EventType.USER_LOGIN, + metadata: { + email, + userAgent, + ipAddress: ip, + authMethod: decodedProviderToken.authMethod, + organizationId, + ...(isAuthMethodSaml(decodedProviderToken.authMethod) && { + authProvider: decodedProviderToken.authMethod + }) + } + } + }); + } + return { token, isMfaEnabled: false, user: userEnc, decodedProviderToken } as const; }; From abe4b127f9ee07a318083a3e956ffc724c82d0a3 Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Fri, 14 Nov 2025 01:07:45 -0300 Subject: [PATCH 2/4] Rename select org audit log event name --- backend/src/ee/services/audit-log/audit-log-types.ts | 8 ++++---- backend/src/services/auth/auth-login-service.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index 2dc683b58..0d5182097 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -366,7 +366,7 @@ export enum EventType { ORG_ADMIN_ACCESS_PROJECT = "org-admin-accessed-project", ORG_ADMIN_BYPASS_SSO = "org-admin-bypassed-sso", USER_LOGIN = "user-login", - USER_SELECT_ORGANIZATION = "user-select-organization", + SELECT_ORGANIZATION = "select-organization", CREATE_CERTIFICATE_TEMPLATE = "create-certificate-template", UPDATE_CERTIFICATE_TEMPLATE = "update-certificate-template", DELETE_CERTIFICATE_TEMPLATE = "delete-certificate-template", @@ -2672,8 +2672,8 @@ interface UserLoginEvent { }; } -interface UserSelectOrganizationEvent { - type: EventType.USER_SELECT_ORGANIZATION; +interface SelectOrganizationEvent { + type: EventType.SELECT_ORGANIZATION; metadata: { email: string; userAgent: string; @@ -4564,4 +4564,4 @@ export type Event = | AutomatedRenewCertificate | AutomatedRenewCertificateFailed | UserLoginEvent - | UserSelectOrganizationEvent; + | SelectOrganizationEvent; diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index 1c06dcb96..8895933e8 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -686,7 +686,7 @@ export const authLoginServiceFactory = ({ } }, event: { - type: EventType.USER_SELECT_ORGANIZATION, + type: EventType.SELECT_ORGANIZATION, metadata: { email: user.email || "", userAgent, From 8d3b02e66d17a22be58b70e699f0be8cb122a44a Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Fri, 14 Nov 2025 17:46:19 -0300 Subject: [PATCH 3/4] Address PR suggestions --- .../ee/services/audit-log/audit-log-types.ts | 9 +------ .../src/services/auth/auth-login-service.ts | 24 +++++++------------ 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index 0d5182097..57f7bc68f 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -572,6 +572,7 @@ interface UserActorMetadata { email?: string | null; username: string; permission?: Record; + authMethod?: string; } interface ServiceActorMetadata { @@ -2662,10 +2663,6 @@ interface OrgAdminBypassSSOEvent { interface UserLoginEvent { type: EventType.USER_LOGIN; metadata: { - email: string; - userAgent: string; - ipAddress: string; - authMethod: string; organizationId?: string; organizationName?: string; authProvider?: string; @@ -2675,12 +2672,8 @@ interface UserLoginEvent { interface SelectOrganizationEvent { type: EventType.SELECT_ORGANIZATION; metadata: { - email: string; - userAgent: string; - ipAddress: string; organizationId: string; organizationName: string; - authMethod: string; }; } diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index 8895933e8..e2f0f5f16 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -465,16 +465,14 @@ export const authLoginServiceFactory = ({ metadata: { email: userEnc.email, userId: userEnc.userId, - username: userEnc.username + username: userEnc.username, + authMethod } }, event: { type: EventType.USER_LOGIN, metadata: { - email, - userAgent, - ipAddress: ip, - authMethod + organizationId } } }); @@ -682,18 +680,15 @@ export const authLoginServiceFactory = ({ metadata: { email: user.email, userId: user.id, - username: user.username + username: user.username, + authMethod: decodedToken.authMethod } }, event: { type: EventType.SELECT_ORGANIZATION, metadata: { - email: user.email || "", - userAgent, - ipAddress, organizationId, - organizationName: selectedOrg.name, - authMethod: decodedToken.authMethod + organizationName: selectedOrg.name } } }); @@ -1102,16 +1097,13 @@ export const authLoginServiceFactory = ({ metadata: { email: userEnc.email, userId: userEnc.userId, - username: userEnc.username + username: userEnc.username, + authMethod: decodedProviderToken.authMethod } }, event: { type: EventType.USER_LOGIN, metadata: { - email, - userAgent, - ipAddress: ip, - authMethod: decodedProviderToken.authMethod, organizationId, ...(isAuthMethodSaml(decodedProviderToken.authMethod) && { authProvider: decodedProviderToken.authMethod From 99df4e38d5dcea380d0f0e843a454f8a25bb406b Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Fri, 14 Nov 2025 17:54:04 -0300 Subject: [PATCH 4/4] Remove orgName from user login audit log --- backend/src/ee/services/audit-log/audit-log-types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index 57f7bc68f..de3ce9af6 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -2664,7 +2664,6 @@ interface UserLoginEvent { type: EventType.USER_LOGIN; metadata: { organizationId?: string; - organizationName?: string; authProvider?: string; }; }