add 2fa and env var(not in conf files)
This commit is contained in:
parent
47863325ea
commit
2b16af1785
37
.env
37
.env
@ -1,3 +1,8 @@
|
||||
#nessecarr var
|
||||
#API_SECRET
|
||||
|
||||
|
||||
|
||||
# POSTGRES_USER=kinou
|
||||
# POSTGRES_PASSWORD=pass
|
||||
# POSTGRES_DB=postgreDB
|
||||
@ -5,11 +10,35 @@
|
||||
# POSTGRES_HOST=localhost
|
||||
# POSTGRES_HOST_AUTH_METHOD=trust
|
||||
|
||||
POSTGRES_HOST=127.0.0.1
|
||||
POSTGRES_PORT=5432
|
||||
#URL
|
||||
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_PASSWORD=pass
|
||||
POSTGRES_DATABASE=postgres
|
||||
PORT=3000
|
||||
MODE=DEV
|
||||
RUN_MIGRATIONS=true
|
||||
|
||||
#port
|
||||
API_PORT=3000
|
||||
# REACT_PORT=3000 (current = 8080)
|
||||
NGINX_PORT=80
|
||||
PONG_PORT=4000
|
||||
CHAT_PORT=4001
|
||||
POSTGRES_PORT=5432
|
||||
|
||||
#????
|
||||
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 80 ssl;
|
||||
# listen 443 ssl;
|
||||
listen 80;
|
||||
|
||||
# listen ${NGINX_PORT};
|
||||
listen 80;
|
||||
|
||||
location /{
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass http://react_app:8080;
|
||||
}
|
||||
|
||||
@ -19,7 +18,6 @@ server {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
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",
|
||||
"hi-base32": "^0.5.1",
|
||||
"nanoid": "^3.3.4",
|
||||
"otpauth": "^9.1.2",
|
||||
"passport": "^0.6.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"passport-local": "^1.0.0",
|
||||
@ -6099,6 +6100,14 @@
|
||||
"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": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
||||
@ -6685,6 +6694,17 @@
|
||||
"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": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
"express-session": "^1.17.3",
|
||||
"hi-base32": "^0.5.1",
|
||||
"nanoid": "^3.3.4",
|
||||
"otpauth": "^9.1.2",
|
||||
"passport": "^0.6.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"passport-local": "^1.0.0",
|
||||
|
||||
@ -9,7 +9,15 @@ import { UsersService } from './users/users.service';
|
||||
|
||||
import { MatchLog } from './model/user.entity'
|
||||
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';
|
||||
|
||||
@ -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)
|
||||
@Get('auth/login')
|
||||
async login2(@Req() request: Request) {
|
||||
const url = request.url;
|
||||
const user = await this.loginClass.Login42(url);
|
||||
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}`)
|
||||
|
||||
const myJSON = JSON.stringify(data);
|
||||
console.log(`all data json version= ${myJSON}`)
|
||||
|
||||
console.log(`data in api = ${(await data).access_token}`)
|
||||
// console.log(`data i = ${(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))}` };
|
||||
}
|
||||
|
||||
@ -238,17 +256,49 @@ export class AppController {
|
||||
async get2fa(@Request() req)
|
||||
{
|
||||
const user = await this.userService.findOne(req.user.username);
|
||||
return user.doubleAuth;
|
||||
return user.otp_enabled;
|
||||
}
|
||||
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Get('/QRcode')
|
||||
async createQrCode(@Request() req)
|
||||
@Post('/otp')
|
||||
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)
|
||||
@Post('/quit')
|
||||
async setOffline(@Request() req) {
|
||||
@ -271,6 +321,8 @@ export class AppController {
|
||||
async createConv(@Request() req, @Body() data: any) {
|
||||
///create conv and return it ? id?
|
||||
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"};
|
||||
return await this.chatService.createConv(data);
|
||||
// res.json(messages);
|
||||
@ -278,20 +330,10 @@ export class AppController {
|
||||
|
||||
|
||||
|
||||
// @UseGuards(JwtAuthGuard)
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Get('/conv')
|
||||
async getConv(@Request() req, @Body() data: any) {
|
||||
///create conv and return it ? id?
|
||||
// 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);
|
||||
async getConv(@Request() req) {
|
||||
return await this.chatService.getConv(req.user.username);
|
||||
}
|
||||
|
||||
// @UseGuards(JwtAuthGuard)
|
||||
|
||||
@ -28,7 +28,7 @@ import { JwtStrategy } from './jwt.strategy';
|
||||
PassportModule,
|
||||
JwtModule.register({
|
||||
secret: jwtConstants.secret,
|
||||
signOptions: { expiresIn: '60000s' },
|
||||
// signOptions: { expiresIn: '60000s' },
|
||||
}),
|
||||
],
|
||||
providers: [AuthService, LocalStrategy, JwtStrategy],
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { UsersService } from '../users/users.service';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { User } from 'src/model/user.entity';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
@ -19,13 +20,13 @@ export class AuthService {
|
||||
return null;
|
||||
}
|
||||
|
||||
async login(user) {
|
||||
const myJSON = JSON.stringify(user);
|
||||
async login(user: User) {
|
||||
// const myJSON = JSON.stringify(user);
|
||||
// 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 };
|
||||
// console.log(`in login payload name= ${payload.username}`)
|
||||
// console.log(`in login payload sub= ${payload.sub}`)
|
||||
console.log(`in login payload name= ${payload.username}`)
|
||||
console.log(`in login payload sub= ${payload.sub}`)
|
||||
return {
|
||||
access_token: this.jwtService.sign(payload),
|
||||
};
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
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 = {
|
||||
grant_type: 'authorization_code',
|
||||
client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41',
|
||||
client_secret: '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',
|
||||
client_id: process.env.CLIENT_UID || 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41',
|
||||
// client_secret: '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',
|
||||
client_secret: process.env.API_SECRET,
|
||||
code: code,
|
||||
redirect_uri: 'http://localhost:80/api/auth/login',
|
||||
redirect_uri: process.env.REDIRECT_URI || 'http://localhost:80/api/auth/login',
|
||||
};
|
||||
|
||||
try {
|
||||
@ -64,9 +65,12 @@ export class loginClass {
|
||||
loss: 0,
|
||||
rank: 1200,
|
||||
userId: userId,
|
||||
otp_base32: null,
|
||||
children: null,
|
||||
status: 1,
|
||||
doubleAuth: 0,
|
||||
// doubleAuth: 0,
|
||||
otp_enabled: false,
|
||||
otp_verified: false,
|
||||
friendRequest: null,
|
||||
friends: null,
|
||||
photo: null,
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 => ({
|
||||
type: 'postgres',
|
||||
host: 'postgresql',
|
||||
port: 5432,
|
||||
username: 'postgres',
|
||||
password: 'pass',
|
||||
database: 'postgres',
|
||||
host: process.env.POSTGRES_HOST || 'postgresql',
|
||||
port: parseInt(process.env.POSTGRES_PORT, 10) || 5432,
|
||||
username: process.env.POSTGRES_USER || 'postgres',
|
||||
password: process.env.POSTGRES_PASSWORD || 'pass',
|
||||
database: process.env.POSTGRES_DATABASE || 'postgres',
|
||||
entities: ["dist/**/*.entity.js"],
|
||||
// entities: [join(__dirname, '**', '*.entity.{ts,js}')]
|
||||
// entities: ['**/*.entity{.ts,.js}'], //basic
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
import * as session from 'express-session';
|
||||
import * as dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
console.log(process.env);
|
||||
|
||||
// async function bootstrap() {
|
||||
// const app = await NestFactory.create(AppModule);
|
||||
@ -27,6 +31,6 @@ async function bootstrap() {
|
||||
saveUninitialized: false,
|
||||
}),
|
||||
);
|
||||
await app.listen(3000);
|
||||
await app.listen(parseInt(process.env.API_PORT) || 3000);
|
||||
}
|
||||
bootstrap();
|
||||
@ -20,6 +20,18 @@ export class User {
|
||||
@PrimaryGeneratedColumn()
|
||||
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 })
|
||||
nickname: string;
|
||||
|
||||
@ -47,8 +59,8 @@ export class User {
|
||||
@Column({ default: 0 })
|
||||
userId: number;
|
||||
|
||||
@Column({ default: 0 })
|
||||
doubleAuth: number;
|
||||
// @Column({ default: 0 })
|
||||
// doubleAuth: number;
|
||||
|
||||
@Column('text', { array: true, nullable: true })
|
||||
friendRequest: string[];
|
||||
|
||||
@ -1,6 +1,109 @@
|
||||
import crypto from 'crypto';
|
||||
// import crypto from 'crypto';
|
||||
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 { promisify } from 'util';
|
||||
|
||||
@ -33,48 +136,48 @@ import base32Decode from 'base32-decode';
|
||||
|
||||
// type QRcode = any;
|
||||
|
||||
export function generateHOTP(secret, counter) {
|
||||
const decodedSecret = base32Decode(secret, 'RFC4648');
|
||||
// export function generateHOTP(secret, counter) {
|
||||
// const decodedSecret = base32Decode(secret, 'RFC4648');
|
||||
|
||||
const buffer = Buffer.alloc(8);
|
||||
for (let i = 0; i < 8; i++) {
|
||||
buffer[7 - i] = counter & 0xff;
|
||||
counter = counter >> 8;
|
||||
}
|
||||
|
||||
// Step 1: Generate an HMAC-SHA-1 value
|
||||
const hmac = crypto.createHmac('sha1', Buffer.from(decodedSecret));
|
||||
hmac.update(buffer);
|
||||
const hmacResult = hmac.digest();
|
||||
|
||||
// Step 2: Generate a 4-byte string (Dynamic Truncation)
|
||||
const offset = hmacResult[hmacResult.length - 1] & 0xf;
|
||||
const code =
|
||||
((hmacResult[offset] & 0x7f) << 24) |
|
||||
((hmacResult[offset + 1] & 0xff) << 16) |
|
||||
((hmacResult[offset + 2] & 0xff) << 8) |
|
||||
(hmacResult[offset + 3] & 0xff);
|
||||
|
||||
// Step 3: Compute an HOTP value
|
||||
return code % 10 ** 6;
|
||||
}
|
||||
// const buffer = Buffer.alloc(8);
|
||||
// for (let i = 0; i < 8; i++) {
|
||||
// buffer[7 - i] = counter & 0xff;
|
||||
// counter = counter >> 8;
|
||||
// }
|
||||
|
||||
export function generateTOTP(secret, window = 0)
|
||||
{
|
||||
const counter = Math.floor(Date.now() / 30000);
|
||||
return generateHOTP(secret, counter + window);
|
||||
}
|
||||
// // Step 1: Generate an HMAC-SHA-1 value
|
||||
// const hmac = crypto.createHmac('sha1', Buffer.from(decodedSecret));
|
||||
// hmac.update(buffer);
|
||||
// const hmacResult = hmac.digest();
|
||||
|
||||
export function verifyTOTP(token, secret, window = 1)
|
||||
{
|
||||
for (let errorWindow = -window; errorWindow <= +window; errorWindow++)
|
||||
{
|
||||
const totp = generateTOTP(secret, errorWindow);
|
||||
if (token === totp)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// // Step 2: Generate a 4-byte string (Dynamic Truncation)
|
||||
// const offset = hmacResult[hmacResult.length - 1] & 0xf;
|
||||
// const code =
|
||||
// ((hmacResult[offset] & 0x7f) << 24) |
|
||||
// ((hmacResult[offset + 1] & 0xff) << 16) |
|
||||
// ((hmacResult[offset + 2] & 0xff) << 8) |
|
||||
// (hmacResult[offset + 3] & 0xff);
|
||||
|
||||
// // Step 3: Compute an HOTP value
|
||||
// return code % 10 ** 6;
|
||||
// }
|
||||
|
||||
// export function generateTOTP(secret, window = 0)
|
||||
// {
|
||||
// const counter = Math.floor(Date.now() / 30000);
|
||||
// return generateHOTP(secret, counter + window);
|
||||
// }
|
||||
|
||||
// export function verifyTOTP(token, secret, window = 1)
|
||||
// {
|
||||
// for (let errorWindow = -window; errorWindow <= +window; errorWindow++)
|
||||
// {
|
||||
// const totp = generateTOTP(secret, errorWindow);
|
||||
// if (token === totp)
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@ -94,86 +197,86 @@ export function verifyTOTP(token, secret, window = 1)
|
||||
// import * as 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 fs from 'fs';
|
||||
// import * as qrcode from 'qrcode';
|
||||
// import * as fs from 'fs';
|
||||
|
||||
|
||||
import { nanoid } from "nanoid";
|
||||
// import * as nanoid from 'nanoid'
|
||||
// import { nanoid } from "nanoid";
|
||||
// // import * as nanoid from 'nanoid'
|
||||
|
||||
export async function generateQRcode(req)
|
||||
{
|
||||
// const base32Encode = (await import('base32-encode'));
|
||||
// const nanoid = (await import('nanoid'));
|
||||
// export async function generateQRcode(req)
|
||||
// {
|
||||
// // const base32Encode = (await import('base32-encode'));
|
||||
// // const nanoid = (await import('nanoid'));
|
||||
|
||||
// const util = (await import('util'));
|
||||
// const qrcode = (await import('qrcode'));
|
||||
// // const util = (await import('util'));
|
||||
// // const qrcode = (await import('qrcode'));
|
||||
|
||||
const user = req.user;
|
||||
let res;
|
||||
// For security, we no longer show the QR code after is verified
|
||||
// if (user.mfaEnabled) return res.status(404).end();
|
||||
// const user = req.user;
|
||||
// let res;
|
||||
// // For security, we no longer show the QR code after is verified
|
||||
// // if (user.mfaEnabled) return res.status(404).end();
|
||||
|
||||
// if (!user.mfaSecret) { //to do
|
||||
const buffer = nanoid(14);
|
||||
// generate unique secret for user
|
||||
// this secret will be used to check the verification code sent by user
|
||||
// const buffer = await util.promisify(crypto.randomBytes)(14);
|
||||
// const buffer = crypto.lib.WordArray.random(32)
|
||||
user.mfaSecret = encode(buffer).toString('utf8');
|
||||
// user.mfaSecret = base32Encoded(buffer, 'RFC4648', { padding: false });
|
||||
// // if (!user.mfaSecret) { //to do
|
||||
// const buffer = nanoid(14);
|
||||
// // generate unique secret for user
|
||||
// // this secret will be used to check the verification code sent by user
|
||||
// // const buffer = await util.promisify(crypto.randomBytes)(14);
|
||||
// // const buffer = crypto.lib.WordArray.random(32)
|
||||
// user.mfaSecret = encode(buffer).toString('utf8');
|
||||
// // user.mfaSecret = base32Encoded(buffer, 'RFC4648', { padding: false });
|
||||
|
||||
// setUser(user); // to do !!
|
||||
// // setUser(user); // to do !!
|
||||
|
||||
|
||||
// }
|
||||
// // }
|
||||
|
||||
const issuer = 'Google';
|
||||
const algorithm = 'SHA1';
|
||||
const digits = '6';
|
||||
const period = '30';
|
||||
const otpType = 'totp';
|
||||
const configUri = `otpauth://${otpType}/${issuer}:${user.username}?algorithm=${algorithm}&digits=${digits}&period=${period}&issuer=${issuer}&secret=${user.mfaSecret}`;
|
||||
// const issuer = 'Google';
|
||||
// const algorithm = 'SHA1';
|
||||
// const digits = '6';
|
||||
// const period = '30';
|
||||
// const otpType = 'totp';
|
||||
// const configUri = `otpauth://${otpType}/${issuer}:${user.username}?algorithm=${algorithm}&digits=${digits}&period=${period}&issuer=${issuer}&secret=${user.mfaSecret}`;
|
||||
|
||||
// res.setHeader('Content-Type', 'image/png');
|
||||
const QRCode = require('qrcode');
|
||||
console.log(`before done`);
|
||||
// QRCode.toFileStream(res, configUri);
|
||||
// const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
|
||||
// // res.setHeader('Content-Type', 'image/png');
|
||||
// const QRCode = require('qrcode');
|
||||
// console.log(`before done`);
|
||||
// // QRCode.toFileStream(res, configUri);
|
||||
// // 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 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 filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
|
||||
|
||||
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, 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) {
|
||||
// console.error(error);
|
||||
// // Handle the error appropriately
|
||||
// return;
|
||||
// }
|
||||
// const readableStream = fs.createReadStream(filePath);
|
||||
// res.data = readableStream;
|
||||
// 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);
|
||||
console.log(`QRcode done`);
|
||||
return res;
|
||||
// return
|
||||
}
|
||||
// // qrcode.toFileStream(res, configUri);
|
||||
// console.log(`QRcode done`);
|
||||
// return res;
|
||||
// // 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/websockets": "^9.4.0",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.1.4",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rxjs": "^7.2.0",
|
||||
"socket.io-client": "^4.6.1",
|
||||
@ -3398,6 +3399,17 @@
|
||||
"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": {
|
||||
"version": "1.1.1",
|
||||
"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/websockets": "^9.4.0",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.1.4",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rxjs": "^7.2.0",
|
||||
"socket.io-client": "^4.6.1",
|
||||
|
||||
@ -3,6 +3,10 @@ import { AppModule } from './app.module';
|
||||
import * as cors from 'cors';
|
||||
import { Server } from 'socket.io';
|
||||
import * as socketio from 'socket.io';
|
||||
import * as dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
console.log(process.env);
|
||||
|
||||
async function bootstrap() {
|
||||
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();
|
||||
|
||||
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/websockets": "^9.4.0",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.1.4",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rxjs": "^7.2.0",
|
||||
"socket.io-client": "^4.6.1",
|
||||
@ -3398,6 +3399,17 @@
|
||||
"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": {
|
||||
"version": "1.1.1",
|
||||
"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/websockets": "^9.4.0",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.1.4",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rxjs": "^7.2.0",
|
||||
"socket.io-client": "^4.6.1",
|
||||
|
||||
@ -21,6 +21,10 @@ import { AppModule } from './app.module';
|
||||
import * as cors from 'cors';
|
||||
import { Server } from 'socket.io';
|
||||
import * as socketio from 'socket.io';
|
||||
import * as dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
console.log(process.env);
|
||||
|
||||
async function bootstrap() {
|
||||
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();
|
||||
@ -68,11 +68,19 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
|
||||
// }
|
||||
// // 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')
|
||||
addMatchmaking(client: Socket, payload: any): void {
|
||||
console.log("matchmaking");
|
||||
console.log(payload);
|
||||
console.log(`option= ${payload.option}`);
|
||||
// Add the client to the waitingClients set along with their chosen option
|
||||
this.waitingClients.add({ client, option: payload.option });
|
||||
console.log("Adding client to waiting list...");
|
||||
@ -147,6 +155,21 @@ addMatchmaking(client: Socket, payload: any): void {
|
||||
// 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')
|
||||
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 {Routes, Route} from 'react-router-dom';
|
||||
import {Routes, Route, Navigate} from 'react-router-dom';
|
||||
import HomeLogin from "../pages/Home.js";
|
||||
|
||||
import Home from "../pages/Home.jsx";
|
||||
@ -17,15 +17,32 @@ import SuccessToken from '../script/tokenSuccess'
|
||||
import DoubleAuth from "../pages/2fa.js";
|
||||
import Game from "../pages/Game.jsx";
|
||||
import Social from "../components/Social/Social.jsx";
|
||||
import PageNotFound from "../components/404.jsx";
|
||||
import Logout from "../components/Profile/Logout.jsx";
|
||||
|
||||
function AnimatedRoute () {
|
||||
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 (
|
||||
<AnimatePresence>
|
||||
<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/:username" element={<Home/>}/>
|
||||
|
||||
@ -41,6 +58,9 @@ function AnimatedRoute () {
|
||||
<Route exact path="/login42" element={<Login42 />}/>
|
||||
<Route exact path="/logout" element={<Logout />}/>
|
||||
<Route exact path="/messages" element={<Messages />}/>
|
||||
|
||||
<Route path="/404" element={<PageNotFound />} />
|
||||
<Route path="*" element={<Navigate to="/404" />} />
|
||||
</Routes>
|
||||
</AnimatePresence>
|
||||
)
|
||||
|
||||
@ -6,10 +6,33 @@ function PlayButton() {
|
||||
|
||||
const history = useNavigate();
|
||||
|
||||
// const handleButtonClick = () => {
|
||||
// let path = `play`;
|
||||
// history(path);
|
||||
// };
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="notClicked" id="canvas_container">
|
||||
|
||||
@ -1,13 +1,9 @@
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import {AiOutlineMenuUnfold} from 'react-icons/ai';
|
||||
// import * as AiIcons from 'react-icons/ai';
|
||||
import {Link} from 'react-router-dom';
|
||||
// import { SidebarData } from './Sidebar/SidebarData';
|
||||
import DefaultPicture from '../assets/profile.jpg'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
import Modal from './Sidebar/Modal';
|
||||
// import {BiLogOutCircle} from 'react-icons/bi';
|
||||
// import AnimatePresence from
|
||||
import '../styles/Header.css';
|
||||
|
||||
import api from '../script/axiosApi';
|
||||
@ -32,8 +28,8 @@ function Header() {
|
||||
console.error('Error fetching profile picture:', error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchProfilePicture();
|
||||
if (localStorage.getItem('token'))
|
||||
fetchProfilePicture();
|
||||
}, []);
|
||||
|
||||
// console.log(`profile pic= ${profilePicture}`)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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();
|
||||
})
|
||||
|
||||
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) => {
|
||||
let path = `http://localhost/profile/${user.username}`;
|
||||
@ -79,10 +58,12 @@ export default function Friend({currentUser})
|
||||
|
||||
const Accept = (user) => {
|
||||
console.log("accept")
|
||||
console.log(`request = ${request}`)
|
||||
}
|
||||
|
||||
const Refuse = (user) => {
|
||||
console.log("refuse")
|
||||
console.log(`request = ${request}`)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@ -1,13 +1,48 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useLocation } 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 { useParams } from "react-router-dom";
|
||||
|
||||
// import { withRouter } from 'react-router-dom';
|
||||
|
||||
function Field()
|
||||
{
|
||||
useEffect(() => {
|
||||
// const location = useLocation();
|
||||
const queryParams = queryString.parse(window.location.search);
|
||||
|
||||
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);
|
||||
@ -28,6 +63,7 @@ function Field()
|
||||
}
|
||||
|
||||
export default Field;
|
||||
// export default withRouter(Field);
|
||||
|
||||
|
||||
// function Field() {
|
||||
|
||||
@ -2,19 +2,44 @@
|
||||
|
||||
import api from '../script/axiosApi';
|
||||
|
||||
// import { useEffect } from 'react';
|
||||
// import { useEffect, useRef } from 'react';
|
||||
import io from 'socket.io-client';
|
||||
// const socket = io('http://192.168.1.14:4000');
|
||||
// const socket = io('http://86.209.110.20: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()
|
||||
// const socket = socketRef.current
|
||||
console.log("start function");
|
||||
const canvas = document.getElementById('myCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// useEffect(() => {
|
||||
// console.log("useeffect?????????????????")
|
||||
// return () => {
|
||||
// console.log("000000000000000000000000000000000")
|
||||
// socketRef.current.disconnect();
|
||||
// };
|
||||
// }, []);
|
||||
|
||||
|
||||
//========================================================================================================
|
||||
//========================================================================================================
|
||||
// Var Declaration
|
||||
@ -28,6 +53,7 @@ export function drawCanvas() {
|
||||
let opRank;
|
||||
|
||||
//general canvas
|
||||
let running = true;
|
||||
const scale = window.devicePixelRatio;
|
||||
canvas.width = canvas.offsetWidth;
|
||||
// canvas.height = canvas.width * 0.7
|
||||
@ -39,8 +65,9 @@ export function drawCanvas() {
|
||||
let paddleY = canvas.height / 2 - (paddleHeight / 2);
|
||||
let paddleX = canvas.width / 40;
|
||||
let paddleSpeed = canvas.height / 40;
|
||||
|
||||
|
||||
//opponent var
|
||||
let opPaddleHeight = canvas.height * 0.25;
|
||||
let oPaddleY = paddleY;
|
||||
|
||||
//mouse and touch
|
||||
@ -81,6 +108,7 @@ export function drawCanvas() {
|
||||
console.log(`id ion matcj= ${myId}`)
|
||||
const info = {
|
||||
id: myId,
|
||||
option: option,
|
||||
};
|
||||
socket.emit('pong:matchmaking', info);
|
||||
}
|
||||
@ -165,6 +193,27 @@ export function drawCanvas() {
|
||||
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()
|
||||
{
|
||||
if (gameId === 0)
|
||||
@ -183,11 +232,6 @@ export function drawCanvas() {
|
||||
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()
|
||||
{
|
||||
if (gameId === 0)
|
||||
@ -229,6 +273,17 @@ export function drawCanvas() {
|
||||
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()
|
||||
{
|
||||
if (gameId === 0)
|
||||
@ -275,7 +330,7 @@ export function drawCanvas() {
|
||||
function drawPaddle() {
|
||||
ctx.fillStyle = 'white';
|
||||
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()
|
||||
@ -287,7 +342,7 @@ export function drawCanvas() {
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//========================================================================================================
|
||||
//========================================================================================================
|
||||
// Loop
|
||||
@ -298,9 +353,18 @@ matchmaking();
|
||||
// while (!gameId)
|
||||
// ;
|
||||
|
||||
// Define a function to stop the drawing process
|
||||
const stopDrawCanvas = () => {
|
||||
running = false;
|
||||
// Perform any necessary cleanup tasks
|
||||
// ...
|
||||
};
|
||||
|
||||
function draw(timestamp)
|
||||
{
|
||||
console.log("send loose");
|
||||
if (!running)
|
||||
return ;
|
||||
if (gameId === 0 )
|
||||
{
|
||||
requestAnimationFrame(draw);
|
||||
@ -333,7 +397,7 @@ function draw(timestamp)
|
||||
const deltaTime = timestamp - lastUpdateTime;
|
||||
lastUpdateTime = timestamp;
|
||||
ballX += vX * deltaTime * canvas.width;
|
||||
ballY += vY * deltaTime * canvas.width;
|
||||
ballY += vY * deltaTime * canvas.height;
|
||||
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
drawPaddle();
|
||||
@ -343,7 +407,8 @@ function draw(timestamp)
|
||||
is_out();
|
||||
requestAnimationFrame(draw);
|
||||
}
|
||||
requestAnimationFrame(draw);
|
||||
|
||||
|
||||
|
||||
//========================================================================================================
|
||||
//========================================================================================================
|
||||
@ -360,6 +425,13 @@ requestAnimationFrame(draw);
|
||||
vY = vX * Math.sin(-bounceAngle);
|
||||
if (vX < 0)
|
||||
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 ()
|
||||
vY = -vY;
|
||||
if (ballY > (canvas.height / 2))//down wall
|
||||
ballY = canvas.height - ballRadius - 2
|
||||
else
|
||||
ballY = ballRadius + 2
|
||||
// send_info();
|
||||
}
|
||||
// else if (ballX + ballRadius + 2 >= canvas.width) //touch right wall
|
||||
@ -416,6 +493,24 @@ requestAnimationFrame(draw);
|
||||
send_point();
|
||||
// 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")
|
||||
{
|
||||
if (!superpowerModifier)
|
||||
return ;
|
||||
paddleY = 0;
|
||||
paddleHeight = canvas.height;
|
||||
use_power();
|
||||
setTimeout(() => {
|
||||
// code à exécuter après 5 secondes
|
||||
paddleHeight = canvas.height * 0.25;
|
||||
@ -521,4 +619,9 @@ requestAnimationFrame(draw);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
requestAnimationFrame(draw);
|
||||
console.log("retuuuuuuuuuuurn")
|
||||
return (stopDrawCanvas);
|
||||
}
|
||||
|
||||
export default DrawCanvas
|
||||
@ -13,7 +13,7 @@ console.log(`getToken = ${getToken()}`)
|
||||
console.log(`Bearer ${localStorage.getItem("token")}`)
|
||||
|
||||
let api = axios.create({
|
||||
baseURL: 'http://localhost/api',
|
||||
baseURL: 'http://localhost/api',
|
||||
headers: {
|
||||
// Authorization: `Bearer ${getToken()}`,
|
||||
Authorization : `Bearer ${localStorage.getItem("token")}`
|
||||
|
||||
@ -8,14 +8,25 @@ services:
|
||||
env_file: .env
|
||||
depends_on:
|
||||
- api
|
||||
|
||||
# command: sh -c "envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
|
||||
ports:
|
||||
- 80:80
|
||||
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
|
||||
networks:
|
||||
- pongNetwork
|
||||
|
||||
|
||||
|
||||
react_app:
|
||||
image: node:latest
|
||||
container_name: react_app
|
||||
@ -48,6 +59,7 @@ services:
|
||||
entrypoint: ["sh", "-c" , "npm install && npm run start:dev"]
|
||||
|
||||
postgresql:
|
||||
env_file: .env
|
||||
image: postgres:14.1-alpine
|
||||
restart: unless-stopped
|
||||
container_name: postgresql
|
||||
|
||||
Loading…
Reference in New Issue
Block a user