Skip to content

Commit 2af1d0e

Browse files
committed
Added auth samples
1 parent 066fc95 commit 2af1d0e

24 files changed

+614
-32
lines changed

client/src/components/User.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,39 @@
11
import Button from '@mui/material/Button'
22
import { UserInfo } from './Users'
33
import React, { useEffect, useState } from 'react'
4+
import TextField from '@mui/material/TextField';
45

56
interface IProps {
67
user: UserInfo
78
}
89

910
export default function User(props: IProps) {
10-
const [count, setCount] = useState<number>(0);
11+
const [count, setCount] = useState<number>(0);
12+
const [description, setDescription] = useState<string>("");
1113

12-
const clickHandler = () => {
14+
const clickHandler = () => {
1315
console.log(count + 1);
1416
setCount(count + 1);
1517
}
1618

19+
const textChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
20+
setDescription(event.target.value);
21+
}
22+
23+
useEffect(() => {
24+
let isMounted = true;
25+
console.log("useEffect called when text changed");
26+
return () => { isMounted = false }
27+
}, [description, setDescription]);
28+
1729
return (
1830
<>
1931
<h3>Имя пользователя: {props.user.username}</h3>
2032
<h3>ФИО: {props.user.fullname}</h3>
2133
<h3>email: {props.user.email}</h3>
2234
<h3>Count: {count}</h3>
35+
<TextField id="outlined-basic" label="Description" variant="outlined" onChange={textChanged} />
36+
<p>{description}</p>
2337
<Button variant="contained" onClick={clickHandler}>Contained</Button>
2438
</>
2539
)

client/src/components/Users.tsx

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,6 @@ const getUsers = async ():Promise<UserInfo[]> => {
1212
const resp = await fetch("/api/users");
1313
const data = await resp.json();
1414
return data;
15-
// console.log(data);
16-
17-
// const users: UserInfo[] =
18-
// [
19-
// {
20-
// id: "de1b01ad-c4aa-45d9-8147-c091ce89cd02",
21-
// username: "testuser",
22-
// fullname: "test",
23-
// email: "test@test.ru"
24-
// },
25-
// {
26-
// id: "de1b01ad-c4aa-45d9-8147-c091ce89cd01",
27-
// username: "testuser2",
28-
// fullname: "test2",
29-
// email: "222@test2.ru"
30-
// }
31-
// ]
32-
// const promise = new Promise<UserInfo[]>((res, rej) =>{
33-
// setTimeout(()=>{
34-
// res(users);
35-
// }, 5000)
36-
// });
37-
// return promise;
38-
3915
}
4016

4117

server/.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"version": "0.2.0",
66
"configurations": [
77
{
8-
"type": "pwa-node",
8+
"type": "node",
99
"request": "launch",
1010
"name": "Launch Server",
1111
"cwd": "${workspaceRoot}",

server/migrations/.snapshot-webdev.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@
4444
"nullable": false,
4545
"length": 255,
4646
"mappedType": "string"
47+
},
48+
"password": {
49+
"name": "password",
50+
"type": "varchar(255)",
51+
"unsigned": false,
52+
"autoincrement": false,
53+
"primary": false,
54+
"nullable": false,
55+
"length": 255,
56+
"mappedType": "string"
4757
}
4858
},
4959
"name": "user",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Migration } from '@mikro-orm/migrations';
2+
3+
export class Migration20241116145833 extends Migration {
4+
5+
override async up(): Promise<void> {
6+
this.addSql(`alter table "user" add column "password" varchar(255) not null default 'changeme';`);
7+
}
8+
9+
override async down(): Promise<void> {
10+
this.addSql(`alter table "user" drop column "password";`);
11+
}
12+
13+
}

server/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,15 @@
3838
"@mikro-orm/postgresql": "^6.3.11",
3939
"@nestjs/common": "^10.4.4",
4040
"@nestjs/core": "^10.4.4",
41+
"@nestjs/jwt": "^10.2.0",
4142
"@nestjs/mapped-types": "^2.0.5",
43+
"@nestjs/passport": "^10.0.3",
4244
"@nestjs/platform-express": "^10.4.4",
4345
"@nestjs/typeorm": "^10.0.2",
46+
"passport": "^0.7.0",
47+
"passport-google-oauth": "^2.0.0",
48+
"passport-jwt": "^4.0.1",
49+
"passport-local": "^1.0.0",
4450
"pg": "^8.13.0",
4551
"reflect-metadata": "^0.2.2",
4652
"rimraf": "^6.0.1",
@@ -52,6 +58,9 @@
5258
"@nestjs/testing": "^10.4.4",
5359
"@types/jest": "29.5.13",
5460
"@types/node": "^22.7.3",
61+
"@types/passport-google-oauth": "^1.0.45",
62+
"@types/passport-jwt": "^4.0.1",
63+
"@types/passport-local": "^1.0.38",
5564
"@types/supertest": "^6.0.2",
5665
"@typescript-eslint/eslint-plugin": "8.7.0",
5766
"@typescript-eslint/parser": "8.7.0",

server/src/app.controller.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,48 @@
1-
import { Controller, Get } from '@nestjs/common';
1+
import { Controller, Get, Post, Request, UseGuards } from '@nestjs/common';
22
import { AppService } from './app.service';
3+
import { LocalAuthGuard } from './auth/local-auth.guard';
4+
import { AuthService } from './auth/auth.service';
5+
import { GoogleStrategy } from './auth/google.strategy';
6+
import { GoogleAuthGuard } from './auth/google-auth.guard';
37

48
@Controller()
59
export class AppController {
6-
constructor(private readonly appService: AppService) {}
10+
constructor(
11+
private readonly appService: AppService,
12+
private authService: AuthService,
13+
private googleStrategy: GoogleStrategy,
14+
) {}
715

816
@Get()
917
getHello(): string {
1018
return this.appService.getHello();
1119
}
20+
21+
@UseGuards(LocalAuthGuard)
22+
@Post('auth/login')
23+
async login(@Request() req) {
24+
return this.authService.login(req.user);
25+
}
26+
27+
@UseGuards(LocalAuthGuard)
28+
@Post('auth/logout')
29+
async logout(@Request() req) {
30+
return req.logout();
31+
}
32+
33+
@UseGuards(GoogleAuthGuard)
34+
@Get('auth/google-login')
35+
async googleLogin(@Request() req) {
36+
console.log('request', req);
37+
return this.googleStrategy.authenticate(req);
38+
}
39+
40+
@UseGuards(GoogleAuthGuard)
41+
@Get('auth/google/google-redirect')
42+
async googleLoginCallback(@Request() req) {
43+
console.log(req);
44+
console.log('REDIrect');
45+
return req.user;
46+
// return this.googleStrategy.validate(req);
47+
}
1248
}

server/src/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { MikroOrmModule } from '@mikro-orm/nestjs';
66
import { PostgreSqlDriver } from '@mikro-orm/postgresql';
77
import { UsersModule } from './users/users.module';
88
import { User } from './users/entities/user.entity';
9+
import { AuthModule } from './auth/auth.module';
910

1011
@Module({
1112
imports: [
@@ -28,6 +29,7 @@ import { User } from './users/entities/user.entity';
2829
},
2930
}),
3031
UsersModule,
32+
AuthModule,
3133
],
3234
controllers: [AppController, DemoController],
3335
providers: [AppService],

server/src/auth/auth.module.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Module } from '@nestjs/common';
2+
import { AuthService } from './auth.service';
3+
import { UsersModule } from '../users/users.module';
4+
import { LocalStrategy } from './local.strategy';
5+
import { PassportModule } from '@nestjs/passport';
6+
import { JwtModule } from '@nestjs/jwt';
7+
import { jwtConstants } from './constants';
8+
import { JwtStrategy } from './jwt.strategy';
9+
import { GoogleStrategy } from './google.strategy';
10+
11+
12+
@Module({
13+
imports: [
14+
UsersModule,
15+
PassportModule,
16+
JwtModule.register({
17+
secret: jwtConstants.secret,
18+
signOptions: { expiresIn: '60s' },
19+
}),
20+
],
21+
providers: [AuthService, LocalStrategy, JwtStrategy, GoogleStrategy],
22+
exports: [AuthService, GoogleStrategy],
23+
})
24+
export class AuthModule {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { AuthService } from './auth.service';
3+
4+
describe('AuthService', () => {
5+
let service: AuthService;
6+
7+
beforeEach(async () => {
8+
const module: TestingModule = await Test.createTestingModule({
9+
providers: [AuthService],
10+
}).compile();
11+
12+
service = module.get<AuthService>(AuthService);
13+
});
14+
15+
it('should be defined', () => {
16+
expect(service).toBeDefined();
17+
});
18+
});

0 commit comments

Comments
 (0)