feat(notifications): login service notifications

This commit is contained in:
x032205
2025-09-16 01:36:53 -04:00
parent 4431fe687d
commit 55eceb725c
3 changed files with 32 additions and 3 deletions
+2 -1
View File
@@ -773,7 +773,8 @@ export const registerRoutes = async (
orgDAL, orgDAL,
totpService, totpService,
orgMembershipDAL, orgMembershipDAL,
auditLogService auditLogService,
notificationService
}); });
const passwordService = authPaswordServiceFactory({ const passwordService = authPaswordServiceFactory({
tokenService, tokenService,
@@ -14,6 +14,8 @@ import { getServerCfg } from "@app/services/super-admin/super-admin-service";
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service"; import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
import { TokenType } from "../auth-token/auth-token-types"; import { TokenType } from "../auth-token/auth-token-types";
import { TNotificationServiceFactory } from "../notification/notification-service";
import { NotificationType } from "../notification/notification-types";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
import { getDefaultOrgMembershipRole } from "../org/org-role-fns"; import { getDefaultOrgMembershipRole } from "../org/org-role-fns";
import { TOrgMembershipDALFactory } from "../org-membership/org-membership-dal"; import { TOrgMembershipDALFactory } from "../org-membership/org-membership-dal";
@@ -47,6 +49,7 @@ type TAuthLoginServiceFactoryDep = {
totpService: Pick<TTotpServiceFactory, "verifyUserTotp" | "verifyWithUserRecoveryCode">; totpService: Pick<TTotpServiceFactory, "verifyUserTotp" | "verifyWithUserRecoveryCode">;
auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">; auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">;
orgMembershipDAL: TOrgMembershipDALFactory; orgMembershipDAL: TOrgMembershipDALFactory;
notificationService: Pick<TNotificationServiceFactory, "createUserNotifications">;
}; };
export type TAuthLoginFactory = ReturnType<typeof authLoginServiceFactory>; export type TAuthLoginFactory = ReturnType<typeof authLoginServiceFactory>;
@@ -57,7 +60,8 @@ export const authLoginServiceFactory = ({
orgDAL, orgDAL,
orgMembershipDAL, orgMembershipDAL,
totpService, totpService,
auditLogService auditLogService,
notificationService
}: TAuthLoginServiceFactoryDep) => { }: TAuthLoginServiceFactoryDep) => {
/* /*
* Private * Private
@@ -71,6 +75,16 @@ export const authLoginServiceFactory = ({
if (!isDeviceSeen) { if (!isDeviceSeen) {
const newDeviceList = devices.concat([{ ip, userAgent }]); const newDeviceList = devices.concat([{ ip, userAgent }]);
await userDAL.updateById(user.id, { devices: JSON.stringify(newDeviceList) }, tx); await userDAL.updateById(user.id, { devices: JSON.stringify(newDeviceList) }, tx);
await notificationService.createUserNotifications([
{
userId: user.id,
type: NotificationType.LOGIN_FROM_NEW_DEVICE,
title: "Login From New Device",
body: `A new device with IP **${ip}** and User Agent **${userAgent}** has logged into your account.`
}
]);
if (user.email) { if (user.email) {
await smtpService.sendMail({ await smtpService.sendMail({
template: SmtpTemplates.NewDeviceJoin, template: SmtpTemplates.NewDeviceJoin,
@@ -563,6 +577,18 @@ export const authLoginServiceFactory = ({
.filter(Boolean) as string[]; .filter(Boolean) as string[];
if (adminEmails.length > 0) { if (adminEmails.length > 0) {
await notificationService.createUserNotifications(
orgAdmins
.filter((admin) => admin.user.id !== user.id)
.map((admin) => ({
userId: admin.user.id,
orgId: organizationId,
type: NotificationType.ADMIN_SSO_BYPASS,
title: "Security Alert: Admin SSO Bypass",
body: `The org admin **${user.email}** has bypassed enforced SSO login.`
}))
);
await smtpService.sendMail({ await smtpService.sendMail({
recipients: adminEmails, recipients: adminEmails,
subjectLine: "Security Alert: Admin SSO Bypass", subjectLine: "Security Alert: Admin SSO Bypass",
@@ -6,7 +6,9 @@ export enum NotificationType {
SECRET_CHANGE_POLICY_BYPASSED = "secret-change-policy-bypassed", SECRET_CHANGE_POLICY_BYPASSED = "secret-change-policy-bypassed",
SECRET_ROTATION_FAILED = "secret-rotation-failed", SECRET_ROTATION_FAILED = "secret-rotation-failed",
SECRET_SCANNING_SECRETS_DETECTED = "secret-scanning-secrets-detected", SECRET_SCANNING_SECRETS_DETECTED = "secret-scanning-secrets-detected",
SECRET_SCANNING_SCAN_FAILED = "secret-scanning-scan-failed" SECRET_SCANNING_SCAN_FAILED = "secret-scanning-scan-failed",
LOGIN_FROM_NEW_DEVICE = "login-from-new-device",
ADMIN_SSO_BYPASS = "admin-sso-bypass"
} }
export interface TCreateUserNotificationDTO { export interface TCreateUserNotificationDTO {