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
RUN addgroup app && adduser -SG app app
RUN mkdir /app && chown app:app /app
# Use Node.js 18 with Alpine Linux as the base image
FROM node:18-alpine
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
# Set up the frontend environment
WORKDIR /app/frontend
COPY --chown=app:app ./frontend/package*.json ./
RUN ln -s ./frontend/src/types /app
RUN npm i
RUN ln -s /app/frontend/src/types /app/shared/types \
&& npm install --legacy-peer-deps --unsafe-perm
# Set up the backend environment
WORKDIR /app/backend
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
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 4200
CMD ./bin/start-dev.sh
EXPOSE 3001
# Start the application
CMD ["sh", "./bin/start-dev.sh"]

View File

@ -1,6 +1,6 @@
# PVTChat - Messaging Made Simple.
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.
**PVTChat is based on [acrd.app](https://github.com/theADAMJR/acrd.app), leave a star to original creator!**
@ -34,6 +34,16 @@ Main point of PVT Chat is to fix accord bugs and continue maintenance for said a
mkdir -p assets/upload
```
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
```
---
@ -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
- **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
### App does not connect to MongoDB on Windows?
### App does not connect to MongoDB in Docker?
- Ensure MongoDB is installed.
- If localhost does not work, use `mongodb://127.0.0.1:27017/accord`.
- https://stackoverflow.com/a/73139137/8304458
- If localhost does not work, use `mongodb://database/accord`.

View File

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

2983
backend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -22,32 +22,48 @@ export default class Channels extends DBWrapper<string, ChannelDocument> {
}
public async create(options: Partial<Entity.Channel>): Promise<ChannelDocument> {
const isVoice = options.type === 'VOICE';
return Channel.create({
_id: options.id ?? generateSnowflake(),
name: 'chat',
name: options.name || (isVoice ? 'Voice Channel' : 'chat'),
position: await Channel.countDocuments({ guildId: options.guildId }),
type: 'TEXT',
type: options.type || 'TEXT',
userIds: isVoice ? [] : undefined,
...options as any,
});
}
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) {
if (!channel.userIds) channel.userIds = [];
channel.userIds.push(userId);
return await channel.save();
}
public async leaveVC(channel: VoiceChannelDocument, userId: string) {
if (!channel.userIds) return channel;
const index = channel.userIds.indexOf(userId);
channel.userIds.splice(index, 1);
if (index > -1) channel.userIds.splice(index, 1);
return await channel.save();
}

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
#!/bin/sh
cd /app/backend && npm run start:dev &
cd /app/frontend && npm run start:dev
cd /app/backend && PORT=3000 NODE_ENV=dev 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'
services:
database:
container_name: accord_database
container_name: pvtchat_database
image: mongo:5-focal
ports: [27018:27017]
volumes: [accord:/data/db]
volumes: [pvtchat:/data/db]
restart: unless-stopped
app:
container_name: accord_app
container_name: pvtchat_app
depends_on: [database]
build:
context: ./
dockerfile: Dockerfile.dev
ports: [3000:3000, 4200:4200]
ports: [3000:3000, 3001:3001]
env_file: [./backend/.env, ./frontend/env/.env.dev]
volumes:
- ./backend/src:/app/backend/src
- ./backend/assets:/app/backend/assets
- ./backend/logs:/app/backend/logs
- ./frontend/src:/app/frontend/src
restart: unless-stopped
volumes:
accord:
pvtchat:

View File

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