﻿1
00:00:00,960 --> 00:00:03,130
‫So, over the last few videos,

2
00:00:03,130 --> 00:00:06,220
‫we allowed a user to reset his password

3
00:00:06,220 --> 00:00:08,070
‫and then create a new one,

4
00:00:08,070 --> 00:00:09,910
‫but now we also want to allow

5
00:00:09,910 --> 00:00:13,383
‫a logged-in user to simply update his password

6
00:00:13,383 --> 00:00:15,740
‫without having to forget it,

7
00:00:15,740 --> 00:00:18,880
‫and so without that whole reset process.

8
00:00:18,880 --> 00:00:20,833
‫So, let's build that now.

9
00:00:22,620 --> 00:00:23,810
‫And, just like before,

10
00:00:23,810 --> 00:00:26,413
‫let's do that in our authentication controller.

11
00:00:28,420 --> 00:00:30,523
‫So, export.updatePassword.

12
00:00:35,142 --> 00:00:38,940
‫All right, and so, just like always,

13
00:00:38,940 --> 00:00:43,940
‫our three Middleware parameters here, and okay.

14
00:00:44,380 --> 00:00:48,250
‫Now remember that this password updating functionality is

15
00:00:48,250 --> 00:00:50,260
‫only for logged-in users,

16
00:00:50,260 --> 00:00:54,290
‫but still we need the user to pass in his current password,

17
00:00:54,290 --> 00:00:55,920
‫so in order to confirm

18
00:00:55,920 --> 00:00:58,990
‫that user actually is who he says he is.

19
00:00:58,990 --> 00:01:01,260
‫So, just as a security measure

20
00:01:01,260 --> 00:01:04,950
‫because imagine that someone would find your computer open

21
00:01:04,950 --> 00:01:08,150
‫and then be able to change passwords on the sites

22
00:01:08,150 --> 00:01:09,530
‫that you have currently open

23
00:01:09,530 --> 00:01:12,610
‫without being prompted for a password again.

24
00:01:12,610 --> 00:01:15,300
‫And so that would basically log you out

25
00:01:15,300 --> 00:01:18,260
‫of all your existing applications,

26
00:01:18,260 --> 00:01:21,000
‫which would, of course, be a terrible experience.

27
00:01:21,000 --> 00:01:23,800
‫And so, as a security measure, we always need to ask

28
00:01:23,800 --> 00:01:27,800
‫for the current password before updating it, all right.

29
00:01:27,800 --> 00:01:30,530
‫And, with that in mind, let's lay out all the steps

30
00:01:30,530 --> 00:01:32,760
‫that we need to take in order to implement

31
00:01:32,760 --> 00:01:36,030
‫this functionality just like before.

32
00:01:36,030 --> 00:01:39,530
‫So, first up, we need to get the user

33
00:01:39,530 --> 00:01:41,903
‫from the collection, basically.

34
00:01:44,840 --> 00:01:47,480
‫Then second, we need to check

35
00:01:47,480 --> 00:01:50,263
‫if the posted password is correct.

36
00:01:56,430 --> 00:01:57,880
‫Right.

37
00:01:57,880 --> 00:02:01,800
‫Then, third, so if the password is correct,

38
00:02:01,800 --> 00:02:04,623
‫then update the password.

39
00:02:07,170 --> 00:02:11,013
‫And finally, we need to again log the user in,

40
00:02:12,180 --> 00:02:16,610
‫so basically to send the jsonwebtoken back to the user,

41
00:02:16,610 --> 00:02:20,860
‫now logged in with the new password that was just updated.

42
00:02:20,860 --> 00:02:23,860
‫Okay, and this is actually all very similar to

43
00:02:23,860 --> 00:02:25,510
‫what we did already before,

44
00:02:25,510 --> 00:02:27,370
‫and so I'm leaving this one for you

45
00:02:27,370 --> 00:02:29,430
‫as a challenge, okay?

46
00:02:29,430 --> 00:02:32,660
‫So, please try to go ahead and implement this on your own,

47
00:02:32,660 --> 00:02:35,313
‫and if you need, you can of course take a look at the code

48
00:02:35,313 --> 00:02:36,800
‫that we wrote before,

49
00:02:36,800 --> 00:02:39,440
‫but really try to write the code on your own

50
00:02:39,440 --> 00:02:41,720
‫without copying too much, okay?

51
00:02:41,720 --> 00:02:44,140
‫So, you can take a look at the rest of the code to see

52
00:02:44,140 --> 00:02:47,680
‫how it works, but then don't really just copy it, okay?

53
00:02:47,680 --> 00:02:50,610
‫Because then you're not really gonna learn, all right.

54
00:02:50,610 --> 00:02:52,900
‫So, pause the video here, and I'll see you in a second

55
00:02:52,900 --> 00:02:54,083
‫with my solution.

56
00:02:57,510 --> 00:03:00,450
‫Okay, so I hoped you managed to implement this

57
00:03:00,450 --> 00:03:03,533
‫and to get it working, this is how I did it.

58
00:03:04,960 --> 00:03:08,963
‫So, as always, we create a new user variable,

59
00:03:09,970 --> 00:03:14,353
‫and in there we await the result of doing User.findById,

60
00:03:17,930 --> 00:03:20,940
‫and now where is this ID actually coming from?

61
00:03:20,940 --> 00:03:24,590
‫Well, remember again that this update password is only

62
00:03:24,590 --> 00:03:27,710
‫for authenticated, so for logged in users,

63
00:03:27,710 --> 00:03:30,830
‫and so therefore, at this point, we will already have

64
00:03:30,830 --> 00:03:33,123
‫the current user on our request object.

65
00:03:34,380 --> 00:03:37,273
‫Okay, so that's coming from the protect Middleware.

66
00:03:38,640 --> 00:03:42,670
‫So, req.user.id, and then remember

67
00:03:42,670 --> 00:03:46,933
‫that we need to explicitly ask for the password, okay?

68
00:03:48,830 --> 00:03:53,260
‫Because it is, by default, not included in the output.

69
00:03:53,260 --> 00:03:55,883
‫So, we defined that on the schema, remember?

70
00:03:56,860 --> 00:03:58,730
‫And, we actually need that password

71
00:03:58,730 --> 00:04:01,860
‫because now we want to compare it with the one

72
00:04:01,860 --> 00:04:03,690
‫that's stored in the database,

73
00:04:03,690 --> 00:04:05,300
‫and for that, just like before,

74
00:04:05,300 --> 00:04:08,850
‫we're gonna use this instance object

75
00:04:08,850 --> 00:04:10,720
‫that we have somewhere here.

76
00:04:10,720 --> 00:04:13,360
‫Yeah, so correctPassword, which is available

77
00:04:13,360 --> 00:04:15,250
‫on all the user documents,

78
00:04:15,250 --> 00:04:17,680
‫so it takes in the candidate password first,

79
00:04:17,680 --> 00:04:21,850
‫and then the actual user password, all right.

80
00:04:21,850 --> 00:04:23,370
‫Oh, and now it's giving me this error

81
00:04:23,370 --> 00:04:26,120
‫because, of course, I didn't declare this

82
00:04:26,120 --> 00:04:28,203
‫as an async function just yet.

83
00:04:29,610 --> 00:04:32,534
‫So, async, and before we forget it,

84
00:04:32,534 --> 00:04:36,577
‫let's wrap it into the catchAsync function here as well.

85
00:04:38,589 --> 00:04:40,513
‫Anyway, just like before,

86
00:04:40,513 --> 00:04:43,157
‫we basically want to create an error here

87
00:04:43,157 --> 00:04:46,402
‫if the current password is not correct,

88
00:04:46,402 --> 00:04:48,572
‫and so, let's write that in code.

89
00:04:48,572 --> 00:04:51,239
‫So, if not user.correctPassword,

90
00:04:53,870 --> 00:04:56,283
‫and then the candidate password remember,

91
00:04:56,283 --> 00:04:58,808
‫and so that one is gonna be in a body,

92
00:04:58,808 --> 00:05:03,808
‫in a property that we're gonna call the passwordConfirm.

93
00:05:03,980 --> 00:05:07,941
‫Okay, and then as a second argument the actual password,

94
00:05:07,941 --> 00:05:10,108
‫so that's a user.password.

95
00:05:11,036 --> 00:05:13,820
‫And then, remember that this is an asynchronous function,

96
00:05:13,820 --> 00:05:16,323
‫and so we need to also await it here.

97
00:05:18,400 --> 00:05:22,173
‫Good, so in case that the password is not correct,

98
00:05:24,020 --> 00:05:27,500
‫just like always, we create a new error here.

99
00:05:27,500 --> 00:05:32,000
‫So, new AppError, and this time we're saying

100
00:05:32,930 --> 00:05:37,930
‫your current password is wrong,

101
00:05:38,720 --> 00:05:43,660
‫and then status code 401 for unauthorized.

102
00:05:43,660 --> 00:05:45,650
‫All right, great.

103
00:05:45,650 --> 00:05:48,240
‫Now, if we make it to this point in code,

104
00:05:48,240 --> 00:05:51,750
‫so basically if the password is also correct,

105
00:05:51,750 --> 00:05:54,460
‫well then we can actually update the password,

106
00:05:54,460 --> 00:05:56,400
‫and how do we do that?

107
00:05:56,400 --> 00:05:58,763
‫Well, very simple, we did that before.

108
00:05:59,630 --> 00:06:04,630
‫All we say is user.password is equal to req.body.password,

109
00:06:08,200 --> 00:06:11,793
‫and then the same, of course, for the password confirm.

110
00:06:14,010 --> 00:06:17,560
‫Okay, and the validation will be done automatically

111
00:06:17,560 --> 00:06:21,300
‫by the validator that we specified on the schema,

112
00:06:21,300 --> 00:06:23,823
‫and that will be done once we actually save it.

113
00:06:24,690 --> 00:06:29,280
‫So, we await user.save,

114
00:06:29,280 --> 00:06:32,400
‫and so this time we do not turn off the validation

115
00:06:32,400 --> 00:06:35,920
‫because, of course, we want the validation to happen,

116
00:06:35,920 --> 00:06:39,120
‫so just as I said before, we want to check

117
00:06:39,120 --> 00:06:42,010
‫that the password confirm is actually the same

118
00:06:42,010 --> 00:06:44,560
‫as the password, right?

119
00:06:44,560 --> 00:06:45,570
‫Good.

120
00:06:45,570 --> 00:06:49,460
‫And, now just to really make sure that you understand

121
00:06:49,460 --> 00:06:53,533
‫why we didn't do something like user.findByIdAndUpdate.

122
00:06:56,530 --> 00:06:59,260
‫So, why didn't we do it like this?

123
00:06:59,260 --> 00:07:02,450
‫And, I know that I talked about this many times before,

124
00:07:02,450 --> 00:07:05,330
‫but I want you to understand one hundred percent

125
00:07:05,330 --> 00:07:07,990
‫why we cannot use this update,

126
00:07:07,990 --> 00:07:09,540
‫and it is for two reasons,

127
00:07:09,540 --> 00:07:12,143
‫so let me go back again to our model.

128
00:07:13,090 --> 00:07:14,650
‫So, the first one is

129
00:07:14,650 --> 00:07:18,920
‫that this validation here is not going to work, okay?

130
00:07:18,920 --> 00:07:22,670
‫And that's basically because this.password is not defined

131
00:07:22,670 --> 00:07:27,420
‫when we update, so when we use find by ID and update,

132
00:07:27,420 --> 00:07:29,440
‫because internally, behind the scenes,

133
00:07:29,440 --> 00:07:33,200
‫Mongoose does not really keep the current object in memory,

134
00:07:33,200 --> 00:07:36,230
‫and so therefore, this here is not going to work.

135
00:07:36,230 --> 00:07:39,130
‫And, as I said, I already talked about that before,

136
00:07:39,130 --> 00:07:42,650
‫so it's actually written out here as well, okay?

137
00:07:42,650 --> 00:07:45,600
‫But, it's really important to keep in mind not to use update

138
00:07:45,600 --> 00:07:49,340
‫for anything related to passwords, all right?

139
00:07:49,340 --> 00:07:51,160
‫So, this one is not going to work,

140
00:07:51,160 --> 00:07:53,640
‫and also, these two pre-saved

141
00:07:53,640 --> 00:07:56,510
‫Middlewares are also not going to work.

142
00:07:56,510 --> 00:07:59,820
‫So, if we used simply update for updating the password,

143
00:07:59,820 --> 00:08:03,000
‫then that password would not be encrypted,

144
00:08:03,000 --> 00:08:04,750
‫which is this first Middleware,

145
00:08:04,750 --> 00:08:07,530
‫and then also, the passwordChangedAt

146
00:08:07,530 --> 00:08:11,030
‫timestamp would also not be set, okay?

147
00:08:11,030 --> 00:08:12,830
‫So, none of this would work,

148
00:08:12,830 --> 00:08:15,943
‫and so again, we really need to do it like this.

149
00:08:17,470 --> 00:08:19,020
‫Let's just put that here again.

150
00:08:21,330 --> 00:08:24,430
‫And so now, (mumbles), we logged the user in,

151
00:08:24,430 --> 00:08:27,840
‫and sent the token back to the client.

152
00:08:27,840 --> 00:08:30,210
‫Now, that would actually be the fourth time

153
00:08:30,210 --> 00:08:32,320
‫that we did the same code,

154
00:08:32,320 --> 00:08:34,190
‫so basically this piece of code,

155
00:08:34,190 --> 00:08:36,710
‫and so, that's now very quickly refactor this

156
00:08:36,710 --> 00:08:38,410
‫into its own function.

157
00:08:38,410 --> 00:08:42,410
‫Now, this code actually is not the same everywhere.

158
00:08:42,410 --> 00:08:45,090
‫So, here we sent the status code 400,

159
00:08:45,090 --> 00:08:47,250
‫and we do not send the user,

160
00:08:47,250 --> 00:08:51,280
‫but then up here in the signup handler,

161
00:08:51,280 --> 00:08:53,680
‫we actually have a different status code,

162
00:08:53,680 --> 00:08:56,900
‫and we also sent the user to the client, okay?

163
00:08:56,900 --> 00:08:59,873
‫And so, let's make our function actually keep that in mind.

164
00:09:00,890 --> 00:09:05,890
‫So, let's create a function here,

165
00:09:06,140 --> 00:09:09,293
‫create and send token,

166
00:09:11,100 --> 00:09:14,350
‫and then the arguments that we need in here are the user

167
00:09:14,350 --> 00:09:17,070
‫because that's where the ID is stored.

168
00:09:17,070 --> 00:09:18,893
‫Then, we also want the status code,

169
00:09:20,220 --> 00:09:24,060
‫and of course, we need to have access to the response object

170
00:09:24,060 --> 00:09:26,940
‫in order to actually be able to send a response

171
00:09:26,940 --> 00:09:29,510
‫back to the client, okay?

172
00:09:29,510 --> 00:09:32,473
‫And so, basically now what we need is this code.

173
00:09:33,775 --> 00:09:35,930
‫So, let's copy it, put it here,

174
00:09:35,930 --> 00:09:38,700
‫and then replace irrelevant variables.

175
00:09:38,700 --> 00:09:42,480
‫So, the user is simply called user,

176
00:09:42,480 --> 00:09:44,963
‫so just like this, and here, the same.

177
00:09:46,470 --> 00:09:47,510
‫So, not new user,

178
00:09:47,510 --> 00:09:51,150
‫and then here we replace that with the status code,

179
00:09:51,150 --> 00:09:54,440
‫so the one that's coming in into our function,

180
00:09:54,440 --> 00:09:57,053
‫and so I guess that's actually it.

181
00:09:58,330 --> 00:10:01,070
‫So, let's now go ahead and replace it,

182
00:10:01,070 --> 00:10:06,070
‫so createSendToken, and here the user is called the newUser,

183
00:10:09,040 --> 00:10:10,763
‫the status code is 201,

184
00:10:12,260 --> 00:10:15,093
‫and then of course the response object.

185
00:10:16,730 --> 00:10:19,223
‫Okay, now we can get rid of this code,

186
00:10:20,680 --> 00:10:21,863
‫and let's just copy it.

187
00:10:23,200 --> 00:10:26,903
‫All right, so in the log in we of course also sent a token,

188
00:10:28,860 --> 00:10:32,630
‫but this time the user is actually called user

189
00:10:32,630 --> 00:10:34,243
‫and the status code is 200.

190
00:10:38,470 --> 00:10:39,920
‫And now, let's copy this one.

191
00:10:42,210 --> 00:10:45,853
‫So, the next one should be here, and reset password,

192
00:10:46,930 --> 00:10:48,400
‫and here it's actually the same,

193
00:10:48,400 --> 00:10:51,323
‫so the name is user and code 200,

194
00:10:53,740 --> 00:10:57,550
‫and now, finally, here it's also the same.

195
00:10:57,550 --> 00:11:02,360
‫And so, that finishes our update password function.

196
00:11:02,360 --> 00:11:03,740
‫Now, to make this work,

197
00:11:03,740 --> 00:11:06,830
‫we of course need to implement the route here as well

198
00:11:06,830 --> 00:11:08,033
‫in our user router.

199
00:11:09,900 --> 00:11:14,400
‫So, router.patch, and we will do a patch

200
00:11:14,400 --> 00:11:17,610
‫because we're actually changing, so we're manipulating

201
00:11:17,610 --> 00:11:21,460
‫the user document, and so that's what patch is for.

202
00:11:21,460 --> 00:11:24,590
‫And the route is called updateMyPassword.

203
00:11:29,060 --> 00:11:30,630
‫So, my password because it's

204
00:11:30,630 --> 00:11:34,420
‫for the currently logged in user, and then remember, again,

205
00:11:34,420 --> 00:11:36,810
‫this only works for logged in users,

206
00:11:36,810 --> 00:11:41,770
‫and so we need to use authController.protect,

207
00:11:41,770 --> 00:11:44,240
‫which will then also put the user object

208
00:11:44,240 --> 00:11:47,270
‫on a request object, okay?

209
00:11:47,270 --> 00:11:51,593
‫So, protect, and then authController update password

210
00:11:51,593 --> 00:11:55,640
‫that we just created, all right.

211
00:11:55,640 --> 00:11:59,593
‫And so, let's now actually go ahead and test this, okay?

212
00:12:02,720 --> 00:12:05,763
‫So, let's copy this route here,

213
00:12:08,080 --> 00:12:09,790
‫so UpdateMyPassword,

214
00:12:14,300 --> 00:12:18,190
‫and now what we need to send in the body is

215
00:12:18,190 --> 00:12:20,103
‫these three passwords actually,

216
00:12:21,290 --> 00:12:24,817
‫so it's basically the passwordCurrent,

217
00:12:30,350 --> 00:12:32,050
‫and for now I'm leaving them empty,

218
00:12:32,050 --> 00:12:35,000
‫I simply want to put the field names here for now.

219
00:12:35,000 --> 00:12:38,750
‫So, passwordCurrent then just password,

220
00:12:38,750 --> 00:12:40,503
‫which is basically the new one,

221
00:12:41,690 --> 00:12:44,110
‫and then, of course, passwordConfirm.

222
00:12:46,930 --> 00:12:50,320
‫Okay, and now we actually need to log in as a user

223
00:12:50,320 --> 00:12:53,140
‫because remember, this only works

224
00:12:53,140 --> 00:12:56,250
‫if the user is already logged in, all right.

225
00:12:56,250 --> 00:12:59,333
‫And so, let's actually do it with the administrator here.

226
00:13:00,633 --> 00:13:04,620
‫And this here is, should be still the current password,

227
00:13:04,620 --> 00:13:07,610
‫and indeed, we are now logged in.

228
00:13:07,610 --> 00:13:10,520
‫And remember that this token now gets stored

229
00:13:10,520 --> 00:13:13,313
‫into the JWT environment variable,

230
00:13:14,240 --> 00:13:17,080
‫and so, here, in order to authenticate,

231
00:13:17,080 --> 00:13:20,400
‫let's then actually use that just like we did before.

232
00:13:20,400 --> 00:13:24,710
‫So, in this authorization tab, we select Bearer Token,

233
00:13:24,710 --> 00:13:27,480
‫and then it will actually automatically pre-fill

234
00:13:27,480 --> 00:13:29,293
‫this JWT variable.

235
00:13:30,140 --> 00:13:32,830
‫All right, and so that's then where actually

236
00:13:32,830 --> 00:13:35,873
‫the user ID is gonna come from, remember?

237
00:13:37,830 --> 00:13:42,830
‫Anyway, let's now specify the current password, so pass1234,

238
00:13:42,999 --> 00:13:45,613
‫and then let's say newpassword, okay?

239
00:13:49,040 --> 00:13:50,713
‫Copy it and paste it here,

240
00:13:51,560 --> 00:13:54,170
‫but actually again, I want to start by testing it

241
00:13:54,170 --> 00:13:56,960
‫with a wrong password confirm,

242
00:13:56,960 --> 00:13:59,810
‫just to see if our validation is still working,

243
00:13:59,810 --> 00:14:02,720
‫and now the route is not defined,

244
00:14:02,720 --> 00:14:07,300
‫but that's simply because we're using the wrong verb here.

245
00:14:07,300 --> 00:14:09,610
‫Of course, it needs to be patch.

246
00:14:09,610 --> 00:14:11,430
‫Let's try that again,

247
00:14:11,430 --> 00:14:15,040
‫but now we get your current password is wrong,

248
00:14:15,040 --> 00:14:18,270
‫but actually it's not, so it's actually correct.

249
00:14:18,270 --> 00:14:21,163
‫So, something must be wrong with our code,

250
00:14:22,260 --> 00:14:24,143
‫so let's try to take a look here.

251
00:14:26,440 --> 00:14:28,440
‫And yeah, so here is actually the problem

252
00:14:28,440 --> 00:14:32,240
‫because we do not want to compare or confirm password,

253
00:14:32,240 --> 00:14:34,763
‫of course, but with the current password.

254
00:14:35,750 --> 00:14:39,780
‫Okay, so that's just a stupid bug, all right,

255
00:14:39,780 --> 00:14:41,620
‫and so now it should be working.

256
00:14:41,620 --> 00:14:45,000
‫So, of course, we want to compare the current password

257
00:14:45,000 --> 00:14:47,050
‫with the one that is currently stored

258
00:14:47,050 --> 00:14:50,220
‫in the database, all right.

259
00:14:50,220 --> 00:14:51,503
‫So, let's try that again,

260
00:14:52,670 --> 00:14:55,460
‫and so that's the validation error that we were looking for,

261
00:14:55,460 --> 00:14:57,080
‫so the passwords are not the same

262
00:14:57,080 --> 00:14:59,840
‫because, indeed, they are not.

263
00:14:59,840 --> 00:15:02,610
‫And now, before actually updating the password,

264
00:15:02,610 --> 00:15:04,560
‫let's just take a look at Compass here.

265
00:15:06,070 --> 00:15:08,550
‫Let's just update it here quickly,

266
00:15:08,550 --> 00:15:11,160
‫and so, right now, this is the password.

267
00:15:11,160 --> 00:15:15,080
‫So, ending here is pW1i, okay?

268
00:15:15,080 --> 00:15:17,410
‫And so, let's update the password now

269
00:15:17,410 --> 00:15:21,333
‫and see what it's gonna look like afterwards, okay?

270
00:15:23,400 --> 00:15:25,633
‫So, now everything should be correct.

271
00:15:26,720 --> 00:15:31,720
‫And, indeed, we get our success and our token, all right.

272
00:15:33,500 --> 00:15:36,000
‫So, let's confirm that here quickly,

273
00:15:36,000 --> 00:15:38,570
‫and, indeed, you see that the password changed

274
00:15:38,570 --> 00:15:40,830
‫and also the current timestamp,

275
00:15:40,830 --> 00:15:44,403
‫so the time at which basically I'm recording this video.

276
00:15:45,370 --> 00:15:48,670
‫All right, and now, just like before,

277
00:15:48,670 --> 00:15:51,960
‫let's actually get this test here.

278
00:15:51,960 --> 00:15:55,433
‫So, basically storing the token as an environment variable.

279
00:15:59,150 --> 00:16:03,910
‫So, just so that everything really works here in Postman.

280
00:16:03,910 --> 00:16:06,453
‫Okay, let's save that actually,

281
00:16:07,590 --> 00:16:12,590
‫update current user password to make it really explicit,

282
00:16:14,560 --> 00:16:17,780
‫and yeah, I think that's it.

283
00:16:17,780 --> 00:16:21,090
‫I think this is all we need to do

284
00:16:21,090 --> 00:16:24,090
‫in order to update a user's password .

285
00:16:24,090 --> 00:16:27,890
‫Next up, we will then implement updating of other user data,

286
00:16:27,890 --> 00:16:30,713
‫so stuff like email or passwords.

