vvandenb 2 years ago
parent
commit
3fefcc50eb
  1. 11653
      back/volume/package-lock.json
  2. 17
      back/volume/package.json
  3. 6
      back/volume/src/auth/auth.controller.ts
  4. 12
      back/volume/src/auth/auth.module.ts
  5. 15
      back/volume/src/auth/auth.service.ts
  6. 10
      back/volume/src/users/users.controller.ts
  7. 12
      back/volume/src/users/users.service.ts
  8. 980
      front/volume/package-lock.json
  9. 7
      front/volume/package.json
  10. 18
      front/volume/src/App.svelte
  11. 8
      front/volume/src/components/NavBar.svelte
  12. 4
      front/volume/src/components/Profile.svelte
  13. 2
      front/volume/tsconfig.node.json

11653
back/volume/package-lock.json

File diff suppressed because it is too large

17
back/volume/package.json

@ -22,7 +22,6 @@
}, },
"dependencies": { "dependencies": {
"@nestjs-modules/mailer": "^1.8.1", "@nestjs-modules/mailer": "^1.8.1",
"@nestjs/axios": "^2.0.0",
"@nestjs/common": "^9.0.0", "@nestjs/common": "^9.0.0",
"@nestjs/config": "^2.3.1", "@nestjs/config": "^2.3.1",
"@nestjs/core": "^9.0.0", "@nestjs/core": "^9.0.0",
@ -33,59 +32,49 @@
"@nestjs/platform-socket.io": "^9.3.9", "@nestjs/platform-socket.io": "^9.3.9",
"@nestjs/platform-ws": "^9.2.0", "@nestjs/platform-ws": "^9.2.0",
"@nestjs/schedule": "^2.2.0", "@nestjs/schedule": "^2.2.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/swagger": "^6.2.1", "@nestjs/swagger": "^6.2.1",
"@nestjs/testing": "^9.0.0", "@nestjs/testing": "^9.0.0",
"@nestjs/typeorm": "^9.0.1", "@nestjs/typeorm": "^9.0.1",
"@nestjs/websockets": "^9.2.0", "@nestjs/websockets": "^9.2.0",
"@types/bcrypt": "^5.0.0", "@types/bcrypt": "^5.0.0",
"@types/cookie-parser": "^1.4.3", "@types/cookie-parser": "^1.4.3",
"@types/cron": "^2.0.0",
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/express-session": "^1.17.6", "@types/express-session": "^1.17.6",
"@types/multer": "^1.4.7", "@types/multer": "^1.4.7",
"@types/node": "^16.18.14", "@types/node": "^16.18.14",
"@types/nodemailer": "^6.4.7",
"@types/passport": "^1.0.12", "@types/passport": "^1.0.12",
"@types/ws": "^8.5.3", "@types/ws": "^8.5.3",
"bcrypt": "^5.1.0", "bcrypt": "^5.1.0",
"class-transformer": "^0.5.1", "class-transformer": "^0.5.1",
"class-validator": "^0.14.0", "class-validator": "^0.14.0",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"express": "^4.18.2",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"joi": "^17.8.3", "joi": "^17.8.3",
"multer": "^1.4.5-lts.1",
"nodemailer": "^6.9.1", "nodemailer": "^6.9.1",
"passport": "^0.6.0", "passport": "^0.6.0",
"passport-42": "^1.2.6", "passport-42": "^1.2.6",
"passport-jwt": "^4.0.1",
"pg": "^8.9.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"rxjs": "^7.2.0", "rxjs": "^7.2.0",
"socket.io": "^4.6.1", "socket.io": "^4.6.1",
"source-map-support": "^0.5.21",
"typeorm": "^0.3.12", "typeorm": "^0.3.12",
"ws": "^8.11.0" "ws": "^8.11.0"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "28.1.8",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.53.0", "@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.0.0", "@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.34.0", "eslint": "^8.34.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-standard-with-typescript": "^34.0.0", "eslint-config-standard-with-typescript": "^34.0.0",
"eslint-plugin-import": "^2.27.5", "eslint-plugin-import": "^2.27.5",
"eslint-plugin-n": "^15.6.1", "eslint-plugin-n": "^15.6.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^6.1.1", "eslint-plugin-promise": "^6.1.1",
"jest": "28.1.3", "jest": "28.1.3",
"prettier": "^2.3.2", "prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "28.0.8", "ts-jest": "28.0.8",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0", "ts-node": "^10.0.0",
"tsconfig-paths": "4.1.0",
"typescript": "^4.9.5" "typescript": "^4.9.5"
}, },
"jest": { "jest": {

6
back/volume/src/auth/auth.controller.ts

@ -51,16 +51,16 @@ export class AuthController {
@Get('/verify') @Get('/verify')
@UseGuards(AuthenticatedGuard) @UseGuards(AuthenticatedGuard)
@Redirect(`http://${frontHost}:${frontPort}`) @Redirect(`http://${frontHost}:${frontPort}`)
async VerifyEmail (@Profile42() profile: Profile) { async VerifyEmail (@Profile42() profile: Profile): Promise<void> {
const ftId: number = profile.id const ftId: number = profile.id
const user = await this.usersService.findUser(ftId) const user = await this.usersService.findUser(ftId)
if (user == null) throw new Error('User not found') if (user == null) throw new Error('User not found')
this.authService.sendConfirmationEmail(user) await this.authService.sendConfirmationEmail(user)
} }
@Post('/verify') @Post('/verify')
@Redirect(`http://${frontHost}:${frontPort}`) @Redirect(`http://${frontHost}:${frontPort}`)
async Verify (@Body() body: any) { async Verify (@Body() body: any): Promise<void> {
await this.authService.verifyAccount(body.code) await this.authService.verifyAccount(body.code)
} }

12
back/volume/src/auth/auth.module.ts

@ -10,12 +10,12 @@ import { MailerModule } from '@nestjs-modules/mailer'
import { AuthService } from './auth.service' import { AuthService } from './auth.service'
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter' import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter'
const mail_user = const mailUser =
process.env.MAIL_USER && process.env.MAIL_USER !== '' process.env.MAIL_USER !== null && process.env.MAIL_USER !== ''
? process.env.MAIL_USER ? process.env.MAIL_USER
: '' : ''
const mail_pass = const mailPass =
process.env.MAIL_PASSWORD && process.env.MAIL_PASSWORD !== '' process.env.MAIL_PASSWORD !== null && process.env.MAIL_PASSWORD !== ''
? process.env.MAIL_PASSWORD ? process.env.MAIL_PASSWORD
: '' : ''
@ -32,8 +32,8 @@ const mail_pass =
transport: { transport: {
service: 'gmail', service: 'gmail',
auth: { auth: {
user: mail_user, user: mailUser,
pass: mail_pass pass: mailPass
} }
}, },
template: { template: {

15
back/volume/src/auth/auth.service.ts

@ -1,8 +1,7 @@
import { HttpException, HttpStatus, Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { type User } from 'src/users/entity/user.entity' import { type User } from 'src/users/entity/user.entity'
import { UsersService } from 'src/users/users.service' import { UsersService } from 'src/users/users.service'
import { MailerService } from '@nestjs-modules/mailer' import { MailerService } from '@nestjs-modules/mailer'
import { UserDto } from 'src/users/dto/user.dto'
@Injectable() @Injectable()
export class AuthService { export class AuthService {
@ -11,7 +10,7 @@ export class AuthService {
private readonly mailerService: MailerService private readonly mailerService: MailerService
) {} ) {}
async sendConfirmedEmail (user: User) { async sendConfirmedEmail (user: User): Promise<void> {
const { email, username } = user const { email, username } = user
await this.mailerService.sendMail({ await this.mailerService.sendMail({
to: email, to: email,
@ -24,9 +23,9 @@ export class AuthService {
}) })
} }
async sendConfirmationEmail (user: User) { async sendConfirmationEmail (user: User): Promise<void> {
user.authToken = Math.floor(10000 + Math.random() * 90000).toString() user.authToken = Math.floor(10000 + Math.random() * 90000).toString()
this.usersService.save(user) await this.usersService.save(user)
await this.mailerService.sendMail({ await this.mailerService.sendMail({
to: user.email, to: user.email,
subject: 'Welcome to ft_transcendence! Confirm Email', subject: 'Welcome to ft_transcendence! Confirm Email',
@ -40,12 +39,6 @@ export class AuthService {
async verifyAccount (code: string): Promise<boolean> { async verifyAccount (code: string): Promise<boolean> {
const user = await this.usersService.findByCode(code) const user = await this.usersService.findByCode(code)
if (!user) {
throw new HttpException(
'Verification code has expired or not found',
HttpStatus.UNAUTHORIZED
)
}
user.authToken = '' user.authToken = ''
user.isVerified = true user.isVerified = true
await this.usersService.save(user) await this.usersService.save(user)

10
back/volume/src/users/users.controller.ts

@ -139,10 +139,14 @@ export class UsersController {
@Profile42() profile: Profile, @Profile42() profile: Profile,
@Param('username') username: string @Param('username') username: string
): Promise<void> { ): Promise<void> {
const target: User | null = await this.usersService.findUserByName(username) const target: User | null = await this.usersService.findUserByName(
if (target === null) throw new BadRequestException(`User ${username} not found.`) username
)
if (target === null) {
throw new BadRequestException(`User ${username} not found.`)
}
if (+profile.id === target.ftId) { if (+profile.id === target.ftId) {
throw new BadRequestException('You can\'t invite yourself.') throw new BadRequestException("You can't invite yourself.")
} }
const ret: string = await this.usersService.invit(profile.id, target.ftId) const ret: string = await this.usersService.invit(profile.id, target.ftId)
if (ret !== 'OK') throw new BadRequestException(ret) if (ret !== 'OK') throw new BadRequestException(ret)

12
back/volume/src/users/users.service.ts

@ -167,11 +167,13 @@ export class UsersService {
(follower) => follower.ftId === targetFtId (follower) => follower.ftId === targetFtId
) )
if ( if (
target.followers.findIndex((follower) => follower.ftId === user.ftId) !== -1 target.followers.findIndex((follower) => follower.ftId === user.ftId) !==
-1
) { ) {
return 'Invitation already sent.' return 'Invitation already sent.'
} else if ( } else if (
user.followers.findIndex((follower) => follower.ftId === targetFtId) !== -1 user.followers.findIndex((follower) => follower.ftId === targetFtId) !==
-1
) { ) {
user.friends.push(target) user.friends.push(target)
target.friends.push(user) target.friends.push(user)
@ -182,13 +184,13 @@ export class UsersService {
return 'OK' return 'OK'
} }
async findByCode (code: string) { async findByCode (code: string): Promise<User> {
const user = await this.usersRepository.findOneBy({ authToken: code }) const user = await this.usersRepository.findOneBy({ authToken: code })
if (user == null) throw new BadRequestException('User not found') if (user == null) throw new BadRequestException('User not found')
return user return user
} }
async turnOnTwoFactorAuthentication (ftId: number) { async turnOnTwoFactorAuthentication (ftId: number): Promise<void> {
return await this.usersRepository.update({ ftId }, { twoFA: true}) await this.usersRepository.update({ ftId }, { twoFA: true })
} }
} }

980
front/volume/package-lock.json

File diff suppressed because it is too large

7
front/volume/package.json

@ -12,14 +12,13 @@
}, },
"devDependencies": { "devDependencies": {
"prettier": "^2.8.4", "prettier": "^2.8.4",
"prettier-plugin-svelte": "^2.9.0", "svelte-check": "^2.10.3"
"svelte-check": "^2.10.3",
"tslib": "^2.5.0",
"typescript": "^4.9.3"
}, },
"dependencies": { "dependencies": {
"@sveltejs/vite-plugin-svelte": "^2.0.2", "@sveltejs/vite-plugin-svelte": "^2.0.2",
"@tsconfig/svelte": "^3.0.0", "@tsconfig/svelte": "^3.0.0",
"@types/node": "^18.15.0",
"prettier-plugin-svelte": "^2.9.0",
"svelte": "^3.55.1", "svelte": "^3.55.1",
"vite": "^4.1.0" "vite": "^4.1.0"
} }

18
front/volume/src/App.svelte

@ -254,7 +254,10 @@
</div> </div>
{/if} {/if}
{#if appState === APPSTATE.HISTORY_ID} {#if appState === APPSTATE.HISTORY_ID}
<div on:click={() => setAppState(APPSTATE.PROFILE)} on:keydown={() => setAppState(APPSTATE.PROFILE)}> <div
on:click={() => setAppState(APPSTATE.PROFILE)}
on:keydown={() => setAppState(APPSTATE.PROFILE)}
>
<MatchHistory username={$store.username} {matches} /> <MatchHistory username={$store.username} {matches} />
</div> </div>
{/if} {/if}
@ -264,9 +267,16 @@
</div> </div>
{/if} {/if}
{#if appState === APPSTATE.PROFILE_ID} {#if appState === APPSTATE.PROFILE_ID}
<div on:click={() => setAppState(APPSTATE.CHANNELS + "#" + selectedChannel.name)} on:keydown={() => setAppState(APPSTATE.CHANNELS + "#" + selectedChannel.name)}> <div
<Profile user={userProfile} edit={0} on:click={() =>
on:view-history={openIdHistory} setAppState(APPSTATE.CHANNELS + "#" + selectedChannel.name)}
on:keydown={() =>
setAppState(APPSTATE.CHANNELS + "#" + selectedChannel.name)}
>
<Profile
user={userProfile}
edit={0}
on:view-history={openIdHistory}
/> />
</div> </div>
{/if} {/if}

8
front/volume/src/components/NavBar.svelte

@ -62,7 +62,13 @@
{/each} {/each}
</div> </div>
<button on:click={toggle}> <button on:click={toggle}>
<svg class="hamburger" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <svg
class="hamburger"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z" /> <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z" />
</svg> </svg>
</button> </button>

4
front/volume/src/components/Profile.svelte

@ -35,6 +35,7 @@
async function handle2fa(event: Event) { async function handle2fa(event: Event) {
event.preventDefault(); event.preventDefault();
user.twoFA = !user.twoFA;
let response = await fetch(API_URL, { let response = await fetch(API_URL, {
headers: { "content-type": "application/json" }, headers: { "content-type": "application/json" },
method: "POST", method: "POST",
@ -42,8 +43,7 @@
credentials: "include", credentials: "include",
}); });
if (response.ok) { if (response.ok) {
alert("Succefully " + (user.twoFA ? "disabled" : "enabled") + " 2FA"); alert("Succefully " + (user.twoFA ? "enabled" : "disabled") + " 2FA");
user.twoFA = !user.twoFA;
} }
} }
</script> </script>

2
front/volume/tsconfig.node.json

@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"composite": true, "composite": true,
"module": "ESNext", "module": "ESNext",
"moduleResolution": "Node" "moduleResolution": "Node",
}, },
"include": ["vite.config.ts"] "include": ["vite.config.ts"]
} }

Loading…
Cancel
Save