forked from fmeringdal/nettu-meet
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1 parent
da6b857
commit b0d4b0a
Showing
16 changed files
with
543 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
node_modules/ | ||
dist/ | ||
build/ | ||
infra/ | ||
.env | ||
.vscode | ||
.eslintcache | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import axios, { AxiosInstance } from "axios"; | ||
import { apiConfig } from "../../../config/api"; | ||
|
||
export abstract class BaseAPI { | ||
protected baseUrl: string; | ||
private axiosInstance: AxiosInstance | any = null; | ||
|
||
constructor() { | ||
this.baseUrl = apiConfig.baseUrl; | ||
this.axiosInstance = axios.create({}); | ||
this.enableInterceptors(); | ||
} | ||
|
||
private enableInterceptors(): void { | ||
this.axiosInstance.interceptors.response.use( | ||
this.getSuccessResponseHandler(), | ||
this.getErrorResponseHandler() | ||
); | ||
} | ||
|
||
private getSuccessResponseHandler() { | ||
return (response: any) => { | ||
return response; | ||
}; | ||
} | ||
|
||
private getErrorResponseHandler() { | ||
return async (error: any) => { | ||
return Promise.reject({ ...error }); | ||
}; | ||
} | ||
|
||
protected get(url: string, params?: any, headers?: any): Promise<any> { | ||
return this.axiosInstance({ | ||
method: "GET", | ||
url: `${this.baseUrl}${url}`, | ||
params: params ? params : null, | ||
headers: headers ? headers : null, | ||
}); | ||
} | ||
|
||
protected post( | ||
url: string, | ||
data?: any, | ||
params?: any, | ||
headers?: any | ||
): Promise<any> { | ||
return this.axiosInstance({ | ||
method: "POST", | ||
url: `${this.baseUrl}${url}`, | ||
data: data ? data : null, | ||
params: params ? params : null, | ||
headers: headers ? headers : null, | ||
}); | ||
} | ||
|
||
protected put( | ||
url: string, | ||
data?: any, | ||
params?: any, | ||
headers?: any | ||
): Promise<any> { | ||
return this.axiosInstance({ | ||
method: "PUT", | ||
url: `${this.baseUrl}${url}`, | ||
data: data ? data : null, | ||
params: params ? params : null, | ||
headers: headers ? headers : null, | ||
}); | ||
} | ||
|
||
protected delete( | ||
url: string, | ||
data?: any, | ||
params?: any, | ||
headers?: any | ||
): Promise<any> { | ||
return this.axiosInstance({ | ||
method: "DELETE", | ||
url: `${this.baseUrl}${url}`, | ||
data: data ? data : null, | ||
params: params ? params : null, | ||
headers: headers ? headers : null, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import express from 'express'; | ||
import { middleware } from '../../../../../shared/infra/http'; | ||
import { createAccountController } from '../../../useCases/createAccount'; | ||
import { updateAccountController } from '../../../useCases/updateAccount'; | ||
|
||
const accountRouter = express.Router(); | ||
|
||
accountRouter.post('/', (req, res) => createAccountController.execute(req, res)); | ||
|
||
accountRouter.put('/', middleware.ensureAccountAdmin(), (req, res) => updateAccountController.execute(req, res)); | ||
|
||
export { accountRouter }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import express from 'express'; | ||
import { getChatController } from '../../../useCases/getChat'; | ||
|
||
const chatRouter = express.Router(); | ||
|
||
chatRouter.get('/:meetingId/:chatId', (req, res) => getChatController.execute(req, res)); | ||
|
||
export { chatRouter }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import express from 'express'; | ||
import { Socket } from 'socket.io'; | ||
import { middleware } from '../../../../../shared/infra/http'; | ||
import { io } from '../../../../../shared/infra/http/app'; | ||
import { sendChatMessageController } from '../../../../chat/useCases/sendChatMessage'; | ||
import { onPeerJoinedMeeting } from '../../../services/mediasoup'; | ||
import { createCanvasController } from '../../../useCases/createCanvas'; | ||
import { createDemoMeetingController } from '../../../useCases/createDemoMeeting'; | ||
import { createMeetingController } from '../../../useCases/createMeeting'; | ||
import { createResourceController } from '../../../useCases/createResource'; | ||
import { deleteMeetingController } from '../../../useCases/deleteMeeting'; | ||
import { deleteResourceController } from '../../../useCases/deleteResource'; | ||
import { getCanvasController } from '../../../useCases/getCanvas'; | ||
import { getMeetingController } from '../../../useCases/getMeeting'; | ||
import { setActiveCanvasController } from '../../../useCases/setActiveCanvas'; | ||
import { setCanvasDataController } from '../../../useCases/setCanvasData'; | ||
import { updateMeetingController } from '../../../useCases/updateMeeting'; | ||
|
||
const meetingRouter = express.Router(); | ||
|
||
meetingRouter.post('/', middleware.ensureAccountAdmin(), (req, res) => createMeetingController.execute(req, res)); | ||
|
||
meetingRouter.post('/demo', (req, res) => createDemoMeetingController.execute(req, res)); | ||
|
||
meetingRouter.get('/:meetingId', (req, res) => getMeetingController.execute(req, res)); | ||
|
||
meetingRouter.put('/:meetingId', middleware.ensureAccountAdmin(), (req, res) => | ||
updateMeetingController.execute(req, res), | ||
); | ||
|
||
meetingRouter.delete('/:meetingId', middleware.ensureAccountAdmin(), (req, res) => | ||
deleteMeetingController.execute(req, res), | ||
); | ||
|
||
meetingRouter.post('/:meetingId/canvas', (req, res) => createCanvasController.execute(req, res)); | ||
|
||
meetingRouter.post('/:meetingId/resource', (req, res) => createResourceController.execute(req, res)); | ||
|
||
meetingRouter.delete('/:meetingId/resource/:resourceId', (req, res) => deleteResourceController.execute(req, res)); | ||
|
||
meetingRouter.get('/canvas/:canvasId', (req, res) => getCanvasController.execute(req, res)); | ||
|
||
const meetingSocketHandler = (socket: Socket) => { | ||
socket.on('join-room', async (meetingId) => { | ||
console.log('socket: ' + socket.id + ', joined room: ' + meetingId); | ||
|
||
socket.join(meetingId); | ||
socket.broadcast.to(meetingId).emit('user-connected', socket.id); | ||
|
||
onPeerJoinedMeeting(socket, meetingId); | ||
|
||
socket.on('canvas-update', (canvasId, event) => { | ||
setCanvasDataController.executeImpl(socket, { | ||
canvasId, | ||
meetingId, | ||
event, | ||
}); | ||
}); | ||
|
||
socket.on('active-canvas-change', (canvasId) => { | ||
setActiveCanvasController.executeImpl(socket, { | ||
canvasId, | ||
meetingId, | ||
}); | ||
}); | ||
|
||
socket.on('chat-message', (chatId, event) => { | ||
sendChatMessageController.executeImpl(socket, { | ||
meetingId, | ||
chatId, | ||
content: event.content, | ||
}); | ||
}); | ||
|
||
socket.on('new-resource', (data) => { | ||
io.to(meetingId).emit('new-resource', data); | ||
}); | ||
}); | ||
}; | ||
|
||
export { meetingRouter, meetingSocketHandler }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import express from 'express'; | ||
import { createEmailVerificationController } from '../../../useCases/createEmailVerificationCode'; | ||
import { validateEmailVerificationController } from '../../../useCases/validateEmailVerificationCode'; | ||
|
||
const userRouter = express.Router(); | ||
|
||
userRouter.post('/email-verification', (req, res) => createEmailVerificationController.execute(req, res)); | ||
|
||
userRouter.post('/email-verification/validate', (req, res) => validateEmailVerificationController.execute(req, res)); | ||
|
||
export { userRouter }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Collection, Db } from 'mongodb'; | ||
import { UniqueEntityID } from '../../domain/UniqueEntityID'; | ||
|
||
export interface BaseRepoEntity { | ||
_id: UniqueEntityID; | ||
[key: string]: any; | ||
} | ||
|
||
export abstract class BaseRepo { | ||
protected db!: Db; | ||
protected collection!: Collection; | ||
|
||
constructor(db: Promise<Db>, collectionName: string) { | ||
db.then((_db) => { | ||
this.db = _db; | ||
this.collection = _db.collection(collectionName); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { MongoClient, Db } from 'mongodb'; | ||
|
||
const dbName = process.env.MONGODB_NAME as string; | ||
|
||
export const mongoDBClient = new MongoClient(process.env.MONGODB_CONNECTION_STRING as string, { | ||
useNewUrlParser: true, | ||
useUnifiedTopology: true, | ||
}); | ||
|
||
export const _db_connect_promise = mongoDBClient | ||
.connect() | ||
.then((_) => mongoDBClient.db(dbName)) | ||
.catch((e) => { | ||
console.log('db error'); | ||
console.log(e); | ||
}) as Promise<Db>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import express from 'express'; | ||
import { Socket } from 'socket.io'; | ||
import { docsRouter } from '../../../../docs/spec'; | ||
import { chatRouter } from '../../../../modules/chat/infra/http/routes'; | ||
import { accountRouter } from '../../../../modules/account/infra/http/routes'; | ||
import { meetingRouter, meetingSocketHandler } from '../../../../modules/meeting/infra/http/routes'; | ||
import { signalingRouter } from '../../../../modules/meeting/services/mediasoup'; | ||
import { userRouter } from '../../../../modules/user/infra/http/routes'; | ||
|
||
const v1Router = express.Router(); | ||
|
||
v1Router.get('/', (req, res) => { | ||
return res.json({ message: 'Ofc we are up ...' }); | ||
}); | ||
|
||
v1Router.use('/account', accountRouter); | ||
v1Router.use('/meeting', meetingRouter); | ||
v1Router.use('/chat', chatRouter); | ||
v1Router.use('/user', userRouter); | ||
v1Router.use('/signaling', signalingRouter); | ||
v1Router.use('/docs', docsRouter); | ||
|
||
const v1SocketHandler = (socket: Socket) => { | ||
console.log('user connected: ' + socket.id); | ||
|
||
meetingSocketHandler(socket); | ||
|
||
socket.on('disconnect', () => { | ||
socket.broadcast.emit('user-disconnected', socket.id); | ||
}); | ||
}; | ||
|
||
export { v1Router, v1SocketHandler }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import fs from 'fs'; | ||
import bodyParser from 'body-parser'; | ||
import compression from 'compression'; | ||
import cors from 'cors'; | ||
import http from 'http'; | ||
import https from 'https'; | ||
import express from 'express'; | ||
import helmet from 'helmet'; | ||
import morgan from 'morgan'; | ||
import { Server, Socket } from 'socket.io'; | ||
import { createAdapter } from 'socket.io-redis'; | ||
import { v1Router, v1SocketHandler } from './api/v1'; | ||
import { redisConnection } from '../../services'; | ||
import { createDefaultAccountController } from '../../../modules/account/useCases/createDefaultAccount'; | ||
import { _db_connect_promise } from '../db/connection'; | ||
|
||
const isProduction = process.env.ENVIRONMENT === 'prod'; | ||
|
||
const corsConfig = { | ||
origin: isProduction ? '*' : '*', | ||
}; | ||
|
||
const app = express(); | ||
|
||
const createServer = () => { | ||
if (isProduction) { | ||
// Certificate | ||
const domain = process.env['SERVER_DOMAIN_NAME']; | ||
const privateKey = fs.readFileSync(`/etc/letsencrypt/live/${domain}/privkey.pem`, 'utf8'); | ||
const certificate = fs.readFileSync(`/etc/letsencrypt/live/${domain}/cert.pem`, 'utf8'); | ||
const ca = fs.readFileSync(`/etc/letsencrypt/live/${domain}/chain.pem`, 'utf8'); | ||
const credentials = { | ||
key: privateKey, | ||
cert: certificate, | ||
ca: ca, | ||
}; | ||
return https.createServer(credentials, app); | ||
} else { | ||
return http.createServer(app); | ||
} | ||
}; | ||
|
||
const server = createServer(); | ||
|
||
const port = process.env.PORT || (isProduction ? 443 : 5000); | ||
|
||
export const io = new Server(server, { | ||
path: '/api/v1/ws', | ||
adapter: createAdapter({ | ||
pubClient: redisConnection, | ||
subClient: redisConnection.duplicate(), | ||
}), | ||
cors: corsConfig, | ||
}); | ||
|
||
io.on('connection', (socket: Socket) => { | ||
v1SocketHandler(socket); | ||
}); | ||
|
||
app.use(bodyParser.json()); | ||
app.use(bodyParser.urlencoded({ extended: true })); | ||
app.use(cors(corsConfig)); | ||
app.use(compression()); | ||
app.use(helmet()); | ||
app.use(morgan('combined')); | ||
app.use('/api/v1', v1Router); | ||
|
||
server.listen(port, async () => { | ||
console.log(`[App]: Listening on port ${port}`); | ||
|
||
// Setup default account if provided | ||
await _db_connect_promise; | ||
createDefaultAccountController.execute(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { accountRepo } from '../../../modules/account/repos'; | ||
import { Middleware } from './utils/Middleware'; | ||
|
||
const middleware = new Middleware(accountRepo); | ||
|
||
export { middleware }; |
Oops, something went wrong.