add 2fa and env var(not in conf files)
This commit is contained in:
parent
47863325ea
commit
2b16af1785
35
.env
35
.env
@ -1,3 +1,8 @@
|
|||||||
|
#nessecarr var
|
||||||
|
#API_SECRET
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# POSTGRES_USER=kinou
|
# POSTGRES_USER=kinou
|
||||||
# POSTGRES_PASSWORD=pass
|
# POSTGRES_PASSWORD=pass
|
||||||
# POSTGRES_DB=postgreDB
|
# POSTGRES_DB=postgreDB
|
||||||
@ -5,11 +10,35 @@
|
|||||||
# POSTGRES_HOST=localhost
|
# POSTGRES_HOST=localhost
|
||||||
# POSTGRES_HOST_AUTH_METHOD=trust
|
# POSTGRES_HOST_AUTH_METHOD=trust
|
||||||
|
|
||||||
POSTGRES_HOST=127.0.0.1
|
#URL
|
||||||
POSTGRES_PORT=5432
|
NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf"
|
||||||
|
|
||||||
|
BASE_URL=http://localhost
|
||||||
|
|
||||||
|
#postgres var
|
||||||
|
# POSTGRES_HOST=127.0.0.1
|
||||||
|
# DB_TYPE=postgres
|
||||||
|
POSTGRES_HOST=postgresql
|
||||||
POSTGRES_USER=postgres
|
POSTGRES_USER=postgres
|
||||||
POSTGRES_PASSWORD=pass
|
POSTGRES_PASSWORD=pass
|
||||||
POSTGRES_DATABASE=postgres
|
POSTGRES_DATABASE=postgres
|
||||||
PORT=3000
|
|
||||||
MODE=DEV
|
MODE=DEV
|
||||||
|
|
||||||
|
#port
|
||||||
|
API_PORT=3000
|
||||||
|
# REACT_PORT=3000 (current = 8080)
|
||||||
|
NGINX_PORT=80
|
||||||
|
PONG_PORT=4000
|
||||||
|
CHAT_PORT=4001
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
|
||||||
|
#????
|
||||||
RUN_MIGRATIONS=true
|
RUN_MIGRATIONS=true
|
||||||
|
REACT_HOST=0.0.0.0
|
||||||
|
|
||||||
|
|
||||||
|
#auth var
|
||||||
|
JWT_SECRET=secrethere
|
||||||
|
REDIRECT_URI=http://localhost:80/api/auth/login
|
||||||
|
API_SECRET=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
|
||||||
|
CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41
|
||||||
@ -2,15 +2,14 @@ server {
|
|||||||
# listen 443 ssl;
|
# listen 443 ssl;
|
||||||
# listen 80 ssl;
|
# listen 80 ssl;
|
||||||
# listen 443 ssl;
|
# listen 443 ssl;
|
||||||
|
# listen ${NGINX_PORT};
|
||||||
listen 80;
|
listen 80;
|
||||||
|
|
||||||
|
|
||||||
location /{
|
location /{
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
proxy_pass http://react_app:8080;
|
proxy_pass http://react_app:8080;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +18,6 @@ server {
|
|||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
proxy_pass http://api:3000/api;
|
proxy_pass http://api:3000/api;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
20
containers/api/package-lock.json
generated
20
containers/api/package-lock.json
generated
@ -22,6 +22,7 @@
|
|||||||
"express-session": "^1.17.3",
|
"express-session": "^1.17.3",
|
||||||
"hi-base32": "^0.5.1",
|
"hi-base32": "^0.5.1",
|
||||||
"nanoid": "^3.3.4",
|
"nanoid": "^3.3.4",
|
||||||
|
"otpauth": "^9.1.2",
|
||||||
"passport": "^0.6.0",
|
"passport": "^0.6.0",
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
@ -6099,6 +6100,14 @@
|
|||||||
"npm": ">=6"
|
"npm": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jssha": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-w9OtT4ALL+fbbwG3gw7erAO0jvS5nfvrukGPMWIAoea359B26ALXGpzy4YJSp9yGnpUvuvOw1nSjSoHDfWSr1w==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/jwa": {
|
"node_modules/jwa": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
||||||
@ -6685,6 +6694,17 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/otpauth": {
|
||||||
|
"version": "9.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/otpauth/-/otpauth-9.1.2.tgz",
|
||||||
|
"integrity": "sha512-iI5nlVvMFP3aTPdjG/fnC4mhVJ/KZOSnBrvo/VnYHUwlTp9jVLjAe2B3i3pyCH+3/E5jYQRSvuHk/8oas3870g==",
|
||||||
|
"dependencies": {
|
||||||
|
"jssha": "~3.3.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/hectorm/otpauth?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/p-limit": {
|
"node_modules/p-limit": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
"express-session": "^1.17.3",
|
"express-session": "^1.17.3",
|
||||||
"hi-base32": "^0.5.1",
|
"hi-base32": "^0.5.1",
|
||||||
"nanoid": "^3.3.4",
|
"nanoid": "^3.3.4",
|
||||||
|
"otpauth": "^9.1.2",
|
||||||
"passport": "^0.6.0",
|
"passport": "^0.6.0",
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
|
|||||||
@ -9,7 +9,15 @@ import { UsersService } from './users/users.service';
|
|||||||
|
|
||||||
import { MatchLog } from './model/user.entity'
|
import { MatchLog } from './model/user.entity'
|
||||||
import { generate } from 'rxjs';
|
import { generate } from 'rxjs';
|
||||||
import { generateQRcode } from './users/2fa';
|
|
||||||
|
// import { generateQRcode } from './users/2fa';
|
||||||
|
import { generateOTP } from './users/2fa';
|
||||||
|
import { VerifyOTP } from './users/2fa';
|
||||||
|
import { ValidateOTP } from './users/2fa';
|
||||||
|
|
||||||
|
|
||||||
|
//2fa
|
||||||
|
|
||||||
|
|
||||||
// import { initStorage, getUser, setUser } from './storage';
|
// import { initStorage, getUser, setUser } from './storage';
|
||||||
|
|
||||||
@ -216,20 +224,30 @@ export class AppController {
|
|||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
|
|
||||||
|
// import { Prisma } from "@prisma/client";
|
||||||
|
// import { Request, Response, NextFunction } from "express";
|
||||||
|
// import { prisma } from "../server";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Redirect('http://localhost/token', 302)
|
@Redirect('http://localhost/token', 302)
|
||||||
@Get('auth/login')
|
@Get('auth/login')
|
||||||
async login2(@Req() request: Request) {
|
async login2(@Req() request: Request) {
|
||||||
const url = request.url;
|
const url = request.url;
|
||||||
const user = await this.loginClass.Login42(url);
|
const user = await this.loginClass.Login42(url);
|
||||||
console.log(`user in auth/login= ${user}`);
|
console.log(`user in auth/login= ${user}`);
|
||||||
const data = this.authService.login(user);
|
console.log(`user in auth/login= ${user.username}`);
|
||||||
|
const data = await this.authService.login(user);
|
||||||
console.log(`all data in api = ${data}`)
|
console.log(`all data in api = ${data}`)
|
||||||
|
|
||||||
const myJSON = JSON.stringify(data);
|
const myJSON = JSON.stringify(data);
|
||||||
console.log(`all data json version= ${myJSON}`)
|
console.log(`all data json version= ${myJSON}`)
|
||||||
|
|
||||||
console.log(`data in api = ${(await data).access_token}`)
|
console.log(`data in api = ${(await data).access_token}`)
|
||||||
|
// console.log(`data i = ${(await data).access_token}`)
|
||||||
const token = (await data).access_token;
|
const token = (await data).access_token;
|
||||||
|
// console
|
||||||
|
await this.userService.save(user);
|
||||||
return { url: `http://localhost/token?data=${encodeURIComponent(JSON.stringify(token))}` };
|
return { url: `http://localhost/token?data=${encodeURIComponent(JSON.stringify(token))}` };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,17 +256,49 @@ export class AppController {
|
|||||||
async get2fa(@Request() req)
|
async get2fa(@Request() req)
|
||||||
{
|
{
|
||||||
const user = await this.userService.findOne(req.user.username);
|
const user = await this.userService.findOne(req.user.username);
|
||||||
return user.doubleAuth;
|
return user.otp_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Get('/QRcode')
|
@Post('/otp')
|
||||||
async createQrCode(@Request() req)
|
async createOTP(@Request() req)
|
||||||
{
|
{
|
||||||
return (await generateQRcode(req));
|
const user = await this.userService.findOne(req.user.username);
|
||||||
|
// const user2 = await this.userService.findOne(req.user.username);
|
||||||
|
const res = await generateOTP(user);
|
||||||
|
await this.userService.save(user);
|
||||||
|
// console.log(user);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Post('/verifyOtp')
|
||||||
|
async verifyOTP(@Request() req, @Body() data: any)
|
||||||
|
{
|
||||||
|
const user = await this.userService.findOne(req.user.username);
|
||||||
|
const res = await VerifyOTP(user, data.token)
|
||||||
|
await this.userService.save(user);
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Post('/validateOtp')
|
||||||
|
async validateOTP(@Request() req, @Body() data: any)
|
||||||
|
{
|
||||||
|
const user = await this.userService.findOne(req.user.username);
|
||||||
|
const res = await ValidateOTP(user, data.token)
|
||||||
|
// await this.userService.save(user);
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// @UseGuards(JwtAuthGuard)
|
||||||
|
// @Get('/QRcode')
|
||||||
|
// async createQrCode(@Request() req)
|
||||||
|
// {
|
||||||
|
// return (await generateQRcode(req));
|
||||||
|
// }
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/quit')
|
@Post('/quit')
|
||||||
async setOffline(@Request() req) {
|
async setOffline(@Request() req) {
|
||||||
@ -271,6 +321,8 @@ export class AppController {
|
|||||||
async createConv(@Request() req, @Body() data: any) {
|
async createConv(@Request() req, @Body() data: any) {
|
||||||
///create conv and return it ? id?
|
///create conv and return it ? id?
|
||||||
console.log(`data post /conv= ${data}`);
|
console.log(`data post /conv= ${data}`);
|
||||||
|
console.log(`data post /conv= ${data.members}`);
|
||||||
|
console.log(`data post /conv= ${data.name}`);
|
||||||
// let test = {id: 2, members: "cc"};
|
// let test = {id: 2, members: "cc"};
|
||||||
return await this.chatService.createConv(data);
|
return await this.chatService.createConv(data);
|
||||||
// res.json(messages);
|
// res.json(messages);
|
||||||
@ -278,20 +330,10 @@ export class AppController {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// @UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Get('/conv')
|
@Get('/conv')
|
||||||
async getConv(@Request() req, @Body() data: any) {
|
async getConv(@Request() req) {
|
||||||
///create conv and return it ? id?
|
return await this.chatService.getConv(req.user.username);
|
||||||
// console.log(`data get /conv= ${data}`);
|
|
||||||
// let test = {id: 2, members: "cc"};
|
|
||||||
|
|
||||||
// let tab = [data.member, "test"];
|
|
||||||
// console.log(`tab= ${tab}`);
|
|
||||||
return await this.chatService.getConv(data.member);
|
|
||||||
// return await this.chatService.getConv(req.user.username);
|
|
||||||
|
|
||||||
|
|
||||||
// res.json(messages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @UseGuards(JwtAuthGuard)
|
// @UseGuards(JwtAuthGuard)
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import { JwtStrategy } from './jwt.strategy';
|
|||||||
PassportModule,
|
PassportModule,
|
||||||
JwtModule.register({
|
JwtModule.register({
|
||||||
secret: jwtConstants.secret,
|
secret: jwtConstants.secret,
|
||||||
signOptions: { expiresIn: '60000s' },
|
// signOptions: { expiresIn: '60000s' },
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
providers: [AuthService, LocalStrategy, JwtStrategy],
|
providers: [AuthService, LocalStrategy, JwtStrategy],
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { UsersService } from '../users/users.service';
|
import { UsersService } from '../users/users.service';
|
||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
|
import { User } from 'src/model/user.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
@ -19,13 +20,13 @@ export class AuthService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async login(user) {
|
async login(user: User) {
|
||||||
const myJSON = JSON.stringify(user);
|
// const myJSON = JSON.stringify(user);
|
||||||
// console.log(`in login all user= ${myJSON}`)
|
// console.log(`in login all user= ${myJSON}`)
|
||||||
// console.log(`in login user= ${user.username}`)
|
console.log(`in login user= ${user.username}`)
|
||||||
const payload = { username: user.username, sub: user.userId };
|
const payload = { username: user.username, sub: user.userId };
|
||||||
// console.log(`in login payload name= ${payload.username}`)
|
console.log(`in login payload name= ${payload.username}`)
|
||||||
// console.log(`in login payload sub= ${payload.sub}`)
|
console.log(`in login payload sub= ${payload.sub}`)
|
||||||
return {
|
return {
|
||||||
access_token: this.jwtService.sign(payload),
|
access_token: this.jwtService.sign(payload),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
export const jwtConstants = {
|
export const jwtConstants = {
|
||||||
secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
|
// secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
|
||||||
|
secret: process.env.JWT_SECRET,
|
||||||
};
|
};
|
||||||
@ -24,10 +24,11 @@ export class loginClass {
|
|||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
grant_type: 'authorization_code',
|
grant_type: 'authorization_code',
|
||||||
client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41',
|
client_id: process.env.CLIENT_UID || 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41',
|
||||||
client_secret: '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',
|
// client_secret: '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',
|
||||||
|
client_secret: process.env.API_SECRET,
|
||||||
code: code,
|
code: code,
|
||||||
redirect_uri: 'http://localhost:80/api/auth/login',
|
redirect_uri: process.env.REDIRECT_URI || 'http://localhost:80/api/auth/login',
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -64,9 +65,12 @@ export class loginClass {
|
|||||||
loss: 0,
|
loss: 0,
|
||||||
rank: 1200,
|
rank: 1200,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
|
otp_base32: null,
|
||||||
children: null,
|
children: null,
|
||||||
status: 1,
|
status: 1,
|
||||||
doubleAuth: 0,
|
// doubleAuth: 0,
|
||||||
|
otp_enabled: false,
|
||||||
|
otp_verified: false,
|
||||||
friendRequest: null,
|
friendRequest: null,
|
||||||
friends: null,
|
friends: null,
|
||||||
photo: null,
|
photo: null,
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/04/09 14:53:49 by apommier #+# #+# */
|
/* Created: 2023/04/09 14:53:49 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/01 13:07:12 by apommier ### ########.fr */
|
/* Updated: 2023/06/12 14:51:44 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -14,11 +14,11 @@ import { TypeOrmModuleOptions } from '@nestjs/typeorm';
|
|||||||
|
|
||||||
export const getTypeOrmConfig = (): TypeOrmModuleOptions => ({
|
export const getTypeOrmConfig = (): TypeOrmModuleOptions => ({
|
||||||
type: 'postgres',
|
type: 'postgres',
|
||||||
host: 'postgresql',
|
host: process.env.POSTGRES_HOST || 'postgresql',
|
||||||
port: 5432,
|
port: parseInt(process.env.POSTGRES_PORT, 10) || 5432,
|
||||||
username: 'postgres',
|
username: process.env.POSTGRES_USER || 'postgres',
|
||||||
password: 'pass',
|
password: process.env.POSTGRES_PASSWORD || 'pass',
|
||||||
database: 'postgres',
|
database: process.env.POSTGRES_DATABASE || 'postgres',
|
||||||
entities: ["dist/**/*.entity.js"],
|
entities: ["dist/**/*.entity.js"],
|
||||||
// entities: [join(__dirname, '**', '*.entity.{ts,js}')]
|
// entities: [join(__dirname, '**', '*.entity.{ts,js}')]
|
||||||
// entities: ['**/*.entity{.ts,.js}'], //basic
|
// entities: ['**/*.entity{.ts,.js}'], //basic
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
import * as session from 'express-session';
|
import * as session from 'express-session';
|
||||||
|
import * as dotenv from 'dotenv';
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
console.log(process.env);
|
||||||
|
|
||||||
// async function bootstrap() {
|
// async function bootstrap() {
|
||||||
// const app = await NestFactory.create(AppModule);
|
// const app = await NestFactory.create(AppModule);
|
||||||
@ -27,6 +31,6 @@ async function bootstrap() {
|
|||||||
saveUninitialized: false,
|
saveUninitialized: false,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
await app.listen(3000);
|
await app.listen(parseInt(process.env.API_PORT) || 3000);
|
||||||
}
|
}
|
||||||
bootstrap();
|
bootstrap();
|
||||||
@ -20,6 +20,18 @@ export class User {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id: number;
|
id: number;
|
||||||
|
|
||||||
|
// otp_enabled Boolean @default(false)
|
||||||
|
// otp_verified Boolean @default(false)
|
||||||
|
|
||||||
|
@Column({ default: false })
|
||||||
|
otp_enabled: boolean;
|
||||||
|
|
||||||
|
@Column({ default: false })
|
||||||
|
otp_verified: boolean;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
otp_base32: string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
nickname: string;
|
nickname: string;
|
||||||
|
|
||||||
@ -47,8 +59,8 @@ export class User {
|
|||||||
@Column({ default: 0 })
|
@Column({ default: 0 })
|
||||||
userId: number;
|
userId: number;
|
||||||
|
|
||||||
@Column({ default: 0 })
|
// @Column({ default: 0 })
|
||||||
doubleAuth: number;
|
// doubleAuth: number;
|
||||||
|
|
||||||
@Column('text', { array: true, nullable: true })
|
@Column('text', { array: true, nullable: true })
|
||||||
friendRequest: string[];
|
friendRequest: string[];
|
||||||
|
|||||||
@ -1,6 +1,109 @@
|
|||||||
import crypto from 'crypto';
|
// import crypto from 'crypto';
|
||||||
import base32Decode from 'base32-decode';
|
import base32Decode from 'base32-decode';
|
||||||
|
|
||||||
|
import crypto from "crypto";
|
||||||
|
import * as OTPAuth from "otpauth";
|
||||||
|
import { encode } from "hi-base32";
|
||||||
|
|
||||||
|
// [...] Register user
|
||||||
|
|
||||||
|
// [...] Login user
|
||||||
|
|
||||||
|
// [...] Generate OTP
|
||||||
|
|
||||||
|
const generateRandomBase32 = async () => {
|
||||||
|
const {randomBytes} = await import('crypto');
|
||||||
|
const buffer = randomBytes(15);
|
||||||
|
const base32 = encode(buffer).replace(/=/g, "").substring(0, 24);
|
||||||
|
return base32;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const generateOTP = async (user) => {
|
||||||
|
try {
|
||||||
|
const base32_secret = await generateRandomBase32();
|
||||||
|
|
||||||
|
let totp = new OTPAuth.TOTP({
|
||||||
|
issuer: "Localhost",
|
||||||
|
label: "OnlinePong",
|
||||||
|
algorithm: "SHA1",
|
||||||
|
digits: 6,
|
||||||
|
period: 15,
|
||||||
|
secret: base32_secret,
|
||||||
|
});
|
||||||
|
|
||||||
|
let otpauth_url = totp.toString();
|
||||||
|
|
||||||
|
const res = {
|
||||||
|
otpauth_url: otpauth_url,
|
||||||
|
base32_secret: base32_secret
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("res= ", res)
|
||||||
|
|
||||||
|
//update db with otp var
|
||||||
|
user.otp_enabled = true;
|
||||||
|
user.otp_base32 = base32_secret;
|
||||||
|
return (res)
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const VerifyOTP = async (user, token: string) => {
|
||||||
|
try {
|
||||||
|
let totp = new OTPAuth.TOTP({
|
||||||
|
issuer: "Localhost",
|
||||||
|
label: "OnlinePong",
|
||||||
|
algorithm: "SHA1",
|
||||||
|
digits: 6,
|
||||||
|
period: 15,
|
||||||
|
secret: user.otp_base32,
|
||||||
|
});
|
||||||
|
|
||||||
|
let delta = totp.validate({ token });
|
||||||
|
|
||||||
|
if (delta === null) {
|
||||||
|
console.log("error verify token")
|
||||||
|
return ("error verify token")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user.otp_verified = true;
|
||||||
|
console.log("token verified")
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ValidateOTP = async (user, token: string) => {
|
||||||
|
try {
|
||||||
|
let totp = new OTPAuth.TOTP({
|
||||||
|
issuer: "Localhost",
|
||||||
|
label: "OnlinePong",
|
||||||
|
algorithm: "SHA1",
|
||||||
|
digits: 6,
|
||||||
|
period: 15,
|
||||||
|
secret: user.otp_base32,
|
||||||
|
});
|
||||||
|
|
||||||
|
let delta = totp.validate({ token });
|
||||||
|
|
||||||
|
if (delta === null) {
|
||||||
|
console.log("error validate token")
|
||||||
|
return ("error validate token")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// user.otp_verified = true;
|
||||||
|
console.log("token validated")
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// import { randomBytes} from 'crypto';
|
// import { randomBytes} from 'crypto';
|
||||||
// import { promisify } from 'util';
|
// import { promisify } from 'util';
|
||||||
|
|
||||||
@ -33,48 +136,48 @@ import base32Decode from 'base32-decode';
|
|||||||
|
|
||||||
// type QRcode = any;
|
// type QRcode = any;
|
||||||
|
|
||||||
export function generateHOTP(secret, counter) {
|
// export function generateHOTP(secret, counter) {
|
||||||
const decodedSecret = base32Decode(secret, 'RFC4648');
|
// const decodedSecret = base32Decode(secret, 'RFC4648');
|
||||||
|
|
||||||
const buffer = Buffer.alloc(8);
|
// const buffer = Buffer.alloc(8);
|
||||||
for (let i = 0; i < 8; i++) {
|
// for (let i = 0; i < 8; i++) {
|
||||||
buffer[7 - i] = counter & 0xff;
|
// buffer[7 - i] = counter & 0xff;
|
||||||
counter = counter >> 8;
|
// counter = counter >> 8;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Step 1: Generate an HMAC-SHA-1 value
|
// // Step 1: Generate an HMAC-SHA-1 value
|
||||||
const hmac = crypto.createHmac('sha1', Buffer.from(decodedSecret));
|
// const hmac = crypto.createHmac('sha1', Buffer.from(decodedSecret));
|
||||||
hmac.update(buffer);
|
// hmac.update(buffer);
|
||||||
const hmacResult = hmac.digest();
|
// const hmacResult = hmac.digest();
|
||||||
|
|
||||||
// Step 2: Generate a 4-byte string (Dynamic Truncation)
|
// // Step 2: Generate a 4-byte string (Dynamic Truncation)
|
||||||
const offset = hmacResult[hmacResult.length - 1] & 0xf;
|
// const offset = hmacResult[hmacResult.length - 1] & 0xf;
|
||||||
const code =
|
// const code =
|
||||||
((hmacResult[offset] & 0x7f) << 24) |
|
// ((hmacResult[offset] & 0x7f) << 24) |
|
||||||
((hmacResult[offset + 1] & 0xff) << 16) |
|
// ((hmacResult[offset + 1] & 0xff) << 16) |
|
||||||
((hmacResult[offset + 2] & 0xff) << 8) |
|
// ((hmacResult[offset + 2] & 0xff) << 8) |
|
||||||
(hmacResult[offset + 3] & 0xff);
|
// (hmacResult[offset + 3] & 0xff);
|
||||||
|
|
||||||
// Step 3: Compute an HOTP value
|
// // Step 3: Compute an HOTP value
|
||||||
return code % 10 ** 6;
|
// return code % 10 ** 6;
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function generateTOTP(secret, window = 0)
|
// export function generateTOTP(secret, window = 0)
|
||||||
{
|
// {
|
||||||
const counter = Math.floor(Date.now() / 30000);
|
// const counter = Math.floor(Date.now() / 30000);
|
||||||
return generateHOTP(secret, counter + window);
|
// return generateHOTP(secret, counter + window);
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function verifyTOTP(token, secret, window = 1)
|
// export function verifyTOTP(token, secret, window = 1)
|
||||||
{
|
// {
|
||||||
for (let errorWindow = -window; errorWindow <= +window; errorWindow++)
|
// for (let errorWindow = -window; errorWindow <= +window; errorWindow++)
|
||||||
{
|
// {
|
||||||
const totp = generateTOTP(secret, errorWindow);
|
// const totp = generateTOTP(secret, errorWindow);
|
||||||
if (token === totp)
|
// if (token === totp)
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -94,86 +197,86 @@ export function verifyTOTP(token, secret, window = 1)
|
|||||||
// import * as base32Encode from 'base32-encode';
|
// import * as base32Encode from 'base32-encode';
|
||||||
// import { base32Encode } from 'base32-encode';
|
// import { base32Encode } from 'base32-encode';
|
||||||
// import base32Encode from 'base32-encode';
|
// import base32Encode from 'base32-encode';
|
||||||
import { encode } from 'thirty-two';
|
// import { encode } from 'thirty-two';
|
||||||
|
|
||||||
// ...
|
// // ...
|
||||||
|
|
||||||
import * as qrcode from 'qrcode';
|
// import * as qrcode from 'qrcode';
|
||||||
import * as fs from 'fs';
|
// import * as fs from 'fs';
|
||||||
|
|
||||||
|
|
||||||
import { nanoid } from "nanoid";
|
// import { nanoid } from "nanoid";
|
||||||
// import * as nanoid from 'nanoid'
|
// // import * as nanoid from 'nanoid'
|
||||||
|
|
||||||
export async function generateQRcode(req)
|
// export async function generateQRcode(req)
|
||||||
{
|
// {
|
||||||
// const base32Encode = (await import('base32-encode'));
|
// // const base32Encode = (await import('base32-encode'));
|
||||||
// const nanoid = (await import('nanoid'));
|
// // const nanoid = (await import('nanoid'));
|
||||||
|
|
||||||
// const util = (await import('util'));
|
// // const util = (await import('util'));
|
||||||
// const qrcode = (await import('qrcode'));
|
// // const qrcode = (await import('qrcode'));
|
||||||
|
|
||||||
const user = req.user;
|
// const user = req.user;
|
||||||
let res;
|
// let res;
|
||||||
// For security, we no longer show the QR code after is verified
|
// // For security, we no longer show the QR code after is verified
|
||||||
// if (user.mfaEnabled) return res.status(404).end();
|
// // if (user.mfaEnabled) return res.status(404).end();
|
||||||
|
|
||||||
// if (!user.mfaSecret) { //to do
|
// // if (!user.mfaSecret) { //to do
|
||||||
const buffer = nanoid(14);
|
// const buffer = nanoid(14);
|
||||||
// generate unique secret for user
|
// // generate unique secret for user
|
||||||
// this secret will be used to check the verification code sent by user
|
// // this secret will be used to check the verification code sent by user
|
||||||
// const buffer = await util.promisify(crypto.randomBytes)(14);
|
// // const buffer = await util.promisify(crypto.randomBytes)(14);
|
||||||
// const buffer = crypto.lib.WordArray.random(32)
|
// // const buffer = crypto.lib.WordArray.random(32)
|
||||||
user.mfaSecret = encode(buffer).toString('utf8');
|
// user.mfaSecret = encode(buffer).toString('utf8');
|
||||||
// user.mfaSecret = base32Encoded(buffer, 'RFC4648', { padding: false });
|
// // user.mfaSecret = base32Encoded(buffer, 'RFC4648', { padding: false });
|
||||||
|
|
||||||
// setUser(user); // to do !!
|
// // setUser(user); // to do !!
|
||||||
|
|
||||||
|
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
const issuer = 'Google';
|
// const issuer = 'Google';
|
||||||
const algorithm = 'SHA1';
|
// const algorithm = 'SHA1';
|
||||||
const digits = '6';
|
// const digits = '6';
|
||||||
const period = '30';
|
// const period = '30';
|
||||||
const otpType = 'totp';
|
// const otpType = 'totp';
|
||||||
const configUri = `otpauth://${otpType}/${issuer}:${user.username}?algorithm=${algorithm}&digits=${digits}&period=${period}&issuer=${issuer}&secret=${user.mfaSecret}`;
|
// const configUri = `otpauth://${otpType}/${issuer}:${user.username}?algorithm=${algorithm}&digits=${digits}&period=${period}&issuer=${issuer}&secret=${user.mfaSecret}`;
|
||||||
|
|
||||||
// res.setHeader('Content-Type', 'image/png');
|
// // res.setHeader('Content-Type', 'image/png');
|
||||||
const QRCode = require('qrcode');
|
// const QRCode = require('qrcode');
|
||||||
console.log(`before done`);
|
// console.log(`before done`);
|
||||||
// QRCode.toFileStream(res, configUri);
|
// // QRCode.toFileStream(res, configUri);
|
||||||
// const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
|
// // const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
|
||||||
|
|
||||||
|
|
||||||
const qrCodeData = buffer; // Replace with your actual QR code data
|
// const qrCodeData = buffer; // Replace with your actual QR code data
|
||||||
const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
|
// const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
|
||||||
|
|
||||||
qrcode.toFile(filePath, qrCodeData, (error) => {
|
// qrcode.toFile(filePath, qrCodeData, (error) => {
|
||||||
if (error) {
|
|
||||||
console.error(error);
|
|
||||||
// Handle the error appropriately
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// QR code image has been generated and saved to the file
|
|
||||||
// Or, you can create a buffer of the image data directly
|
|
||||||
})
|
|
||||||
|
|
||||||
// qrcode.toFile(filePath, configUri, (error) => {
|
|
||||||
// if (error) {
|
// if (error) {
|
||||||
// console.error(error);
|
// console.error(error);
|
||||||
// // Handle the error appropriately
|
// // Handle the error appropriately
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
// const readableStream = fs.createReadStream(filePath);
|
// // QR code image has been generated and saved to the file
|
||||||
// res.data = readableStream;
|
// // Or, you can create a buffer of the image data directly
|
||||||
// Use the readable stream as needed
|
// })
|
||||||
// });
|
|
||||||
|
// // qrcode.toFile(filePath, configUri, (error) => {
|
||||||
|
// // if (error) {
|
||||||
|
// // console.error(error);
|
||||||
|
// // // Handle the error appropriately
|
||||||
|
// // return;
|
||||||
|
// // }
|
||||||
|
// // const readableStream = fs.createReadStream(filePath);
|
||||||
|
// // res.data = readableStream;
|
||||||
|
// // Use the readable stream as needed
|
||||||
|
// // });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// qrcode.toFileStream(res, configUri);
|
// // qrcode.toFileStream(res, configUri);
|
||||||
console.log(`QRcode done`);
|
// console.log(`QRcode done`);
|
||||||
return res;
|
// return res;
|
||||||
// return
|
// // return
|
||||||
}
|
// }
|
||||||
12
containers/chat/package-lock.json
generated
12
containers/chat/package-lock.json
generated
@ -15,6 +15,7 @@
|
|||||||
"@nestjs/platform-socket.io": "^9.4.0",
|
"@nestjs/platform-socket.io": "^9.4.0",
|
||||||
"@nestjs/websockets": "^9.4.0",
|
"@nestjs/websockets": "^9.4.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^16.1.4",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.2.0",
|
"rxjs": "^7.2.0",
|
||||||
"socket.io-client": "^4.6.1",
|
"socket.io-client": "^4.6.1",
|
||||||
@ -3398,6 +3399,17 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dotenv": {
|
||||||
|
"version": "16.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz",
|
||||||
|
"integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/motdotla/dotenv?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ee-first": {
|
"node_modules/ee-first": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
"@nestjs/platform-socket.io": "^9.4.0",
|
"@nestjs/platform-socket.io": "^9.4.0",
|
||||||
"@nestjs/websockets": "^9.4.0",
|
"@nestjs/websockets": "^9.4.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^16.1.4",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.2.0",
|
"rxjs": "^7.2.0",
|
||||||
"socket.io-client": "^4.6.1",
|
"socket.io-client": "^4.6.1",
|
||||||
|
|||||||
@ -3,6 +3,10 @@ import { AppModule } from './app.module';
|
|||||||
import * as cors from 'cors';
|
import * as cors from 'cors';
|
||||||
import { Server } from 'socket.io';
|
import { Server } from 'socket.io';
|
||||||
import * as socketio from 'socket.io';
|
import * as socketio from 'socket.io';
|
||||||
|
import * as dotenv from 'dotenv';
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
console.log(process.env);
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule, {
|
const app = await NestFactory.create(AppModule, {
|
||||||
@ -36,7 +40,7 @@ async function bootstrap() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await app.listen(4001);
|
await app.listen(parseInt(process.env.CHAT_PORT) || 4001);
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrap();
|
bootstrap();
|
||||||
|
|||||||
12
containers/pong/package-lock.json
generated
12
containers/pong/package-lock.json
generated
@ -15,6 +15,7 @@
|
|||||||
"@nestjs/platform-socket.io": "^9.4.0",
|
"@nestjs/platform-socket.io": "^9.4.0",
|
||||||
"@nestjs/websockets": "^9.4.0",
|
"@nestjs/websockets": "^9.4.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^16.1.4",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.2.0",
|
"rxjs": "^7.2.0",
|
||||||
"socket.io-client": "^4.6.1",
|
"socket.io-client": "^4.6.1",
|
||||||
@ -3398,6 +3399,17 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dotenv": {
|
||||||
|
"version": "16.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz",
|
||||||
|
"integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/motdotla/dotenv?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ee-first": {
|
"node_modules/ee-first": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
"@nestjs/platform-socket.io": "^9.4.0",
|
"@nestjs/platform-socket.io": "^9.4.0",
|
||||||
"@nestjs/websockets": "^9.4.0",
|
"@nestjs/websockets": "^9.4.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^16.1.4",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.2.0",
|
"rxjs": "^7.2.0",
|
||||||
"socket.io-client": "^4.6.1",
|
"socket.io-client": "^4.6.1",
|
||||||
|
|||||||
@ -21,6 +21,10 @@ import { AppModule } from './app.module';
|
|||||||
import * as cors from 'cors';
|
import * as cors from 'cors';
|
||||||
import { Server } from 'socket.io';
|
import { Server } from 'socket.io';
|
||||||
import * as socketio from 'socket.io';
|
import * as socketio from 'socket.io';
|
||||||
|
import * as dotenv from 'dotenv';
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
console.log(process.env);
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule, {
|
const app = await NestFactory.create(AppModule, {
|
||||||
@ -54,7 +58,7 @@ async function bootstrap() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await app.listen(4000);
|
await app.listen(process.env.PONG_PORT || 4000);
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrap();
|
bootstrap();
|
||||||
@ -68,11 +68,19 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
|
|||||||
// }
|
// }
|
||||||
// // console.log(`from: ${client.id}`);
|
// // console.log(`from: ${client.id}`);
|
||||||
// }
|
// }
|
||||||
|
@SubscribeMessage('pong:invite')
|
||||||
|
createPrivateGame(client: Socket, payload: any): void {
|
||||||
|
//after invite accepted ?
|
||||||
|
//set the two user in a game ?
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SubscribeMessage('pong:matchmaking')
|
@SubscribeMessage('pong:matchmaking')
|
||||||
addMatchmaking(client: Socket, payload: any): void {
|
addMatchmaking(client: Socket, payload: any): void {
|
||||||
console.log("matchmaking");
|
console.log("matchmaking");
|
||||||
console.log(payload);
|
console.log(payload);
|
||||||
|
console.log(`option= ${payload.option}`);
|
||||||
// Add the client to the waitingClients set along with their chosen option
|
// Add the client to the waitingClients set along with their chosen option
|
||||||
this.waitingClients.add({ client, option: payload.option });
|
this.waitingClients.add({ client, option: payload.option });
|
||||||
console.log("Adding client to waiting list...");
|
console.log("Adding client to waiting list...");
|
||||||
@ -147,6 +155,21 @@ addMatchmaking(client: Socket, payload: any): void {
|
|||||||
// console.log("END OF HANDLE");
|
// console.log("END OF HANDLE");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@SubscribeMessage('pong:power')
|
||||||
|
sendPower(client: Socket, payload: any): void
|
||||||
|
{
|
||||||
|
console.log(`from: ${client.id}`);
|
||||||
|
console.log(payload);
|
||||||
|
|
||||||
|
const game = this.games.get(payload.gameId);
|
||||||
|
const playersIds = game.map(socket => socket.id);
|
||||||
|
if (playersIds[0] === payload.id)
|
||||||
|
this.clients[playersIds[1]].emit('pong:power', payload);
|
||||||
|
else if (playersIds[1] === payload.id)
|
||||||
|
this.clients[playersIds[0]].emit('pong:power', payload);
|
||||||
|
console.log("END OF HANDLE");
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeMessage('pong:message')
|
@SubscribeMessage('pong:message')
|
||||||
handleMessage(client: Socket, payload: any): void
|
handleMessage(client: Socket, payload: any): void
|
||||||
{
|
{
|
||||||
|
|||||||
21
containers/react/src/components/404.jsx
Normal file
21
containers/react/src/components/404.jsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* 404.jsx :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/06/09 23:07:12 by apommier #+# #+# */
|
||||||
|
/* Updated: 2023/06/12 17:09:11 by apommier ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
function PageNotFound() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>404 Page not found</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PageNotFound
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {Routes, Route} from 'react-router-dom';
|
import {Routes, Route, Navigate} from 'react-router-dom';
|
||||||
import HomeLogin from "../pages/Home.js";
|
import HomeLogin from "../pages/Home.js";
|
||||||
|
|
||||||
import Home from "../pages/Home.jsx";
|
import Home from "../pages/Home.jsx";
|
||||||
@ -17,15 +17,32 @@ import SuccessToken from '../script/tokenSuccess'
|
|||||||
import DoubleAuth from "../pages/2fa.js";
|
import DoubleAuth from "../pages/2fa.js";
|
||||||
import Game from "../pages/Game.jsx";
|
import Game from "../pages/Game.jsx";
|
||||||
import Social from "../components/Social/Social.jsx";
|
import Social from "../components/Social/Social.jsx";
|
||||||
|
import PageNotFound from "../components/404.jsx";
|
||||||
import Logout from "../components/Profile/Logout.jsx";
|
import Logout from "../components/Profile/Logout.jsx";
|
||||||
|
|
||||||
function AnimatedRoute () {
|
function AnimatedRoute () {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
if (!localStorage.getItem('token'))
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<AnimatePresence>
|
||||||
|
<Routes location={location} key={location.pathname}>
|
||||||
|
<Route exact path="/" element={<HomeLogin/>}/>
|
||||||
|
<Route exact path="/token" element={<SuccessToken />}/>
|
||||||
|
|
||||||
|
<Route path="/404" element={<HomeLogin/>} />
|
||||||
|
<Route path="*" element={<Navigate to="/404" />} />
|
||||||
|
</Routes>
|
||||||
|
</AnimatePresence>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
<Routes location={location} key={location.pathname}>
|
<Routes location={location} key={location.pathname}>
|
||||||
|
|
||||||
<Route exact path="/" element={<HomeLogin/>}/>
|
{/* <Route exact path="/login" element={<HomeLogin/>}/> */}
|
||||||
|
<Route exact path="/" element={<Home/>}/>
|
||||||
<Route exact path="/profile" element={<Home/>}/>
|
<Route exact path="/profile" element={<Home/>}/>
|
||||||
<Route exact path="/profile/:username" element={<Home/>}/>
|
<Route exact path="/profile/:username" element={<Home/>}/>
|
||||||
|
|
||||||
@ -41,6 +58,9 @@ function AnimatedRoute () {
|
|||||||
<Route exact path="/login42" element={<Login42 />}/>
|
<Route exact path="/login42" element={<Login42 />}/>
|
||||||
<Route exact path="/logout" element={<Logout />}/>
|
<Route exact path="/logout" element={<Logout />}/>
|
||||||
<Route exact path="/messages" element={<Messages />}/>
|
<Route exact path="/messages" element={<Messages />}/>
|
||||||
|
|
||||||
|
<Route path="/404" element={<PageNotFound />} />
|
||||||
|
<Route path="*" element={<Navigate to="/404" />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -6,8 +6,31 @@ function PlayButton() {
|
|||||||
|
|
||||||
const history = useNavigate();
|
const history = useNavigate();
|
||||||
|
|
||||||
|
// const handleButtonClick = () => {
|
||||||
|
// let path = `play`;
|
||||||
|
// history(path);
|
||||||
|
// };
|
||||||
const handleButtonClick = () => {
|
const handleButtonClick = () => {
|
||||||
let path = `play`;
|
let path = `play?`;
|
||||||
|
|
||||||
|
const superpowerCheckbox = document.querySelector('input[value="superpower"]');
|
||||||
|
if (superpowerCheckbox.checked) {
|
||||||
|
path += 'superpower=true&';
|
||||||
|
}
|
||||||
|
|
||||||
|
const obstacleCheckbox = document.querySelector('input[value="obstacle"]');
|
||||||
|
if (obstacleCheckbox.checked) {
|
||||||
|
path += 'obstacle=true&';
|
||||||
|
}
|
||||||
|
|
||||||
|
const speedCheckbox = document.querySelector('input[value="speed"]');
|
||||||
|
if (speedCheckbox.checked) {
|
||||||
|
path += 'speed=true&';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the trailing '&' character
|
||||||
|
path = path.slice(0, -1);
|
||||||
|
console.log(path)
|
||||||
history(path);
|
history(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,9 @@
|
|||||||
import React, {useState, useEffect} from 'react';
|
import React, {useState, useEffect} from 'react';
|
||||||
import {AiOutlineMenuUnfold} from 'react-icons/ai';
|
import {AiOutlineMenuUnfold} from 'react-icons/ai';
|
||||||
// import * as AiIcons from 'react-icons/ai';
|
|
||||||
import {Link} from 'react-router-dom';
|
import {Link} from 'react-router-dom';
|
||||||
// import { SidebarData } from './Sidebar/SidebarData';
|
|
||||||
import DefaultPicture from '../assets/profile.jpg'
|
import DefaultPicture from '../assets/profile.jpg'
|
||||||
import { motion, AnimatePresence } from 'framer-motion'
|
import { motion, AnimatePresence } from 'framer-motion'
|
||||||
import Modal from './Sidebar/Modal';
|
import Modal from './Sidebar/Modal';
|
||||||
// import {BiLogOutCircle} from 'react-icons/bi';
|
|
||||||
// import AnimatePresence from
|
|
||||||
import '../styles/Header.css';
|
import '../styles/Header.css';
|
||||||
|
|
||||||
import api from '../script/axiosApi';
|
import api from '../script/axiosApi';
|
||||||
@ -32,7 +28,7 @@ function Header() {
|
|||||||
console.error('Error fetching profile picture:', error);
|
console.error('Error fetching profile picture:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if (localStorage.getItem('token'))
|
||||||
fetchProfilePicture();
|
fetchProfilePicture();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/01 18:24:46 by apommier #+# #+# */
|
/* Created: 2023/06/01 18:24:46 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/09 09:00:06 by apommier ### ########.fr */
|
/* Updated: 2023/06/12 17:05:08 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|||||||
@ -46,28 +46,7 @@ export default function Friend({currentUser})
|
|||||||
};
|
};
|
||||||
|
|
||||||
fetchProfilePicture();
|
fetchProfilePicture();
|
||||||
})
|
}, [])
|
||||||
|
|
||||||
function getStatus(friend)
|
|
||||||
{
|
|
||||||
let status = friend.status
|
|
||||||
console.log(`status= ${status}`)
|
|
||||||
let statusColor;
|
|
||||||
|
|
||||||
if (status === 0)
|
|
||||||
statusColor = 'grey';
|
|
||||||
else if (status === 1)
|
|
||||||
statusColor = 'green';
|
|
||||||
else if (status === 2)
|
|
||||||
statusColor = 'blue';
|
|
||||||
return statusColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSpectate = (user) => {
|
|
||||||
//socket connection and add to party with one with username
|
|
||||||
console.log(`spectate hehe`)
|
|
||||||
console.log(`user= ${user}`)
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleButtonClick = (user) => {
|
const handleButtonClick = (user) => {
|
||||||
let path = `http://localhost/profile/${user.username}`;
|
let path = `http://localhost/profile/${user.username}`;
|
||||||
@ -79,10 +58,12 @@ export default function Friend({currentUser})
|
|||||||
|
|
||||||
const Accept = (user) => {
|
const Accept = (user) => {
|
||||||
console.log("accept")
|
console.log("accept")
|
||||||
|
console.log(`request = ${request}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Refuse = (user) => {
|
const Refuse = (user) => {
|
||||||
console.log("refuse")
|
console.log("refuse")
|
||||||
|
console.log(`request = ${request}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,13 +1,48 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect, useLocation } from 'react';
|
||||||
// import { useState, useRef } from 'react';
|
// import { useState, useRef } from 'react';
|
||||||
import { drawCanvas } from './canvas.js';
|
import DrawCanvas from './canvas.js';
|
||||||
|
import queryString from 'query-string';
|
||||||
import '../styles/field.css';
|
import '../styles/field.css';
|
||||||
|
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
|
// import { withRouter } from 'react-router-dom';
|
||||||
|
|
||||||
function Field()
|
function Field()
|
||||||
{
|
{
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// const location = useLocation();
|
||||||
|
const queryParams = queryString.parse(window.location.search);
|
||||||
|
|
||||||
console.log("launch canva hehe")
|
console.log("launch canva hehe")
|
||||||
drawCanvas();
|
let Modifiers = 0;
|
||||||
|
|
||||||
|
if (queryParams.superpower === 'true') {
|
||||||
|
Modifiers += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.obstacle === 'true') {
|
||||||
|
Modifiers += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryParams.speed === 'true') {
|
||||||
|
Modifiers += 4;
|
||||||
|
}
|
||||||
|
// console.log(`modifiers= ${Modifiers}`)
|
||||||
|
// DrawCanvas(Modifiers);
|
||||||
|
// return () => {
|
||||||
|
// console.log("000000000000000000000000000000000")
|
||||||
|
// // socketRef.current.disconnect();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// console.log(`modifiers= ${Modifiers}`)
|
||||||
|
const cleanup = DrawCanvas(Modifiers);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
console.log("Cleanup");
|
||||||
|
cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks
|
||||||
|
};
|
||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// const [buttonClicked, setButtonClicked] = useState(false);
|
// const [buttonClicked, setButtonClicked] = useState(false);
|
||||||
@ -28,6 +63,7 @@ function Field()
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default Field;
|
export default Field;
|
||||||
|
// export default withRouter(Field);
|
||||||
|
|
||||||
|
|
||||||
// function Field() {
|
// function Field() {
|
||||||
|
|||||||
@ -2,19 +2,44 @@
|
|||||||
|
|
||||||
import api from '../script/axiosApi';
|
import api from '../script/axiosApi';
|
||||||
|
|
||||||
// import { useEffect } from 'react';
|
// import { useEffect, useRef } from 'react';
|
||||||
import io from 'socket.io-client';
|
import io from 'socket.io-client';
|
||||||
// const socket = io('http://192.168.1.14:4000');
|
// const socket = io('http://192.168.1.14:4000');
|
||||||
// const socket = io('http://86.209.110.20:4000');
|
// const socket = io('http://86.209.110.20:4000');
|
||||||
// const socket = io('http://172.29.113.91:4000');
|
// const socket = io('http://172.29.113.91:4000');
|
||||||
|
|
||||||
export function drawCanvas() {
|
function DrawCanvas(option) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
console.log(`option= ${option}`);
|
||||||
|
const superpowerModifier = option & 1; // Retrieves the superpower modifier
|
||||||
|
const obstacleModifier = (option >> 1) & 1; // Retrieves the obstacle modifier
|
||||||
|
const speedModifier = (option >> 2) & 1; // Retrieves the speed modifier
|
||||||
|
|
||||||
|
console.log(`superpowerModifier = ${superpowerModifier}`);
|
||||||
|
console.log(`obstacleModifier = ${obstacleModifier}`);
|
||||||
|
console.log(`speedModifier = ${speedModifier}`);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// const socketRef = useRef(null);
|
||||||
|
// socketRef.current = io('http://localhost:4000');
|
||||||
const socket = io('http://localhost:4000');
|
const socket = io('http://localhost:4000');
|
||||||
// const socket = io()
|
// const socket = socketRef.current
|
||||||
console.log("start function");
|
console.log("start function");
|
||||||
const canvas = document.getElementById('myCanvas');
|
const canvas = document.getElementById('myCanvas');
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// console.log("useeffect?????????????????")
|
||||||
|
// return () => {
|
||||||
|
// console.log("000000000000000000000000000000000")
|
||||||
|
// socketRef.current.disconnect();
|
||||||
|
// };
|
||||||
|
// }, []);
|
||||||
|
|
||||||
|
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
// Var Declaration
|
// Var Declaration
|
||||||
@ -28,6 +53,7 @@ export function drawCanvas() {
|
|||||||
let opRank;
|
let opRank;
|
||||||
|
|
||||||
//general canvas
|
//general canvas
|
||||||
|
let running = true;
|
||||||
const scale = window.devicePixelRatio;
|
const scale = window.devicePixelRatio;
|
||||||
canvas.width = canvas.offsetWidth;
|
canvas.width = canvas.offsetWidth;
|
||||||
// canvas.height = canvas.width * 0.7
|
// canvas.height = canvas.width * 0.7
|
||||||
@ -41,6 +67,7 @@ export function drawCanvas() {
|
|||||||
let paddleSpeed = canvas.height / 40;
|
let paddleSpeed = canvas.height / 40;
|
||||||
|
|
||||||
//opponent var
|
//opponent var
|
||||||
|
let opPaddleHeight = canvas.height * 0.25;
|
||||||
let oPaddleY = paddleY;
|
let oPaddleY = paddleY;
|
||||||
|
|
||||||
//mouse and touch
|
//mouse and touch
|
||||||
@ -81,6 +108,7 @@ export function drawCanvas() {
|
|||||||
console.log(`id ion matcj= ${myId}`)
|
console.log(`id ion matcj= ${myId}`)
|
||||||
const info = {
|
const info = {
|
||||||
id: myId,
|
id: myId,
|
||||||
|
option: option,
|
||||||
};
|
};
|
||||||
socket.emit('pong:matchmaking', info);
|
socket.emit('pong:matchmaking', info);
|
||||||
}
|
}
|
||||||
@ -165,6 +193,27 @@ export function drawCanvas() {
|
|||||||
vY = data.vY;
|
vY = data.vY;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
socket.on('pong:paddle', (data) => {
|
||||||
|
console.log("paddle info receive")
|
||||||
|
oPaddleY = (data.paddleY / data.height) * canvas.height
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('pong:power', (data) => {
|
||||||
|
console.log("paddle info receive")
|
||||||
|
|
||||||
|
oPaddleY = 0;
|
||||||
|
opPaddleHeight = canvas.height;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
// code à exécuter après 5 secondes
|
||||||
|
opPaddleHeight = canvas.height * 0.25;
|
||||||
|
oPaddleY = canvas.height / 2 - paddleHeight / 2;
|
||||||
|
console.log('Cinq secondes se sont écoulées.');
|
||||||
|
}, 5000);
|
||||||
|
// oPaddleY = (data.paddleY / data.height) * canvas.height
|
||||||
|
});
|
||||||
|
|
||||||
function send_info()
|
function send_info()
|
||||||
{
|
{
|
||||||
if (gameId === 0)
|
if (gameId === 0)
|
||||||
@ -183,11 +232,6 @@ export function drawCanvas() {
|
|||||||
socket.emit('pong:message', info);
|
socket.emit('pong:message', info);
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.on('pong:paddle', (data) => {
|
|
||||||
console.log("paddle info receive")
|
|
||||||
oPaddleY = (data.paddleY / data.height) * canvas.height
|
|
||||||
});
|
|
||||||
|
|
||||||
function send_point()
|
function send_point()
|
||||||
{
|
{
|
||||||
if (gameId === 0)
|
if (gameId === 0)
|
||||||
@ -229,6 +273,17 @@ export function drawCanvas() {
|
|||||||
socket.emit('pong:paddle', info);
|
socket.emit('pong:paddle', info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function use_power()
|
||||||
|
{
|
||||||
|
const info = {
|
||||||
|
gameId: gameId,
|
||||||
|
width: canvas.width,
|
||||||
|
height: canvas.height,
|
||||||
|
id: myId,
|
||||||
|
}
|
||||||
|
socket.emit('pong:power', info);
|
||||||
|
}
|
||||||
|
|
||||||
function send_forced_info()
|
function send_forced_info()
|
||||||
{
|
{
|
||||||
if (gameId === 0)
|
if (gameId === 0)
|
||||||
@ -275,7 +330,7 @@ export function drawCanvas() {
|
|||||||
function drawPaddle() {
|
function drawPaddle() {
|
||||||
ctx.fillStyle = 'white';
|
ctx.fillStyle = 'white';
|
||||||
ctx.fillRect(paddleX, paddleY, paddleWidth, paddleHeight);
|
ctx.fillRect(paddleX, paddleY, paddleWidth, paddleHeight);
|
||||||
ctx.fillRect(canvas.width - paddleX - paddleWidth, oPaddleY, paddleWidth, paddleHeight);
|
ctx.fillRect(canvas.width - paddleX - paddleWidth, oPaddleY, paddleWidth, opPaddleHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawball()
|
function drawball()
|
||||||
@ -298,9 +353,18 @@ matchmaking();
|
|||||||
// while (!gameId)
|
// while (!gameId)
|
||||||
// ;
|
// ;
|
||||||
|
|
||||||
|
// Define a function to stop the drawing process
|
||||||
|
const stopDrawCanvas = () => {
|
||||||
|
running = false;
|
||||||
|
// Perform any necessary cleanup tasks
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
|
||||||
function draw(timestamp)
|
function draw(timestamp)
|
||||||
{
|
{
|
||||||
|
console.log("send loose");
|
||||||
|
if (!running)
|
||||||
|
return ;
|
||||||
if (gameId === 0 )
|
if (gameId === 0 )
|
||||||
{
|
{
|
||||||
requestAnimationFrame(draw);
|
requestAnimationFrame(draw);
|
||||||
@ -333,7 +397,7 @@ function draw(timestamp)
|
|||||||
const deltaTime = timestamp - lastUpdateTime;
|
const deltaTime = timestamp - lastUpdateTime;
|
||||||
lastUpdateTime = timestamp;
|
lastUpdateTime = timestamp;
|
||||||
ballX += vX * deltaTime * canvas.width;
|
ballX += vX * deltaTime * canvas.width;
|
||||||
ballY += vY * deltaTime * canvas.width;
|
ballY += vY * deltaTime * canvas.height;
|
||||||
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
drawPaddle();
|
drawPaddle();
|
||||||
@ -343,7 +407,8 @@ function draw(timestamp)
|
|||||||
is_out();
|
is_out();
|
||||||
requestAnimationFrame(draw);
|
requestAnimationFrame(draw);
|
||||||
}
|
}
|
||||||
requestAnimationFrame(draw);
|
|
||||||
|
|
||||||
|
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
@ -360,6 +425,13 @@ requestAnimationFrame(draw);
|
|||||||
vY = vX * Math.sin(-bounceAngle);
|
vY = vX * Math.sin(-bounceAngle);
|
||||||
if (vX < 0)
|
if (vX < 0)
|
||||||
vX = -vX;
|
vX = -vX;
|
||||||
|
if (speedModifier)
|
||||||
|
{
|
||||||
|
if (vX > 0)
|
||||||
|
vX += 0.0001;
|
||||||
|
else
|
||||||
|
vX -= 0.0001;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -387,7 +459,12 @@ requestAnimationFrame(draw);
|
|||||||
}
|
}
|
||||||
if (ballY - ballRadius - 2 <= 0 || ballY + ballRadius + 2 >= canvas.height) //touch up or down wall
|
if (ballY - ballRadius - 2 <= 0 || ballY + ballRadius + 2 >= canvas.height) //touch up or down wall
|
||||||
{
|
{
|
||||||
|
// if ()
|
||||||
vY = -vY;
|
vY = -vY;
|
||||||
|
if (ballY > (canvas.height / 2))//down wall
|
||||||
|
ballY = canvas.height - ballRadius - 2
|
||||||
|
else
|
||||||
|
ballY = ballRadius + 2
|
||||||
// send_info();
|
// send_info();
|
||||||
}
|
}
|
||||||
// else if (ballX + ballRadius + 2 >= canvas.width) //touch right wall
|
// else if (ballX + ballRadius + 2 >= canvas.width) //touch right wall
|
||||||
@ -416,6 +493,24 @@ requestAnimationFrame(draw);
|
|||||||
send_point();
|
send_point();
|
||||||
// send_forced_info();
|
// send_forced_info();
|
||||||
}
|
}
|
||||||
|
if (ballX > canvas.width)
|
||||||
|
{
|
||||||
|
console.log("win point")
|
||||||
|
// if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)
|
||||||
|
// {
|
||||||
|
// console.log('true hehe');
|
||||||
|
// ballX = paddleX + paddleWidth + ballRadius;
|
||||||
|
// updateVector();
|
||||||
|
// return ;
|
||||||
|
// }
|
||||||
|
// ballX = canvas.width / 2;
|
||||||
|
// ballY = canvas.height / 2;
|
||||||
|
// vX = 0;
|
||||||
|
// vY = 0;
|
||||||
|
// hisScore += 1;
|
||||||
|
// send_point();
|
||||||
|
// // send_forced_info();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,8 +605,11 @@ requestAnimationFrame(draw);
|
|||||||
}
|
}
|
||||||
else if (event.code === "KeyR")
|
else if (event.code === "KeyR")
|
||||||
{
|
{
|
||||||
|
if (!superpowerModifier)
|
||||||
|
return ;
|
||||||
paddleY = 0;
|
paddleY = 0;
|
||||||
paddleHeight = canvas.height;
|
paddleHeight = canvas.height;
|
||||||
|
use_power();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// code à exécuter après 5 secondes
|
// code à exécuter après 5 secondes
|
||||||
paddleHeight = canvas.height * 0.25;
|
paddleHeight = canvas.height * 0.25;
|
||||||
@ -521,4 +619,9 @@ requestAnimationFrame(draw);
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
requestAnimationFrame(draw);
|
||||||
|
console.log("retuuuuuuuuuuurn")
|
||||||
|
return (stopDrawCanvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default DrawCanvas
|
||||||
@ -8,14 +8,25 @@ services:
|
|||||||
env_file: .env
|
env_file: .env
|
||||||
depends_on:
|
depends_on:
|
||||||
- api
|
- api
|
||||||
|
|
||||||
|
# command: sh -c "envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
volumes:
|
volumes:
|
||||||
- ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
|
- ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
# volumes:
|
||||||
|
# - "./conf:/etc/nginx/templates/"
|
||||||
|
# ports:
|
||||||
|
# - 80:80
|
||||||
|
# volumes:
|
||||||
|
# - ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
# command: sh -c "envsubst < /etc/nginx/conf.d/default.conf > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
|
||||||
# - ./containers/frontend:/var/www/html
|
# - ./containers/frontend:/var/www/html
|
||||||
networks:
|
networks:
|
||||||
- pongNetwork
|
- pongNetwork
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
react_app:
|
react_app:
|
||||||
image: node:latest
|
image: node:latest
|
||||||
container_name: react_app
|
container_name: react_app
|
||||||
@ -48,6 +59,7 @@ services:
|
|||||||
entrypoint: ["sh", "-c" , "npm install && npm run start:dev"]
|
entrypoint: ["sh", "-c" , "npm install && npm run start:dev"]
|
||||||
|
|
||||||
postgresql:
|
postgresql:
|
||||||
|
env_file: .env
|
||||||
image: postgres:14.1-alpine
|
image: postgres:14.1-alpine
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
container_name: postgresql
|
container_name: postgresql
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user