
- 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.
104 lines
3.3 KiB
JavaScript
104 lines
3.3 KiB
JavaScript
var defaults = require('./defaults.js');
|
|
var underscore = require('./underscore.js');
|
|
require('./templateSettings.js');
|
|
|
|
// When customizing `_.templateSettings`, if you don't want to define an
|
|
// interpolation, evaluation or escaping regex, we need one that is
|
|
// guaranteed not to match.
|
|
var noMatch = /(.)^/;
|
|
|
|
// Certain characters need to be escaped so that they can be put into a
|
|
// string literal.
|
|
var escapes = {
|
|
"'": "'",
|
|
'\\': '\\',
|
|
'\r': 'r',
|
|
'\n': 'n',
|
|
'\u2028': 'u2028',
|
|
'\u2029': 'u2029'
|
|
};
|
|
|
|
var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
|
|
|
|
function escapeChar(match) {
|
|
return '\\' + escapes[match];
|
|
}
|
|
|
|
// In order to prevent third-party code injection through
|
|
// `_.templateSettings.variable`, we test it against the following regular
|
|
// expression. It is intentionally a bit more liberal than just matching valid
|
|
// identifiers, but still prevents possible loopholes through defaults or
|
|
// destructuring assignment.
|
|
var bareIdentifier = /^\s*(\w|\$)+\s*$/;
|
|
|
|
// JavaScript micro-templating, similar to John Resig's implementation.
|
|
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
|
// and correctly escapes quotes within interpolated code.
|
|
// NB: `oldSettings` only exists for backwards compatibility.
|
|
function template(text, settings, oldSettings) {
|
|
if (!settings && oldSettings) settings = oldSettings;
|
|
settings = defaults({}, settings, underscore.templateSettings);
|
|
|
|
// Combine delimiters into one regular expression via alternation.
|
|
var matcher = RegExp([
|
|
(settings.escape || noMatch).source,
|
|
(settings.interpolate || noMatch).source,
|
|
(settings.evaluate || noMatch).source
|
|
].join('|') + '|$', 'g');
|
|
|
|
// Compile the template source, escaping string literals appropriately.
|
|
var index = 0;
|
|
var source = "__p+='";
|
|
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
|
|
source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
|
|
index = offset + match.length;
|
|
|
|
if (escape) {
|
|
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
|
} else if (interpolate) {
|
|
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
|
} else if (evaluate) {
|
|
source += "';\n" + evaluate + "\n__p+='";
|
|
}
|
|
|
|
// Adobe VMs need the match returned to produce the correct offset.
|
|
return match;
|
|
});
|
|
source += "';\n";
|
|
|
|
var argument = settings.variable;
|
|
if (argument) {
|
|
// Insure against third-party code injection. (CVE-2021-23358)
|
|
if (!bareIdentifier.test(argument)) throw new Error(
|
|
'variable is not a bare identifier: ' + argument
|
|
);
|
|
} else {
|
|
// If a variable is not specified, place data values in local scope.
|
|
source = 'with(obj||{}){\n' + source + '}\n';
|
|
argument = 'obj';
|
|
}
|
|
|
|
source = "var __t,__p='',__j=Array.prototype.join," +
|
|
"print=function(){__p+=__j.call(arguments,'');};\n" +
|
|
source + 'return __p;\n';
|
|
|
|
var render;
|
|
try {
|
|
render = new Function(argument, '_', source);
|
|
} catch (e) {
|
|
e.source = source;
|
|
throw e;
|
|
}
|
|
|
|
var template = function(data) {
|
|
return render.call(this, data, underscore);
|
|
};
|
|
|
|
// Provide the compiled source as a convenience for precompilation.
|
|
template.source = 'function(' + argument + '){\n' + source + '}';
|
|
|
|
return template;
|
|
}
|
|
|
|
module.exports = template;
|