Skip to content

Commit

Permalink
connected front reg and auth
Browse files Browse the repository at this point in the history
connected front reg and auth
roles for auth
  • Loading branch information
kreepslayer committed Apr 9, 2024
1 parent 74db967 commit 60a8669
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 41 deletions.
57 changes: 57 additions & 0 deletions chat-backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions chat-backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@
"@nestjs/config": "^3.2.2",
"@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/typeorm": "^10.0.2",
"bcrypt": "^5.1.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"firebase": "^10.6.0",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"pg": "^8.11.5",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1",
Expand All @@ -50,6 +53,7 @@
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/passport-jwt": "^4.0.1",
"@types/passport-local": "^1.0.38",
"@types/supertest": "^6.0.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
Expand Down
9 changes: 7 additions & 2 deletions chat-backend/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { Module } from '@nestjs/common';
import { forwardRef, Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './services/auth.service';
import { RolesGuard } from './guards/roles.guard';
import { JwtAuthGuard } from './guards/jwt-guard';
import { JwtStrategy } from './guards/jwt-srategy';
import { userModule } from 'src/users/users.module';

@Module({
imports: [
forwardRef(() => userModule),
JwtModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
Expand All @@ -14,7 +19,7 @@ import { AuthService } from './services/auth.service';
}),
}),
],
providers: [AuthService],
providers: [AuthService, RolesGuard, JwtAuthGuard, JwtStrategy],
exports: [AuthService],
})
export class AuthModule {}
4 changes: 4 additions & 0 deletions chat-backend/src/auth/decorator/roles.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { SetMetadata } from '@nestjs/common';

export const hasRoles = (...hasRoles: string[]) =>
SetMetadata('roles', hasRoles);
5 changes: 5 additions & 0 deletions chat-backend/src/auth/guards/jwt-guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
18 changes: 18 additions & 0 deletions chat-backend/src/auth/guards/jwt-srategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private ConfigService: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: ConfigService.get('JWT_SECRET'),
});
}
async validate(payload: any) {
return { user: payload.user };
}
}
34 changes: 34 additions & 0 deletions chat-backend/src/auth/guards/roles.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
ExecutionContext,
Injectable,
CanActivate,
Inject,
forwardRef,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { log } from 'console';
import { Observable } from 'rxjs';
import { UsersService } from 'src/users/service/users.service';

@Injectable()
export class RolesGuard implements CanActivate {
constructor(
private reflector: Reflector,
@Inject(forwardRef(() => UsersService))
private usersService: UsersService,
) {}

canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) {
return true;
}

const request = context.switchToHttp().getRequest();
log(request);
const user = request.user;
return true;
}
}
17 changes: 15 additions & 2 deletions chat-backend/src/users/controller/users.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,50 @@ import {
HttpException,
Patch,
Put,
UseGuards,
} from '@nestjs/common';
import { UsersService } from '../service/users.service';
import { User } from '../models/user.interfase';
import { map, type Observable, catchError, throwError, of } from 'rxjs';
import { hasRoles } from 'src/auth/decorator/roles.decorator';
import { JwtAuthGuard } from 'src/auth/guards/jwt-guard';
import { RolesGuard } from 'src/auth/guards/roles.guard';
// import { User } from 'src/schemas/User.schema';

@Controller('users')
export class UsersController {
constructor(private UsersService: UsersService) {}

@Post()
//'http://localhost:3000/users + {user}'
@Post('register')
createUser(@Body() user: User): Observable<User | Object> {
return this.UsersService.createUser(user).pipe(
map((user: User) => user),
catchError((err) => of({ error: err.message })),
);
}

// 'http://localhost:3000/users/login'
@Post('login')
@UsePipes(ValidationPipe)
login(@Body() user: User): Observable<Object> {
return this.UsersService.login(user).pipe(
map((jwt: string) => {
return { access_token: jwt };
return { access_token: jwt, success: true };
}),
catchError((err) => throwError(new HttpException(err.message, 401))),
);
}

// 'http://localhost:3000/users/:id'
@Get(':id')
getUser(@Param() params): Observable<User> {
return this.UsersService.getUserById(params.id);
}

// 'http://localhost:3000/users'
@hasRoles('Admin')
@UseGuards(JwtAuthGuard, RolesGuard)
@Get()
getAllUsers(): Observable<User[]> {
return this.UsersService.findAll();
Expand All @@ -57,4 +68,6 @@ export class UsersController {
updateUser(@Param('id') id: string, @Body() user: User): Observable<any> {
return this.UsersService.updateUser(+id, user);
}
//TODO
// @Patch(':id')
}
1 change: 1 addition & 0 deletions chat-backend/src/users/users.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ import { AuthModule } from 'src/auth/auth.module';
imports: [TypeOrmModule.forFeature([UserEntity]), AuthModule],
providers: [UsersService],
controllers: [UsersController],
exports: [UsersService],
})
export class userModule {}
4 changes: 1 addition & 3 deletions chat-frontend/src/app/component/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ export class LoginComponent {
username = '';
password = '';
login() {
this.authService.login(this.username, this.password).subscribe((data) => {
console.log(data); // log server response
});
this.authService.login(this.username, this.password);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class RegisterComponent {
console.log(passCheck.value, this.password);
if (passCheck.value == this.password) {
this.authService
.signup(this.username, this.password)
.register(this.username, this.password)
.subscribe((data) => {
console.log(data); // log server response
console.log('no errors');
Expand Down
37 changes: 27 additions & 10 deletions chat-frontend/src/app/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,43 @@ import { Observable } from 'rxjs';
})
export class AuthService {
constructor(private http: HttpClient) {}
signup(userName: string, password: string) {
avatarURL = '/none';
displayName: string = '';

register(
userName: string,
password: string,
displayName: string = userName,
avatarURL: string = '/none'
) {
this.displayName = userName;
return this.http
.post<any>('/api/users', {
.post<any>('/api/users/register', {
userName,
password,
displayName,
avatarURL,
})
.pipe(
map(({ token }) => {
localStorage.setItem('token', token);
return token;
map(({ access_token }) => {
localStorage.setItem('token', access_token);
return access_token;
})
);
}

login(userName: string, password: string) {
return this.http.get<any>(`/api/users/${userName}/${password}`, {}).pipe(
map(({ token }) => {
localStorage.setItem('token', token);
return token;
this.displayName = userName;
this.avatarURL = '/none';
return this.http
.post<any>(`/api/users/login`, {
userName,
password,
})
);
.subscribe((data) => {
console.log(data);
console.log(data.success);
localStorage.setItem('token', data.access_token);
});
}
}

0 comments on commit 60a8669

Please sign in to comment.