Fixed Voice Channels type and display, updated vulnerable modules, fully re-worked dev docker compose file. Production usage not ready.

This commit is contained in:
root 2025-03-22 13:42:37 +00:00
parent 24ea281650
commit ba9e975e10
11 changed files with 1740 additions and 1397 deletions

View File

@ -1,20 +1,36 @@
FROM node:16-alpine3.14 # Use Node.js 18 with Alpine Linux as the base image
RUN addgroup app && adduser -SG app app FROM node:18-alpine
RUN mkdir /app && chown app:app /app RUN apk add --no-cache python3 make g++ && ln -sf python3 /usr/bin/python
# Create a new user and group for better security
RUN addgroup app && adduser -SG app app \
&& mkdir -p /app/frontend /app/backend /app/shared \
&& chown -R app:app /app
# Switch to the new user
USER app USER app
# Set up the frontend environment
WORKDIR /app/frontend WORKDIR /app/frontend
COPY --chown=app:app ./frontend/package*.json ./ COPY --chown=app:app ./frontend/package*.json ./
RUN ln -s ./frontend/src/types /app RUN ln -s /app/frontend/src/types /app/shared/types \
RUN npm i && npm install --legacy-peer-deps --unsafe-perm
# Set up the backend environment
WORKDIR /app/backend WORKDIR /app/backend
COPY --chown=app:app ./backend/package*.json ./ COPY --chown=app:app ./backend/package*.json ./
RUN npm i RUN npm install --legacy-peer-deps --unsafe-perm
# Copy the remaining application files
WORKDIR /app WORKDIR /app
COPY --chown=app:app . . COPY --chown=app:app . .
RUN chown -R app:app /app
RUN chmod -R 777 /app/backend/upload
# Expose ports for frontend and backend applications
EXPOSE 3000 EXPOSE 3000
EXPOSE 4200 EXPOSE 3001
CMD ./bin/start-dev.sh
# Start the application
CMD ["sh", "./bin/start-dev.sh"]

View File

@ -1,6 +1,6 @@
# PVTChat - Messaging Made Simple. # PVTChat - Messaging Made Simple.
PVTChat is an app, similar to Discord, but cooler. PVTChat is an app, similar to Discord, but cooler.
Built with React, TypeScript, and Node.js. Built with React, TypeScript, and Node.js (18).
Main point of PVT Chat is to fix accord bugs and continue maintenance for said app. Main point of PVT Chat is to fix accord bugs and continue maintenance for said app.
**PVTChat is based on [acrd.app](https://github.com/theADAMJR/acrd.app), leave a star to original creator!** **PVTChat is based on [acrd.app](https://github.com/theADAMJR/acrd.app), leave a star to original creator!**
@ -34,7 +34,17 @@ Main point of PVT Chat is to fix accord bugs and continue maintenance for said a
mkdir -p assets/upload mkdir -p assets/upload
``` ```
5. In `backend` directory, configure `.env.example` and rename the file to `.env` 5. In `backend` directory, configure `.env.example` and rename the file to `.env`
6. In `frontend/env` directory, configure `.env.dev` and `.env.prod` file.
7. To run application in dev or production mode move back to project root directory and type:
```
# for development
docker-compose -f docker-compose.dev.yml up
# for production
docker-compose -f docker-compose.prod.yml up
# use -d tag to run it in the background
# use --build tag to build app
```
--- ---
## Features ## Features
@ -59,43 +69,10 @@ Main point of PVT Chat is to fix accord bugs and continue maintenance for said a
- Delete your user and prevent it from being used to login - Delete your user and prevent it from being used to login
- **and more** (of course) - **and more** (of course)
---
`backend/.env`
(dev with Docker)
```
EMAIL_ADDRESS="...@gmail.com"
EMAIL_PASSWORD="..."
MONGO_URI="mongodb://database/accord"
NODE_ENV="dev"
PORT=3000
WEBSITE_URL="http://localhost:4200"
SESSION_SECRET="Please ⭐ this repository."
```
`backend/test/.env`
(test without Docker)
```
API_URL="http://localhost:3001/api"
EMAIL_ADDRESS="...@gmail.com"
EMAIL_PASSWORD="..."
MONGO_URI="mongodb://localhost/accord-test"
NODE_ENV="dev"
PORT=3001
ROOT_ENDPOINT="http://localhost:3001"
WEBSITE_URL="http://localhost:4200"
SESSION_SECRET="Please ⭐ this repository."
```
--- ---
## Troubleshooting ## Troubleshooting
### App does not connect to MongoDB on Windows? ### App does not connect to MongoDB in Docker?
- Ensure MongoDB is installed. - Ensure MongoDB is installed.
- If localhost does not work, use `mongodb://127.0.0.1:27017/accord`. - If localhost does not work, use `mongodb://database/accord`.
- https://stackoverflow.com/a/73139137/8304458

View File

@ -3,6 +3,6 @@ EMAIL_PASSWORD="password"
MONGO_URI="mongodb://localhost/accord" MONGO_URI="mongodb://localhost/accord"
NODE_ENV="dev" NODE_ENV="dev"
PORT=3000 PORT=3000
WEBSITE_URL="http://localhost:4200" WEBSITE_URL="http://localhost:3001"
SESSION_SECRET="Please ⭐ this repository." SESSION_SECRET="Please ⭐ this repository."
RECAPTCHA_SECRET="" RECAPTCHA_SECRET=""

2985
backend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -22,36 +22,52 @@ export default class Channels extends DBWrapper<string, ChannelDocument> {
} }
public async create(options: Partial<Entity.Channel>): Promise<ChannelDocument> { public async create(options: Partial<Entity.Channel>): Promise<ChannelDocument> {
const isVoice = options.type === 'VOICE';
return Channel.create({ return Channel.create({
_id: options.id ?? generateSnowflake(), _id: options.id ?? generateSnowflake(),
name: 'chat', name: options.name || (isVoice ? 'Voice Channel' : 'chat'),
position: await Channel.countDocuments({ guildId: options.guildId }), position: await Channel.countDocuments({ guildId: options.guildId }),
type: 'TEXT', type: options.type || 'TEXT',
userIds: isVoice ? [] : undefined,
...options as any, ...options as any,
}); });
} }
public async createDM(userIds: string[]) { public async createDM(userIds: string[]) {
return this.create({ userIds }) as Promise<DMChannelDocument>; return this.create({ userIds, type: 'DM' }) as Promise<DMChannelDocument>;
} }
public async createText(guildId: string) {
return this.create({ guildId }) as Promise<TextChannelDocument>; public async createText(guildId: string, name?: string) {
return this.create({
guildId,
type: 'TEXT',
name: name || 'chat'
}) as Promise<TextChannelDocument>;
} }
public async createVoice(guildId: string) {
return this.create({ guildId, type: 'VOICE' }) as Promise<VoiceChannelDocument>; public async createVoice(guildId: string, name?: string) {
return this.create({
guildId,
type: 'VOICE',
name: name || 'Voice Channel',
userIds: []
}) as Promise<VoiceChannelDocument>;
} }
public async joinVC(channel: VoiceChannelDocument, userId: string) { public async joinVC(channel: VoiceChannelDocument, userId: string) {
if (!channel.userIds) channel.userIds = [];
channel.userIds.push(userId); channel.userIds.push(userId);
return await channel.save(); return await channel.save();
} }
public async leaveVC(channel: VoiceChannelDocument, userId: string) { public async leaveVC(channel: VoiceChannelDocument, userId: string) {
if (!channel.userIds) return channel;
const index = channel.userIds.indexOf(userId); const index = channel.userIds.indexOf(userId);
channel.userIds.splice(index, 1); if (index > -1) channel.userIds.splice(index, 1);
return await channel.save(); return await channel.save();
} }
public async getSystem(guildId: string) { public async getSystem(guildId: string) {
return await Channel.findOne({ guildId, type: 'TEXT' }); return await Channel.findOne({ guildId, type: 'TEXT' });
} }
} }

View File

@ -114,8 +114,8 @@ export const User = model<UserDocument>('user', new Schema({
AttemptTooSoonError: 'Account is currently locked. Try again later', AttemptTooSoonError: 'Account is currently locked. Try again later',
TooManyAttemptsError: 'Account locked due to too many failed login attempts', TooManyAttemptsError: 'Account locked due to too many failed login attempts',
NoSaltValueStoredError: 'Authentication not possible. No salt value stored', NoSaltValueStoredError: 'Authentication not possible. No salt value stored',
IncorrectPasswordError: 'Password or username are incorrect', IncorrectPasswordError: 'Password is incorrect',
IncorrectUsernameError: 'Password or username are incorrect', IncorrectUsernameError: 'Username is incorrect',
MissingUsernameError: 'No username was given', MissingUsernameError: 'No username was given',
UserExistsError: 'Email is already in use', UserExistsError: 'Email is already in use',
} }

View File

@ -14,7 +14,7 @@ export class REST {
applyRoutes(app, prefix); applyRoutes(app, prefix);
applyErrorHandling(app, prefix); applyErrorHandling(app, prefix);
const port = process.env.PORT || 8080; const port = process.env.PORT || 3000;
const server = app.listen(port, async () => { const server = app.listen(port, async () => {
log.info(`API is running on port ${port}`); log.info(`API is running on port ${port}`);
await deps.webSocket.init(server); await deps.webSocket.init(server);

View File

@ -22,7 +22,6 @@
"strictPropertyInitialization": false, "strictPropertyInitialization": false,
"target": "ES2020", "target": "ES2020",
"skipLibCheck": true, "skipLibCheck": true,
"watch": true,
}, },
"include": [ "include": [
"src", "src",

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
cd /app/backend && npm run start:dev & cd /app/backend && PORT=3000 NODE_ENV=dev npm run start:dev &
cd /app/frontend && npm run start:dev cd /app/frontend && DISABLE_ESLINT_PLUGIN=true NODE_ENV=dev PORT=3001 WDS_SOCKET_PORT=3001 npm run start:dev
fg %1 wait

View File

@ -1,22 +1,24 @@
version: '3.8' version: '3.8'
services: services:
database: database:
container_name: accord_database container_name: pvtchat_database
image: mongo:5-focal image: mongo:5-focal
ports: [27018:27017] ports: [27018:27017]
volumes: [accord:/data/db] volumes: [pvtchat:/data/db]
restart: unless-stopped
app: app:
container_name: accord_app container_name: pvtchat_app
depends_on: [database] depends_on: [database]
build: build:
context: ./ context: ./
dockerfile: Dockerfile.dev dockerfile: Dockerfile.dev
ports: [3000:3000, 4200:4200] ports: [3000:3000, 3001:3001]
env_file: [./backend/.env, ./frontend/env/.env.dev] env_file: [./backend/.env, ./frontend/env/.env.dev]
volumes: volumes:
- ./backend/src:/app/backend/src - ./backend/src:/app/backend/src
- ./backend/assets:/app/backend/assets - ./backend/assets:/app/backend/assets
- ./backend/logs:/app/backend/logs - ./backend/logs:/app/backend/logs
- ./frontend/src:/app/frontend/src - ./frontend/src:/app/frontend/src
restart: unless-stopped
volumes: volumes:
accord: pvtchat:

View File

@ -1,13 +1,13 @@
version: '3.8' version: '3.8'
services: services:
database: database:
container_name: accord_database container_name: pvtchat_database
image: mongo:5-focal image: mongo:5-focal
ports: [27017:27017] ports: [27017:27017]
volumes: [accord:/data/db] volumes: [pvtchat:/data/db]
restart: unless-stopped restart: unless-stopped
app: app:
container_name: accord_app container_name: pvtchat_app
depends_on: [database] depends_on: [database]
build: build:
context: ./ context: ./
@ -21,4 +21,4 @@ services:
- ./frontend/src:/app/frontend/src - ./frontend/src:/app/frontend/src
restart: unless-stopped restart: unless-stopped
volumes: volumes:
accord: pvtchat: