Skip to content

Commit e702f45

Browse files
committed
Fix conflicts
2 parents 5e1ae7a + 50ebcfc commit e702f45

File tree

10 files changed

+83
-50
lines changed

10 files changed

+83
-50
lines changed

backend/user-service/.env.sample

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,8 @@ USER=EMAIL_ADDRESS
2929
PASS=PASSWORD
3030

3131
# Redis configuration
32-
REDIS_URI=REDIS_URI
32+
REDIS_URI=REDIS_URI
33+
34+
# Test
35+
MONGO_URI_TEST=mongodb://mongo:mongo@test-mongo:27017/
36+
REDIS_URI_TEST=redis://test-redis:6379

backend/user-service/config/redis.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import dotenv from "dotenv";
33

44
dotenv.config();
55

6-
const REDIS_URI = process.env.REDIS_URI || "redis://localhost:6379";
6+
const REDIS_URI =
7+
process.env.NODE_ENV === "test"
8+
? process.env.REDIS_URI_TEST
9+
: process.env.REDIS_URI || "redis://localhost:6379";
710

811
const client = createClient({ url: REDIS_URI });
912

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,10 @@ export const verifyUser = async (
164164

165165
const updatedUser = await _updateUserVerification(email);
166166
if (!updatedUser) {
167-
return res.status(404).json({ message: `User ${email} not verified.` });
167+
return res.status(404).json({ message: `User not verified.` });
168168
}
169169

170-
return res
171-
.status(200)
172-
.json({ message: `User ${email} verified successfully.` });
170+
return res.status(200).json({ message: `User verified successfully.` });
173171
} catch (error) {
174172
return res
175173
.status(500)

backend/user-service/scripts/seed.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export async function seedAdminAccount() {
3838
adminUsername,
3939
adminEmail,
4040
hashedPassword,
41+
true,
4142
true
4243
);
4344
console.log("Admin account created successfully.");

backend/user-service/tests/authRoutes.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import supertest from "supertest";
44
import app from "../app";
55
import UserModel from "../model/user-model";
66

7+
jest.setTimeout(10000);
8+
79
const request = supertest(app);
810

911
const AUTH_BASE_URL = "/api/auth";
@@ -25,6 +27,7 @@ const insertAdminUser = async () => {
2527
email,
2628
password: hashedPassword,
2729
isAdmin: true,
30+
isVerified: true,
2831
}).save();
2932

3033
return { email, password };
@@ -37,6 +40,7 @@ const insertNonAdminUser = async () => {
3740
lastName,
3841
email,
3942
password: hashedPassword,
43+
isVerified: true,
4044
}).save();
4145

4246
return { email, password };

backend/user-service/tests/setup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import redisClient from "../config/redis";
33

44
beforeAll(async () => {
55
const mongoUri =
6-
process.env.MONGO_URI_TEST || "mongodb://mongo:mongo@mongo:27017/";
6+
process.env.MONGO_URI_TEST || "mongodb://mongo:mongo@test-mongo:27017/";
77

88
await mongoose.connect(mongoUri, {});
99
await redisClient.connect();

docker-compose-test.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1+
name: peerprep-test
2+
13
services:
24
test-user-service:
35
image: peerprep/user-service
46
build: ./backend/user-service
57
env_file: ./backend/user-service/.env
6-
environment:
7-
- MONGO_URI_TEST=mongodb://mongo:mongo@mongo:27017/
88
depends_on:
9-
- mongo
10-
- redis
9+
- test-mongo
10+
- test-redis
1111
networks:
1212
- peerprep-network
1313
volumes:
@@ -16,17 +16,17 @@ services:
1616
restart: on-failure
1717
command: ["npm", "test"]
1818

19-
mongo:
19+
test-mongo:
2020
image: mongo
2121
restart: always
2222
networks:
2323
- peerprep-network
2424
env_file:
2525
- ./backend/.env
2626

27-
redis:
27+
test-redis:
2828
image: redis:8.0-M01
29-
container_name: redis
29+
container_name: test-redis
3030
networks:
3131
- peerprep-network
3232
healthcheck:

frontend/src/App.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Routes, Route } from "react-router-dom";
1+
import { Routes, Route, Navigate } from "react-router-dom";
22

33
import NewQuestion from "./pages/NewQuestion";
44
import QuestionDetail from "./pages/QuestionDetail";
@@ -65,11 +65,16 @@ function App() {
6565
</Route>
6666
<Route path="*" element={<PageNotFound />} />
6767
</Route>
68-
<Route path="/auth">
68+
<Route path="auth">
69+
<Route index element={<Navigate to="/auth/login" />} />
6970
<Route path="signup" element={<SignUp />} />
7071
<Route path="login" element={<LogIn />} />
71-
<Route path="verifyEmail/:userId" element={<EmailVerification />} />
72+
<Route
73+
path="verifyEmail/:userId?"
74+
element={<EmailVerification />}
75+
/>
7276
<Route path="forget-password" element={<ForgetPassword />} />
77+
<Route path="*" element={<Navigate to="/auth/login" />} />
7378
</Route>
7479
</Routes>
7580
</MatchProvider>

frontend/src/contexts/AuthContext.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ const AuthProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
6767
.then(() => userClient.post("users/send-verification-email", { email }))
6868
.then((res) => {
6969
navigate(`/auth/verifyEmail/${res.data.data.id}`);
70-
// navigate("/login");
71-
// toast.success(res.data.message);
7270
})
7371
.catch((err) => {
7472
setUser(null);
@@ -89,6 +87,9 @@ const AuthProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
8987
navigate("/home");
9088
})
9189
.catch((err) => {
90+
if (err.response?.data.message === "User not verified.") {
91+
navigate(`/auth/verifyEmail`);
92+
}
9293
setUser(null);
9394
toast.error(err.response?.data.message || err.message);
9495
});

frontend/src/pages/EmailVerification/index.tsx

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import classes from "./index.module.css";
77
import { toast } from "react-toastify";
88

99
const EmailVerification: React.FC = () => {
10-
const { userId } = useParams<{ userId: string }>();
10+
const { userId } = useParams<{ userId?: string }>();
1111
const [token, setToken] = useState("");
1212
const [email, setEmail] = useState("");
1313
const navigate = useNavigate();
@@ -19,16 +19,17 @@ const EmailVerification: React.FC = () => {
1919
setEmail(res.data.data.email);
2020
})
2121
.catch((err) => console.error(err));
22+
// eslint-disable-next-line react-hooks/exhaustive-deps
2223
}, []);
2324

24-
const handleResend = () => {
25+
const handleSendEmail = () => {
2526
userClient
2627
.post(`/users/send-verification-email`, { email })
28+
.then((res) => toast.success(res.data.message))
2729
.catch((err) => console.error(err));
2830
};
2931

30-
const handleVerify = (e: React.FormEvent<HTMLFormElement>) => {
31-
e.preventDefault();
32+
const handleVerifyAcc = () => {
3233
userClient
3334
.get(`/users/verify-email/${email}/${token}`)
3435
.then((res) => {
@@ -59,35 +60,51 @@ const EmailVerification: React.FC = () => {
5960
})}
6061
>
6162
<Typography variant="h5">Verify your email address</Typography>
62-
<Typography sx={(theme) => ({ margin: theme.spacing(2, 0) })}>
63-
An account verification token has been sent to your email.
64-
</Typography>
65-
<form onSubmit={handleVerify}>
66-
<TextField
63+
{userId ? (
64+
<Typography sx={(theme) => ({ margin: theme.spacing(2, 0) })}>
65+
An account verification token has been sent to your email.
66+
</Typography>
67+
) : (
68+
<Typography sx={(theme) => ({ margin: theme.spacing(2, 0) })}>
69+
An account verification token will be sent to your email.
70+
</Typography>
71+
)}
72+
<TextField
73+
fullWidth
74+
margin="normal"
75+
label="Email"
76+
value={email}
77+
onChange={(e) => setEmail(e.target.value)}
78+
slotProps={{
79+
input: {
80+
endAdornment: <Button onClick={handleSendEmail}>Send</Button>,
81+
},
82+
}}
83+
/>
84+
<TextField
85+
fullWidth
86+
margin="normal"
87+
label="Token"
88+
value={token}
89+
onChange={(e) => setToken(e.target.value)}
90+
/>
91+
<Stack
92+
direction="row"
93+
spacing={2}
94+
sx={(theme) => ({ marginTop: theme.spacing(4) })}
95+
>
96+
<Button
6797
fullWidth
68-
margin="normal"
69-
label="Token"
70-
value={token}
71-
onChange={(e) => setToken(e.target.value)}
72-
/>
73-
<Stack
74-
direction="row"
75-
spacing={2}
76-
sx={(theme) => ({ marginTop: theme.spacing(4) })}
98+
variant="contained"
99+
color="secondary"
100+
onClick={handleSendEmail}
77101
>
78-
<Button
79-
fullWidth
80-
variant="contained"
81-
color="secondary"
82-
onClick={handleResend}
83-
>
84-
Resend
85-
</Button>
86-
<Button fullWidth variant="contained" type="submit">
87-
Verify
88-
</Button>
89-
</Stack>
90-
</form>
102+
Resend
103+
</Button>
104+
<Button fullWidth variant="contained" onClick={handleVerifyAcc}>
105+
Verify
106+
</Button>
107+
</Stack>
91108
</Box>
92109
</AppMargin>
93110
</Box>

0 commit comments

Comments
 (0)