Skip to content

Instantly share code, notes, and snippets.

@KevLehman
Last active November 11, 2021 14:24
Show Gist options
  • Save KevLehman/33254bda74d7a7cefd70e73740cf40e5 to your computer and use it in GitHub Desktop.
Save KevLehman/33254bda74d7a7cefd70e73740cf40e5 to your computer and use it in GitHub Desktop.
RC Documentation [DRAFT]

RC Arch

  1. App is a monorepo containing FE & BE
  • App is made with Meteor
  • API and server information can be found at /server folder
  • There's also "common" (server code) at /app folder (this looks like the meteor standard for packages)
  • Packaging was using Meteor packages but now normal import/requires can be used. This is much better

/app

  • This folder encapsulates packages (like a Pluggabble structure)
  • Each folder is a package (A Meteor Pack) which can be used in the project
  • There is some code to migrate this structure into a services structure (see /services)
  • Each package has its own flags and configurations
  • Inside each package, there are 2 folders:
    • client: with FE logic to manage the feature
    • server: with API logic for the feature and ACL schema
  • There's a migrations folder.
    • A migration is an object with an up/down function and a version. The version determines the order in which it's applied to the database

Inside /package/server folder

  • Each package has its own structure inside this folder
  • The idea is that each package is an insolated service. Sharing code between FE and BE
  • Some of them use subfolders to organize code, others doesn't
  • Some of them have test folder, others doesn't
  • Some of them have a config file, others a settings, others embed the config within the code
    • This should be standardized when changing architecture
  • Some of them have a permissions file, others embed ACLs within logic
  • Some packages have a startup file, which calls init logic for the package.
    • This is used to build permissions, configurations, register the package at the global context, etc

Inside /server/

  • This folder contains the overall application (backend) structure.
  • Dedicated place for serverside of the app

/configuration

  • Should contain configuration items used in the app
    • Currently, instead of a centralized place for storing configuration, each module is responsible for propagating its own configuration
  • Contains just one file in charge of registering an account using a third party (from a predefined list of oauth services)

/cron

nps.js

  • Used to collect data from Survey items
  • If Surveys are disabled, this cron will close all open surveys

oembed.js

  • Used to clear the oEmbed cache each time the job is invoked.

statistics.js

  • Used to gather statistics from the application and POST them to the stats aggregator tool (collector.rocket.chat)

/database

  • Contains DB utils and prefferences for the Mongo client

readSecondaryPreferred.js

  • Used to let mongodb know that we want the read operations to be performed against Secondary databases, and not the master

/email

  • This folder contains logic related to email handling
    • This probably should be merged with features/emailimbox?

IMAPInterceptor.js

  • Used to fetch unread emails from a user. Probably to serve them in the omnichannel

/features/emailimbox

  • Feature folder: contains logic for a specific feature
  • Handles Email in/out from RC channels
  • Should new features be added here?

incoming.ts

  • In charge of handling received emails for Omnichannel feature.
  • Written in Typescript
  • Each "guest" is registered using a Random.id result
    • This returns a 17-char unique string. It ensures the ID will be unique, in the world.

outgoing.ts

  • In charge of handling sent messages for omnichannel
  • It adds a slash command to upload attachments to emails. It also sends the attachment
  • It also converts the message to a markdown message to embed the attachment
  • A callback (something like a hook, it seems) is added: The callback will add an attachment to the messages
    • Looks like messages can have before and after hooks
      • This callbacks can have priority, and a name

inbox.ts

  • A type inbox is defined. This type holds the smtp + imap + config of the mail client
  • Multiple inboxes can be created, with different elements, like one for gmail, outlook... etc
  • Nodemailer is used to manage multiple inboxes
  • Each inbox details' are stored in the database (meteor_email_inbox)
    • Passwords for email servers are stored in plain text, could this be a problem?

/lib

  • As the name implies, this folder contains useful methods and functions
    • Most of the files here are utilities, if they are not used globally we can consider moving them
  • This should be the place for global library methods. That is, functions that will be used by many pieces of the code and it's better to have them centralized

channelExport.ts

  • Contains logic and types for managing Channel messages' export.
  • Export also includes attachments
  • Exported data can be stored as a zip or sent via email

compareUserPassword.ts

  • Contains an algorithm to check if the actual and provided passwordds match
    • It's somewhat difficult to understand without having the context
    • The main point: accounts._checkpassword which takes the user and the password, and then compares
      • This is a "private method". Shouldn't have been called here.\

fileutils.ts

  • Has 2 functions
    • fileName which uses filenamify to remove weird chars from filenames
    • joinPath which... joins a path

getClientAddress

  • Returns the client address based on the real-ip header

getMomentLocale

  • Returns a moment locale file from a provided locale string

markRoomAsRead

  • Will mark a room as read
  • If the room has unread threads, it won't mark it as unread
  • This will clear the Notification queue for the user.
  • Another callback: afterReadMessages
    • Hooks are tied to actions, instead of data (as in ORMs)

pushConfig

  • Manages push notifications

resetUserE2EKey.ts

  • Allows users to reset their E2E password
  • After reset, user has to logout

sendMessagestoAdmins

  • Allows the app to put banners and send messages to admin users

/methods

  • The folder is selfdescriptive. It contains utility functions based on specific use case scenarios and actions performed by users.
  • Each possible action has its own file, and each file registers itself as a Meteor.method
  • Methods can be called via REST

/modules

  • A bad thing: everything is in the module file, instead of dividing that into different files
  • Each folder represents a base module, there are 5
    • coreapps
    • listeners
    • notifications
    • streamer
    • watchers
  • They are main pieces of the application (at least, the OSS version)
  • The idea is to have a "modularized" structure in which each feature represents a module itself
    • Like NestJS modules
  • Modules follow the angular naming convention, appending .module to the name of the file (or depending on the purpose of it)
  • Modules doesn't have services, they are mostly one-file modules yet

/listeners

  • This contains listeners for different events and watchers
  • looks like each of this listeners will trigger a notification when the event is fired

/notifications

  • This relies on the streamer module.
  • This is in charge of sending notifications to the client via stream (which can be a websocket)

/streamer

  • Module to stream notifications from server to client (using ws)
  • There's a method named iniPublication instead of init lel

/watchers

  • This manages watchers for different things.
  • It also can broadcast "messages" which are listened at other places
    • These are listened at DDPStreamer
      • So yes, all of these modules are for EE
  • There's a list of Event signatures, but not all events are there.

/publications

  • This has the spotlight feature, which is being used. This provides the typeahead functionality
  • This also has some GET methods for rooms, subscriptions and settings

/restapi

  • This is no longer used

/routes/avatar

  • Contains avatar handling features.
  • Has 2 middlewares
    • 1 prevents unauthenticated access to user avatars
    • 2 prevents accesing the page with IE
  • The restt of the folder just handle avatar operations
    • It also generates the default avatar, which is the initials of the name/lastname

/sdk

  • This folders has a development kit for services communication
  • Written in typescript, /types contains the interfaces and classes to handle all
  • The exported item is an Api instance.
    • Api instance holds a reference to local broker and the list of registered services.

/lib

  • api.ts is the one that register services and instantiates the broker (localbroker)
    • Each service is registered in the broker, which allows communication
    • When a service is registered, all of its methods will be registered as well (this is done by a config object)
  • There's a localbroker
    • The broker appears to be the communication method for microservices
  • There's a proxify file. Not sure what this file does.
    • A lot of complex logic has 0 documentation or comments :(

/services

  • Has 4 services in it: banner, nps, meteor, uikit-core, authorization
  • These servers are used when running the free version (not all, but at least the authorization one should get killed, no?)
  • The idea of a service is to have a pluggable structure, in which each service is an isolated package with its own dependencies, and that can be used or not without affecting the app
  • Each service folder has a service file
    • The service file holds the entire logic for the service (this can be changed, to a more modular structure)
    • Each service has additional files to hold specific logic helping the service itself
    • The service doesn't require data from other services directly
  • Each service extends the ServiceClass abstract class and implements a I<Service> interface
    • Both types can be found at /sdk folder

Authorization

- Manages permissions and access logic
- Performs validations to see if the user has a permission, a role, or if has at least one 
- Validates if users can access rooms
- Enforces roles restrictions

meteor

  • Manages base service & Meteor interactions with the database
  • Controls a specific database behavior: changes observer
    • This change only happens when disable-oplog is true
      • There are multiple tweaks when op log is disabled. interesting

banner

  • There's something weird at line 48: you can expect the result of insertOne and then broadcast the id, instead of looking the database for it (since you already have the ID)
  • This service allows admins to put banners on channels
  • Banner dissmisals are stored in database too

nps

  • Yep, its a poll system. Not like Polly (for open polls) it seems.
  • Maybe like a "qualification" system? To assign a "star" value to clients? who knows
  • It can only be closed when all users have submitted an answer

uikit-core

  • Not sure for what is this

/startup

  • Logic for warm up the application
  • Migrations are here (migrations looks a lot like seeders)
    • Each migration is a new file, with a correlative number
    • The latest migration is fetched everytime the app starts and the migrator will continue from that point
    • If there are no more migrations, it won't do anything.
    • Instead of doing a file discovery, the runner uses the package itself to discover all migration files and then get the version of the last of them
    • All migration logic is custom.
  • AppCache defines items that will be cached (mostly client things)
  • CoreApps registers 2 important apps
    • NPS
    • Banner
  • Cron uses a SyncedCron (a "thread safe" implementation of cronjobs for Meteor)
    • Each time a cron is executed, it's logged in rocketchat_cron_history
    • There are 3 crons:
      • oembed cache clean
      • application stats
      • nps
  • initialData creates some default values, for example Rocket.cat and #general
  • Instance registers the instance details (os type, node version, etc)
  • presence: not sure what this file does
  • streamBroadcast
    • Manages user presence events (as streams)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment