Skip to content

Commit cf564ab

Browse files
committed
Merge branch 'development' of https://github.com/ruiqi7/peer-prep into feature/user-authentication
2 parents c659144 + c8d996a commit cf564ab

File tree

25 files changed

+1331
-182
lines changed

25 files changed

+1331
-182
lines changed

backend/user-service/controller/user-controller.ts

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,19 @@ export async function createUser(
3434
.json({ message: "Username or email already exists" });
3535
}
3636

37-
// TODO: validate first and last name
3837
if (firstName && lastName && username && email && password) {
38+
const { isValid: isValidFirstName, message: firstNameMessage } =
39+
validateName(firstName, "first name");
40+
if (!isValidFirstName) {
41+
return res.status(400).json({ message: firstNameMessage });
42+
}
43+
44+
const { isValid: isValidLastName, message: lastNameMessage } =
45+
validateName(lastName, "last name");
46+
if (!isValidLastName) {
47+
return res.status(400).json({ message: lastNameMessage });
48+
}
49+
3950
const { isValid: isValidUsername, message: usernameMessage } =
4051
validateUsername(username);
4152
if (!isValidUsername) {
@@ -56,12 +67,13 @@ export async function createUser(
5667

5768
const salt = bcrypt.genSaltSync(10);
5869
const hashedPassword = bcrypt.hashSync(password, salt);
70+
5971
const createdUser = await _createUser(
6072
firstName,
6173
lastName,
6274
username,
6375
email,
64-
hashedPassword
76+
hashedPassword,
6577
);
6678
return res.status(201).json({
6779
message: `Created new user ${username} successfully`,
@@ -128,18 +140,15 @@ export async function updateUser(
128140
): Promise<Response> {
129141
try {
130142
const {
131-
username,
132-
email,
133-
password,
143+
oldPassword,
144+
newPassword,
134145
profilePictureUrl,
135146
firstName,
136147
lastName,
137148
biography,
138149
} = req.body;
139150
if (
140-
username ||
141-
email ||
142-
password ||
151+
(oldPassword && newPassword) ||
143152
profilePictureUrl ||
144153
firstName ||
145154
lastName ||
@@ -156,42 +165,23 @@ export async function updateUser(
156165
return res.status(404).json({ message: `User ${userId} not found` });
157166
}
158167

159-
if (username) {
160-
const { isValid: isValidUsername, message: usernameMessage } =
161-
validateUsername(username);
162-
if (!isValidUsername) {
163-
return res.status(400).json({ message: usernameMessage });
164-
}
165-
166-
const existingUser = await _findUserByUsername(username);
167-
if (existingUser && existingUser.id !== userId) {
168-
return res.status(409).json({ message: "username already exists" });
169-
}
170-
}
171-
172-
if (email) {
173-
const { isValid: isValidEmail, message: emailMessage } =
174-
validateEmail(email);
175-
if (!isValidEmail) {
176-
return res.status(400).json({ message: emailMessage });
168+
let hashedPassword: string | undefined;
169+
if (oldPassword && newPassword) {
170+
const match = await bcrypt.compare(oldPassword, user.password);
171+
if (!match) {
172+
return res
173+
.status(403)
174+
.json({ message: "Wrong current password given" });
177175
}
178176

179-
const existingUser = await _findUserByEmail(email);
180-
if (existingUser && existingUser.id !== userId) {
181-
return res.status(409).json({ message: "email already exists" });
182-
}
183-
}
184-
185-
let hashedPassword: string | undefined;
186-
if (password) {
187177
const { isValid: isValidPassword, message: passwordMessage } =
188-
validatePassword(password);
178+
validatePassword(newPassword);
189179
if (!isValidPassword) {
190180
return res.status(400).json({ message: passwordMessage });
191181
}
192182

193183
const salt = bcrypt.genSaltSync(10);
194-
hashedPassword = bcrypt.hashSync(password, salt);
184+
hashedPassword = bcrypt.hashSync(newPassword, salt);
195185
}
196186

197187
if (firstName) {
@@ -220,8 +210,6 @@ export async function updateUser(
220210

221211
const updatedUser = await _updateUserById(
222212
userId,
223-
username,
224-
email,
225213
hashedPassword,
226214
profilePictureUrl,
227215
firstName,

backend/user-service/model/repository.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export async function createUser(
2121
isAdmin: boolean = false
2222
): Promise<IUser> {
2323
return new UserModel({
24-
firstName: firstName,
25-
lastName: lastName,
24+
firstName,
25+
lastName,
2626
username,
2727
email,
2828
password,
@@ -59,8 +59,6 @@ export async function findAllUsers(): Promise<IUser[]> {
5959

6060
export async function updateUserById(
6161
userId: string,
62-
username: string,
63-
email: string,
6462
password: string | undefined,
6563
profilePictureUrl: string,
6664
firstName: string,
@@ -71,8 +69,6 @@ export async function updateUserById(
7169
userId,
7270
{
7371
$set: {
74-
username,
75-
email,
7672
password,
7773
profilePictureUrl,
7874
firstName,

backend/user-service/model/user-model.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export interface IUser extends Document {
88
isAdmin: boolean;
99

1010
profilePictureUrl?: string;
11-
firstName?: string;
12-
lastName?: string;
11+
firstName: string;
12+
lastName: string;
1313
biography?: string;
1414
}
1515

@@ -43,11 +43,11 @@ const UserModelSchema: Schema<IUser> = new mongoose.Schema({
4343
},
4444
firstName: {
4545
type: String,
46-
required: false,
46+
required: true,
4747
},
4848
lastName: {
4949
type: String,
50-
required: false,
50+
required: true,
5151
},
5252
biography: {
5353
type: String,

backend/user-service/swagger.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,58 @@ paths:
179179
required: true
180180
schema:
181181
type: string
182+
requestBody:
183+
content:
184+
application/json:
185+
schema:
186+
type: object
187+
properties:
188+
oldPassword:
189+
type: string
190+
required: false
191+
newPassword:
192+
type: string
193+
required: false
194+
firstName:
195+
type: string
196+
required: false
197+
lastName:
198+
type: string
199+
required: false
200+
biography:
201+
type: string
202+
required: false
203+
responses:
204+
200:
205+
description: Successful Response
206+
content:
207+
application/json:
208+
schema:
209+
$ref: "#/components/schemas/UserResponse"
210+
400:
211+
description: Bad Request
212+
content:
213+
application/json:
214+
schema:
215+
$ref: "#/components/schemas/ErrorResponse"
216+
403:
217+
description: Forbidden
218+
content:
219+
application/json:
220+
schema:
221+
$ref: "#/components/schemas/ErrorResponse"
222+
404:
223+
description: Not Found
224+
content:
225+
application/json:
226+
schema:
227+
$ref: "#/components/schemas/ErrorResponse"
228+
500:
229+
description: Internal Server Error
230+
content:
231+
application/json:
232+
schema:
233+
$ref: "#/components/schemas/ErrorResponse"
182234
delete:
183235
summary: Delete a user account
184236
tags:

frontend/package-lock.json

Lines changed: 63 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"@types/react-dom": "^18.3.0",
4242
"@types/uuid": "^10.0.0",
4343
"@vitejs/plugin-react": "^4.3.1",
44+
"babel-jest": "^29.7.0",
4445
"eslint": "^9.9.0",
4546
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
4647
"eslint-plugin-react-refresh": "^0.4.9",

0 commit comments

Comments
 (0)