Merge branch 'sadjigui'

This commit is contained in:
kinou-p 2023-06-06 14:04:47 +02:00
commit 586e138918
183 changed files with 37260 additions and 1313 deletions

View File

@ -3,10 +3,10 @@
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: apommier <apommier@student.42.fr> +#+ +:+ +#+ #
# By: sadjigui <sadjigui@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2023/03/19 09:29:27 by apommier #+# #+# #
# Updated: 2023/05/10 13:37:27 by apommier ### ########.fr #
# Updated: 2023/05/26 17:43:56 by sadjigui ### ########.fr #
# #
# **************************************************************************** #

25
backend/.eslintrc.js Normal file
View File

@ -0,0 +1,25 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};

35
backend/.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
# compiled output
/dist
/node_modules
# Logs
logs
*.log
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# OS
.DS_Store
# Tests
/coverage
/.nyc_output
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

4
backend/.prettierrc Normal file
View File

@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}

73
backend/README.md Normal file
View File

@ -0,0 +1,73 @@
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="200" alt="Nest Logo" /></a>
</p>
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
```
## Running the app
```bash
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
```
## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).

8
backend/nest-cli.json Normal file
View File

@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true
}
}

View File

@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});

View File

@ -0,0 +1,61 @@
import { Body, Controller, Get, Param, Post, Query, InternalServerErrorException } from '@nestjs/common';
// import { AppService } from './app.service.js';
import { UsersService } from './app.service';
import { User } from './model/item.entity';
// import { HttpService } from '@nestjs/common';
// import { HttpService } from '@nestjs/axios'
import axios from 'axios';
import { AxiosResponse } from 'axios';
@Controller()
export class AppController2 {
constructor(private readonly usersService: UsersService) {}
@Get()
getHello(): string {
return this.usersService.getHello();
}
}
@Controller('api')
export class AppController
{
constructor(private readonly usersService: UsersService) {}
@Post('token')
async getToken(@Body('code') code: string): Promise<any>
{
const http = axios;
console.log(`here is the code= ${code}`);
const data = {
grant_type: 'authorization_code',
client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41',
client_secret: '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',
code: code,
redirect_uri: 'http://localhost:8080/login42',
};
try {
const response: AxiosResponse = await http.post('https://api.intra.42.fr/oauth/token', data);
// console.log(`response= ${response}`);
return response;
}
catch (error)
{
console.error(error);
throw new InternalServerErrorException('Failed to get access token');
}
}
@Post('login')
async create(@Body() user: User)
{
return this.usersService.create(user);
}
@Get('user/:id')
async getUser(@Param('id') id: number)
{
return this.usersService.findOne(id);
}
}

30
backend/src/app.module.ts Normal file
View File

@ -0,0 +1,30 @@
// import { Module } from '@nestjs/common';
// import { AppController } from './app.controller';
// import { AppService } from './app.service';
// @Module({
// imports: [],
// controllers: [AppController],
// providers: [AppService],
// })
// export class AppModule {}
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService, UsersService } from './app.service';
import { User } from './model/item.entity';
import { TypeOrmModule } from '@nestjs/typeorm';
import { getTypeOrmConfig } from './config/config.service';
@Module({
imports: [
TypeOrmModule.forRoot(getTypeOrmConfig()),
TypeOrmModule.forFeature([User]),
// TypeOrmModule.forFeature([UserRepository]),
],
controllers: [AppController],
providers: [AppService, UsersService],
})
export class AppModule { }

View File

@ -0,0 +1,46 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './model/item.entity';
// import { User } from './entity/user.entity';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User) private userRepository: Repository<User>,
) {}
// constructor(
// @InjectRepository(User)
// private usersRepository: Repository<User>,
// ) {}
// constructor(
// @InjectRepository(User)
// private usersRepository: Repository<User>,
// ) {}
// constructor(private usersRepository: Repository<User>) {}
getHello(): string {
return 'Hello World!';
}
async create(user: User): Promise<User> {
return await this.userRepository.save(user);
}
async findAll(): Promise<User[]> {
return await this.userRepository.find();
}
async findOne(id: number): Promise<User> {
return await this.userRepository.findOneBy({id: id});
}
}

View File

@ -0,0 +1,26 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* config.service.ts :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/09 14:53:49 by apommier #+# #+# */
/* Updated: 2023/04/09 14:55:40 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
export const getTypeOrmConfig = (): TypeOrmModuleOptions => ({
type: 'postgres',
host: 'postgresql',
port: 5432,
username: 'postgres',
password: 'pass',
database: 'postgres',
entities: ['**/*.entity{.ts,.js}'],
migrationsTableName: 'migration',
migrations: ['src/migration/*.ts'],
ssl: process.env.MODE !== 'DEV',
synchronize: true,
});

17
backend/src/main.ts Normal file
View File

@ -0,0 +1,17 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
cors: {
origin: '*',
methods: '*',
// preflightContinue: false,
// optionsSuccessStatus: 204,
// credentials: true,
allowedHeaders: '*',
},
});
await app.listen(3000);
}
bootstrap();

View File

@ -0,0 +1,83 @@
// // import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
// import {Entity, PrimaryGeneratedColumn, Column} from 'typeorm';
// @Entity()
// export class User {
// @PrimaryGeneratedColumn()
// id: number;
// @Column()
// nickName: string;
// @Column()
// Password: string;
// @Column()
// email: string;
// @Column()
// password: string;
// @Column()
// win: number;
// @Column()
// loose: number;
// // friend
// // joined chat
// // jsp
// // prout
// }
// base.entity.ts
// @PrimaryGeneratedColumn('uuid')
// id: string;
// @Column({ type: 'boolean', default: true })
// isActive: boolean;
// @Column({ type: 'boolean', default: false })
// isArchived: boolean;
// @CreateDateColumn({ type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
// createDateTime: Date;
// @Column({ type: 'varchar', length: 300 })
// createdBy: string;
// @UpdateDateColumn({ type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
// lastChangedDateTime: Date;
// @Column({ type: 'varchar', length: 300 })
// lastChangedBy: string;
// @Column({ type: 'varchar', length: 300, nullable: true })
// internalComment: string | null;
import { PrimaryGeneratedColumn, Column, UpdateDateColumn, CreateDateColumn } from 'typeorm';
export abstract class BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ nullable: true })
nickname: string;
@Column({ nullable: true })
password: string;
@Column({ nullable: true })
email: string;
// @Column({ nullable: true })
// password: string;
@Column({ default: 0 })
win: number;
@Column({ default: 0 })
loose: number;
@Column({ default: 0 })
rank: number;
}

View File

@ -0,0 +1,13 @@
// item.entity.ts
import { Entity, Column } from 'typeorm';
import { BaseEntity } from './base.entity';
@Entity({ name: 'User' })
export class User extends BaseEntity {
@Column({ type: 'varchar', length: 300 , nullable: true})
name: string;
@Column({ type: 'varchar', length: 300 , nullable: true})
description: string;
}

View File

@ -0,0 +1,24 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});

View File

@ -0,0 +1,9 @@
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}

View File

@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}

21
backend/tsconfig.json Normal file
View File

@ -0,0 +1,21 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
}
}

25
chat/.eslintrc.js Normal file
View File

@ -0,0 +1,25 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};

35
chat/.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
# compiled output
/dist
/node_modules
# Logs
logs
*.log
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# OS
.DS_Store
# Tests
/coverage
/.nyc_output
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

4
chat/.prettierrc Normal file
View File

@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}

73
chat/README.md Normal file
View File

@ -0,0 +1,73 @@
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="200" alt="Nest Logo" /></a>
</p>
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
```
## Running the app
```bash
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
```
## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).

8
chat/nest-cli.json Normal file
View File

@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true
}
}

8353
chat/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

72
chat/package.json Normal file
View File

@ -0,0 +1,72 @@
{
"name": "chat",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/websockets": "^9.4.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.2.0",
"socket.io": "^4.6.1",
"uuid": "^9.0.0"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@types/express": "^4.17.13",
"@types/jest": "29.5.0",
"@types/node": "18.15.11",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "29.5.0",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "29.0.5",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.2.0",
"typescript": "^4.7.4"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}

View File

@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});

View File

@ -0,0 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}

11
chat/src/app.module.ts Normal file
View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ChatGateway } from './chat/chat.gateway';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService, ChatGateway],
})
export class AppModule {}

8
chat/src/app.service.ts Normal file
View File

@ -0,0 +1,8 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}

View File

@ -0,0 +1,19 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ChatGateway } from './chat.gateway';
describe('ChatGateway', () => {
let gateway: ChatGateway;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ChatGateway],
}).compile();
gateway = module.get<ChatGateway>(ChatGateway);
});
it('should be defined', () => {
expect(gateway).toBeDefined();
});
});
4

View File

@ -0,0 +1,45 @@
import { SubscribeMessage, WebSocketGateway, OnGatewayInit, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { v4 as uuidv4 } from 'uuid';
@WebSocketGateway({ cors: true })
export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
private clients: Record<string, Socket> = {};
afterInit(server: Server)
{
console.log('ChatGateway initialized');
}
handleConnection(client: Socket, ...args: any[])
{
console.log(`Client connected: ${client.id}`);
const clientId = uuidv4();
this.clients[clientId] = client;
client.emit('chat:clientId', clientId);
console.log(`Total connected clients: ${Object.keys(this.clients).length}`);
}
handleDisconnect(client: Socket)
{
console.log(`Client disconnected: ${client.id}`);
const disconnectedClientId = Object.keys(this.clients).find(clientId => this.clients[clientId] === client);
if (disconnectedClientId)
{
delete this.clients[disconnectedClientId];
console.log(`Client disconnected: ${disconnectedClientId}`);
console.log(`Total connected clients: ${Object.keys(this.clients).length}`);
}
}
@SubscribeMessage('message')
handleMessage(client: any, payload: any): string {
return 'Hello world!';
}
}

36
chat/src/main.ts Normal file
View File

@ -0,0 +1,36 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as socketio from 'socket.io';
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
cors:
{
origin: '*',
methods: '*',
allowedHeaders: '*',
},
});
const httpServer = app.getHttpServer();
const io = new socketio.Server(httpServer);
io.on('connection', (socket) => {
console.log('Client connected:', socket.id);
// Gestion des événements personnalisés ici
socket.on('customEvent', (data) => {
console.log('Custom event received:', data);
// Exemple de réponse à un événement personnalisé
socket.emit('customEventResponse', { message: 'Event processed.' });
});
socket.on('disconnect', () => {
console.log('Client disconnected:', socket.id);
});
});
await app.listen(4001);
}
bootstrap();

24
chat/test/app.e2e-spec.ts Normal file
View File

@ -0,0 +1,24 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});

9
chat/test/jest-e2e.json Normal file
View File

@ -0,0 +1,9 @@
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}

4
chat/tsconfig.build.json Normal file
View File

@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}

21
chat/tsconfig.json Normal file
View File

@ -0,0 +1,21 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
}
}

View File

@ -16,13 +16,19 @@
"@nestjs/platform-express": "^9.0.0",
"@nestjs/typeorm": "^9.0.1",
"axios": "^1.4.0",
"base32-decode": "^1.0.0",
"base32-encode": "^2.0.0",
"express-session": "^1.17.3",
"hi-base32": "^0.5.1",
"nanoid": "^3.3.4",
"passport": "^0.6.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"pg": "^8.10.0",
"qrcode": "^1.5.3",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1",
"thirty-two": "^1.0.2",
"typeorm": "^0.3.15",
"webpack": "^5.82.0"
},
@ -3065,6 +3071,22 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/base32-decode": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/base32-decode/-/base32-decode-1.0.0.tgz",
"integrity": "sha512-KNWUX/R7wKenwE/G/qFMzGScOgVntOmbE27vvc6GrniDGYb6a5+qWcuoXl8WIOQL7q0TpK7nZDm1Y04Yi3Yn5g=="
},
"node_modules/base32-encode": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base32-encode/-/base32-encode-2.0.0.tgz",
"integrity": "sha512-mlmkfc2WqdDtMl/id4qm3A7RjW6jxcbAoMjdRmsPiwQP0ufD4oXItYMnPgVHe80lnAIy+1xwzhHE1s4FoIceSw==",
"dependencies": {
"to-data-view": "^2.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@ -3310,7 +3332,6 @@
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true,
"engines": {
"node": ">=6"
}
@ -3741,6 +3762,14 @@
}
}
},
"node_modules/decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/dedent": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
@ -3836,6 +3865,11 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/dijkstrajs": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
},
"node_modules/dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@ -3903,6 +3937,11 @@
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/encode-utf8": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz",
"integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
},
"node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -4919,6 +4958,11 @@
"node": ">=8"
}
},
"node_modules/hi-base32": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz",
"integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA=="
},
"node_modules/highlight.js": {
"version": "10.7.3",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
@ -6421,6 +6465,17 @@
"thenify-all": "^1.0.0"
}
},
"node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@ -6669,7 +6724,6 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true,
"engines": {
"node": ">=6"
}
@ -6784,7 +6838,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -7039,6 +7092,14 @@
"node": ">=4"
}
},
"node_modules/pngjs": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
@ -7205,6 +7266,132 @@
}
]
},
"node_modules/qrcode": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz",
"integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
"dependencies": {
"dijkstrajs": "^1.0.1",
"encode-utf8": "^1.0.3",
"pngjs": "^5.0.0",
"yargs": "^15.3.1"
},
"bin": {
"qrcode": "bin/qrcode"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/qrcode/node_modules/cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"node_modules/qrcode/node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/qrcode/node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/qrcode/node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/qrcode/node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/qrcode/node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/qrcode/node_modules/y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
},
"node_modules/qrcode/node_modules/yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"dependencies": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/qrcode/node_modules/yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"dependencies": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
@ -7356,6 +7543,11 @@
"node": ">=0.10.0"
}
},
"node_modules/require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"node_modules/resolve": {
"version": "1.22.2",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
@ -7669,6 +7861,11 @@
"node": ">= 0.8.0"
}
},
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@ -8118,6 +8315,14 @@
"node": ">=0.8"
}
},
"node_modules/thirty-two": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz",
"integrity": "sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==",
"engines": {
"node": ">=0.2.6"
}
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@ -8142,6 +8347,14 @@
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
"dev": true
},
"node_modules/to-data-view": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-2.0.0.tgz",
"integrity": "sha512-RGEM5KqlPHr+WVTPmGNAXNeFEmsBnlkxXaIfEpUYV0AST2Z5W1EGq9L/MENFrMMmL2WQr1wjkmZy/M92eKhjYA==",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@ -8855,6 +9068,11 @@
"node": ">= 8"
}
},
"node_modules/which-module": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
},
"node_modules/windows-release": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz",

View File

@ -27,13 +27,19 @@
"@nestjs/platform-express": "^9.0.0",
"@nestjs/typeorm": "^9.0.1",
"axios": "^1.4.0",
"base32-decode": "^1.0.0",
"base32-encode": "^2.0.0",
"express-session": "^1.17.3",
"hi-base32": "^0.5.1",
"nanoid": "^3.3.4",
"passport": "^0.6.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"pg": "^8.10.0",
"qrcode": "^1.5.3",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1",
"thirty-two": "^1.0.2",
"typeorm": "^0.3.15",
"webpack": "^5.82.0"
},

View File

@ -7,6 +7,10 @@ import { ChatService } from './chat/chat.service';
import { UsersService } from './users/users.service';
import { MatchLog } from './model/user.entity'
import { generate } from 'rxjs';
import { generateQRcode } from './users/2fa';
// import { initStorage, getUser, setUser } from './storage';
// import { AuthGuard } from '@nestjs/passport';
// import { Login42 } from './auth/login42'
@ -49,6 +53,12 @@ export class AppController {
return req.user;
}
@UseGuards(JwtAuthGuard)
@Get('/user')
async getUser( @Body() data: any) {
return await this.userService.findOne(data.username);
}
@UseGuards(JwtAuthGuard)
@Post('/win')
async addWin(@Request() req, @Body() data: any) {
@ -100,6 +110,22 @@ export class AppController {
return user.rank;
}
@UseGuards(JwtAuthGuard)
@Get('/2fa')
async get2fa(@Request() req)
{
const user = await this.userService.findOne(req.user.username);
return user.doubleAuth;
}
@UseGuards(JwtAuthGuard)
@Get('/QRcode')
async createQrCode(@Request() req)
{
return (await generateQRcode(req));
}
@UseGuards(JwtAuthGuard)
@Post('/quit')
async setOffline(@Request() req) {
@ -111,9 +137,67 @@ export class AppController {
console.log("User quit");
}
// @Get('/chat')
// async Chat(@Res() res) {
// const messages = await this.chatService.getMessages();
@Post('/conv')
async createConv(@Request() req, @Body() data: any) {
///create conv and return it ? id?
console.log(`data post /conv= ${data}`);
// let test = {id: 2, members: "cc"};
return await this.chatService.createConv(data);
// res.json(messages);
// }
}
// @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);
}
// @UseGuards(JwtAuthGuard)
@Post('/message')
async postMessage(@Request() req, @Body() data: any) {
//if i can post post ?
let message =
{
convid: data.convId,
sender: data.sender,
text: data.text,
// createdAt: null,
id: null,
}
console.log(data);
return await this.chatService.createMessage(message);
}
@Post('/member')
async getMember(@Body() data: any) {
console.log(data);
console.log(`get member= ${data.convId}`);
return await this.chatService.findConv(data.convId);
}
@Post('/getMessage')
async getMessage(@Body() data: any) {
console.log(data);
// console.log(req.query)
console.log(`data get /conv= ${data.convId}`);
// let test = {id: 2, members: "cc"};
return await this.chatService.getMessages(data.convId);
// return await this.chatService.getConv(req.user.username);
// res.json(messages);
}
}

View File

@ -19,7 +19,7 @@ export class AuthService {
return null;
}
async login(user: any) {
async login(user) {
const myJSON = JSON.stringify(user);
// console.log(`in login all user= ${myJSON}`)
// console.log(`in login user= ${user.username}`)

View File

@ -66,6 +66,7 @@ export class loginClass {
userId: userId,
children: null,
status: 1,
doubleAuth: 0
};
await this.usersService.create(user);
}

View File

@ -8,13 +8,15 @@ import { ChatService} from './chat.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { getTypeOrmConfig } from '../config/config.service';
import { Chat } from '../model/chat.entity';
import { Conv } from '../model/chat.entity';
import { Message } from '../model/chat.entity';
@Module({
imports:
[
TypeOrmModule.forRoot(getTypeOrmConfig()),
TypeOrmModule.forFeature([Chat]),
TypeOrmModule.forFeature([Conv]),
TypeOrmModule.forFeature([Message]),
// TypeOrmModule.forFeature([UserRepository]),
],
providers:[ChatService],

View File

@ -1,22 +1,99 @@
// import { Injectable } from '@nestjs/common';
// @Injectable()
// export class ChatService {}
// export class ConvService {}
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Chat } from '../model/chat.entity';
import { Conv } from '../model/chat.entity';
import { Message } from '../model/chat.entity';
import { ArrayContains } from "typeorm"
import { query } from 'express';
@Injectable()
export class ChatService {
constructor(@InjectRepository(Chat) private chatRepository: Repository<Chat>,) {}
constructor(@InjectRepository(Conv) private chatRepository: Repository<Conv>,
@InjectRepository(Message) private messageRepository: Repository<Message>,
) {}
async createMessage(chat: Chat): Promise<Chat> {
return await this.chatRepository.save(chat);
async createConv(conv: Conv): Promise<Conv> {
return await this.chatRepository.save(conv);
}
async getMessages(): Promise<Chat[]> {
return await this.chatRepository.find();
// SELECT "conv"."id" AS "conv_id", "conv"."members" AS "conv_members", "conv"."name" AS "conv_name", "conv"."banned" AS "conv_banned", "conv"."admin" AS "conv_admin", "conv"."messages" AS "conv_messages" FROM "conv" "conv" WHERE $1 = ANY("conv"."members")
// import { createConnection } from 'typeorm';
async getConv(username: string): Promise<Conv[]>{
username = "apommier"
const convs = await this.chatRepository.query("SELECT * FROM \"conv\" WHERE $1 = ANY (ARRAY[members]);", [username])
console.log(`convs= ${convs}`)
return convs;
}
async findConv(number: number){
// username = "apommier"
console.log(`fincConv; ${number}`)
const conv = await this.chatRepository.findOneBy({id: number})
return conv;
}
// Usage
// const user = 'user1';
// findConvsContainingUser(user)
// .then((convs) => {
// console.log('Convs containing user:', convs);
// })
// .catch((error) => {
// console.error('Error:', error);
// });
// return await this.chatRepository.findOneBy({
// members: { $in: [username] },
// });
// return await this.chatRepository.find()
// return await this.chatRepository.findOneBy({
// members: ArrayContains(["apommier"]),
// })
// console.log(`get conv username= ${username} `)
// let test = await this.chatRepository.find({
// where : {
// members: { $all: ["apommier"] },
// }})
// console.log(`test= ${test}`)
// return test
// }
//
// message
//
async createMessage(message: Message): Promise<Message> {
return await this.messageRepository.save(message);
}
async getMessages(convId: number): Promise<Message[]> {
// return await this.messageRepository.find({
// where: {
// convId: convId,
// },
// });
const convs = await this.chatRepository
.query("SELECT * FROM \"message\" WHERE $1 = message.convid;", [convId])
return (convs)
}
}

View File

@ -6,11 +6,12 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/09 14:53:49 by apommier #+# #+# */
/* Updated: 2023/05/05 23:11:44 by apommier ### ########.fr */
/* Updated: 2023/06/01 13:07:12 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
export const getTypeOrmConfig = (): TypeOrmModuleOptions => ({
type: 'postgres',
host: 'postgresql',

View File

@ -1,18 +1,35 @@
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, BaseEntity } from 'typeorm';
@Entity()
export class Chat{
@PrimaryGeneratedColumn('uuid')
export class Conv{
@PrimaryGeneratedColumn()
id: number;
@Column()
email: string;
@Column('text', { array: true, nullable: true })
members: string[];
@Column({ nullable: true })
name: string
@Column({ nullable: true })
group: boolean
// @Column()
// members: string;// arry ??? one to many ???
@Column({ nullable: true })
banned: string;// arry ??? one to many ???
@Column({ nullable: true })
admin: string;// arry ??? one to many ???
@Column({ nullable: true })
messages: string;
// @CreateDateColumn()
// createdAt: Date;
@Column({ unique: true })
text: string;
@CreateDateColumn()
createdAt: Date;
//ban user
//user list
@ -21,3 +38,23 @@ import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, BaseEntity }
//a way to stock conv ?
}
@Entity()
export class Message{
@PrimaryGeneratedColumn()
id: number;
@Column({nullable: true})
convid: number;
@Column()
sender: string;
@Column()
text: string;
@CreateDateColumn({ nullable: true })
createdAt?: Date;
}

View File

@ -44,6 +44,9 @@ export class User {
@Column({ default: 0 })
userId: number;
@Column({ default: 0 })
doubleAuth: number;
@OneToMany(() => MatchLog, child => child.parent)
children: MatchLog[];
}

View File

@ -0,0 +1,179 @@
import crypto from 'crypto';
import base32Decode from 'base32-decode';
// import { randomBytes} from 'crypto';
// import { promisify } from 'util';
// 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}`.padStart(6, '0');
// }
// type QRcode = any;
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;
}
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;
}
// import { initStorage, getUser, setUser } from './storage';
// import util from 'util';
// import qrcode from 'qrcode';
// // import base32Encode from 'base32-encode';
// import * as util from 'util';
// import * as qrcode from 'qrcode';
// import * as base32Encode from 'base32-encode';
// import * as util from 'util';
// import * as qrcode from 'qrcode';
// import * as crypto from 'crypto';
// import { Response } from 'express';
// import { Readable } from 'stream';
// import * as base32Encode from 'base32-encode';
// import { base32Encode } from 'base32-encode';
// import base32Encode from 'base32-encode';
import { encode } from 'thirty-two';
// ...
import * as qrcode from 'qrcode';
import * as fs from 'fs';
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'));
// 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();
// 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 !!
// }
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
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, 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
}

View File

@ -1,21 +1,23 @@
{
"name": "chat",
"name": "pong",
"version": "0.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "chat",
"name": "pong",
"version": "0.0.1",
"license": "UNLICENSED",
"dependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/platform-socket.io": "^9.4.0",
"@nestjs/websockets": "^9.4.0",
"cors": "^2.8.5",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.2.0",
"socket.io": "^4.6.1",
"socket.io-client": "^4.6.1",
"uuid": "^9.0.0"
},
"devDependencies": {
@ -1406,199 +1408,6 @@
"node": ">= 12.9.0"
}
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/ast": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
"integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
"dev": true,
"dependencies": {
"@webassemblyjs/helper-numbers": "1.11.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.1"
}
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/floating-point-hex-parser": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
"integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
"dev": true
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/helper-api-error": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
"integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
"dev": true
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/helper-buffer": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
"integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
"dev": true
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/helper-numbers": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
"integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
"dev": true,
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": "1.11.1",
"@webassemblyjs/helper-api-error": "1.11.1",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/helper-wasm-bytecode": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
"integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
"dev": true
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
"integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
"dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/helper-buffer": "1.11.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
"@webassemblyjs/wasm-gen": "1.11.1"
}
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/ieee754": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
"integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
"dev": true,
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/leb128": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
"integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
"dev": true,
"dependencies": {
"@xtuc/long": "4.2.2"
}
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/utf8": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
"integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
"dev": true
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/wasm-edit": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
"integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
"dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/helper-buffer": "1.11.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
"@webassemblyjs/helper-wasm-section": "1.11.1",
"@webassemblyjs/wasm-gen": "1.11.1",
"@webassemblyjs/wasm-opt": "1.11.1",
"@webassemblyjs/wasm-parser": "1.11.1",
"@webassemblyjs/wast-printer": "1.11.1"
}
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/wasm-gen": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
"integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
"dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
"@webassemblyjs/ieee754": "1.11.1",
"@webassemblyjs/leb128": "1.11.1",
"@webassemblyjs/utf8": "1.11.1"
}
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/wasm-opt": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
"integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
"dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/helper-buffer": "1.11.1",
"@webassemblyjs/wasm-gen": "1.11.1",
"@webassemblyjs/wasm-parser": "1.11.1"
}
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/wasm-parser": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
"integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
"dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/helper-api-error": "1.11.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
"@webassemblyjs/ieee754": "1.11.1",
"@webassemblyjs/leb128": "1.11.1",
"@webassemblyjs/utf8": "1.11.1"
}
},
"node_modules/@nestjs/cli/node_modules/@webassemblyjs/wast-printer": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
"integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
"dev": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.1",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@nestjs/cli/node_modules/webpack": {
"version": "5.79.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.79.0.tgz",
"integrity": "sha512-3mN4rR2Xq+INd6NnYuL9RC9GAmc1ROPKJoHhrZ4pAjdMFEkJJWrsPw8o2JjCIyQyTu7rTXYn4VG6OpyB3CobZg==",
"dev": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.0",
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/wasm-edit": "1.11.1",
"@webassemblyjs/wasm-parser": "1.11.1",
"acorn": "^8.7.1",
"acorn-import-assertions": "^1.7.6",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.10.0",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.2.9",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
"schema-utils": "^3.1.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.3.7",
"watchpack": "^2.4.0",
"webpack-sources": "^3.2.3"
},
"bin": {
"webpack": "bin/webpack.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependenciesMeta": {
"webpack-cli": {
"optional": true
}
}
},
"node_modules/@nestjs/common": {
"version": "9.4.0",
"resolved": "https://registry.npmjs.org/@nestjs/common/-/common-9.4.0.tgz",
@ -1688,6 +1497,24 @@
"@nestjs/core": "^9.0.0"
}
},
"node_modules/@nestjs/platform-socket.io": {
"version": "9.4.0",
"resolved": "https://registry.npmjs.org/@nestjs/platform-socket.io/-/platform-socket.io-9.4.0.tgz",
"integrity": "sha512-pk5uWItnsrFKzvQrFcAmyfcb8cpGgoj4yR4+vbA5H/MLcv+8vGqruQO8riN8jAYGNPN9Y02ihBKbIvQqn92M5g==",
"dependencies": {
"socket.io": "4.6.1",
"tslib": "2.5.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/nest"
},
"peerDependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/websockets": "^9.0.0",
"rxjs": "^7.1.0"
}
},
"node_modules/@nestjs/schematics": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-9.1.0.tgz",
@ -2019,9 +1846,9 @@
}
},
"node_modules/@types/estree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
"dev": true
},
"node_modules/@types/express": {
@ -2188,15 +2015,15 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.59.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.0.tgz",
"integrity": "sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==",
"version": "5.58.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.58.0.tgz",
"integrity": "sha512-vxHvLhH0qgBd3/tW6/VccptSfc8FxPQIkmNTVLWcCOVqSBvqpnKkBTYrhcGlXfSnd78azwe+PsjYFj0X34/njA==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.59.0",
"@typescript-eslint/type-utils": "5.59.0",
"@typescript-eslint/utils": "5.59.0",
"@typescript-eslint/scope-manager": "5.58.0",
"@typescript-eslint/type-utils": "5.58.0",
"@typescript-eslint/utils": "5.58.0",
"debug": "^4.3.4",
"grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
@ -2222,14 +2049,14 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "5.59.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.0.tgz",
"integrity": "sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==",
"version": "5.58.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.58.0.tgz",
"integrity": "sha512-ixaM3gRtlfrKzP8N6lRhBbjTow1t6ztfBvQNGuRM8qH1bjFFXIJ35XY+FC0RRBKn3C6cT+7VW1y8tNm7DwPHDQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.59.0",
"@typescript-eslint/types": "5.59.0",
"@typescript-eslint/typescript-estree": "5.59.0",
"@typescript-eslint/scope-manager": "5.58.0",
"@typescript-eslint/types": "5.58.0",
"@typescript-eslint/typescript-estree": "5.58.0",
"debug": "^4.3.4"
},
"engines": {
@ -2249,13 +2076,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "5.59.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.0.tgz",
"integrity": "sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==",
"version": "5.58.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz",
"integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.59.0",
"@typescript-eslint/visitor-keys": "5.59.0"
"@typescript-eslint/types": "5.58.0",
"@typescript-eslint/visitor-keys": "5.58.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -2266,13 +2093,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "5.59.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.0.tgz",
"integrity": "sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==",
"version": "5.58.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.58.0.tgz",
"integrity": "sha512-FF5vP/SKAFJ+LmR9PENql7fQVVgGDOS+dq3j+cKl9iW/9VuZC/8CFmzIP0DLKXfWKpRHawJiG70rVH+xZZbp8w==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "5.59.0",
"@typescript-eslint/utils": "5.59.0",
"@typescript-eslint/typescript-estree": "5.58.0",
"@typescript-eslint/utils": "5.58.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@ -2293,9 +2120,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "5.59.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz",
"integrity": "sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==",
"version": "5.58.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz",
"integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -2306,13 +2133,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.59.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz",
"integrity": "sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==",
"version": "5.58.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz",
"integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.59.0",
"@typescript-eslint/visitor-keys": "5.59.0",
"@typescript-eslint/types": "5.58.0",
"@typescript-eslint/visitor-keys": "5.58.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@ -2333,17 +2160,17 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "5.59.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.0.tgz",
"integrity": "sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==",
"version": "5.58.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.58.0.tgz",
"integrity": "sha512-gAmLOTFXMXOC+zP1fsqm3VceKSBQJNzV385Ok3+yzlavNHZoedajjS4UyS21gabJYcobuigQPs/z71A9MdJFqQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.59.0",
"@typescript-eslint/types": "5.59.0",
"@typescript-eslint/typescript-estree": "5.59.0",
"@typescript-eslint/scope-manager": "5.58.0",
"@typescript-eslint/types": "5.58.0",
"@typescript-eslint/typescript-estree": "5.58.0",
"eslint-scope": "^5.1.1",
"semver": "^7.3.7"
},
@ -2359,12 +2186,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.59.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz",
"integrity": "sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==",
"version": "5.58.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz",
"integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.59.0",
"@typescript-eslint/types": "5.58.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@ -2376,163 +2203,148 @@
}
},
"node_modules/@webassemblyjs/ast": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.5.tgz",
"integrity": "sha512-LHY/GSAZZRpsNQH+/oHqhRQ5FT7eoULcBqgfyTB5nQHogFnK3/7QoN7dLnwSE/JkUAF0SrRuclT7ODqMFtWxxQ==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
"integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/helper-numbers": "1.11.5",
"@webassemblyjs/helper-wasm-bytecode": "1.11.5"
"@webassemblyjs/helper-numbers": "1.11.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.1"
}
},
"node_modules/@webassemblyjs/floating-point-hex-parser": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.5.tgz",
"integrity": "sha512-1j1zTIC5EZOtCplMBG/IEwLtUojtwFVwdyVMbL/hwWqbzlQoJsWCOavrdnLkemwNoC/EOwtUFch3fuo+cbcXYQ==",
"dev": true,
"peer": true
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
"integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
"dev": true
},
"node_modules/@webassemblyjs/helper-api-error": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.5.tgz",
"integrity": "sha512-L65bDPmfpY0+yFrsgz8b6LhXmbbs38OnwDCf6NpnMUYqa+ENfE5Dq9E42ny0qz/PdR0LJyq/T5YijPnU8AXEpA==",
"dev": true,
"peer": true
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
"integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
"dev": true
},
"node_modules/@webassemblyjs/helper-buffer": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.5.tgz",
"integrity": "sha512-fDKo1gstwFFSfacIeH5KfwzjykIE6ldh1iH9Y/8YkAZrhmu4TctqYjSh7t0K2VyDSXOZJ1MLhht/k9IvYGcIxg==",
"dev": true,
"peer": true
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
"integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
"dev": true
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.5.tgz",
"integrity": "sha512-DhykHXM0ZABqfIGYNv93A5KKDw/+ywBFnuWybZZWcuzWHfbp21wUfRkbtz7dMGwGgT4iXjWuhRMA2Mzod6W4WA==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
"integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": "1.11.5",
"@webassemblyjs/helper-api-error": "1.11.5",
"@webassemblyjs/floating-point-hex-parser": "1.11.1",
"@webassemblyjs/helper-api-error": "1.11.1",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/helper-wasm-bytecode": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.5.tgz",
"integrity": "sha512-oC4Qa0bNcqnjAowFn7MPCETQgDYytpsfvz4ujZz63Zu/a/v71HeCAAmZsgZ3YVKec3zSPYytG3/PrRCqbtcAvA==",
"dev": true,
"peer": true
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
"integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
"dev": true
},
"node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.5.tgz",
"integrity": "sha512-uEoThA1LN2NA+K3B9wDo3yKlBfVtC6rh0i4/6hvbz071E8gTNZD/pT0MsBf7MeD6KbApMSkaAK0XeKyOZC7CIA==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
"integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.5",
"@webassemblyjs/helper-buffer": "1.11.5",
"@webassemblyjs/helper-wasm-bytecode": "1.11.5",
"@webassemblyjs/wasm-gen": "1.11.5"
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/helper-buffer": "1.11.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
"@webassemblyjs/wasm-gen": "1.11.1"
}
},
"node_modules/@webassemblyjs/ieee754": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.5.tgz",
"integrity": "sha512-37aGq6qVL8A8oPbPrSGMBcp38YZFXcHfiROflJn9jxSdSMMM5dS5P/9e2/TpaJuhE+wFrbukN2WI6Hw9MH5acg==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
"integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
"dev": true,
"peer": true,
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
},
"node_modules/@webassemblyjs/leb128": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.5.tgz",
"integrity": "sha512-ajqrRSXaTJoPW+xmkfYN6l8VIeNnR4vBOTQO9HzR7IygoCcKWkICbKFbVTNMjMgMREqXEr0+2M6zukzM47ZUfQ==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
"integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
"dev": true,
"peer": true,
"dependencies": {
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/utf8": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.5.tgz",
"integrity": "sha512-WiOhulHKTZU5UPlRl53gHR8OxdGsSOxqfpqWeA2FmcwBMaoEdz6b2x2si3IwC9/fSPLfe8pBMRTHVMk5nlwnFQ==",
"dev": true,
"peer": true
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
"integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
"dev": true
},
"node_modules/@webassemblyjs/wasm-edit": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.5.tgz",
"integrity": "sha512-C0p9D2fAu3Twwqvygvf42iGCQ4av8MFBLiTb+08SZ4cEdwzWx9QeAHDo1E2k+9s/0w1DM40oflJOpkZ8jW4HCQ==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
"integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.5",
"@webassemblyjs/helper-buffer": "1.11.5",
"@webassemblyjs/helper-wasm-bytecode": "1.11.5",
"@webassemblyjs/helper-wasm-section": "1.11.5",
"@webassemblyjs/wasm-gen": "1.11.5",
"@webassemblyjs/wasm-opt": "1.11.5",
"@webassemblyjs/wasm-parser": "1.11.5",
"@webassemblyjs/wast-printer": "1.11.5"
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/helper-buffer": "1.11.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
"@webassemblyjs/helper-wasm-section": "1.11.1",
"@webassemblyjs/wasm-gen": "1.11.1",
"@webassemblyjs/wasm-opt": "1.11.1",
"@webassemblyjs/wasm-parser": "1.11.1",
"@webassemblyjs/wast-printer": "1.11.1"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.5.tgz",
"integrity": "sha512-14vteRlRjxLK9eSyYFvw1K8Vv+iPdZU0Aebk3j6oB8TQiQYuO6hj9s4d7qf6f2HJr2khzvNldAFG13CgdkAIfA==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
"integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.5",
"@webassemblyjs/helper-wasm-bytecode": "1.11.5",
"@webassemblyjs/ieee754": "1.11.5",
"@webassemblyjs/leb128": "1.11.5",
"@webassemblyjs/utf8": "1.11.5"
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
"@webassemblyjs/ieee754": "1.11.1",
"@webassemblyjs/leb128": "1.11.1",
"@webassemblyjs/utf8": "1.11.1"
}
},
"node_modules/@webassemblyjs/wasm-opt": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.5.tgz",
"integrity": "sha512-tcKwlIXstBQgbKy1MlbDMlXaxpucn42eb17H29rawYLxm5+MsEmgPzeCP8B1Cl69hCice8LeKgZpRUAPtqYPgw==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
"integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.5",
"@webassemblyjs/helper-buffer": "1.11.5",
"@webassemblyjs/wasm-gen": "1.11.5",
"@webassemblyjs/wasm-parser": "1.11.5"
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/helper-buffer": "1.11.1",
"@webassemblyjs/wasm-gen": "1.11.1",
"@webassemblyjs/wasm-parser": "1.11.1"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.5.tgz",
"integrity": "sha512-SVXUIwsLQlc8srSD7jejsfTU83g7pIGr2YYNb9oHdtldSxaOhvA5xwvIiWIfcX8PlSakgqMXsLpLfbbJ4cBYew==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
"integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.5",
"@webassemblyjs/helper-api-error": "1.11.5",
"@webassemblyjs/helper-wasm-bytecode": "1.11.5",
"@webassemblyjs/ieee754": "1.11.5",
"@webassemblyjs/leb128": "1.11.5",
"@webassemblyjs/utf8": "1.11.5"
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/helper-api-error": "1.11.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
"@webassemblyjs/ieee754": "1.11.1",
"@webassemblyjs/leb128": "1.11.1",
"@webassemblyjs/utf8": "1.11.1"
}
},
"node_modules/@webassemblyjs/wast-printer": {
"version": "1.11.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.5.tgz",
"integrity": "sha512-f7Pq3wvg3GSPUPzR0F6bmI89Hdb+u9WXrSKc4v+N0aV0q6r42WoF92Jp2jEorBEBRoRNXgjp53nBniDXcqZYPA==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
"integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
"dev": true,
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.5",
"@webassemblyjs/ast": "1.11.1",
"@xtuc/long": "4.2.2"
}
},
@ -3092,9 +2904,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001480",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001480.tgz",
"integrity": "sha512-q7cpoPPvZYgtyC4VaBSN0Bt+PJ4c4EYRf0DrduInOz2SkFpHD5p3LnvEpqBp7UnJn+8x1Ogl1s38saUxe+ihQQ==",
"version": "1.0.30001478",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz",
"integrity": "sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==",
"dev": true,
"funding": [
{
@ -3592,9 +3404,9 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"node_modules/electron-to-chromium": {
"version": "1.4.368",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.368.tgz",
"integrity": "sha512-e2aeCAixCj9M7nJxdB/wDjO6mbYX+lJJxSJCXDzlr5YPGYVofuJwGN9nKg2o6wWInjX6XmxRinn3AeJMK81ltw==",
"version": "1.4.362",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.362.tgz",
"integrity": "sha512-PYzAoScDfUcAwZfJQvr6hK2xXzLsMocj/Wuz6LpW6TZQNVv9TflBSB+UoEPuFujc478BgAxCoCFarcVPmjzsog==",
"dev": true
},
"node_modules/emittery": {
@ -3652,6 +3464,18 @@
"node": ">=10.0.0"
}
},
"node_modules/engine.io-client": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.4.0.tgz",
"integrity": "sha512-GyKPDyoEha+XZ7iEqam49vz6auPnNJ9ZBfy89f+rMMas8AuiMWOZ9PVzu8xb9ZC6rafUqiGHSCfu22ih66E+1g==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.0.3",
"ws": "~8.11.0",
"xmlhttprequest-ssl": "~2.0.0"
}
},
"node_modules/engine.io-parser": {
"version": "5.0.6",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz",
@ -3669,9 +3493,9 @@
}
},
"node_modules/enhanced-resolve": {
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.13.0.tgz",
"integrity": "sha512-eyV8f0y1+bzyfh8xAwW/WTSZpLbjhqc4ne9eGSH4Zo2ejdyiNG9pU6mf9DG8a7+Auk6MFTlNOT4Y2y/9k8GKVg==",
"version": "5.12.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
"integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.4",
@ -6369,9 +6193,9 @@
"dev": true
},
"node_modules/path-scurry": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.7.0.tgz",
"integrity": "sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==",
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz",
"integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==",
"dev": true,
"dependencies": {
"lru-cache": "^9.0.0",
@ -6385,9 +6209,9 @@
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.0.tgz",
"integrity": "sha512-qFXQEwchrZcMVen2uIDceR8Tii6kCJak5rzDStfEM0qA3YLMswaxIEZO0DhIbJ3aqaJiDjt+3crlplOb0tDtKQ==",
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.2.tgz",
"integrity": "sha512-7zYMKApzQ9qQE13xQUzbXVY3p2C5lh+9V+bs8M9fRf1TF59id+8jkljRWtIPfBfNP4yQAol5cqh/e8clxatdXw==",
"dev": true,
"engines": {
"node": "14 || >=16.14"
@ -6984,9 +6808,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/schema-utils": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz",
"integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
"integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
@ -7033,9 +6857,9 @@
"dev": true
},
"node_modules/semver": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
"integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==",
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz",
"integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@ -7230,6 +7054,20 @@
"ws": "~8.11.0"
}
},
"node_modules/socket.io-client": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.6.1.tgz",
"integrity": "sha512-5UswCV6hpaRsNg5kkEHVcbBIXEYoVbMQaHJBXJCyEQ+CiFPV1NIOY0XOFWG4XR4GZcB8Kn6AsRs/9cy9TbqVMQ==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.4.0",
"socket.io-parser": "~4.2.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz",
@ -7483,9 +7321,9 @@
}
},
"node_modules/terser": {
"version": "5.17.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz",
"integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==",
"version": "5.16.9",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.16.9.tgz",
"integrity": "sha512-HPa/FdTB9XGI2H1/keLFZHxl6WNvAI4YalHGtDQTlMnJcoqSab1UwL4l1hGEhs6/GmLHBZIg/YgB++jcbzoOEg==",
"dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.2",
@ -7916,9 +7754,9 @@
}
},
"node_modules/update-browserslist-db": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
"integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
"integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
"dev": true,
"funding": [
{
@ -7928,10 +7766,6 @@
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/browserslist"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"dependencies": {
@ -7939,7 +7773,7 @@
"picocolors": "^1.0.0"
},
"bin": {
"update-browserslist-db": "cli.js"
"browserslist-lint": "cli.js"
},
"peerDependencies": {
"browserslist": ">= 4.21.0"
@ -8046,22 +7880,21 @@
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/webpack": {
"version": "5.80.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.80.0.tgz",
"integrity": "sha512-OIMiq37XK1rWO8mH9ssfFKZsXg4n6klTEDL7S8/HqbAOBBaiy8ABvXvz0dDCXeEF9gqwxSvVk611zFPjS8hJxA==",
"version": "5.79.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.79.0.tgz",
"integrity": "sha512-3mN4rR2Xq+INd6NnYuL9RC9GAmc1ROPKJoHhrZ4pAjdMFEkJJWrsPw8o2JjCIyQyTu7rTXYn4VG6OpyB3CobZg==",
"dev": true,
"peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.0",
"@webassemblyjs/ast": "^1.11.5",
"@webassemblyjs/wasm-edit": "^1.11.5",
"@webassemblyjs/wasm-parser": "^1.11.5",
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/wasm-edit": "1.11.1",
"@webassemblyjs/wasm-parser": "1.11.1",
"acorn": "^8.7.1",
"acorn-import-assertions": "^1.7.6",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.13.0",
"enhanced-resolve": "^5.10.0",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
@ -8071,7 +7904,7 @@
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
"schema-utils": "^3.1.2",
"schema-utils": "^3.1.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.3.7",
"watchpack": "^2.4.0",
@ -8262,6 +8095,14 @@
}
}
},
"node_modules/xmlhttprequest-ssl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

View File

@ -1,5 +1,5 @@
{
"name": "chat",
"name": "pong",
"version": "0.0.1",
"description": "",
"author": "",
@ -23,10 +23,12 @@
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/platform-socket.io": "^9.4.0",
"@nestjs/websockets": "^9.4.0",
"cors": "^2.8.5",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.2.0",
"socket.io": "^4.6.1",
"socket.io-client": "^4.6.1",
"uuid": "^9.0.0"
},
"devDependencies": {

View File

@ -5,7 +5,13 @@ import { v4 as uuidv4 } from 'uuid';
@WebSocketGateway({ cors: true })
export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer()
server: Server;
private clients: Record<string, Socket> = {};
// private clientsNames: Record<string, Socket[]> = {};
private clientsNames: Map<string, string[]> = new Map();
// private games: Map<string, Socket[]> = new Map();// Chat en cours, identifiées par un ID
afterInit(server: Server)
{
@ -15,30 +21,212 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
handleConnection(client: Socket, ...args: any[])
{
console.log(`Client connected: ${client.id}`);
// console.log(`Client connected: ${args[0].username}`);
const clientId = uuidv4();
// const clientId = args[0].username;
const clientId = client.id;
this.clients[clientId] = client;
client.emit('chat:clientId', clientId);
// client.emit('chat:clientId', clientId);
console.log(`Total connected clients: ${Object.keys(this.clients).length}`);
}
handleDisconnect(client: Socket)
{
console.log(`Client disconnected: ${client.id}`);
console.log(`Client want to deco: ${client.id}`);
const disconnectedClientId = Object.keys(this.clients).find(clientId => this.clients[clientId] === client);
// const disconnectedClientId = Object.keys(this.clients).find(clientId => this.clients[clientId] === client);
const disconnectedClientId = client.id
if (disconnectedClientId)
{
this.clientsNames.forEach((clientArray, clientName) =>
{
// clientArray.
console.log(`Clients with name ${clientName}:`);
console.log(`array= ${clientArray}`)
console.log(`lenght= ${clientArray.length}`)
clientArray.forEach((targetClient, index) =>
{
console.log(`index= ${index}`)
console.log(`lenght2= ${clientArray.length}`)
if (targetClient === disconnectedClientId)
{
console.log("find it")
console.log(`target= ${clientArray[index]}`)
// delete this.clientsNames[clientName][index];
if (clientArray.length === 1)
{
console.log("delete true")
this.clientsNames.delete(clientName);
return
}
else
{
const newArray = clientArray.filter(item => item !== targetClient);
this.clientsNames.delete(clientName);
this.clientsNames.set(clientName, newArray);
}
//
// this.clientsNames[clientName].delete(index);
// else
return ;
}
});
});
delete this.clients[disconnectedClientId];
// delete this.clientsNames;
console.log(`Client disconnected: ${disconnectedClientId}`);
console.log(`Total connected clients: ${Object.keys(this.clients).length}`);
}
}
@SubscribeMessage('connection')
connectClient(client: any, payload: any): void {
console.log("connect client")
if (this.clientsNames.has(payload.username)) {
console.log("get it")
const clientArray = this.clientsNames.get(payload.username); // Retrieve the array
clientArray.push(client.id); // Add the new client to the array
} else {
console.log("create")
this.clientsNames.set(payload.username, [client.id]); // Create a new array with the new client as the value
}
// let clientLenght = Object.keys(this.clientsNames[payload.username]).length
// const clientArray = this.clientsNames.get(payload.username)
// let clientLenght = clientArray.
// console.log(`lenght= ${clientLenght}`)
@SubscribeMessage('message')
handleMessage(client: any, payload: any): string {
return 'Hello world!';
// this.clientsNames[payload.username][clientLenght] = this.clients[client.id];
// console.log(`clients: ${Object.keys(this.clientsNames).length}`)
// this.clients[clientId] = client;
//add a new client with socket and name for key
//payload.username
}
// @SubscribeMessage('sendMessage')
// handleMessage(user: any, payload: any): void {
// console.log(`message recceveid: ${payload}`)
// console.log(`message recceveid: ${payload.sender}`)
// console.log(`message recceveid: ${payload.convId}`)
// console.log(`message recceveid: ${payload.members}`)
// console.log(`client id: ${user.id}`)
// this.clientsNames.forEach((clientArray, clientName) => {
// console.log(`Clients with name ${clientName}:`);
// // clientArray.forEach((client) => {
// this.clientsNames[clientName]
// // .forEach(client => {
// // // if(client.id != user.id)
// // // {
// // console.log("send to someone")
// // console.log(client); // Perform actions on each client
// // // clients.emit('message', payload)
// // client.emit('message')
// // // }
// // });
// // .forEach((client) => {
// // if(client.id != user.id)
// // {
// // console.log("send to someone")
// // console.log(client); // Perform actions on each client
// // // clients.emit('message', payload)
// // client.emit('message')
// // }
// });
// };
@SubscribeMessage('sendMessage')
handleMessage(client: Socket, payload: any): void {
// console.log(`message received: ${payload}`);
console.log(`message sender: ${payload.sender}`);
console.log(`client id: ${client.id}`);
console.log(`conversation ID: ${payload.convId}`);
console.log(`members: ${payload.members}`);
this.clientsNames.forEach((clientArray, clientName) =>
{
console.log(` 5Clients with name ${clientName}:`);
if (payload.members.includes(clientName))
{
clientArray.forEach((targetClient, index) =>
{
console.log(`client id: ${client.id}`);
console.log(`target: ${targetClient}`);
console.log(`target id: ${targetClient}`);
if (targetClient && targetClient !== client.id)
{
console.log("Sending to someone");
console.log(`index= ${index}`);
console.log(`target: ${targetClient}`); // Perform actions on each target client
// targetClient.emit('message')
// this.clientsNames[clientName].emit('message')
// this.clientsNames["apommier"].emit('message')
this.clients[targetClient].emit('message', payload)
// console.log(test)
// console.log(test)
// this.clientsNames[clientName][index].emit('message');
// const socket = this.server.sockets.sockets.get(targetClient.id);
// if (socket) {
// socket.emit('message', payload);
// } else {
// console.log(`Socket with ID ${client.id} not found.`);
// }
// targetClient.emit('message', payload);
// targetClient.emit('message', payload);
}
else {
console.log("not sending");
}
});
}
});
}
}
// for (let key in this.clientsNames) {
// if (payload.members.includes(key)) {
// console.log("Key exists in the array");
// // if (key !== payload.sender)
// // {
// for (let key2 in this.clientsNames[key])
// {
// if (client.id !== this.clientsNames[key][key2])
// {
// console.log("send to someone")
// this.clientsNames[key][key2].emit('message', payload)
// }
// }
// // }
// //if member socket different from mine
// //send
// } else {
// console.log("Key does not exist in the array");
// }
//if key is in member
// let socket = this.clients[key];
// console.log("Clé:", key);
// console.log("Socket:", socket);
// }
// payload.convId // conv user instead ?
//find user to send message to
//const res = {
//convId: payload.convId
//sender: payload.sender
// }
//while (user of conv)//how to get conv user
// if (user connected)
//send res to user
// }

View File

@ -1,16 +1,21 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cors from 'cors';
import { Server } from 'socket.io';
import * as socketio from 'socket.io';
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
cors:
{
cors: {
origin: '*',
methods: '*',
// preflightContinue: false,
// optionsSuccessStatus: 204,
// credentials: true,
allowedHeaders: '*',
},
});
// const app = await NestFactory.create(AppModule);
const httpServer = app.getHttpServer();
const io = new socketio.Server(httpServer);
@ -33,4 +38,5 @@ async function bootstrap() {
await app.listen(4001);
}
bootstrap();

View File

@ -1,92 +0,0 @@
import { useEffect, useState } from "react";
import { Navigate, Route, Routes, useNavigate } from "react-router-dom";
import "../styles/App.css";
import Field from './Field';
import PlayButton from './PlayButton';
import SuccessToken from '../script/tokenSuccess'
import Home from './Home';
import api from '../script/axiosApi';
// import Login42 from './Login42';
// const navigate = useNavigate();
// const [isLoggedIn, setisLoggedIn] = useState(false);
// useEffect(() => {
// if (!localStorage.getItem('token'))
// {
// navigate("/");
// }
// else
// {
// setisLoggedIn(true);
// }
// },);
function App() {
useEffect(() => {
const handleUnload = async (event) => {
await api.post('/quit');
// Custom logic when the user is quitting the app
// You can perform any necessary cleanup or trigger actions here
// This function will be called when the user leaves the app
};
// Add the event listener when the component mounts
window.addEventListener('beforeunload', handleUnload);
// Remove the event listener when the component unmounts
return () => {
window.removeEventListener('beforeunload', handleUnload);
};
}, []);
return (
<>
<Routes>
<Route exact path="/" element={<Home/>}/>
<Route exact path="/pong" element={<PlayButton />}/>
<Route exact path="/pong/play" element={<Field />}/>
<Route exact path="/token" element={<SuccessToken />}/>
<Route path='*' element={<Navigate to='/' />} />
</Routes>
</>
);
}
export default App;
// {/* <Route path="*"><Navigate to="/" /></Route>
// */}
// {/* Gestion des pages inexistantes */}
// {/* ------- ROUTE FOR CHAT APP HERE --------- */}
// {/* <Route exact path="/chat" element={<NOM DU COMPONENT == index dans le tuto/>}/> */}
// {/* <Routes>
// {/* {redirectToUrl} */}
// <Route exact path="/" element={<Home/>}/>
// <Route exact path="/pong" element={<PlayButton />}/>
// <Route exact path="/pong/play" element={<Field />}/>
// <Route exact path="/token" element={<SuccessToken />}/>
// <Route path='*' element={<Navigate to='/' />} />
// {/* <Route path="*"><Navigate to="/" /></Route>
// */}
// {/* Gestion des pages inexistantes */}
// {/* ------- ROUTE FOR CHAT APP HERE --------- */}
// {/* <Route exact path="/chat" element={<NOM DU COMPONENT == index dans le tuto/>}/> */}
// </Routes> */}

View File

@ -1,49 +0,0 @@
import '../styles/old.css';
import '../styles/field.css';
import { useLocation } from 'react-router-dom';
import api from '../script/axiosApi';
function Home()
{
const login2 = () => {
console.log('Hello from myFunction');
api.get('/profile').then((response) => {
const data = response;
const myJSON = JSON.stringify(response.data);
console.log(`data response= ${myJSON}`)
});
}
const location = useLocation();
const handleButtonClick = () => {
const token = localStorage.getItem('token')
console.log(`token type= ${typeof token}`);
if (token !== null && typeof token === 'string')
{
console.log(`already token= ${localStorage.getItem('token')}`)
return ;
}
// else
let path = "https://api.intra.42.fr/oauth/authorize?client_id=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41&redirect_uri=http%3A%2F%2Flocalhost%3A80%2Fapi%2Fauth%2Flogin&response_type=code";
window.location.replace(path);
};
return (
<div className="notClicked">
<button onClick={handleButtonClick} className="playButton" >LOGIN</button>
<div className ="loginForm">
<button className="submit" onClick={login2}>test button</button>
</div>
<div className ="loginForm">
<button className="submit" onClick={() => api.post('/win')}>add win</button>
</div>
<div className ="loginForm">
<button className="submit" onClick={() => api.post('/loss')}>add loss</button>
</div>
</div>
);
}
export default Home;

View File

@ -1,23 +0,0 @@
import React, { useEffect } from 'react';
import axios from 'axios';
function MyComponent() {
useEffect(() => {
const api = axios.create({
baseURL: 'https://api.example.com',
withCredentials: true, // this is required to send cookies
headers: {
'X-Custom-Header': 'foobar', // you can also set other default headers
},
});
const response = api.get('/some-endpoint').then((response) => {
console.log(response.data);
response.data.username
});
}, []);
return <div>My Component</div>;
}
export default MyComponent;

View File

@ -1,58 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import App from './components/App';
import Header from './components/Header';
// import Home from './components/Home';
// import Login42 from './components/Login42';
import Head from './components/Head';
// import Field from './components/Field';
// import PlayButton from './components/PlayButton';
import reportWebVitals from './reportWebVitals';
// import SuccessToken from './script/tokenSuccess'
import { BrowserRouter, Route, Routes, Navigate} from 'react-router-dom'
// let redirectToUrl;
// if (localStorage.getItem('token') !== null) //check condition
// {
// redirectToUrl = <Navigate to='/'/>;
// }
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<>
<Head />
<Header />
<BrowserRouter>
<App></App>
</BrowserRouter>
</>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
{/* <Route exact path="/login42" element={<Login42 />}/> */}
// <Routes>
// {/* {redirectToUrl} */}
// <Route exact path="/" element={<Home/>}/>
// <Route exact path="/pong" element={<PlayButton />}/>
// <Route exact path="/pong/play" element={<Field />}/>
// <Route exact path="/token" element={<SuccessToken />}/>
// <Route path='*' element={<Navigate to='/' />} />
// {/* <Route path="*"><Navigate to="/" /></Route>
// */}
// {/* Gestion des pages inexistantes */}
// {/* ------- ROUTE FOR CHAT APP HERE --------- */}
// {/* <Route exact path="/chat" element={<NOM DU COMPONENT == index dans le tuto/>}/> */}
// </Routes>

View File

@ -1,28 +0,0 @@
// console.log(`toktoken= ${token}`)
import axios from 'axios';
// const token = localStorage.getItem('token');
function getToken() {
// your code to retrieve the token from localStorage or any other source
const token = localStorage.getItem('token');
if (typeof token === 'string') {
console.log("is a string !!!")
}
return token;
}
console.log(`getToken = ${getToken()}`)
console.log(`Bearer ${localStorage.getItem("token")}`)
let api = axios.create({
baseURL: 'http://localhost/api',
headers: {
// Authorization: `Bearer ${getToken()}`,
Authorization : `Bearer ${localStorage.getItem("token")}`
},
withCredentials: true,
});
export default api;

View File

@ -1,35 +0,0 @@
import { useLocation } from 'react-router-dom';
import queryString from 'query-string';
function SuccessToken() {
const location = useLocation();
const { data } = queryString.parse(location.search);
// localStorage data.token;
const cleanData = data.slice(1, -1);
// console.log(`prout token= ${cleanData}`)
localStorage.setItem('token', `${cleanData}`);
console.log(`prout token2= ${localStorage.getItem('token')}`)
window.location.replace("http://localhost/pong");
// return (
// <div>
// <h2>Success!</h2>
// <p>Data: {data}</p>
// </div>
// );
}
export default SuccessToken;
// // Store a value in localStorage
// localStorage.setItem('key', 'value');
// // Retrieve a value from localStorage
// const value = localStorage.getItem('key');
// // Remove a value from localStorage
// localStorage.removeItem('key');
// // Clear all values from localStorage
// localStorage.clear();

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
"react-scripts": "5.0.1",
"socket.io-client": "^4.6.1",
"styled-components": "^5.3.10",
"typescript": "^3.2.1",
"web-vitals": "^2.1.4"
},
"scripts": {

View File

@ -28,7 +28,7 @@
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="root" style=" height: 100%;"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

View File

@ -1,10 +0,0 @@
import DefaultPic from '../assets/profile.jpg';
const UserProfile = [
{
Pic: DefaultPic,
UserName: "Dipper Ratman",
},
]
export default UserProfile

View File

@ -0,0 +1,58 @@
export const Rank = [
{
rank: '1',
name: 'jean',
},
{
rank: '2',
name: 'marc',
},
{
rank: '3',
name: 'dujardain',
},
{
rank: '4',
name: 'mom',
},
{
rank: '5',
name: 'fary',
},
{
rank: '6',
name: 'aba',
},
{
rank: '7',
name: 'preach',
},
{
rank: '1',
name: 'jean',
},
{
rank: '2',
name: 'marc',
},
{
rank: '3',
name: 'dujardain',
},
{
rank: '4',
name: 'mom',
},
{
rank: '5',
name: 'fary',
},
{
rank: '6',
name: 'aba',
},
{
rank: '7',
name: 'preach',
},
]

View File

@ -0,0 +1,8 @@
import DefaultPic from '../assets/profile.jpg';
export const UserProfile = {
Pic: DefaultPic,
UserName: 'Dipper Ratman',
}
// export default UserProfile

View File

@ -2,29 +2,36 @@ export const DBWinLoss = [
{
title: 'Victory',
score: '10 - 6',
opponent: 'chef bandit'
},
{
title: 'Defeat',
score: '9 - 10',
opponent: 'ex tueur'
},
{
title: 'Victory',
score: '10 - 0',
opponent: 'tueur'
},
{
title: 'Victory',
score: '10 - 9',
opponent: 'boulanger'
},
{
title: 'Defeat',
score: '3 - 10',
opponent: 'charcutier'
},
{
title: 'Deafet',
score: '9 - 10',
opponent: 'preach'
},
{
title: 'Victory',
score: '10 - 9',
opponent: 'aba'
},
]

View File

@ -4,7 +4,7 @@ import HomeLogin from "../pages/Home.js";
import Home from "../pages/Home.jsx";
import PlayButton from "../pages/PlayButton.js";
import PlayButton from "./Game/PlayButton.js";
import Field from "../pages/Field";
import Login42 from "../pages/Login42.js";
import Messages from "../pages/Messages.jsx";
@ -14,6 +14,10 @@ import {AnimatePresence} from "framer-motion";
import SuccessToken from '../script/tokenSuccess'
import DoubleAuth from "../pages/2fa.js";
import Game from "../pages/Game.jsx";
import Social from "../pages/Social.jsx";
function AnimatedRoute () {
const location = useLocation();
return (
@ -22,9 +26,13 @@ function AnimatedRoute () {
<Route exact path="/" element={<HomeLogin/>}/>
<Route exact path="/profile" element={<Home/>}/>
<Route exact path="/2fa" element={<DoubleAuth/>}/>
<Route exact path="/Social" element={<Social/>}/>
<Route exact path="/token" element={<SuccessToken />}/>
<Route path="/game" element={<PlayButton />}/>
<Route exact path="/pong" element={<PlayButton />}/>
<Route exact path="/pong" element={<Game />}/>
<Route exact path="/pong/play" element={<Field />}/>
{/* <Route path="/profile" element={<PlayButton />}/> */}

View File

@ -0,0 +1,27 @@
import '../../styles/field.css';
// import { useHistory } from 'react-router-dom';
import { useNavigate } from "react-router-dom";
function PlayButton() {
const history = useNavigate();
const handleButtonClick = () => {
let path = `play`;
history(path);
};
return (
<div className="notClicked" id="canvas_container">
<button onClick={handleButtonClick} className="playButton">Play</button>
{/* !buttonClicked && <button onClick={handleButtonClick}>Draw on Canvas</button> */}
<div className='checkbox'>
<p><input type="checkbox" value="superpower"/> Super Power </p>
<p><input type="checkbox" value="obstacle"/> Obstacle </p>
<p><input type="checkbox" value="speed"/> Faster and Faster </p>
</div>
</div>
);
}
export default PlayButton;

View File

@ -0,0 +1,27 @@
import React from "react"
import {Rank} from '../../DataBase/DataRank.js'
import defaultpic from '../../assets/profile.jpg'
function Ranking(){
return (
<div>
<h1 className='title'>Ranking</h1>
<div className='scroll'>
{Rank.map((item, index) => {
return (
<div className='rank_elements'>
<li key={index}>
<div>
<h4>{item.rank}: {item.name} <img className="profilePic" src={defaultpic}/></h4>
</div>
{/* <h4 className='content'>{item.openent}</h4> */}
</li>
</div>
)
})}
</div>
</div>
)
}
export default Ranking

View File

@ -36,8 +36,8 @@ function Chat(){
</TouchDiv>
</div>
</div>
<Conversation/>
<Input/>
{/* <Conversation/> */}
{/* <Input/> */}
</div>
)
}

View File

@ -1,7 +1,15 @@
import React from "react";
import React, { useState, useEffect, useRef } from "react";
import '../../styles/Messages.css'
import styled from "styled-components";
import DefaultPic from '../../assets/profile.jpg'
import api from '../../script/axiosApi';
import io from 'socket.io-client';
import { TbSend } from 'react-icons/tb';
import MessageYou from "./MessageYou"
import Message from "./Message"
import Input from "./Input";
const UserChat = styled.div `
padding: 5px;
@ -16,10 +24,10 @@ const UserChat = styled.div `
}
`
const SideSpan = styled.span`
font-size: 18px;
font-weight: 500;
`
// const SideSpan = styled.span`
// font-size: 18px;
// font-weight: 500;
// `
const SideP = styled.p`
font-size: 14px;
@ -27,37 +35,191 @@ const SideP = styled.p`
margin-left: 15px;
`
//========================================================================================================
//========================================================================================================
// Socket handler
//========================================================================================================
//========================================================================================================
//========================================================================================================
//========================================================================================================
// Logical part
//========================================================================================================
//========================================================================================================
function Chats(){
const [conversations, setConversation] = useState([]);
const [user, setUser] = useState(null);
const [currentChat, setCurrentChat] = useState(null);
const [messages, setMessage] = useState([]);
const [newMessages, setNewMessage] = useState("");
const [incomingMessage, setIncomingMessage] = useState("");
const socket = useRef();
// Socket handler
// socket.on('message', (data) => { //data should be a message ?
// console.log(`message received data= ${data}`)
// setMessage([...messages, data]);
// });
//End of socket handler
useEffect(()=> {
const getConv = async ()=>{
try{
const convs = await api.get("/conv")
const tmpUser = await api.get("/profile")
console.log(convs);
setUser(tmpUser);
setConversation(convs.data);
// return tmpUser;
console.log(`tmpUser= ${tmpUser.data}`);
socket.current = io("http://localhost:4001");
console.log(`connection....`);
socket.current.emit('connection', {username: tmpUser.data.username})
// const socket = io("http://localhost:4001", {
// query: {
// username: user.data.username,
// },});
socket.current.on('message', (data) => { //data should be a message ?
console.log(`message received data= ${data.sender}`)
console.log(`message received data= ${data.convId}`)
console.log(`message received data= ${data.sender}`)
console.log(`curretn chat = ${currentChat}`)
setIncomingMessage(data);
});
}
catch(err){
console.log(err);
}
};
getConv();
}, [])
useEffect(()=> {
if (currentChat)
console.log(currentChat.id)
// console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`)
if (currentChat !== null && currentChat.id === incomingMessage.convId)
setMessage((prev) => [...prev, incomingMessage]);
}, [incomingMessage, currentChat])
// useEffect(()=> {
// const getConv = async ()=>{
// try{
// const convs = await api.get("/conv")
// const tmpUser = await api.get("/profile")
// console.log(convs);
// setUser(tmpUser);
// setConversation(convs.data);
// }
// catch(err){
// console.log(err);
// }
// };
// getConv();
// }, [])
useEffect(()=> {
const getMessage = async ()=>
{
const data = {
convId: currentChat.id
};
try{
const res = await api.post('/getMessage', data);
setMessage(res.data);
} catch(err){
}
}
getMessage()
}, [currentChat])
const handleSubmit = async (e)=>{
e.preventDefault();
const message = {
sender: user.data.username,
text: newMessages,
convId: currentChat.id,
members: null
};
try{
console.log(`id= ${currentChat.id}`)
const res = await api.post('/message', message);
const convMember = await api.post('/member', message);
message.members = convMember.data.members;
console.log(convMember);
// console.log(`currentChat= ${currentChat.id}`)
setMessage([...messages, res.data]);
setNewMessage("");
socket.current.emit('sendMessage', message);
}
catch(err){
console.log(err)
}
}
return (
<div className="chat">
{conversations.map(c=> (
<div onClick={() => setCurrentChat(c)}>
<UserChat>
<img className="pic-user" src={DefaultPic} alt="User" />
<div className="infoSideBar">
<SideSpan>Dummy</SideSpan>
<SideP>yo</SideP>
<span>{c.name}</span>
<SideP>Desc?</SideP>
</div>
</UserChat>
<UserChat>
<img className="pic-user" src={DefaultPic} alt="User" />
<div className="infoSideBar">
<SideSpan>Dummy</SideSpan>
<SideP>yo</SideP>
</div>
</UserChat><UserChat>
<img className="pic-user" src={DefaultPic} alt="User" />
<div className="infoSideBar">
<SideSpan>Dummy</SideSpan>
<SideP>yo</SideP>
))}
{
currentChat ? (
<>
<div className="messages">
{messages.map(m=>(
<Message message = {m} own={m.sender === user.data.username}/>
))}
{/* <Input/> */}
<div className="input">
<input
type="text"
placeholder="What do you want to say"
onChange={(e) => setNewMessage(e.target.value)}
value={newMessages}
/>
<div className="send">
<TbSend onClick={handleSubmit}></TbSend>
</div>
</UserChat><UserChat>
<img className="pic-user" src={DefaultPic} alt="User" />
<div className="infoSideBar">
<SideSpan>Dummy</SideSpan>
<SideP>yo</SideP>
</div>
</UserChat>
</div></>) : (<span className="noConv">Open a conversation</span>)}
</div>
);
}
export default Chats

View File

@ -1,17 +1,22 @@
import MessageYou from "./MessageYou"
import MessageMe from "./MessageMe"
// import { useRef } from "react";
// import { useEffect } from "react";
import { useEffect, useState } from "react";
import '../../styles/Messages.css'
import Input from "./Input";
function Conversation(){
// const scrollRef = useRef();
// useEffect(() => {
// scrollRef.current?.scrollIntoView({ behavior: "smooth"})
// }, [])
const [currentChat, setCurrentChat] = useState(null);
const [message, setMessage] = useState([]);
// setCurrentChat(true)
return (
<div className="messages">
{
currentChat ? (
<>
<div>
<MessageYou/>
<MessageMe/>
<MessageYou/>
@ -33,7 +38,10 @@ function Conversation(){
<MessageMe/>
<MessageYou/>
<MessageMe/>
<Input/>
</div></>) : (<span className="noConv">Open a conversation</span>)}
</div>
)
}

View File

@ -0,0 +1,47 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* Message.jsx :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/01 18:24:46 by apommier #+# #+# */
/* Updated: 2023/06/01 18:33:43 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import React from "react"
import styled from "styled-components"
import DefaultPic from '../../assets/profile.jpg'
import { useRef } from "react";
import { useEffect } from "react";
import '../../styles/Messages.css'
const MeStyleP = styled.p`
background-color: lightgray;
padding 10px 20px;
border-radius 10px 0px 10px 10px;
color: black;
margin-right: 20px;
`
function MessageMe({message, own}){
const scrollRef = useRef();
useEffect(() => {
scrollRef.current?.scrollIntoView({ behavior: "smooth"})
}, [])
return (
<div className={own ? "meMessage" : "youMessage"} ref={scrollRef}>
<div>
<img className="messageInfo" src={DefaultPic} alt="profile" />
</div>
<div className="usernameMesage">{message.sender}</div>
<div className="messageContent">
<MeStyleP>{message.text}</MeStyleP>
</div>
</div>
)
}
export default MessageMe

View File

@ -0,0 +1,55 @@
import {motion} from "framer-motion"
// import Backdrop from "../Sidebar/Backdrop"
import {Link} from 'react-router-dom';
import { UserProfile } from "../../DataBase/DataUserProfile";
import {useState} from 'react';
import "../../styles/Profile.css"
const dropIn = {
hidden: {
opacity: '0',
},
visible: {
opacity: "1",
},
exit: {
opacity: "0",
},
}
// const changeName = ({handleClose, name}) => {
// return (
// UserProfile.UserName = name
// )
// }
const ModalEdit = ({ handleClose }) => {
// let new_name = "";
const [username, setUserName] = useState("");
const handler = e =>
{
setUserName (e.target.value);
}
void(handleClose);
return (
// <Backdrop onClick={handleClose}>
<motion.div
className="modal"
variants={dropIn}
initial="hidden"
animate="visible"
exit="exit">
<h2>Type your new name</h2>
<input className="text" type="text" value={username} onChange={handler} handleClose/>
<div onClick={handleClose}>
<div onClick={() => {UserProfile.UserName = username;}}>
<Link className="button">change</Link>
</div>
</div>
</motion.div>
// </Backdrop>
)
}
export default ModalEdit

View File

@ -0,0 +1,77 @@
// import PropTypes from "prop-types"
// import styled from 'styled-components';
// import '../DataBase/DummyDBWinLoss.js'
// import '../DataBase/DataProfileUser.js'
import { DBWinLoss } from '../../DataBase/DummyDBWinLoss.js';
import '../../styles/Win_Loss.css'
import { UserProfile } from '../../DataBase/DataUserProfile';
// import color from '../../utils/style/color.js';
// const CardWrapper = styled.div`
// display: flex;
// flex-direction: column;
// padding: 15px;
// background-color: black;
// border-radius: 30px;
// width: 350px;
// transition: 200ms;
// margin-top: 50px;
// &:hover {
// cursor: pointer;
// box-shadow: 2px 2px 10px #b6b6b6;
// }
// `
// const CardLabel1 = styled.h1`
// color: #5843e4;
// // font-size: 22px;
// font-weight: bold;
// margin-bottom: 25px;
// `
// const CardLabel2 = styled.span`
// color: #5843e4;
// font-size: 22px;
// font-weight: bold;
// display: flex;
// flex-direction: column;
// `
// const CardImage = styled.img`
// heigh: 80px;
// width: 80px;
// border-radius: 50%;
// `
function WinLoss() {
return (
<div className='tab'>
<h1 className='title'>Match history Win/Loss</h1>
<div className='scroll'>
{DBWinLoss.map((item, index) => {
return (
<div key={index} className='elements'>
<li key={index}>
<h4 className='content'>{item.title}</h4>
<div className='content2nd'>
<h4 className='me'>{UserProfile.UserName}</h4> <h4 className='score'>{item.score}</h4> <h4 className="opponent">{item.opponent}</h4>
</div>
{/* <h4 className='content'>{item.openent}</h4> */}
</li>
</div>
)
})}
</div>
</div>
)
}
// Card.propTypes = {
// label: PropTypes.string,
// title: PropTypes.string.isRequired,
// picture: PropTypes.string,
// }
export default WinLoss

View File

@ -5,9 +5,9 @@ const Backdrop = ({ children, onClick }) => {
return (
<motion.div className="backdrop"
onClick={onClick}
initial={{ opacity: 0}}
initial={{ opacity: -1}}
animate={{ opacity: 1}}
exit={{ opacity: 0}}>
exit={{ opacity: -1}}>
{children}
</motion.div>
)

View File

@ -55,9 +55,10 @@ const Modal = ({ handleClose }) => {
</li>
<div
className="nav-menu">
<ul className='nav-menu-items'>
{SidebarData.map((item, index) => {
return (
<motion.div whileHover={{scale: 1.1}}>
<motion.div key={index} whileHover={{scale: 1.1}}>
<li key={index} className={item.cName}>
<Link to={item.path}>
{item.icon}
@ -67,6 +68,8 @@ const Modal = ({ handleClose }) => {
</motion.div>
)
})}
</ul>
</div>
</motion.div>
</Backdrop>

View File

@ -27,7 +27,7 @@ export const SidebarData = [
},
{
title: 'Social',
path: '/team',
path: '/social',
icon: <IoIcons.IoMdPeople />,
cName: 'nav-text'
},

View File

@ -1,67 +0,0 @@
// import PropTypes from "prop-types"
import styled from 'styled-components';
import '../DataBase/DummyDBWinLoss.js'
import { DBWinLoss } from '../DataBase/DummyDBWinLoss.js';
// import color from '../../utils/style/color.js';
const CardWrapper = styled.div`
display: flex;
flex-direction: column;
padding: 15px;
background-color: black;
// border-radius: 30px;
// width: 350px;
// transition: 200ms;
margin-top: 50px;
&:hover {
cursor: pointer;
box-shadow: 2px 2px 10px #b6b6b6;
}
`
const CardLabel1 = styled.span`
color: #5843e4;
font-size: 22px;
font-weight: bold;
margin-bottom: 25px;
`
const CardLabel2 = styled.span`
color: #5843e4;
font-size: 22px;
font-weight: bold;
display: flex;
flex-direction: column;
`
// const CardImage = styled.img`
// heigh: 80px;
// width: 80px;
// border-radius: 50%;
// `
function WinLoss() {
return (
<CardWrapper>
<CardLabel1>Match history Win/Loss</CardLabel1>
{/* <CardImage src={picture} alt="freelance" height={80} width={80} /> */}
{DBWinLoss.map((item, index) => {
return (
<li key={index}>
<CardLabel2>{item.title}</CardLabel2>
<CardLabel2>{item.score}</CardLabel2>
</li>
)
})}
</CardWrapper>
)
}
// Card.propTypes = {
// label: PropTypes.string,
// title: PropTypes.string.isRequired,
// picture: PropTypes.string,
// }
export default WinLoss

View File

@ -12,7 +12,7 @@ import './styles/App.css'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<div className='App'>
<div className="App">
<Head />
<BrowserRouter>
<Header />

View File

@ -0,0 +1,146 @@
import React, { useCallback, useState, useEffect } from 'react';
import api from '../script/axiosApi';
// function DoubleAuth() {
// // const enabled = await api.get("/2fa");
// // const response = await api.get("/2fa");
// // const enabled = response.data;
// // console.log(`enable= ${enabled.data}`)
// // const enabled = 0;
// let enabled;
// useEffect(() => {
// async function get2fa()
// {
// const response = await api.get("/2fa");
// const enabled = response.data;
// console.log(`enable= ${enabled.data}`)
// }
// // const enabled = 0;
// }, [])
// useEffect(() => {
// async function get2fa()
// {
// api.get('/api/QRcode', { responseType: 'blob' })
// .then(response => {
// const reader = new FileReader();
// reader.onloadend = () => {
// setImageSrc(reader.result);
// };
// reader.readAsDataURL(response.data);
// })
// .catch(error => {
// console.error(error);
// });
// } }, []);
// // const [verificationCode, setVerificationCode] = useState('');
// // const [invalidCode, setInvalidCode] = useState(false);
// const handleSubmit = () => {
// // async (e) => {
// // e.preventDefault();
// // const result = await verifyOtp(verificationCode);
// // if (result) return (window.location = '/');
// // setInvalidCode(true);
// // },
// // [verificationCode]
// };
// let sourceCode
// if (!enabled)
// {
// api.get('/QRcode')
// .then(response => {
// sourceCode = response.data;
// console.log(sourceCode);
// })
// .catch(error => {
// console.error(error);
// });
// }
// return (
// <div>
// {!enabled && (
// <div>
// <p>Scan the QR code on your authenticator app</p>
// <img src={sourceCode} />
// </div>
// )}
// <form onSubmit={handleSubmit}>
// {/* <Input
// id="verificationCode"
// label="Verification code"
// type="text"
// value={verificationCode}
// onChange={(e) => setVerificationCode(e.target.value)}
// /> */}
// <button type="submit">Confirm</button>
// {/* {invalidCode && <p>Invalid verification code</p>} */}
// </form>
// </div>
// );
// }
// import { toFileStream } from 'qrcode';
const DoubleAuth = () => {
const [imageSrc, setImageSrc] = useState('');
useEffect(() => {
async function getCode(){
await api.get('/QRcode', { responseType: 'blob' })
.then(response => {
const reader = new FileReader();
reader.onloadend = () => {
setImageSrc(reader.result);
};
reader.readAsDataURL(response.data);
})
.catch(error => {
console.error(error);
});
}
getCode();
}, []);
// return (
// <div>
// {imageSrc && <img src={imageSrc} alt="QR Code" />}
// </div>
// );
// <img src={sourceCode} />
return (
<div>
<div>
<p>Scan the QR code on your authenticator app</p>
{imageSrc && <img src={imageSrc} alt="QR Code" />}
</div>
{/* <form onSubmit={handleSubmit}>
<button type="submit">Confirm</button>
</form> */}
</div>
);
};
export default DoubleAuth;

View File

@ -0,0 +1,18 @@
import React from "react";
import PlayButton from "../components/Game/PlayButton";
import Ranking from "../components/Game/Ranking";
import '../styles/Game.css'
function Game(){
return (
<div className="game">
<div className="game">
<Ranking/>
</div>
<div className="game">
<PlayButton/>
</div>
</div>
)
}
export default Game

View File

@ -1,32 +1,90 @@
import React from "react";
import { React, useState } from "react";
import '../styles/Profile.css'
import '../styles/App.css'
// import '../styles/App.css'
import DefaultPicture from "../assets/profile.jpg";
// import WinLoss from "../components/Win_Loss";
import { motion } from 'framer-motion'
// import {AiOutlineHistory} from 'react-icons/ai'
import WinLoss from "../components/Profile/Win_Loss";
import { motion, AnimatePresence } from 'framer-motion'
// import { AiFillEdit } from 'react-icons/ai'
// import { GrClose } from 'react-icons/gr'
import { Link } from "react-router-dom";
import UserProfile from "../DataBase/DataProfileUser";
import ModalEdit from "../components/Profile/EditName";
import {AiOutlineHistory} from 'react-icons/ai'
// import { Link } from "react-router-dom";
import {UserProfile} from "../DataBase/DataUserProfile";
// import axios from "axios";
import api from '../script/axiosApi';
import { CgEditMarkup } from 'react-icons/cg'
import { IoCloseCircleOutline } from "react-icons/io5";
// axios.get("http://localhost/api")
// .then((response) => {
// response = response.json()
// response.then((result) => {
// console.log(result)
// console.log("ceci est un test")
// })
// })
function Home () {
let name = UserProfile.UserName
function Profile () {
const [modalOpen, setModalOpen] = useState(false);
const close = () => setModalOpen(false);
const open = () => setModalOpen(true);
const getConv = async ()=>{
try{
const convs = await api.get("/profile")
// const tmpUser = await api.get("/profile")
console.log(convs.data);
// setUser(tmpUser);
// setConversation(convs.data);
}
catch(err){
console.log(err);
}
};
getConv();
return (
<motion.div className="App"
initial={{opacity: 0}}
animate={{opacity: 1}}
exit={{opacity: 0}}>
<div className="profile">
<img className="profile-pic" src={DefaultPicture} alt="Profile pic" />
<h1>Dipper Ratman</h1>
<h1>{UserProfile.UserName}</h1>
<motion.div onClick={() => (modalOpen ? close() : open())}>
<Link to="#" className="edit_name">
{modalOpen === true ? <IoCloseCircleOutline/> : <CgEditMarkup/>}
</Link>
</motion.div>
<AnimatePresence
initial={false}
onExitComplete={() => null}>
{modalOpen && <ModalEdit modalOpen={modalOpen} handleClose={close}/>}
</AnimatePresence>
</div>
)
}
<div>
<div className="history">
<Link to='#' className=" history">Match history</Link>
</div>
</div>
function Home () {
const [move, setmove ] = useState(false);
return (
<motion.div className="page"
initial={{opacity: -1}}
animate={{opacity: 1}}
exit={{opacity: -1}}>
<div className="home">
<motion.div animate={{x: move ? -200: 170}}
transition={{type: "tween", duration: 0.5}}>
<Profile/>
</motion.div>
<motion.div animate={{opacity: !move ? -1 : 1}}>
<WinLoss/>
</motion.div>
</div>
<motion.div
className="div_history"
// className="history"
onClick={ () => setmove(!move)}>
<Link to="#" className="history"><AiOutlineHistory/> Match History</Link>
</motion.div>
</motion.div>
)
}

View File

@ -0,0 +1,9 @@
import React from "react";
function Social (){
return (
<div>je suis la partie social</div>
)
}
export default Social

View File

@ -30,6 +30,7 @@ export function drawCanvas() {
//general canvas
const scale = window.devicePixelRatio;
canvas.width = canvas.offsetWidth;
// canvas.height = canvas.width * 0.7
canvas.height = canvas.offsetHeight;
//paddle var
@ -386,11 +387,11 @@ requestAnimationFrame(draw);
vY = -vY;
// send_info();
}
else if (ballX + ballRadius + 2 >= canvas.width) //touch right wall
{
vX = -vX;
// send_info();
}
// else if (ballX + ballRadius + 2 >= canvas.width) //touch right wall
// {
// vX = -vX;
// // send_info();
// }
}
function is_out()
@ -423,6 +424,12 @@ requestAnimationFrame(draw);
//========================================================================================================
//========================================================================================================
document.addEventListener('resize', event => {
// event.height
// event.width
const { clientWidth, clientHeight } = canvas.parentElement;
console.log(`resize detected widht= ${clientWidth} height= ${clientHeight}`)
});
document.addEventListener('mousemove', event => {
const mouseY = event.clientY;

View File

@ -1,11 +1,7 @@
// console.log(`toktoken= ${token}`)
import axios from 'axios';
// const token = localStorage.getItem('token');
function getToken() {
// your code to retrieve the token from localStorage or any other source
const token = localStorage.getItem('token');
if (typeof token === 'string') {
console.log("is a string !!!")

View File

@ -1,6 +1,9 @@
.App {
text-align: center;
height: 100%;
width: 100%;
background-color: black;
height: 100%;
}
.App-logo {

View File

@ -0,0 +1,28 @@
.game{
display:inline-flex;
margin: 50px;
}
.rank_elements {
border-width:1px;
border-style:solid;
/* background-color: #5843e4; */
border-color: grey;
/* overflow: scroll; */
padding: 5px 100px;
font-size: 25px;
}
.scroll {
/* border:3px; */
/* background-color: #5843e4; */
/* border-color: white; */
overflow: scroll;
height: 70vh;
}
.profilePic{
height: 30px;
width: 30px;
border-radius: 50%;
}

View File

@ -41,6 +41,7 @@
/* justify-content: start; */
align-items: center;
padding: 8px 0px 8px 16px;
list-style: none;
height: 60px;
}
@ -53,8 +54,10 @@
height: 100%;
display: flex;
align-items: center;
padding: 0 16px;
border-radius: 4px;
/* padding: 0 16px; */
padding: 8px 8px 8px 8px;
border-radius: 20px;
}
.nav-text a:hover {

View File

@ -1,6 +1,12 @@
.page {
text-align: center;
/* height: 50vh; */
/* width: 50vh; */
/* background-color: black; */
}
.profile {
flex-direction: row;
height: 100vh;
color: white;
}
@ -15,14 +21,73 @@
margin-top: 20px;
}
.home{
/* margin-top: -100px; */
/* display:inline-block; */
/* flex-direction: column; */
/* position: absolute; */
background-color: black;
text-align: center;
}
.history{
display: inline-block;
color: white;
background-color: #5843e4;
border-radius: 4px;
padding: 8px 8px 8px 8px;
font-size: 30px;
border-radius: 20px;
padding: 14px;
font-size: 1.7rem;
text-decoration: none;
font-weight: bold;
}
.div_history {
flex-direction: row;
align-items: center;
margin-top: -80px;
}
.edit_name {
margin-left: 2rem;
font-size: 1.7rem;
background: #5843e4;
color:#f5f5f5;
margin: 0 16px;
text-decoration: none;
padding: 10px 16px;
border-radius: 20px;
}
.modal {
position:initial;
width: 400px;
height: 150px;
margin: auto;
padding: 0 2rem;
border-radius: 12px;
display: flex;
flex-direction: column;
align-items: center;
background-color: rgb(42, 41, 41);
}
.text {
background-color: black;
color: grey;
margin-bottom: 10px;
}
.button{
display: inline-block;
color: white;
background-color: #5843e4;
border-radius: 15px;
padding: 8px;
font-size: 20px;
text-decoration: none;
font-weight: bold;
}
/* canvas {
margin-top: 20px;

View File

@ -0,0 +1,79 @@
.tab{
/* display: flex; */
/* flex-direction: column; */
/* background-color: red; */
height: 70vh;
/* padding: 15px; */
/* overflow: scroll; */
}
.scroll {
/* border:3px; */
/* background-color: #5843e4; */
/* border-color: white; */
overflow: scroll;
}
.elements {
/* display: flex; */
border-width:1px;
border-style:solid;
/* background-color: #5843e4; */
border-color: grey;
/* overflow: scroll; */
}
.title {
color: #5843e4;
/* font-size: 22px; */
font-weight: bold;
margin-bottom: 25px;
}
.content {
color: white;
/* font-size: 22px; */
font-weight: bold;
/* display: flex; */
flex-direction: column;
margin-bottom: 5px;
}
.content2nd {
display:inline;
flex-direction: row;
color: white;
/* font-size: 22px; */
font-weight: bold;
flex-direction: row;
/* text-align: justify; */
/* margin-bottom: 5px; */
}
.me {
text-align: start;
margin-left: 10px;
}
.score {
text-align: center;
}
.opponent {
text-align: end;
margin-right:10px;
}
div::-webkit-scrollbar {
width: 1;
}
div::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}
div::-webkit-scrollbar-thumb {
background-color: red;
outline: 3px solid black;
}

View File

@ -1,5 +1,5 @@
.playButton {
background-color: rgb(0, 0, 0);
background-image: linear-gradient(90deg, #5843e4, #5a0760);;
border-radius: 5vh;
color: white;
display: block;
@ -11,6 +11,19 @@
font-size: 300%;
}
.field {
background-color: rgb(249, 249, 249);
/* border-radius: 5vh; */
/* color: rgb(100, 42, 42); */
display: block;
margin: auto;
margin-top: 5vh;
/* padding: 2vh 5vw; */
height: 80%;
width: 80%;
/* font-size: 300%; */
}
.clicked{
/* justify-content: center; */
/* display: flex;
@ -29,26 +42,28 @@
}
#myCanvas {
background-color: rgb(75, 33, 33);
position: absolute;
top: 0;
left: 0;
cursor: none;
background-color: rgb(124, 47, 47);
/* position: absolute; */
/* top: 0; */
/* left: 0; */
/* cursor: none; */
width: 100%;
height: 100%;
margin: 0;
}
@media screen and (max-width: 768px) {
#canvas_container {
transform: rotate(90deg);
/* @media screen and (max-width: 768px) { */
/* #canvas_container { */
/* width: 50%; */
/* transform: rotate(90deg);
transform-origin: top right;
position: relative;
/* margin-right: 100vw; */
/* height: 100vw; */
width: 100vh;
}
/* width: 100vh; */
/* } */
/* #myCanvas {
height: 100%;
width: 100%;
} */
}
/* } */

View File

@ -5,6 +5,7 @@ body {
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* height: 100%; */
}
code {

View File

@ -75,18 +75,18 @@ services:
- ./containers/pong:/app
entrypoint: ["sh", "-c" , "npm install && npm run start:dev"]
# chat:
# image: node:latest
# container_name: chat
# working_dir: /app
# ports:
# - 4001:4001
# env_file: .env
# networks:
# - pongNetwork
# volumes:
# - ./chat:/app
# entrypoint: ["sh", "-c" , "npm install && npm run start:dev"]
chat:
image: node:latest
container_name: chat
working_dir: /app
ports:
- 4001:4001
env_file: .env
networks:
- pongNetwork
volumes:
- ./containers/chat:/app
entrypoint: ["sh", "-c" , "npm install && npm run start:dev"]
networks:

View File

@ -0,0 +1,2 @@
node_modules/
dist/

View File

@ -0,0 +1,20 @@
# Utilisez l'image de base de Node.js version 14
FROM node:latest
# Définissez le répertoire de travail à /app
WORKDIR /app
# Copiez le fichier package.json et package-lock.json à l'intérieur de l'image
COPY /frontend/pong/my-app/package*.json ./
# Installez les dépendances de l'application
RUN npm install
# Copiez le reste des fichiers de l'application dans l'image
COPY /frontend/pong/my-app/ .
# Exposez le port 3000 pour accéder à l'application dans le navigateur
EXPOSE 8080
# Démarrez l'application avec la commande "npm start"
CMD ["npm", "run", "start"]

View File

@ -12,13 +12,14 @@
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.3.5",
"query-string": "^8.1.0",
"framer-motion": "^10.12.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
"react-router-dom": "^6.10.0",
"react-scripts": "5.0.1",
"socket.io-client": "^4.6.1",
"typescript": "^4.9.5",
"styled-components": "^5.3.10",
"web-vitals": "^2.1.4"
}
},
@ -39,6 +40,22 @@
"node": ">=6.0.0"
}
},
"node_modules/@apideck/better-ajv-errors": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz",
"integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==",
"dependencies": {
"json-schema": "^0.4.0",
"jsonpointer": "^5.0.0",
"leven": "^3.1.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"ajv": ">=8"
}
},
"node_modules/@babel/code-frame": {
"version": "7.21.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz",
@ -2124,6 +2141,29 @@
"postcss-selector-parser": "^6.0.10"
}
},
"node_modules/@emotion/is-prop-valid": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
"integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
"dependencies": {
"@emotion/memoize": "^0.8.0"
}
},
"node_modules/@emotion/memoize": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
"integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
},
"node_modules/@emotion/stylis": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
"integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
},
"node_modules/@emotion/unitless": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@ -2168,6 +2208,21 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/@eslint/eslintrc/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/@eslint/eslintrc/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@ -2198,6 +2253,11 @@
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"node_modules/@eslint/js": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz",
@ -4737,13 +4797,13 @@
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
@ -4767,34 +4827,6 @@
}
}
},
"node_modules/ajv-formats/node_modules/ajv": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/ajv-formats/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"peerDependencies": {
"ajv": "^6.9.1"
}
},
"node_modules/ansi-escapes": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
@ -5208,6 +5240,21 @@
"webpack": ">=2"
}
},
"node_modules/babel-loader/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/babel-loader/node_modules/ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
@ -5216,6 +5263,11 @@
"ajv": "^6.9.1"
}
},
"node_modules/babel-loader/node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"node_modules/babel-loader/node_modules/schema-utils": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
@ -5328,6 +5380,26 @@
"@babel/core": "^7.0.0-0"
}
},
"node_modules/babel-plugin-styled-components": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.1.tgz",
"integrity": "sha512-c8lJlszObVQPguHkI+akXv8+Jgb9Ccujx0EetL7oIvwU100LxO6XAGe45qry37wUL40a5U9f23SYrivro2XKhA==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.16.0",
"@babel/helper-module-imports": "^7.16.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"lodash": "^4.17.21",
"picomatch": "^2.3.0"
},
"peerDependencies": {
"styled-components": ">= 2"
}
},
"node_modules/babel-plugin-syntax-jsx": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
"integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw=="
},
"node_modules/babel-plugin-transform-react-remove-prop-types": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz",
@ -5635,6 +5707,14 @@
"node": ">= 6"
}
},
"node_modules/camelize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/caniuse-api": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@ -6070,6 +6150,14 @@
"postcss": "^8.4"
}
},
"node_modules/css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
"engines": {
"node": ">=4"
}
},
"node_modules/css-declaration-sorter": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz",
@ -6160,21 +6248,6 @@
}
}
},
"node_modules/css-minimizer-webpack-plugin/node_modules/ajv": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
@ -6186,11 +6259,6 @@
"ajv": "^8.8.2"
}
},
"node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz",
@ -6247,6 +6315,16 @@
"resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
"integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w=="
},
"node_modules/css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
"dependencies": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"node_modules/css-tree": {
"version": "1.0.0-alpha.37",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
@ -6477,14 +6555,6 @@
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
"integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
},
"node_modules/decode-uri-component": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.4.1.tgz",
"integrity": "sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==",
"engines": {
"node": ">=14.16"
}
},
"node_modules/dedent": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
@ -7548,21 +7618,6 @@
"webpack": "^5.0.0"
}
},
"node_modules/eslint-webpack-plugin/node_modules/ajv": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
@ -7595,11 +7650,6 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
"node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/eslint-webpack-plugin/node_modules/schema-utils": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz",
@ -7632,6 +7682,21 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/eslint/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/eslint/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@ -7726,6 +7791,11 @@
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/eslint/node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"node_modules/eslint/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@ -8076,17 +8146,6 @@
"node": ">=8"
}
},
"node_modules/filter-obj": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-5.1.0.tgz",
"integrity": "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==",
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/finalhandler": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
@ -8230,6 +8289,21 @@
}
}
},
"node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
@ -8320,6 +8394,11 @@
"node": ">=8"
}
},
"node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
@ -8389,6 +8468,49 @@
"url": "https://www.patreon.com/infusion"
}
},
"node_modules/framer-motion": {
"version": "10.12.8",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.12.8.tgz",
"integrity": "sha512-ylobYq3tGFjjAmRdBs5pL/R1+4AmOm69g/JbF5DcNETfRe8L9CjaX4acG83MjYdIsbsTGJmtR5qKx4glNmXO4A==",
"dependencies": {
"tslib": "^2.4.0"
},
"optionalDependencies": {
"@emotion/is-prop-valid": "^0.8.2"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/framer-motion/node_modules/@emotion/is-prop-valid": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
"integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
"optional": true,
"dependencies": {
"@emotion/memoize": "0.7.4"
}
},
"node_modules/framer-motion/node_modules/@emotion/memoize": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
"optional": true
},
"node_modules/framer-motion/node_modules/tslib": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
},
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@ -8769,6 +8891,19 @@
"he": "bin/he"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/hoist-non-react-statics/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/hoopy": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
@ -11744,9 +11879,9 @@
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1",
@ -12143,21 +12278,6 @@
"webpack": "^5.0.0"
}
},
"node_modules/mini-css-extract-plugin/node_modules/ajv": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
@ -12169,11 +12289,6 @@
"ajv": "^8.8.2"
}
},
"node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/mini-css-extract-plugin/node_modules/schema-utils": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz",
@ -14305,22 +14420,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/query-string": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-8.1.0.tgz",
"integrity": "sha512-BFQeWxJOZxZGix7y+SByG3F36dA0AbTy9o6pSmKFcFz7DAj0re9Frkty3saBn3nHo3D0oZJ/+rx3r8H8r8Jbpw==",
"dependencies": {
"decode-uri-component": "^0.4.1",
"filter-obj": "^5.1.0",
"split-on-first": "^3.0.0"
},
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
@ -14563,6 +14662,14 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
},
"node_modules/react-icons": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz",
"integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==",
"peerDependencies": {
"react": "*"
}
},
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@ -15274,6 +15381,34 @@
"url": "https://opencollective.com/webpack"
}
},
"node_modules/schema-utils/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/schema-utils/node_modules/ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"peerDependencies": {
"ajv": "^6.9.1"
}
},
"node_modules/schema-utils/node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"node_modules/select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@ -15458,6 +15593,11 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"node_modules/shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@ -15655,17 +15795,6 @@
"wbuf": "^1.7.3"
}
},
"node_modules/split-on-first": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-3.0.0.tgz",
"integrity": "sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@ -15913,6 +16042,35 @@
"webpack": "^5.0.0"
}
},
"node_modules/styled-components": {
"version": "5.3.10",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.10.tgz",
"integrity": "sha512-3kSzSBN0TiCnGJM04UwO1HklIQQSXW7rCARUk+VyMR7clz8XVlA3jijtf5ypqoDIdNMKx3la4VvaPFR855SFcg==",
"dependencies": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/traverse": "^7.4.5",
"@emotion/is-prop-valid": "^1.1.0",
"@emotion/stylis": "^0.8.4",
"@emotion/unitless": "^0.7.4",
"babel-plugin-styled-components": ">= 1.12.0",
"css-to-react-native": "^3.0.0",
"hoist-non-react-statics": "^3.0.0",
"shallowequal": "^1.1.0",
"supports-color": "^5.5.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/styled-components"
},
"peerDependencies": {
"react": ">= 16.8.0",
"react-dom": ">= 16.8.0",
"react-is": ">= 16.8.0"
}
},
"node_modules/stylehacks": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
@ -16456,6 +16614,7 @@
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -16791,21 +16950,6 @@
"webpack": "^4.0.0 || ^5.0.0"
}
},
"node_modules/webpack-dev-middleware/node_modules/ajv": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/webpack-dev-middleware/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
@ -16817,11 +16961,6 @@
"ajv": "^8.8.2"
}
},
"node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/webpack-dev-middleware/node_modules/schema-utils": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz",
@ -16898,21 +17037,6 @@
}
}
},
"node_modules/webpack-dev-server/node_modules/ajv": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/webpack-dev-server/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
@ -16924,11 +17048,6 @@
"ajv": "^8.8.2"
}
},
"node_modules/webpack-dev-server/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/webpack-dev-server/node_modules/schema-utils": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz",
@ -17221,37 +17340,6 @@
"node": ">=10.0.0"
}
},
"node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz",
"integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==",
"dependencies": {
"json-schema": "^0.4.0",
"jsonpointer": "^5.0.0",
"leven": "^3.1.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"ajv": ">=8"
}
},
"node_modules/workbox-build/node_modules/ajv": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/workbox-build/node_modules/fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
@ -17266,11 +17354,6 @@
"node": ">=10"
}
},
"node_modules/workbox-build/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/workbox-build/node_modules/source-map": {
"version": "0.8.0-beta.0",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",

View File

@ -2,21 +2,19 @@
"name": "my-app",
"version": "0.1.0",
"private": true,
"compilerOptions": {
"topLevelAwait": true
},
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.3.5",
"query-string": "^8.1.0",
"framer-motion": "^10.12.8",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
"react-router-dom": "^6.10.0",
"react-scripts": "5.0.1",
"socket.io-client": "^4.6.1",
"typescript": "^4.9.5",
"styled-components": "^5.3.10",
"web-vitals": "^2.1.4"
},
"scripts": {

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<!-- <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> -->
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta

Some files were not shown because too many files have changed in this diff Show More