Skip to content

Commit

Permalink
Merge pull request #52 from pcode-at/feature/create-project
Browse files Browse the repository at this point in the history
Feature/create project
  • Loading branch information
t-graski authored Jul 20, 2022
2 parents d91884e + b08fc6e commit 195e393
Show file tree
Hide file tree
Showing 15 changed files with 285 additions and 147 deletions.
12 changes: 10 additions & 2 deletions backend/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
import { Body, Controller, Post, Req, UseGuards } from "@nestjs/common";
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
import { AuthService } from "./auth.service";
import { LoginDto } from "./dto/login.dto";
import { AuthorizationResponse } from "./entities/authorization.entity";
import { LocalAuthGuard } from "./local-auth.guard";
import { JwtRefreshTokenAuthGuard } from "./refresh/refresh-auth.guard";

@ApiBearerAuth()
@ApiTags("auth")
@Controller("/api/auth")
export class AuthController {
constructor(private readonly authService: AuthService) { }
constructor(private readonly authService: AuthService) {}

@UseGuards(LocalAuthGuard)
@Post("/login")
@ApiOperation({ summary: "Login" })
@ApiResponse({ status: 201, type: AuthorizationResponse })
async login(@Body() body: LoginDto): Promise<AuthorizationResponse> {
return this.authService.login(body);
}

@UseGuards(JwtRefreshTokenAuthGuard)
@Post("/refresh")
@ApiOperation({ summary: "Refresh token" })
@ApiResponse({ status: 201, type: AuthorizationResponse })
async refresh(@Req() request): Promise<AuthorizationResponse> {
return new AuthorizationResponse({
statusCode: 201,
message: "Token refreshed",
data: {
accessToken: request.user
accessToken: request.user,
refreshToken: null,
},
});
}
Expand Down
12 changes: 6 additions & 6 deletions backend/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import { UserEntity } from "src/entities/user.entity";
import { UserService } from "src/user/user.service";
import { jwtConstants } from "./constants";
import { LoginDto } from "./dto/login.dto";
import { Authorization, AuthorizationResponse } from "./entities/authorization.entity";
import { AuthorizationEntity, AuthorizationResponse } from "./entities/authorization.entity";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const bcrypt = require('bcrypt');
const bcrypt = require("bcrypt");

@Injectable()
export class AuthService {
constructor(private readonly userService: UserService, private readonly jwtService: JwtService) { }
constructor(private readonly userService: UserService, private readonly jwtService: JwtService) {}

async validateUser(identifier: string, pass: string): Promise<any> {
const user = (await this.userService.findOne(identifier)).data as UserEntity;

if (user && await bcrypt.compare(pass, user.password)) {
if (user && (await bcrypt.compare(pass, user.password))) {
const { password, ...result } = user;
return result;
}
Expand All @@ -26,7 +26,7 @@ export class AuthService {
const userIdentifier = { identifier: payload.identifier };
const accessToken = this.jwtService.sign(userIdentifier);
const refreshToken = this.jwtService.sign({ identifier: { userIdentifier } }, { expiresIn: jwtConstants.refreshTokenExpiryTime });
const authorization = new Authorization({
const authorization = new AuthorizationEntity({
accessToken,
refreshToken,
});
Expand All @@ -36,7 +36,7 @@ export class AuthService {
return new AuthorizationResponse({
statusCode: 200,
message: "Login successful",
data: authorization
data: authorization,
});
}

Expand Down
41 changes: 29 additions & 12 deletions backend/src/auth/entities/authorization.entity.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,40 @@
import { ApiProperty } from "@nestjs/swagger";
import { HttpResponse } from "src/entities/http-response.entity";

export class AuthorizationResponse implements HttpResponse, Authorization {
statusCode: number;
error?: string;
message: string;
data?: any;
export class AuthorizationEntity {
accessToken: string;
refreshToken: string;

constructor(partial: Partial<AuthorizationResponse>) {
constructor(partial: Partial<AuthorizationEntity>) {
Object.assign(this, partial);
}
accessToken: string;
refreshToken: string;
}

export class Authorization {
accessToken: string;
refreshToken: string;
export class AuthorizationResponse implements HttpResponse {
@ApiProperty({ example: "200", description: "HTTP status code" })
statusCode: number;

@ApiProperty({ example: "Locations found", description: "Message" })
message: string;

error?: string;

constructor(partial: Partial<Authorization>) {
@ApiProperty({
example: [
{
refreshToken:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGlmaWVyIjp7InVzZXJJZGVudGlmaWVyIjp7ImlkZW50aWZpZXIiOiJhYmMifX0sImlhdCI6MTY1NzExMDE0OSwiZXhwIjoxNjU3NzE0OTQ5fQ.2ElXSU7zacLs2GScN4GJG56bNMnQmRMXwFPihFfq1EY",
accessToken:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGlmaWVyIjp7InVzZXJJZGVudGlmaWVyIjp7ImlkZW50aWZpZXIiOiJhYmMifX0sImlhdCI6MTY1NzExMDE0OSwiZXhwIjoxNjU3NzE0OTQ5fQ.2ElXSU7zacLs2GScN4GJG56bNMnQmRMXwFPihFfq1EY",
},
],
description: "Authorization",
})
data?: AuthorizationEntity;

constructor(partial: Partial<AuthorizationResponse>) {
Object.assign(this, partial);
}
}


4 changes: 2 additions & 2 deletions backend/src/auth/refresh/refresh.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Request } from "express";
import { jwtConstants } from "../constants";
import { PassportStrategy } from "@nestjs/passport";
import { UserService } from "src/user/user.service";
import { Authorization, AuthorizationResponse } from "../entities/authorization.entity";
import { AuthorizationEntity } from "../entities/authorization.entity";

@Injectable()
export class RefreshStrategy extends PassportStrategy(Strategy, "jwt-refresh-token") {
Expand All @@ -31,7 +31,7 @@ export class RefreshStrategy extends PassportStrategy(Strategy, "jwt-refresh-tok
throw new UnauthorizedException();
}
const newToken = await this.refreshService.getNewJwtToken(identifier);
await this.userService.updateAuthorization(identifier, new Authorization({ accessToken: newToken }));
await this.userService.updateAuthorization(identifier, new AuthorizationEntity({ accessToken: newToken }));
return newToken;
}
}
31 changes: 19 additions & 12 deletions backend/src/entities/location.entity.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import { ApiProperty, ApiResponseProperty } from "@nestjs/swagger";
import { HttpResponse } from "./http-response.entity";

export class LocationResponse implements HttpResponse {
statusCode: number;
message: string;
error?: string;
data?: LocationEntity | LocationEntity[];
@ApiProperty({ example: "200", description: "HTTP status code" })
statusCode: number;

constructor(partial: Partial<LocationResponse>) {
Object.assign(this, partial);
}
@ApiProperty({ example: "Locations found", description: "Message" })
message: string;

error?: string;

@ApiProperty({ example: [{ location: "USA" }], description: "Locations" })
data?: LocationEntity | LocationEntity[];

constructor(partial: Partial<LocationResponse>) {
Object.assign(this, partial);
}
}

export class LocationEntity {
location: String;
location: String;

constructor(partial: Partial<LocationEntity>) {
Object.assign(this, partial);
}
}
constructor(partial: Partial<LocationEntity>) {
Object.assign(this, partial);
}
}
64 changes: 40 additions & 24 deletions backend/src/entities/project.entity.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,52 @@
import { ApiProperty } from "@nestjs/swagger";
import { Exclude } from "class-transformer";
import { HttpResponse } from "./http-response.entity";

export class ProjectResponse implements HttpResponse {
statusCode: number;
message: string;
error?: string;
data?: ProjectEntity | ProjectEntity[];

@ApiProperty({ example: "200", description: "HTTP status code" })
statusCode: number;

@ApiProperty({ example: "Locations found", description: "Message" })
message: string;

error?: string;

@ApiProperty({
example: [
{
name: "Project Bluebird",
description: "Project Bluebird is a CIA project that researched interragtion methods.",
creationDate: "1951-05-12",
lastEdited: "1981-02-04",
status: "Discontinued",
},
],
description: "Projects",
})
data?: ProjectEntity | ProjectEntity[];
}

export class ProjectEntity {
id: string;
name: string;
description: string;
creationDate: Date;
lastEdited: Date;
status: string;

id: string;
name: string;
description: string;
creationDate: Date;
lastEdited: Date;
status: string;

@Exclude()
creatorId: string;
@Exclude()
creatorId: string;

@Exclude()
memberIds: string[];
@Exclude()
memberIds: string[];

@Exclude()
skillIds: string[];
@Exclude()
skillIds: string[];

@Exclude()
bookmarkIds: string[]
@Exclude()
bookmarkIds: string[];

constructor(partial: Partial<ProjectEntity>) {
Object.assign(this, partial);
}
}
constructor(partial: Partial<ProjectEntity>) {
Object.assign(this, partial);
}
}
18 changes: 16 additions & 2 deletions backend/src/entities/skill.entity.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import { ApiProperty } from "@nestjs/swagger";
import { Exclude } from "class-transformer";
import { HttpResponse } from "./http-response.entity";

export class SkillResponse implements HttpResponse {
@ApiProperty({ example: "200", description: "HTTP status code" })
statusCode: number;

@ApiProperty({ example: "Locations found", description: "Message" })
message: string;

error?: string;
@ApiProperty({
examples: [
{ id: "62ce572313abfde432", name: "CIA" },
{
id: "62ce572313abfde432",
name: "FBI",
opacity: 0.5,
},
],
description: "Skills",
})
data?: SkillEntity | SkillEntity[];
id: string;
name: string;

constructor(partial: Partial<SkillResponse>) {
Object.assign(this, partial);
Expand Down
22 changes: 22 additions & 0 deletions backend/src/entities/user-response.entity.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
import { ApiProperty } from "@nestjs/swagger";
import { Exclude } from "class-transformer";
import { HttpResponse } from "./http-response.entity";
import { UserEntity } from "./user.entity";

export class UserResponse implements HttpResponse {
@ApiProperty({ example: "200", description: "HTTP status code" })
statusCode: number;

@ApiProperty({ example: "Locations found", description: "Message" })
message: string;

error?: string;
@ApiProperty({
example: [
{
birthdate: "1956-04-04",
email: "john@example.com",
gender: "m",
identifier: "Burn",
location: "USA",
phoneNumber: "+1 252-555-612",
name: "William J. Burns",
departments: ["Development"],
roles: ["Manager"],
photo: "84593u5ijtirhjetiherterkt.png",
},
],
description: "Users",
})
data?: UserEntity | UserEntity[];

constructor(partial: Partial<UserResponse>) {
Expand Down
40 changes: 22 additions & 18 deletions backend/src/project/dto/create-project.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,31 @@ import { ApiProperty } from "@nestjs/swagger";
import { IsNotEmpty } from "class-validator";

export class CreateProjectDto {
@ApiProperty()
@IsNotEmpty()
name: string;
@ApiProperty()
@IsNotEmpty()
name: string;

@ApiProperty()
@IsNotEmpty()
description: string;
@ApiProperty()
@IsNotEmpty()
description: string;

@ApiProperty()
@IsNotEmpty()
creationDate: Date;
@ApiProperty()
@IsNotEmpty()
creationDate: Date;

@ApiProperty()
@IsNotEmpty()
lastEdited: Date;
@ApiProperty()
@IsNotEmpty()
lastEdited: Date;

@ApiProperty()
@IsNotEmpty()
status: string;
@ApiProperty()
@IsNotEmpty()
status: string;

@ApiProperty()
@IsNotEmpty()
creatorId: string;
@ApiProperty()
@IsNotEmpty()
creatorId: string;

@ApiProperty()
@IsNotEmpty()
skills: any[];
}
Loading

0 comments on commit 195e393

Please sign in to comment.