Automated Action 545563e776 Implement comprehensive real-time chat API with NestJS
- Complete NestJS TypeScript implementation with WebSocket support
- Direct messaging (DM) and group chat functionality
- End-to-end encryption with AES encryption and key pairs
- Media file support (images, videos, audio, documents) up to 100MB
- Push notifications with Firebase Cloud Messaging integration
- Mention alerts and real-time typing indicators
- User authentication with JWT and Passport
- SQLite database with TypeORM entities and relationships
- Comprehensive API documentation with Swagger/OpenAPI
- File upload handling with secure access control
- Online/offline status tracking and presence management
- Message editing, deletion, and reply functionality
- Notification management with automatic cleanup
- Health check endpoint for monitoring
- CORS configuration for cross-origin requests
- Environment-based configuration management
- Structured for Flutter SDK integration

Features implemented:
 Real-time messaging with Socket.IO
 User registration and authentication
 Direct messages and group chats
 Media file uploads and management
 End-to-end encryption
 Push notifications
 Mention alerts
 Typing indicators
 Message read receipts
 Online status tracking
 File access control
 Comprehensive API documentation

Ready for Flutter SDK development and production deployment.
2025-06-21 17:13:05 +00:00

88 lines
1.9 KiB
JavaScript

/* eslint-disable no-underscore-dangle */
'use strict';
const fs = require('fs');
const crypto = require('crypto');
const { EventEmitter } = require('events');
class PersistentFile extends EventEmitter {
constructor({ filepath, newFilename, originalFilename, mimetype, hashAlgorithm }) {
super();
this.lastModifiedDate = null;
Object.assign(this, { filepath, newFilename, originalFilename, mimetype, hashAlgorithm });
this.size = 0;
this._writeStream = null;
if (typeof this.hashAlgorithm === 'string') {
this.hash = crypto.createHash(this.hashAlgorithm);
} else {
this.hash = null;
}
}
open() {
this._writeStream = new fs.WriteStream(this.filepath);
this._writeStream.on('error', (err) => {
this.emit('error', err);
});
}
toJSON() {
const json = {
size: this.size,
filepath: this.filepath,
newFilename: this.newFilename,
mimetype: this.mimetype,
mtime: this.lastModifiedDate,
length: this.length,
originalFilename: this.originalFilename,
};
if (this.hash && this.hash !== '') {
json.hash = this.hash;
}
return json;
}
toString() {
return `PersistentFile: ${this.newFilename}, Original: ${this.originalFilename}, Path: ${this.filepath}`;
}
write(buffer, cb) {
if (this.hash) {
this.hash.update(buffer);
}
if (this._writeStream.closed) {
cb();
return;
}
this._writeStream.write(buffer, () => {
this.lastModifiedDate = new Date();
this.size += buffer.length;
this.emit('progress', this.size);
cb();
});
}
end(cb) {
if (this.hash) {
this.hash = this.hash.digest('hex');
}
this._writeStream.end(() => {
this.emit('end');
cb();
});
}
destroy() {
this._writeStream.destroy();
fs.unlink(this.filepath, () => {});
}
}
module.exports = PersistentFile;