Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,170 --> 00:00:03,560
Okay, so now that we've got
2
00:00:03,560 --> 00:00:06,480
this protection code here in place,
3
00:00:06,480 --> 00:00:09,040
in the next step, we know that this request
4
00:00:09,040 --> 00:00:11,270
is coming from an authenticated user
5
00:00:11,270 --> 00:00:15,570
and we know that it's a request with the right method.
6
00:00:15,570 --> 00:00:17,640
So now we need to extract data
7
00:00:17,640 --> 00:00:21,100
from the incoming request, the old and the new password
8
00:00:21,100 --> 00:00:25,910
and we will also need the email address of that user
9
00:00:25,910 --> 00:00:27,950
because of course, in the database,
10
00:00:27,950 --> 00:00:30,600
we store users with emails and passwords
11
00:00:30,600 --> 00:00:33,140
and if we wanna change the password of a user,
12
00:00:33,140 --> 00:00:35,920
we need that email address of the user as well
13
00:00:35,920 --> 00:00:38,470
to identify that user.
14
00:00:38,470 --> 00:00:41,940
Thankfully, getting that email address is not too difficult
15
00:00:41,940 --> 00:00:44,390
even though it's not part of this form here
16
00:00:44,390 --> 00:00:49,240
because we do encode the email address in our token.
17
00:00:49,240 --> 00:00:53,870
We return that object here in our nextauth file
18
00:00:53,870 --> 00:00:56,190
and that data ends up in the token
19
00:00:56,190 --> 00:00:59,283
and therefore, it's part of that session, which we get here.
20
00:01:00,270 --> 00:01:02,770
So we can get the userEmail
21
00:01:02,770 --> 00:01:07,770
by accessing session.user.email here
22
00:01:09,390 --> 00:01:11,680
and we can then also get the other data,
23
00:01:11,680 --> 00:01:15,330
like the oldPassword by reaching out
24
00:01:15,330 --> 00:01:16,900
to the request
25
00:01:16,900 --> 00:01:19,820
and there the body field as we learned it.
26
00:01:19,820 --> 00:01:22,310
So that's what we also do in the signup.js file
27
00:01:22,310 --> 00:01:23,760
when we create a user.
28
00:01:23,760 --> 00:01:27,070
There we also get the email and password
29
00:01:27,070 --> 00:01:29,803
by diving into the request.body in the end.
30
00:01:31,870 --> 00:01:32,910
And here in change-password,
31
00:01:32,910 --> 00:01:36,110
we could, for example, expect that on the body,
32
00:01:36,110 --> 00:01:39,810
we got a oldPassword field
33
00:01:39,810 --> 00:01:42,120
and then we got the newPassword,
34
00:01:42,120 --> 00:01:44,270
which we get from request.body.newPassword.
35
00:01:45,810 --> 00:01:47,550
Of course, we'll have to make sure
36
00:01:47,550 --> 00:01:49,860
that when we send the request from the client
37
00:01:49,860 --> 00:01:51,250
to the server later,
38
00:01:51,250 --> 00:01:54,080
that we have old and newPassword,
39
00:01:54,080 --> 00:01:57,860
that we have these two fields in the request data,
40
00:01:57,860 --> 00:02:00,193
which we attach to the outgoing request.
41
00:02:01,160 --> 00:02:03,820
And with that, we've got all the data we need.
42
00:02:03,820 --> 00:02:06,030
Now we wanna connect to the database
43
00:02:06,030 --> 00:02:08,680
and find a user by that email
44
00:02:08,680 --> 00:02:10,389
and then once we got that user,
45
00:02:10,389 --> 00:02:13,220
we wanna check if the oldPassword is correct,
46
00:02:13,220 --> 00:02:16,040
so if it matches the password currently stored
47
00:02:16,040 --> 00:02:17,260
in the database
48
00:02:17,260 --> 00:02:18,720
and if that's then the case,
49
00:02:18,720 --> 00:02:21,190
we wanna hash the newPassword
50
00:02:21,190 --> 00:02:25,043
and replace the oldPassword with the new one.
51
00:02:26,180 --> 00:02:31,150
And for this, of course, we can call connectToDatabase again
52
00:02:31,150 --> 00:02:35,563
and import that from our lib/db file like this.
53
00:02:37,350 --> 00:02:39,750
And then here call connectToDatabase
54
00:02:39,750 --> 00:02:41,790
and await this, of course
55
00:02:41,790 --> 00:02:44,280
and here we then get the client.
56
00:02:44,280 --> 00:02:46,280
And then once we got the client,
57
00:02:46,280 --> 00:02:48,530
we can reach out to the database
58
00:02:48,530 --> 00:02:50,850
and then there to the collection
59
00:02:50,850 --> 00:02:54,853
that stores our users, which is the users collection here.
60
00:02:56,970 --> 00:03:00,889
So here we then reach out to the users collection.
61
00:03:00,889 --> 00:03:01,722
usersCollection.
62
00:03:01,722 --> 00:03:05,920
I can store access to that collection in a separate constant
63
00:03:05,920 --> 00:03:10,030
and then we can use that usersCollection to findOne user
64
00:03:10,030 --> 00:03:13,010
by email as we did it before as well
65
00:03:13,010 --> 00:03:15,770
in the authentication code.
66
00:03:15,770 --> 00:03:18,197
There we also find a user by email
67
00:03:18,197 --> 00:03:20,780
and now we're going to do the same thing here.
68
00:03:20,780 --> 00:03:23,430
We look for the email field in our documents
69
00:03:23,430 --> 00:03:25,710
and check if we find one document
70
00:03:25,710 --> 00:03:28,620
where the email address stored in the document
71
00:03:28,620 --> 00:03:31,603
is equal to the userEmail we get from the session.
72
00:03:32,600 --> 00:03:34,930
Now, this will return a promise,
73
00:03:34,930 --> 00:03:39,220
so we await that and then we'll get a user document
74
00:03:39,220 --> 00:03:42,510
or not but if we somehow don't find a user,
75
00:03:42,510 --> 00:03:44,180
something is wrong anyways
76
00:03:44,180 --> 00:03:47,470
because that userEmail is coming from the session,
77
00:03:47,470 --> 00:03:50,450
so it would be strange if we have a logged in user
78
00:03:50,450 --> 00:03:54,520
and yet he or she is missing from the database.
79
00:03:54,520 --> 00:03:57,123
But still, we can also handle that case.
80
00:03:58,210 --> 00:04:00,140
Close our connection here
81
00:04:00,140 --> 00:04:03,190
and then possibly also return some error.
82
00:04:03,190 --> 00:04:05,370
This could be a 404 error
83
00:04:05,370 --> 00:04:10,370
where we say user not found or something like this.
84
00:04:12,360 --> 00:04:14,240
Now, if we make it past this check,
85
00:04:14,240 --> 00:04:15,830
which we typically should,
86
00:04:15,830 --> 00:04:18,209
we can now verify the password.
87
00:04:18,209 --> 00:04:20,180
So we get the currentPassword
88
00:04:20,180 --> 00:04:22,910
by accessing user.password.
89
00:04:22,910 --> 00:04:26,070
So this user document, which we get from the database
90
00:04:26,070 --> 00:04:27,860
and there, the password field,
91
00:04:27,860 --> 00:04:29,933
which is this hashed password.
92
00:04:31,020 --> 00:04:32,920
That's the currentPassword now
93
00:04:32,920 --> 00:04:34,770
and now we wanna verify this
94
00:04:34,770 --> 00:04:37,300
and for that, in the lib folder,
95
00:04:37,300 --> 00:04:42,300
we have this auth.js file with the verifyPassword function.
96
00:04:42,570 --> 00:04:44,690
And I wanna call this function now
97
00:04:46,180 --> 00:04:51,180
and hence, we need to import verifyPassword from lib/auth.
98
00:04:51,280 --> 00:04:53,320
We need to add this import
99
00:04:54,720 --> 00:04:58,590
and with it imported, we can call verifyPassword
100
00:04:58,590 --> 00:05:02,490
and pass in the incoming password,
101
00:05:02,490 --> 00:05:05,620
so the oldPassword in our case,
102
00:05:05,620 --> 00:05:07,760
as a first argument
103
00:05:07,760 --> 00:05:10,440
and then the stored hashed password
104
00:05:10,440 --> 00:05:12,080
to which we wanna compare it.
105
00:05:12,080 --> 00:05:16,423
So this currentPassword here as a second argument.
106
00:05:17,710 --> 00:05:19,130
And we then await this
107
00:05:19,130 --> 00:05:21,420
because that returns a promise
108
00:05:21,420 --> 00:05:24,730
and we get back the answer to the question
109
00:05:24,730 --> 00:05:28,030
whether the passwords are equal or not.
110
00:05:28,030 --> 00:05:30,630
And if they are not equal,
111
00:05:30,630 --> 00:05:32,373
if not passwordsAreEqual,
112
00:05:33,840 --> 00:05:36,180
if that is false, then we know
113
00:05:36,180 --> 00:05:40,690
that the old password entered here simply does not match
114
00:05:40,690 --> 00:05:42,360
the user's password.
115
00:05:42,360 --> 00:05:45,040
And in this case, we don't wanna allow the user
116
00:05:45,040 --> 00:05:47,620
to change the password, of course.
117
00:05:47,620 --> 00:05:49,420
So here we wanna return.
118
00:05:49,420 --> 00:05:54,063
We wanna also close our client connection.
119
00:05:55,150 --> 00:05:57,890
And we wanna send back a response
120
00:05:57,890 --> 00:06:01,460
where the status code could be 403,
121
00:06:01,460 --> 00:06:05,980
not 401 as it was before but 403
122
00:06:05,980 --> 00:06:08,800
where we say you are authenticated,
123
00:06:08,800 --> 00:06:11,300
that's why it's not 401,
124
00:06:11,300 --> 00:06:14,743
but you're not authorized for this operation.
125
00:06:14,743 --> 00:06:17,480
You simply do not have the permissions
126
00:06:17,480 --> 00:06:19,460
to perform this operation
127
00:06:19,460 --> 00:06:21,670
even though you're authenticated.
128
00:06:21,670 --> 00:06:24,660
And in this case, the user doesn't have the permissions
129
00:06:24,660 --> 00:06:26,820
for this specific operation
130
00:06:26,820 --> 00:06:29,033
because the passwords are not equal.
131
00:06:29,910 --> 00:06:33,630
Of course, alternatively, we could also use 422,
132
00:06:33,630 --> 00:06:37,990
which kind of indicates that the user input is incorrect.
133
00:06:37,990 --> 00:06:40,780
And that would be a fair assumption here as well,
134
00:06:40,780 --> 00:06:44,490
that the user simply mistyped the old password.
135
00:06:44,490 --> 00:06:47,820
Ultimately, it's up to you which status code you wanna use
136
00:06:47,820 --> 00:06:50,710
because after all, it will also be you
137
00:06:50,710 --> 00:06:54,830
who has to handle these status codes in the front end code
138
00:06:54,830 --> 00:06:58,133
when it comes to showing an error message to the users.
139
00:06:59,010 --> 00:07:01,530
So here I'll go for 403
140
00:07:01,530 --> 00:07:04,650
and then also attach some data with a message key
141
00:07:04,650 --> 00:07:08,233
where I say invalid password.
142
00:07:09,250 --> 00:07:10,593
Or something like this.
143
00:07:11,690 --> 00:07:14,650
Now, if we do make it past this if check though,
144
00:07:14,650 --> 00:07:17,400
then we know that the passwords are equal
145
00:07:17,400 --> 00:07:20,900
and then we can replace the oldPassword in the database
146
00:07:20,900 --> 00:07:22,150
with the new one.
147
00:07:22,150 --> 00:07:25,550
Now, for this we can use our usersCollection again
148
00:07:26,390 --> 00:07:31,090
and call updateOne to update one document
149
00:07:31,090 --> 00:07:34,120
and for that, we now need to pass in our first argument
150
00:07:34,120 --> 00:07:38,130
where we identify the document that should be updated
151
00:07:38,130 --> 00:07:39,980
and in this case, that's the document
152
00:07:39,980 --> 00:07:42,247
where the email matches the userEmail.
153
00:07:43,654 --> 00:07:47,947
So the same filter as we set it up here for finding a user.
154
00:07:49,450 --> 00:07:52,670
But then here we also need to pass in a second argument
155
00:07:52,670 --> 00:07:55,970
where we describe the update.
156
00:07:55,970 --> 00:07:57,900
Now, for describing the update,
157
00:07:57,900 --> 00:08:00,420
we also pass in a JavaScript object
158
00:08:00,420 --> 00:08:02,430
as a second argument
159
00:08:02,430 --> 00:08:07,023
and in there, we add the special $set key.
160
00:08:08,010 --> 00:08:10,390
This is a special key which will be identified
161
00:08:10,390 --> 00:08:11,640
and understood by MongoDB
162
00:08:13,083 --> 00:08:17,160
and $set then wants a nested object as a value
163
00:08:17,160 --> 00:08:20,810
where we just set the properties of the document
164
00:08:20,810 --> 00:08:22,170
that should change.
165
00:08:22,170 --> 00:08:23,700
So in this case, for example,
166
00:08:23,700 --> 00:08:25,140
I don't wanna change the email,
167
00:08:25,140 --> 00:08:26,690
I don't wanna change the ID,
168
00:08:26,690 --> 00:08:28,860
I wanna change the password.
169
00:08:28,860 --> 00:08:32,150
So as a value for $set, I have an object
170
00:08:32,150 --> 00:08:33,940
where I set password
171
00:08:33,940 --> 00:08:36,539
and now this key here has to match one
172
00:08:36,539 --> 00:08:38,210
of the keys of your document
173
00:08:38,210 --> 00:08:41,030
or it's added as a new key if it doesn't,
174
00:08:41,030 --> 00:08:42,370
which I don't want here.
175
00:08:42,370 --> 00:08:45,830
So here I'll set password to the newPassword
176
00:08:47,050 --> 00:08:50,100
but of course, as you learned, not like this.
177
00:08:50,100 --> 00:08:53,000
Instead, we wanna hash that newPassword first
178
00:08:53,000 --> 00:08:55,050
because if the password has changed,
179
00:08:55,050 --> 00:08:59,230
we, of course, still don't wanna store plain text passwords
180
00:08:59,230 --> 00:09:00,213
in the database.
181
00:09:01,420 --> 00:09:05,370
And therefore here, I'll now create my hashedPassword
182
00:09:07,580 --> 00:09:08,780
by calling hashPassword,
183
00:09:10,450 --> 00:09:12,440
which is a function we have to import
184
00:09:12,440 --> 00:09:15,343
from the lib/auth file as well.
185
00:09:17,030 --> 00:09:19,530
And when we call hashPassword,
186
00:09:19,530 --> 00:09:22,620
we pass the newPassword, the plain text password
187
00:09:22,620 --> 00:09:26,720
as a argument and then await this operation,
188
00:09:26,720 --> 00:09:28,800
since it returns a promise,
189
00:09:28,800 --> 00:09:30,750
and we then get this hashedPassword
190
00:09:30,750 --> 00:09:33,696
and that's then the password we wanna set
191
00:09:33,696 --> 00:09:35,800
for the updateOne operation.
192
00:09:35,800 --> 00:09:38,583
And this will now update the user in the database.
193
00:09:39,950 --> 00:09:42,560
Now, we can also await this operation
194
00:09:42,560 --> 00:09:45,230
and we can get the result and do something with it
195
00:09:45,230 --> 00:09:46,520
if we want to.
196
00:09:46,520 --> 00:09:50,260
Here I don't actually need it but still, I'll get it.
197
00:09:50,260 --> 00:09:53,850
And we can also add error handling as we did it before
198
00:09:53,850 --> 00:09:55,700
in the course but for the moment,
199
00:09:55,700 --> 00:09:57,170
I'll ignore all of that.
200
00:09:57,170 --> 00:10:00,150
I'll then just close the client connection
201
00:10:00,150 --> 00:10:02,540
and then send back a response
202
00:10:02,540 --> 00:10:04,730
with a status code of 200
203
00:10:04,730 --> 00:10:09,683
where we, for example, say Password updated.
204
00:10:11,250 --> 00:10:12,740
Like this.
205
00:10:12,740 --> 00:10:14,530
And now with all that in place,
206
00:10:14,530 --> 00:10:16,440
with all that code added,
207
00:10:16,440 --> 00:10:20,930
we should have the code that does change the password
208
00:10:20,930 --> 00:10:22,760
of an authenticated user
209
00:10:22,760 --> 00:10:25,710
and therefore, now with all that in place,
210
00:10:25,710 --> 00:10:27,660
we now need to go to the front end
211
00:10:27,660 --> 00:10:29,320
and work on the front end code
212
00:10:29,320 --> 00:10:34,320
to send a HTTP request to this newly added API route.
16376
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.