Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Merge pull request #255 from Arquisoft/makeFriends
Browse files Browse the repository at this point in the history
Make friends
  • Loading branch information
RubenFern authored Apr 16, 2024
2 parents 773d7ce + 3fb271c commit ebc33fc
Show file tree
Hide file tree
Showing 26 changed files with 13,421 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ jobs:
- run: npm --prefix auth_service ci
- run: npm --prefix webapp ci
- run: npm --prefix game_service ci
- run: npm --prefix friends_service ci
- run: npm --prefix userdetails_service test -- --coverage
- run: npm --prefix question_service test -- --coverage
- run: npm --prefix auth_service test
- run: npm --prefix webapp test -- --coverage
- run: npm --prefix game_service test -- --coverage
- run: npm --prefix friends_service test -- --coverage
- name: Analyze with SonarCloud
uses: sonarsource/sonarcloud-github-action@master
env:
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ jobs:
- run: npm --prefix auth_service ci
- run: npm --prefix webapp ci
- run: npm --prefix game_service ci
- run: npm --prefix friends_service ci
- run: npm --prefix userdetails_service test -- --coverage
- run: npm --prefix question_service test -- --coverage
- run: npm --prefix auth_service test
- run: npm --prefix webapp test -- --coverage
- run: npm --prefix game_service test -- --coverage
- run: npm --prefix friends_service test -- --coverage
- name: Analyze with SonarCloud
uses: sonarsource/sonarcloud-github-action@master
env:
Expand Down Expand Up @@ -76,6 +78,23 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
registry: ghcr.io
workdir: userdetails_service
docker-push-friends:
name: Push friends service Docker Image to GitHub Packages
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
needs: [unit-tests]
steps:
- uses: actions/checkout@v4
- name: Publish to Registry
uses: elgohr/Publish-Docker-Github-Action@v5
with:
name: arquisoft/wiq_es1c/friends
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
registry: ghcr.io
workdir: friends_service
docker-push-game:
name: Push game service Docker Image to GitHub Packages
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions auth_service/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ app.post("/api/auth/register", auth.register);
app.post("/api/auth/login", auth.login);
app.post("/api/auth/verify", auth.verify);
app.post("/api/auth/getName", auth.getUsername);
app.post("/api/auth/getUsers", auth.getUsers);
app.get('/health', (req, res) => {
res.json({ status: 'OK' });
});
Expand Down
12 changes: 11 additions & 1 deletion auth_service/auth/authEndpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,14 @@ const getUsername = async (req,res) => {
});
}

module.exports = {login, register, verify, getUsername}
const getUsers = async (req,res) => {

let userf = await User.findAll();

res.status(200).json(userf.map(user => {return {
name: user.name,
id: user.id
}}));
}

module.exports = {login, register, verify, getUsername, getUsers}
39 changes: 39 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
version: '5'
services:
friend:
restart: unless-stopped
container_name: friends-${teamname:-defaultASW}
image: ghcr.io/arquisoft/wiq_es1c/friend:latest
profiles: ["dev", "prod"]
build: ./friends_service
environment:
- DB_URL=set
depends_on:
FriendDataDB:
condition: service_healthy
ports:
- "8005:8005"
networks:
- mynetwork

question:
restart: unless-stopped
container_name: question-${teamname:-defaultASW}
Expand Down Expand Up @@ -113,6 +129,28 @@ services:
- prometheus

# RELATIONAL DATABASES
FriendDataDB:
restart: unless-stopped
container_name: FriendDataDB-${teamname:-defaultASW}
image: mariadb
profiles: ["dev", "prod"]
volumes:
- friend_data:/var/lib/mysql
ports:
- "9003:9003"
environment:
- MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 # This should be done in a real production server, im aware.
- MARIADB_DATABASE=db
- MYSQL_TCP_PORT=9003
- MYSQL_UNIX_PORT=9003
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect"]
interval: 2s
timeout: 3s
retries: 10
networks:
- mynetwork

UserDataDB:
restart: unless-stopped
container_name: UserDataDB-${teamname:-defaultASW}
Expand Down Expand Up @@ -174,6 +212,7 @@ volumes:
game_data:
prometheus_data:
grafana_data:
friend_data:

networks:
mynetwork:
Expand Down
23 changes: 23 additions & 0 deletions friends_service/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Use an official Node.js runtime as a parent image
FROM node:20

# Set the working directory in the container
WORKDIR /usr/src/friends

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install app dependencies
RUN npm install

# Set the env var
ENV NODE_ENV=production

# Copy the app source code to the working directory
COPY . .

# Expose the port the app runs on
EXPOSE 8003

# Define the command to run your app
CMD ["sh", "-c", "npx sequelize-cli db:migrate && node friends.js"]
31 changes: 31 additions & 0 deletions friends_service/auth/friendsAuthMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const jwt = require('jsonwebtoken');

const privateKey = "ChangeMePlease!!!!"

function validateRequiredFields(req, requiredFields) {
for (const field of requiredFields) {
if (!(field in req.body)) {
return false;
}
}
return true;
}

const authMiddleware = (req, res, next) => {

if(!validateRequiredFields(req,['token'])){
res.status(401).send();
return;
}

try{
jwt.verify(req.body.token, privateKey);
}catch{
res.status(401).send();
return;
}

next()
}

module.exports = authMiddleware
65 changes: 65 additions & 0 deletions friends_service/auth/friendsAuthMiddleware.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const { mockRequest, mockResponse, mockNext } = require('jest-mock-req-res');
const jwt = require('jsonwebtoken');
const authMiddleware = require('./friendsAuthMiddleware'); // Replace with the actual path to your auth middleware module

const privateKey = "ChangeMePlease!!!!"

jest.mock('jsonwebtoken'); // Mocking the jwt module

describe('authMiddleware', () => {
afterEach(() => {
jest.resetAllMocks();
});

it('should call next() for a valid token', () => {
const req = mockRequest({
body: {
token: 'validToken',
},
});
const res = mockResponse();
const next = jest.fn();

jwt.verify.mockImplementation(() => {});

authMiddleware(req, res, next);

expect(jwt.verify).toHaveBeenCalledWith(req.body.token, privateKey);
expect(next).toHaveBeenCalled();
});

it('should respond with 401 for missing required fields', () => {
const req = mockRequest({
body: {},
});
const res = mockResponse();
const next = jest.fn();

authMiddleware(req, res, next);

expect(res.status).toHaveBeenCalledWith(401);
expect(res.send).toHaveBeenCalled();
expect(next).not.toHaveBeenCalled();
});

it('should respond with 401 for invalid token', () => {
const req = mockRequest({
body: {
token: 'invalidToken',
},
});
const res = mockResponse();
const next = jest.fn();

jwt.verify.mockImplementation(() => {
throw new Error('Invalid token');
});

authMiddleware(req, res, next);

expect(jwt.verify).toHaveBeenCalledWith(req.body.token, privateKey);
expect(res.status).toHaveBeenCalledWith(401);
expect(res.send).toHaveBeenCalled();
expect(next).not.toHaveBeenCalled();
});
});
20 changes: 20 additions & 0 deletions friends_service/config/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"production": {
"username": "root",
"password": null,
"database": "db",
"host": "FriendDataDB",
"port": 9003,
"dialect": "mariadb"
},
"development": {
"dialect": "sqlite",
"storage": "./testDB.sqlite",
"logging": false
},
"test": {
"dialect": "sqlite",
"storage": "./testDB.sqlite",
"logging": false
}
}
60 changes: 60 additions & 0 deletions friends_service/friends.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// External libs
require('dotenv').config()
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');

//libraries required for OpenAPI-Swagger
const swaggerUi = require('swagger-ui-express');
const fs = require("fs")
const YAML = require('yaml')

// My own libs
const authMiddleware = require('./auth/friendsAuthMiddleware');

const port = 8005;
const app = express();

//Prometheus configuration
const promBundle = require('express-prom-bundle');
const metricsMiddleware = promBundle({includeMethod: true});
app.use(metricsMiddleware);

// Middleware
app.use(bodyParser.json()); // Parse the request into json
app.use(cors()) // This api is listening on a different port from the frontend
app.use('/api/*',authMiddleware); // Auth middleware for the questions API


// Api endpoints
const endpoints = require("./friends/endpoints");

app.post("/api/friends/request/send",endpoints.sendRequest);
app.post("/api/friends/request/accept",endpoints.acceptRequest);
app.post("/api/friends/request/",endpoints.getRequests);
app.post("/api/friends/",endpoints.getFriends);

// Read the OpenAPI YAML file synchronously
let openapiPath='./openapi.yaml'
if (fs.existsSync(openapiPath)) {
const file = fs.readFileSync(openapiPath, 'utf8');

// Parse the YAML content into a JavaScript object representing the Swagger document
const swaggerDocument = YAML.parse(file);

// Serve the Swagger UI documentation at the '/api-doc' endpoint
// This middleware serves the Swagger UI files and sets up the Swagger UI page
// It takes the parsed Swagger document as input
app.use('/api-doc', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
} else {
console.log("Not configuring OpenAPI. Configuration file not present.")
}


// Start the server
const server = app.listen(port, () => {
console.log(`Friends service listening at http://localhost:${port}`);
});


module.exports = server
Loading

0 comments on commit ebc33fc

Please sign in to comment.