
- 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.
49 lines
1.3 KiB
JavaScript
49 lines
1.3 KiB
JavaScript
'use strict';
|
|
|
|
var punycode = require('punycode/');
|
|
var $decode = punycode.ucs2.decode;
|
|
var $encode = punycode.ucs2.encode;
|
|
|
|
var $TypeError = require('es-errors/type');
|
|
var regexTest = require('safe-regex-test');
|
|
|
|
var revEntities = require('./reversed.json');
|
|
|
|
var endsInSemicolon = regexTest(/;$/);
|
|
|
|
var defaultSpecial = {
|
|
'"': true,
|
|
"'": true,
|
|
'<': true,
|
|
'>': true,
|
|
'&': true
|
|
};
|
|
|
|
module.exports = function encode(str, opts) {
|
|
if (typeof str !== 'string') {
|
|
throw new $TypeError('Expected a String');
|
|
}
|
|
|
|
var numeric = !opts || !opts.named;
|
|
if (opts && typeof opts.numeric !== 'undefined') { numeric = opts.numeric; }
|
|
|
|
var special = (opts && opts.special) || defaultSpecial;
|
|
|
|
var codePoints = $decode(str);
|
|
var chars = [];
|
|
for (var i = 0; i < codePoints.length; i++) {
|
|
var cc = codePoints[i];
|
|
var c = $encode([cc]);
|
|
var e = revEntities[cc];
|
|
if (e && (cc >= 127 || special[c]) && !numeric) {
|
|
var hasSemi = endsInSemicolon(e);
|
|
chars[chars.length] = '&' + (hasSemi ? e : e + ';');
|
|
} else if (cc < 32 || cc >= 127 || special[c]) {
|
|
chars[chars.length] = '&#' + cc + ';';
|
|
} else {
|
|
chars[chars.length] = c;
|
|
}
|
|
}
|
|
return chars.join('');
|
|
};
|