Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/charts
**/docker-compose*
**/compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
11 changes: 11 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"configurations": [
{
"name": "Containers: Node.js Launch",
"type": "docker",
"request": "launch",
"preLaunchTask": "docker-run: debug",
"platform": "node"
}
]
}
39 changes: 39 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "docker-build",
"label": "docker-build",
"platform": "node",
"dockerBuild": {
"dockerfile": "${workspaceFolder}/Dockerfile",
"context": "${workspaceFolder}",
"pull": true
}
},
{
"type": "docker-run",
"label": "docker-run: release",
"dependsOn": [
"docker-build"
],
"platform": "node"
},
{
"type": "docker-run",
"label": "docker-run: debug",
"dependsOn": [
"docker-build"
],
"dockerRun": {
"env": {
"DEBUG": "*",
"NODE_ENV": "development"
}
},
"node": {
"enableDebugging": true
}
}
]
}
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM node:lts-alpine
ENV NODE_ENV=production
WORKDIR /usr/src/app
COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
RUN npm install --production --silent && mv node_modules ../
Comment on lines +4 to +5
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== packageManager declaration =="
rg -n '"packageManager"\s*:' package.json

echo "== yarn config present =="
fd -a '^\.yarnrc\.yml$'

echo "== Dockerfile install command =="
rg -n 'npm install|yarn install|corepack' Dockerfile

Repository: RocketChat/Rocket.Chat

Length of output: 386


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== .yarnrc.yml existence (with hidden) =="
fd -H '^\.yarnrc\.yml$' || echo "Not found at repo root"

echo "== Full Dockerfile content =="
cat -n Dockerfile

echo "== index.js at root =="
ls -la index.js 2>/dev/null || echo "Not found"

echo "== Workspace packages (top-level) =="
ls -la packages/ 2>/dev/null | head -20 || echo "No packages dir"

echo "== Monorepo root structure =="
ls -la | grep -E '^d|\.json$|\.yml$' | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 3009


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== package.json main field =="
rg -A2 '"main"' package.json | head -5

echo "== Search for server/app entry points in packages =="
find packages -name "main.ts" -o -name "main.js" -o -name "index.ts" -o -name "server.ts" 2>/dev/null | head -10

echo "== Other Dockerfiles in repo =="
fd -e Dockerfile

echo "== docker-compose references =="
rg -n 'build:|image:' docker-compose*.yml | head -10

echo "== .yarnrc.yml content (to confirm yarn v4 setup) =="
cat -n .yarnrc.yml

Repository: RocketChat/Rocket.Chat

Length of output: 635


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Build scripts in root package.json =="
rg -A5 '"scripts"' package.json | head -20

echo "== Check if index.js is built artifact (dist/build folders) =="
fd -t f 'index.js' --max-depth 2 2>/dev/null | head -10

echo "== apps/* structure - any server/api apps? =="
ls -1 apps/ 2>/dev/null | head -15

echo "== Check docker-compose.yml for build context =="
grep -A10 'build:' docker-compose*.yml | head -30

echo "== Git history - when was this Dockerfile last changed? =="
git log --oneline -5 -- Dockerfile 2>/dev/null || echo "Not in git"

Repository: RocketChat/Rocket.Chat

Length of output: 2171


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== References to root Dockerfile =="
rg -i 'dockerfile|docker build' --type md --type yml --type json . | grep -v 'apps/\|ee/' | head -20

echo "== Is root Dockerfile mentioned in docs? =="
find docs -name '*.md' 2>/dev/null -exec grep -l -i 'dockerfile\|docker build' {} \;

echo "== CI workflow files - do they use root Dockerfile? =="
rg 'Dockerfile' .github/workflows/ | grep -v 'apps/\|ee/' 

echo "== Check README for docker instructions =="
head -100 README.md | grep -A5 -i docker || echo "Not in first 100 lines"

Repository: RocketChat/Rocket.Chat

Length of output: 146


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Simple grep for Dockerfile references =="
rg 'Dockerfile' --no-heading | grep -v '^apps/\|^ee/' | head -20

echo "== Check if Dockerfile is in .gitignore =="
[ -f .gitignore ] && grep -i dockerfile .gitignore || echo "Not in .gitignore"

echo "== Git status for Dockerfile (is it modified in a PR?) =="
git status Dockerfile 2>/dev/null || echo "File status unknown"

echo "== Check .docker subdirectories =="
find . -type d -name '.docker' 2>/dev/null

echo "== Is there a root-level Docker build documented anywhere? =="
rg 'FROM node:lts' --type-list

Repository: RocketChat/Rocket.Chat

Length of output: 2810


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== compose.yaml service definition =="
grep -A15 'services:' compose.yaml | head -25

echo "== compose.debug.yaml service definition =="
grep -A15 'services:' compose.debug.yaml | head -25

echo "== Check if index.js might be in dist after build =="
find . -type f -name 'index.js' -path '*/dist/*' 2>/dev/null | head -5

echo "== Turbo build output - does it create root index.js? =="
rg 'index.js' turbo.json 2>/dev/null || echo "Not in turbo.json"

Repository: RocketChat/Rocket.Chat

Length of output: 710


Use Yarn v4 and fix missing entrypoint in Dockerfile.

Lines 4-5 use npm despite this repo declaring "packageManager": "yarn@4.12.0" with .yarnrc.yml. This breaks workspace resolution and reproducibility in the container.

Additionally, line 10 runs node index.js, but that file does not exist in the repo. The container will fail at startup.

Proposed fix
-COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
-RUN npm install --production --silent && mv node_modules ../
+COPY ["package.json", "yarn.lock", ".yarnrc.yml", "./"]
+COPY .yarn ./.yarn
+RUN corepack enable && yarn install --immutable --mode=skip-build
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
RUN npm install --production --silent && mv node_modules ../
COPY ["package.json", "yarn.lock", ".yarnrc.yml", "./"]
COPY .yarn ./.yarn
RUN corepack enable && yarn install --immutable --mode=skip-build
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 4 - 5, The Dockerfile currently runs RUN npm install
--production --silent (and COPY package.json/package-lock.json) which conflicts
with the repo's declared packageManager (yarn@4) and will break workspace
resolution; replace the npm-based steps by copying .yarnrc.yml and Yarn files
(and package.json/package.json.lock if used), then run yarn install --immutable
--production --silent (or yarn workspaces focus --all --production for
workspaces) to produce a reproducible install; also the container CMD/ENTRYPOINT
currently runs node index.js which does not exist — change it to invoke the
package start script via yarn (e.g., CMD ["yarn","start"]) or point to the
correct build entry (for example the real built file under dist or the script
name in package.json) so the container starts the actual app.

COPY . .
EXPOSE 3000
RUN chown -R node /usr/src/app
USER node
CMD ["node", "index.js"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== root index.js existence check =="
fd -a '^index\.js$' .

echo "== possible startup scripts in package.json =="
rg -n '"scripts"\s*:|"start"\s*:|"dev"\s*:|"build"\s*:' package.json -A20

Repository: RocketChat/Rocket.Chat

Length of output: 2796


🏁 Script executed:

#!/bin/bash
# Get full Dockerfile context to understand the image purpose and any build steps
fd -a 'Dockerfile' . | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 556


🏁 Script executed:

# Read the Dockerfile to see the full context around line 10
cat -n Dockerfile 2>/dev/null || echo "Dockerfile not found in root"

Repository: RocketChat/Rocket.Chat

Length of output: 423


🏁 Script executed:

# Search for Meteor-specific startup or build configurations
rg -i 'meteor|start|entry' package.json -B2 -A5 | head -50

Repository: RocketChat/Rocket.Chat

Length of output: 1013


🏁 Script executed:

# Check if there are build artifacts or dist directories that might contain index.js
fd -a 'index\.js$' . -type f | grep -E '(dist|build|\.meteor|bundle)' | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 236


🏁 Script executed:

# Read one of the service Dockerfiles to see the correct pattern
head -20 /home/jailuser/git/ee/apps/account-service/Dockerfile

Repository: RocketChat/Rocket.Chat

Length of output: 754


🏁 Script executed:

# Search for any references to index.js as an entry point in build or CI configs
rg 'index\.js' --max-count=10 -B3 -A3

Repository: RocketChat/Rocket.Chat

Length of output: 30061


🏁 Script executed:

# Check if there's a meteor build configuration or output directory
find . -maxdepth 3 -name '.meteor' -type d 2>/dev/null || echo "No .meteor directories in first 3 levels"

Repository: RocketChat/Rocket.Chat

Length of output: 87


🏁 Script executed:

# Look for build output or dist directories that might contain index.js
ls -la apps/meteor/ 2>/dev/null | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 1339


The Dockerfile entry point will fail at container startup—no root index.js exists in this monorepo.

Line 10 hardcodes node index.js, but the repository contains no root-level index.js file. The main application is a Meteor app in apps/meteor/ (confirmed by .meteor/ directory), and the Dockerfile copies the entire monorepo without a corresponding build step or proper entry point for the Meteor application. Additionally, compose.debug.yaml contains the same problematic command. The Dockerfile needs either a build stage that compiles/bundles the Meteor app or a corrected entry point that references the actual application location.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` at line 10, The Dockerfile's CMD currently uses "node index.js"
which will fail because there is no root index.js; update the Dockerfile (and
compose.debug.yaml) to either add a build stage that builds the Meteor app from
apps/meteor/ (e.g., run meteor build or npm install/build in apps/meteor and
produce a runnable bundle) and set CMD to start the built Meteor bundle, or
change CMD to run the Meteor app directly from apps/meteor/ (e.g., start script
in package.json in apps/meteor/) — locate the CMD instruction and any references
in compose.debug.yaml and replace the hardcoded node index.js with the correct
build+start flow or the meteor app start command so the container starts the
actual Meteor application.

25 changes: 25 additions & 0 deletions apps/meteor/app/lib/server/lib/sendNotificationsOnMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,31 @@ export async function sendMessageNotifications(message: IMessage, room: IRoom, u
}

const sender = await roomCoordinator.getRoomDirectives(room.t).getMsgSender(message);

const reasons: any[] = [];

if (message.msg && message.msg.length > 200) {
reasons.push({
type: 'long_message',
message: 'Message unusually long (possible spam)',
});
}

if (/(.)\1{5,}/.test(message.msg || '')) {
reasons.push({
type: 'repetition',
message: 'Repeated characters detected',
});
}

if (reasons.length > 0) {
(message as any).moderationReasons = reasons;

Comment on lines +282 to +300
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether IMessage officially includes moderationReasons
ast-grep --pattern $'interface IMessage {\n  $$$\n  moderationReasons: $_\n  $$$\n}'

# Locate all usages/assumptions of moderationReasons in TS sources
rg -n --type=ts -C3 '\bmoderationReasons\b'

Repository: RocketChat/Rocket.Chat

Length of output: 681


Remove the any type bypass and undeclared moderationReasons mutation; add proper typing or use a separate tracking object.

Lines 299 and 282: The code mutates message via (message as any).moderationReasons to inject a field not declared in the IMessage interface. This bypasses type checking and creates a hidden contract for shared notification objects. Additionally, the console.log at line 301 should not be in production code—remove or replace with proper debug logging.

Define moderationReasons in the IMessage type contract, or use a separate Map<string, any[]> to track moderation metadata outside the message object.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/lib/server/lib/sendNotificationsOnMessage.ts` around lines
282 - 300, The code is mutating message via (message as any).moderationReasons
and using console.log; remove the any-cast and the mutation and instead either
(A) add a properly typed moderationReasons?: ModerationReason[] to the IMessage
interface and assign to message.moderationReasons (no any cast) wherever
IMessage is constructed/validated, or (B) keep IMessage unchanged and create a
separate Map<string, ModerationReason[]> (e.g., moderationReasonsMap) keyed by
message._id and store reasons there; update any consumers to read from the new
typed field or map; also remove the console.log and replace with proper logging
if needed (use existing logger), and ensure the local const reasons:
ModerationReason[] is strongly typed.

console.log('Moderation reasoning:', {
userId: message.u?._id ?? 'unknown',
reasons,
});
Comment on lines +301 to +304
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove raw console.log from the server notification path.

Line 301 logs user-related data in a hot path and can create noisy, unstructured production logs.

Suggested minimal change
-		console.log('Moderation reasoning:', {
-			userId: message.u?._id ?? 'unknown',
-			reasons,
-		});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log('Moderation reasoning:', {
userId: message.u?._id ?? 'unknown',
reasons,
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/lib/server/lib/sendNotificationsOnMessage.ts` around lines
301 - 304, Remove the raw console.log in sendNotificationsOnMessage.ts that
prints "Moderation reasoning" (including userId and reasons) and replace it with
a structured server logger call (e.g., processLogger.debug or the app's central
logger) inside the same function so logs are consistent and not noisy; ensure
you log only non-sensitive identifiers (use message.u?._id ?? 'unknown') and
include reasons as a structured field rather than a freeform console output.

}
if (!sender) {
return message;
}
Expand Down
3 changes: 3 additions & 0 deletions apps/meteor/app/utils/server/escapeRegExp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function escapeRegExp(value: string): string {
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
4 changes: 0 additions & 4 deletions apps/meteor/client/components/UserCard/UserCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const clampStyle = css`
-webkit-box-orient: vertical;
word-break: break-word;
`;

type UserCardProps = {
user?: {
nickname?: string;
Expand All @@ -37,7 +36,6 @@ type UserCardProps = {
onOpenUserInfo?: () => void;
onClose?: () => void;
} & ComponentProps<typeof UserCardDialog>;

const UserCard = ({
user: { name, username, etag, customStatus, roles, bio, status = <Status.Offline />, localTime, nickname } = {},
actions,
Expand All @@ -47,7 +45,6 @@ const UserCard = ({
}: UserCardProps) => {
const { t } = useTranslation();
const isLayoutEmbedded = useEmbeddedLayout();

return (
<UserCardDialog title={t('User_card')} {...props}>
<div>
Expand Down Expand Up @@ -93,5 +90,4 @@ const UserCard = ({
</UserCardDialog>
);
};

export default UserCard;
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { MessageListContext } from '../../list/MessageListContext';

const normalizeUsernames = (names: string[]) => names.map<string>(normalizeUsername);

// TODO: replace it with proper usage of i18next plurals
type ReactionProps = {
hasReacted: (name: string) => boolean;
counter: number;
Expand Down
Loading