remove unused packages

This commit is contained in:
2026-04-21 12:25:16 +03:30
parent 58e1d97294
commit 076793c845
8 changed files with 15700 additions and 31182 deletions
+15698 -16888
View File
File diff suppressed because it is too large Load Diff
+1 -5
View File
@@ -69,14 +69,10 @@
"class-validator": "^0.14.2", "class-validator": "^0.14.2",
"dayjs": "^1.11.19", "dayjs": "^1.11.19",
"fastify": "^5.6.1", "fastify": "^5.6.1",
"firebase-admin": "^13.6.0",
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1", "rxjs": "^7.8.1",
"sanitize-html": "^2.17.0",
"slugify": "^1.6.6",
"socket.io": "^4.8.1", "socket.io": "^4.8.1",
"ulid": "^3.0.1", "ulid": "^3.0.1"
"uuid": "^13.0.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3.2.0", "@eslint/eslintrc": "^3.2.0",
-14002
View File
File diff suppressed because it is too large Load Diff
-19
View File
@@ -1,19 +0,0 @@
import { ApiProperty, PartialType } from "@nestjs/swagger";
import { IsNotEmpty, IsUUID } from "class-validator";
import { CommonMessage } from "../enums/message.enum";
export class ParamDto {
@IsNotEmpty({ message: CommonMessage.ID_REQUIRED })
@IsUUID("4", { message: CommonMessage.ID_SHOULD_BE_UUID })
@ApiProperty({ description: "Id of the entity", example: "8b1e8b1e-8b1e-8b1e-8b1e-8b1e8b1e8b1e" })
id: string;
}
export class OptionalParamDto extends PartialType(ParamDto) {}
export class ParamNumberIdDto {
@IsNotEmpty({ message: CommonMessage.ID_REQUIRED })
@ApiProperty({ description: "Id of the entity", example: "20" })
id: string;
}
@@ -5,9 +5,7 @@ import { JwtModule } from '@nestjs/jwt';
import { Notification } from './entities/notification.entity'; import { Notification } from './entities/notification.entity';
import { NotificationService } from './services/notification.service'; import { NotificationService } from './services/notification.service';
import { NotificationQueueService } from './services/notification-queue.service'; import { NotificationQueueService } from './services/notification-queue.service';
import { PushNotificationService } from './services/push-notification.service';
import { SmsProcessor } from './processors/sms.processor'; import { SmsProcessor } from './processors/sms.processor';
import { PushProcessor } from './processors/push.processor';
import { NotificationsController } from './controllers/notifications.controller'; import { NotificationsController } from './controllers/notifications.controller';
import { User } from '../user/entities/user.entity'; import { User } from '../user/entities/user.entity';
import { AuthModule } from '../auth/auth.module'; import { AuthModule } from '../auth/auth.module';
@@ -53,8 +51,6 @@ import { SmsListeners } from './listeners/sms.listeners';
providers: [ providers: [
NotificationService, NotificationService,
NotificationQueueService, NotificationQueueService,
PushNotificationService,
PushProcessor,
SmsProcessor, SmsProcessor,
InAppProcessor, InAppProcessor,
NotificationsGateway, NotificationsGateway,
@@ -65,6 +61,6 @@ import { SmsListeners } from './listeners/sms.listeners';
SmsListeners, SmsListeners,
], ],
exports: [NotificationService, NotificationQueueService, exports: [NotificationService, NotificationQueueService,
PushNotificationService, SmsService, NotificationsGateway], SmsService, NotificationsGateway],
}) })
export class NotificationsModule { } export class NotificationsModule { }
@@ -1,96 +0,0 @@
import { Processor, WorkerHost, OnWorkerEvent } from '@nestjs/bullmq';
import { Logger } from '@nestjs/common';
import { Job } from 'bullmq';
import { InjectRepository } from '@mikro-orm/nestjs';
import { EntityRepository, EntityManager } from '@mikro-orm/postgresql';
import { Notification } from '../entities/notification.entity';
import { PushNotificationQueueJob } from '../interfaces/jobs-queue.interface';
import { NotificationQueueNameEnum } from '../constants/queue';
import { PushNotificationService } from '../services/push-notification.service';
@Processor(NotificationQueueNameEnum.PUSH)
export class PushProcessor extends WorkerHost {
private readonly logger = new Logger(PushProcessor.name);
constructor(
@InjectRepository(Notification)
private readonly notificationRepository: EntityRepository<Notification>,
private readonly em: EntityManager,
private readonly pushNotificationService: PushNotificationService,
) {
super();
}
async process(job: Job<PushNotificationQueueJob>) {
const { title, content, action, pushToken, pushTokens } = job.data;
this.logger.log(`Processing push notification job: ${job.id} - Title: ${title},`);
try {
// Get push token from job data
const pushToken = job.data.pushToken;
const pushTokens = job.data.pushTokens;
if (!pushToken && (!pushTokens || pushTokens.length === 0)) {
this.logger.warn(`Push token(s) not provided for notification `);
throw new Error('Push token or pushTokens array is required for push notifications');
}
// Send push notification
// Convert NotificationTitle enum to a readable string for the notification title
const notificationTitle = String(title)
.replace(/\./g, ' ')
.replace(/\b\w/g, l => l.toUpperCase());
let pushResult;
if (pushTokens && pushTokens.length > 0) {
// Send to multiple tokens
pushResult = await this.pushNotificationService.sendToMultipleTokens({
title: notificationTitle,
body: content,
tokens: pushTokens,
data: {
action,
},
});
} else if (pushToken) {
// Send to single token
pushResult = await this.pushNotificationService.sendToToken({
title: notificationTitle,
body: content,
token: pushToken,
data: {
action,
},
});
} else {
throw new Error('Push token or pushTokens array is required');
}
if (!pushResult.success) {
throw new Error(pushResult.error || 'Failed to send push notification');
}
this.logger.log(`Push notification sent successfully`);
return {
success: true,
providerResponse: { messageId: pushResult.messageId },
};
} catch (error) {
this.logger.error(`Error processing push notification job ${job.id}:`, error);
throw error;
}
}
@OnWorkerEvent('completed')
onCompleted(job: Job) {
this.logger.log(`Notification job ${job.id} completed`);
}
@OnWorkerEvent('failed')
onFailed(job: Job, error: Error) {
this.logger.error(`Notification job ${job.id} failed:`, error);
}
}
@@ -1,147 +0,0 @@
import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as admin from 'firebase-admin';
export interface PushNotificationPayload {
title: string;
body: string;
data?: Record<string, unknown>;
token?: string;
tokens?: string[];
}
export interface PushNotificationResponse {
success: boolean;
messageId?: string;
error?: string;
}
@Injectable()
export class PushNotificationService {
private readonly logger = new Logger(PushNotificationService.name);
private firebaseApp: admin.app.App | null = null;
constructor(private readonly configService: ConfigService) {
this.initializeFirebase();
}
private initializeFirebase() {
try {
const firebaseConfig = this.configService.get<string>('FIREBASE_SERVICE_ACCOUNT');
if (!firebaseConfig) {
this.logger.warn('Firebase service account not configured. Push notifications will be disabled.');
return;
}
const serviceAccount = JSON.parse(firebaseConfig);
if (!this.firebaseApp) {
this.firebaseApp = admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
this.logger.log('Firebase initialized successfully');
}
} catch (error) {
this.logger.error('Failed to initialize Firebase:', error);
this.logger.warn('Push notifications will be disabled');
}
}
async sendToToken(payload: PushNotificationPayload): Promise<PushNotificationResponse> {
if (!this.firebaseApp || !payload.token) {
throw new HttpException(
'Push notification service not configured or token missing',
HttpStatus.SERVICE_UNAVAILABLE,
);
}
try {
const message: admin.messaging.Message = {
notification: {
title: payload.title,
body: payload.body,
},
data: this.convertDataToString(payload.data || {}),
token: payload.token,
android: {
priority: 'high',
},
apns: {
headers: {
'apns-priority': '10',
},
},
};
const response = await admin.messaging().send(message);
this.logger.log(`Push notification sent successfully: ${response}`);
return {
success: true,
messageId: response,
};
} catch (error) {
this.logger.error(`Failed to send push notification: ${error}`);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error',
};
}
}
async sendToMultipleTokens(payload: PushNotificationPayload): Promise<PushNotificationResponse> {
if (!this.firebaseApp || !payload.tokens || payload.tokens.length === 0) {
throw new HttpException(
'Push notification service not configured or tokens missing',
HttpStatus.SERVICE_UNAVAILABLE,
);
}
try {
const message: admin.messaging.MulticastMessage = {
notification: {
title: payload.title,
body: payload.body,
},
data: this.convertDataToString(payload.data || {}),
tokens: payload.tokens,
android: {
priority: 'high',
},
apns: {
headers: {
'apns-priority': '10',
},
},
};
const response = await admin.messaging().sendEachForMulticast(message);
this.logger.log(`Push notifications sent: ${response.successCount} successful, ${response.failureCount} failed`);
return {
success: response.successCount > 0,
messageId: response.responses[0]?.messageId,
error: response.failureCount > 0 ? `${response.failureCount} notifications failed` : undefined,
};
} catch (error) {
this.logger.error(`Failed to send push notifications: ${error}`);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error',
};
}
}
private convertDataToString(data: Record<string, unknown>): Record<string, string> {
const result: Record<string, string> = {};
for (const [key, value] of Object.entries(data)) {
result[key] = typeof value === 'string' ? value : JSON.stringify(value);
}
return result;
}
isConfigured(): boolean {
return this.firebaseApp !== null;
}
}
-20
View File
@@ -1,20 +0,0 @@
import sanitizeHtml from 'sanitize-html';
/**
* Sanitizes user input to prevent XSS attacks and remove malicious content
* Allows only safe text content, removing all HTML tags and scripts
* @param input - The string to sanitize
* @returns Sanitized string with all HTML tags and scripts removed
*/
export function sanitizeText(input: string | undefined | null): string | undefined | null {
if (!input) {
return input;
}
return sanitizeHtml(input, {
allowedTags: [], // No HTML tags allowed
allowedAttributes: {}, // No attributes allowed
allowedSchemes: [], // No URL schemes allowed
}).trim();
}