﻿1
00:00:01,210 --> 00:00:04,650
‫And now let's finally create the last part

2
00:00:04,650 --> 00:00:07,010
‫of the Password Reset Functionality,

3
00:00:07,010 --> 00:00:10,593
‫where we actually set the new password for the user.

4
00:00:12,250 --> 00:00:15,900
‫And so, just like before, let's start by defining the steps

5
00:00:15,900 --> 00:00:19,713
‫that we're gonna take for this resetPassword flow.

6
00:00:21,240 --> 00:00:26,240
‫So, first off, get user based on the token.

7
00:00:30,350 --> 00:00:35,350
‫Then as the second step, we will set the new password

8
00:00:35,890 --> 00:00:40,153
‫but only if token has not expired,

9
00:00:42,070 --> 00:00:44,040
‫and there is a user.

10
00:00:44,040 --> 00:00:48,633
‫So in that case, set the new password.

11
00:00:51,580 --> 00:00:55,250
‫Then after that, we need to update

12
00:00:57,210 --> 00:01:01,000
‫the changedPasswordAt property

13
00:01:04,080 --> 00:01:05,403
‫for the current user,

14
00:01:07,320 --> 00:01:10,533
‫and then finally, as is usual in this functionality,

15
00:01:11,680 --> 00:01:12,853
‫is to log the user in.

16
00:01:14,010 --> 00:01:18,840
‫Basically, send the JSON Web Token to the client.

17
00:01:18,840 --> 00:01:22,733
‫Okay, so a lot of work to do, and so let's get started.

18
00:01:23,950 --> 00:01:27,493
‫And so, remember from the last video, that the reset token

19
00:01:27,493 --> 00:01:30,450
‫that is actually sent in the URL

20
00:01:30,450 --> 00:01:33,110
‫is this non-encrypted token here.

21
00:01:33,110 --> 00:01:34,723
‫So, actually this one.

22
00:01:35,570 --> 00:01:37,810
‫But the one that we have in the database

23
00:01:37,810 --> 00:01:39,680
‫is the encrypted one.

24
00:01:39,680 --> 00:01:42,580
‫So we talked about that before, and so what we now

25
00:01:42,580 --> 00:01:44,910
‫need to do, is to basically encrypt

26
00:01:44,910 --> 00:01:46,630
‫the original token again,

27
00:01:46,630 --> 00:01:49,240
‫so we can then compare it with the one that is stored,

28
00:01:49,240 --> 00:01:51,433
‫so the encrypted one in the database.

29
00:01:52,870 --> 00:01:55,110
‫So, we actually did something similar before

30
00:01:55,110 --> 00:01:57,890
‫with the password, but with the password,

31
00:01:57,890 --> 00:02:01,010
‫we couldn't compare it as easily as we can with this one,

32
00:02:01,010 --> 00:02:02,650
‫again because for the password

33
00:02:02,650 --> 00:02:05,770
‫we used the quite complex bcrypt algorithm,

34
00:02:05,770 --> 00:02:07,490
‫which in this case, we didn't.

35
00:02:07,490 --> 00:02:09,750
‫So, here it's very straightforward.

36
00:02:09,750 --> 00:02:13,040
‫All we need to do again, is to encrypt the token

37
00:02:13,040 --> 00:02:17,390
‫and compare it with the encrypted one in the database.

38
00:02:17,390 --> 00:02:22,390
‫So, let's say hashedToken, and so we will actually now

39
00:02:23,670 --> 00:02:26,813
‫need the crypto package here as well.

40
00:02:31,730 --> 00:02:36,167
‫Const crypto and then require('crypto').

41
00:02:41,280 --> 00:02:42,123
‫Now right.

42
00:02:43,780 --> 00:02:47,593
‫Then let's go back, and so,

43
00:02:48,750 --> 00:02:51,610
‫we use crypto.createHash.

44
00:02:53,070 --> 00:02:57,973
‫Remember, then the name of the algorithm again, sha256,

45
00:02:58,910 --> 00:03:03,910
‫then .update, basically for the place, for the string

46
00:03:04,140 --> 00:03:06,040
‫that we want to hash.

47
00:03:06,040 --> 00:03:10,110
‫And so, that one is, remember in req.params.

48
00:03:10,110 --> 00:03:14,083
‫So we then use this one for a long time .token.

49
00:03:15,060 --> 00:03:17,950
‫And so again, it is a parameter,

50
00:03:17,950 --> 00:03:22,233
‫because we specified so here in the URL, so like this.

51
00:03:23,250 --> 00:03:26,470
‫So, it's now a parameter called token.

52
00:03:26,470 --> 00:03:31,470
‫And so, of course, here it's req.params.token.

53
00:03:31,804 --> 00:03:34,790
‫And then, finally, we also need to say digest

54
00:03:36,840 --> 00:03:38,633
‫and convert it to hexadecimal.

55
00:03:40,380 --> 00:03:42,760
‫Now this is basically the same

56
00:03:42,760 --> 00:03:46,180
‫as we had before, where we encrypted the original one,

57
00:03:46,180 --> 00:03:49,520
‫and so we could refactor this into its own function,

58
00:03:49,520 --> 00:03:51,693
‫but let's just keep it simple here.

59
00:03:54,240 --> 00:03:58,930
‫So, now let's actually get the user based on this token.

60
00:03:58,930 --> 00:04:01,060
‫Because that is actually, the only thing

61
00:04:01,060 --> 00:04:03,530
‫that we know about the user right now.

62
00:04:03,530 --> 00:04:07,080
‫We have no email, we have nothing, so this token

63
00:04:07,080 --> 00:04:10,130
‫is the only thing that can identify the user.

64
00:04:10,130 --> 00:04:12,520
‫And so we can now, basically, query the database

65
00:04:12,520 --> 00:04:14,170
‫for this token.

66
00:04:14,170 --> 00:04:17,303
‫And it will then find the user which has this token.

67
00:04:19,230 --> 00:04:24,230
‫So, await, as we already know, and then User.findOne.

68
00:04:27,790 --> 00:04:31,213
‫So, that property is called passwordResetToken

69
00:04:32,090 --> 00:04:36,117
‫and we are looking for the hashedToken.

70
00:04:37,940 --> 00:04:42,220
‫And now of course, we need to declare it as async

71
00:04:43,150 --> 00:04:44,643
‫and prep it into catchAsync.

72
00:04:48,557 --> 00:04:51,810
‫Give it a save, that should fix this bug,

73
00:04:51,810 --> 00:04:53,950
‫and indeed it does.

74
00:04:53,950 --> 00:04:56,950
‫So, this will find user who has the token

75
00:04:56,950 --> 00:04:59,100
‫that will send via URL.

76
00:04:59,100 --> 00:05:00,910
‫But, right now, we're not taking

77
00:05:00,910 --> 00:05:04,090
‫the token expiration date into consideration.

78
00:05:04,090 --> 00:05:06,000
‫And so how could we do that?

79
00:05:06,000 --> 00:05:09,020
‫Well, basically, what we want is to check

80
00:05:09,020 --> 00:05:11,860
‫if the passwordResetExpires property

81
00:05:11,860 --> 00:05:13,723
‫is greater than right now.

82
00:05:14,890 --> 00:05:17,350
‫Because if the expires date is greater than now,

83
00:05:17,350 --> 00:05:20,420
‫it means it's in the future, which in turn means,

84
00:05:20,420 --> 00:05:22,313
‫that it hasn't yet expired.

85
00:05:23,180 --> 00:05:24,850
‫And so, that's a very easy way

86
00:05:24,850 --> 00:05:28,343
‫in which we can actually do this right with this query.

87
00:05:30,619 --> 00:05:32,702
‫So, passwordResetExpires,

88
00:05:35,170 --> 00:05:37,460
‫which is where that date is stored,

89
00:05:37,460 --> 00:05:38,840
‫and now all we need to check

90
00:05:38,840 --> 00:05:41,470
‫if it is actually greater than right now.

91
00:05:41,470 --> 00:05:45,440
‫And so we know how to do that already with MongoDB, right?

92
00:05:45,440 --> 00:05:50,110
‫So, new object and then the greater operator

93
00:05:50,110 --> 00:05:53,737
‫and then what we want to compare it with is Date.now,

94
00:05:56,310 --> 00:05:59,410
‫and this will actually be a timestamp of right now,

95
00:05:59,410 --> 00:06:02,900
‫but behind the scenes, MongoDB will then convert everything

96
00:06:02,900 --> 00:06:05,170
‫to the same, and therefore be able

97
00:06:05,170 --> 00:06:06,520
‫to compare them accurately.

98
00:06:08,070 --> 00:06:10,440
‫And so with this we can, at the same time,

99
00:06:10,440 --> 00:06:14,120
‫find the user for the token and also check if the token

100
00:06:14,120 --> 00:06:16,370
‫has not yet expired.

101
00:06:16,370 --> 00:06:18,190
‫So, great.

102
00:06:18,190 --> 00:06:21,190
‫So, next up we want to, of course, send an error

103
00:06:21,190 --> 00:06:25,530
‫if there is no user, or basically, if the token has expired.

104
00:06:25,530 --> 00:06:27,230
‫But that's, in this case, the same,

105
00:06:27,230 --> 00:06:30,500
‫because if the token has expired, well then it will simply

106
00:06:30,500 --> 00:06:32,513
‫not return any user.

107
00:06:33,956 --> 00:06:37,730
‫And so all we need to do is to say, if no user,

108
00:06:38,970 --> 00:06:43,970
‫well then, as always, return next, that's not mext.

109
00:06:47,920 --> 00:06:51,910
‫So new AppError, and let's say

110
00:06:51,910 --> 00:06:56,793
‫Token is invalid or has expired.

111
00:06:59,850 --> 00:07:02,853
‫And then 400, so bad request.

112
00:07:04,140 --> 00:07:07,050
‫And so then, if there is no error,

113
00:07:07,050 --> 00:07:09,400
‫and if next is not called,

114
00:07:09,400 --> 00:07:12,160
‫well then let's actually set the password.

115
00:07:12,160 --> 00:07:15,550
‫So, we already got the user and now it's very simple:

116
00:07:15,550 --> 00:07:20,550
‫user.password is equal to req.body.password.

117
00:07:24,880 --> 00:07:28,140
‫And that's because we will of course, send the password

118
00:07:28,140 --> 00:07:31,713
‫and also passwordConfirm via the body.

119
00:07:33,551 --> 00:07:34,701
‫So let's duplicate that

120
00:07:37,870 --> 00:07:39,553
‫and passwordConfirm as well.

121
00:07:41,425 --> 00:07:44,630
‫And then also, let's basically delete the reset token

122
00:07:44,630 --> 00:07:45,733
‫and the expired.

123
00:07:46,800 --> 00:07:51,800
‫So passwordResetToken, so just like we did before,

124
00:07:52,040 --> 00:07:57,037
‫we set it to undefined, and now user.password expires

125
00:07:59,510 --> 00:08:01,160
‫equals to undefined.

126
00:08:01,160 --> 00:08:02,220
‫All right.

127
00:08:02,220 --> 00:08:04,350
‫And again, of course, we now need to save it,

128
00:08:04,350 --> 00:08:07,000
‫because this only modifies the document,

129
00:08:07,000 --> 00:08:08,410
‫it doesn't really update.

130
00:08:08,410 --> 00:08:09,973
‫So it doesn't really save it.

131
00:08:11,200 --> 00:08:15,503
‫So, await user.save.

132
00:08:17,500 --> 00:08:20,350
‫And in this case, we actually don't have to turn off

133
00:08:20,350 --> 00:08:24,340
‫the validators, because indeed we want to validate.

134
00:08:24,340 --> 00:08:27,620
‫For example, we want the validator to confirm

135
00:08:27,620 --> 00:08:31,440
‫if the password is equal to passwordConfirm.

136
00:08:31,440 --> 00:08:33,380
‫And so that validator automatically

137
00:08:33,380 --> 00:08:35,033
‫does all that work for us.

138
00:08:36,800 --> 00:08:39,390
‫Then the third step, what we're gonna do actually

139
00:08:39,390 --> 00:08:42,030
‫in the end, and so what we're gonna do next

140
00:08:42,030 --> 00:08:43,990
‫is to basically lock the user in.

141
00:08:43,990 --> 00:08:47,400
‫So in other words, send the JSON Web Token.

142
00:08:47,400 --> 00:08:51,930
‫And let's get that code from here, so this one.

143
00:08:51,930 --> 00:08:53,770
‫And again, we're already doing this here

144
00:08:53,770 --> 00:08:55,700
‫in three different places.

145
00:08:55,700 --> 00:08:59,280
‫So here in the login, also in signup,

146
00:08:59,280 --> 00:09:01,400
‫and now for the third time, down here.

147
00:09:01,400 --> 00:09:05,170
‫And so, sometime in the future, we will refactor that

148
00:09:05,170 --> 00:09:06,383
‫into its own function.

149
00:09:07,230 --> 00:09:09,673
‫But for now, we're good like this.

150
00:09:11,180 --> 00:09:14,743
‫And so, let's actually now go ahead and test this.

151
00:09:16,710 --> 00:09:19,020
‫So this reset token that we had before

152
00:09:19,020 --> 00:09:22,080
‫has already expired, and so we need to ask

153
00:09:22,080 --> 00:09:24,640
‫for a new one, basically.

154
00:09:24,640 --> 00:09:29,490
‫So let's come to Postman and hit our forget password route.

155
00:09:29,490 --> 00:09:32,120
‫Let's just reduce the clutter here

156
00:09:32,120 --> 00:09:36,350
‫and get rid of all of these open tabs

157
00:09:36,350 --> 00:09:37,500
‫that we no longer need.

158
00:09:38,910 --> 00:09:41,150
‫Actually here we're gonna need this test

159
00:09:43,480 --> 00:09:45,270
‫for this Reset Password,

160
00:09:45,270 --> 00:09:48,210
‫because remember, that this one actually gets back

161
00:09:48,210 --> 00:09:51,540
‫a JSON Web Token, and so we want to save that

162
00:09:51,540 --> 00:09:52,890
‫into the environment variable,

163
00:09:52,890 --> 00:09:54,830
‫just like we did with all the others.

164
00:09:54,830 --> 00:09:58,373
‫So I'm doing that now, just so that I don't forget it.

165
00:10:00,550 --> 00:10:04,100
‫All right, anyway, let's start with, basically,

166
00:10:04,100 --> 00:10:05,690
‫forgetting the password.

167
00:10:05,690 --> 00:10:08,620
‫So sending that request out, which again,

168
00:10:08,620 --> 00:10:10,750
‫takes some times because of sending the email,

169
00:10:10,750 --> 00:10:14,947
‫but here we go, and let's now go to our email,

170
00:10:16,880 --> 00:10:19,463
‫and so that just arrived a few seconds ago.

171
00:10:20,670 --> 00:10:24,890
‫So, it is this, of course, this token.

172
00:10:24,890 --> 00:10:29,890
‫So let's grab it, copy it and now back to Postman,

173
00:10:31,060 --> 00:10:34,303
‫we use it in the Reset Password, as the URL.

174
00:10:35,750 --> 00:10:37,253
‫Okay, make sense?

175
00:10:38,250 --> 00:10:41,603
‫So again, we're sending that token right in the URL.

176
00:10:43,600 --> 00:10:45,730
‫Then here, let's specify the body,

177
00:10:45,730 --> 00:10:49,453
‫because now, we need to actually specify our new password.

178
00:10:53,720 --> 00:10:57,843
‫So password and let's say newpass.

179
00:11:01,650 --> 00:11:03,050
‫And then...

180
00:11:05,950 --> 00:11:07,450
‫And here let's call it something else,

181
00:11:07,450 --> 00:11:10,263
‫because for now, I actually want to see an error.

182
00:11:11,480 --> 00:11:14,727
‫And of course, this is called passwordConfirm.

183
00:11:17,360 --> 00:11:20,393
‫So let's see what happens when we try to do this.

184
00:11:23,240 --> 00:11:27,080
‫Let's wait for it, and we get password is shorter

185
00:11:27,080 --> 00:11:29,640
‫than the minimum allowed length.

186
00:11:29,640 --> 00:11:34,480
‫Okay, so let's change that, 123, and here let's say 1234.

187
00:11:36,090 --> 00:11:37,740
‫So I want them to be different.

188
00:11:37,740 --> 00:11:40,630
‫But you see that the validation here worked just fine,

189
00:11:40,630 --> 00:11:43,273
‫even when updating the password with save.

190
00:11:45,610 --> 00:11:48,800
‫So, and now we get Passwords are not the same!

191
00:11:48,800 --> 00:11:50,960
‫So again, that's a validation error.

192
00:11:50,960 --> 00:11:53,430
‫And remember, actually, that this is the whole reason

193
00:11:53,430 --> 00:11:56,213
‫why we need to use save and not update.

194
00:11:57,206 --> 00:11:59,090
‫So before, for updating tours,

195
00:11:59,090 --> 00:12:03,220
‫we used to use findOneAndUpdate, but now,

196
00:12:03,220 --> 00:12:06,820
‫for everything related to passwords and to the user,

197
00:12:06,820 --> 00:12:10,110
‫we always use save, because we always want to run

198
00:12:10,110 --> 00:12:12,580
‫all the validators, and above all,

199
00:12:12,580 --> 00:12:14,450
‫the save middleware functions.

200
00:12:14,450 --> 00:12:18,293
‫So, for example, the ones where the passwords are encrypted.

201
00:12:20,400 --> 00:12:21,610
‫So let's end it now.

202
00:12:21,610 --> 00:12:25,030
‫Oh, I didn't actually correct it, sorry for that.

203
00:12:25,030 --> 00:12:28,230
‫And but now it should actually work.

204
00:12:28,230 --> 00:12:32,870
‫And indeed, we get success, and we get a new token.

205
00:12:32,870 --> 00:12:36,600
‫So great, let's see if this token is actually valid.

206
00:12:36,600 --> 00:12:40,973
‫So if we can, get all the tours using this brand new token.

207
00:12:43,870 --> 00:12:46,210
‫And here we go.

208
00:12:46,210 --> 00:12:51,000
‫So, our new token actually works, and now for this user,

209
00:12:51,000 --> 00:12:53,990
‫so for hello@jonas, these two properties

210
00:12:53,990 --> 00:12:56,190
‫should actually be gone.

211
00:12:56,190 --> 00:12:59,760
‫So the password expires and the token should be gone,

212
00:12:59,760 --> 00:13:03,550
‫since, well, since that's what we did in our code.

213
00:13:03,550 --> 00:13:06,760
‫And so, yeah, they are no longer here.

214
00:13:06,760 --> 00:13:10,210
‫Now all we need to do actually, is this missing step here,

215
00:13:10,210 --> 00:13:12,690
‫which is to update the passwordAt property

216
00:13:13,610 --> 00:13:14,773
‫for this current user.

217
00:13:15,680 --> 00:13:17,260
‫But that shouldn't be all too hard,

218
00:13:17,260 --> 00:13:20,690
‫and so let's quickly go back to the userModel,

219
00:13:20,690 --> 00:13:24,550
‫which is where we are gonna do that using middleware.

220
00:13:24,550 --> 00:13:26,800
‫And let's actually put all the middleware

221
00:13:26,800 --> 00:13:29,023
‫together here at the top.

222
00:13:32,241 --> 00:13:35,408
‫So, userSchema.pre and again dot save,

223
00:13:38,830 --> 00:13:42,763
‫and then a function with next.

224
00:13:44,850 --> 00:13:47,010
‫Again, this function here is gonna run

225
00:13:47,010 --> 00:13:50,890
‫right before a new document is actually saved.

226
00:13:50,890 --> 00:13:52,220
‫And so, it's the perfect place

227
00:13:52,220 --> 00:13:54,880
‫for actually specifying this property.

228
00:13:54,880 --> 00:13:57,480
‫And I could, of course, have done it in a controller

229
00:13:58,820 --> 00:14:01,133
‫right next to here to this code, for example.

230
00:14:02,310 --> 00:14:05,853
‫But I really want this to happen, kind of, automatically.

231
00:14:06,740 --> 00:14:08,700
‫So, kind of behind the scenes.

232
00:14:08,700 --> 00:14:11,350
‫Because later on, we will have another place

233
00:14:11,350 --> 00:14:15,290
‫where we update the password and then we would make sure

234
00:14:15,290 --> 00:14:17,410
‫that we're including the same code there.

235
00:14:17,410 --> 00:14:19,300
‫And like this, again, it happens,

236
00:14:19,300 --> 00:14:20,640
‫kind of, behind the scenes,

237
00:14:20,640 --> 00:14:23,810
‫without us having to worry about it at all.

238
00:14:23,810 --> 00:14:26,600
‫Now, when exactly do we actually want to set the

239
00:14:26,600 --> 00:14:30,630
‫passwordChangedAt property to right now?

240
00:14:30,630 --> 00:14:33,450
‫Well we only want it when we actually modified

241
00:14:33,450 --> 00:14:34,660
‫the password property.

242
00:14:34,660 --> 00:14:37,290
‫And I'm not sure if we used this trick before,

243
00:14:37,290 --> 00:14:39,660
‫but anyway, let's use it now.

244
00:14:39,660 --> 00:14:44,660
‫So if we have not modified, so if not this.isModified,

245
00:14:47,620 --> 00:14:49,100
‫so just like this,

246
00:14:49,100 --> 00:14:53,070
‫and then the name of the property, so password.

247
00:14:53,070 --> 00:14:56,380
‫So in that case, return right away

248
00:14:57,270 --> 00:14:59,360
‫and run the next middleware.

249
00:14:59,360 --> 00:15:02,823
‫Okay, not like this, but like this.

250
00:15:04,380 --> 00:15:07,770
‫So again, if we didn't modify the password property,

251
00:15:07,770 --> 00:15:08,770
‫well then of course,

252
00:15:08,770 --> 00:15:12,970
‫do not manipulate the passwordChangedAt.

253
00:15:12,970 --> 00:15:15,860
‫But what about creating new document?

254
00:15:15,860 --> 00:15:18,010
‫Well, when we create a new document,

255
00:15:18,010 --> 00:15:20,150
‫then we did actually modify the password,

256
00:15:20,150 --> 00:15:24,350
‫and then we would set the passwordChangedAt property, right?

257
00:15:24,350 --> 00:15:27,260
‫Well, in the current implementation we actually would.

258
00:15:27,260 --> 00:15:29,860
‫But there is something else that we can use here.

259
00:15:29,860 --> 00:15:32,950
‫So, basically, we want to exit this middleware function

260
00:15:32,950 --> 00:15:36,630
‫right away, if the password has not been modified

261
00:15:36,630 --> 00:15:40,274
‫or if the document is new, and so we can use

262
00:15:40,274 --> 00:15:41,633
‫the isNew property.

263
00:15:42,700 --> 00:15:46,210
‫And again, this is one of these very nice things

264
00:15:46,210 --> 00:15:48,290
‫that are learned by reading your documentation.

265
00:15:48,290 --> 00:15:52,010
‫And so, I cannot stress enough how important it is

266
00:15:52,010 --> 00:15:55,160
‫to really read the documentations when you need something

267
00:15:55,160 --> 00:15:56,870
‫that you cannot find anywhere.

268
00:15:56,870 --> 00:15:59,010
‫Because, there really is so much stuff in there

269
00:15:59,010 --> 00:16:02,983
‫that is completely impossible to teach in one course.

270
00:16:04,810 --> 00:16:08,500
‫Anyway, if the code passes this verification here,

271
00:16:08,500 --> 00:16:10,830
‫well, then let's very simply say,

272
00:16:10,830 --> 00:16:14,217
‫this.passwordChangedAt = Date.now.

273
00:16:18,660 --> 00:16:22,303
‫And then, we call next.

274
00:16:23,640 --> 00:16:26,300
‫Now, in theory, this should work just fine,

275
00:16:26,300 --> 00:16:27,590
‫but actually, in practice,

276
00:16:27,590 --> 00:16:30,160
‫sometimes a small problem happens.

277
00:16:30,160 --> 00:16:33,580
‫And that problem is that sometimes saving to the database

278
00:16:33,580 --> 00:16:37,440
‫is a bit slower than issuing the JSON Web Token,

279
00:16:37,440 --> 00:16:40,460
‫making it so that the changed password timestamp

280
00:16:40,460 --> 00:16:42,560
‫is sometimes set a bit after

281
00:16:42,560 --> 00:16:45,280
‫the JSON Web Token has been created.

282
00:16:45,280 --> 00:16:48,000
‫And so that will then make it so that the user

283
00:16:48,000 --> 00:16:51,120
‫will not be able to log in using the new token.

284
00:16:51,120 --> 00:16:54,570
‫Because, remember, the whole reason this timestamp here

285
00:16:54,570 --> 00:16:57,660
‫actually exists, is so that we can compare it

286
00:16:57,660 --> 00:17:01,200
‫with the timestamp on the JSON Web Token, right?

287
00:17:01,200 --> 00:17:04,353
‫So, just to remember,

288
00:17:05,930 --> 00:17:10,930
‫it is, well, so right here, where we check if the user

289
00:17:11,560 --> 00:17:15,170
‫has changed the password after the token was issued.

290
00:17:15,170 --> 00:17:18,920
‫And so, down here, where we then created this new token

291
00:17:18,920 --> 00:17:21,010
‫in reset password.

292
00:17:21,010 --> 00:17:24,170
‫So right here, remember, we create this new token,

293
00:17:24,170 --> 00:17:27,770
‫and so again, sometimes it happens that this token

294
00:17:27,770 --> 00:17:31,500
‫is created a bit before the changed password timestamp

295
00:17:31,500 --> 00:17:33,960
‫has actually been created.

296
00:17:33,960 --> 00:17:38,960
‫And so, we just need to fix that by subtracting one second.

297
00:17:39,610 --> 00:17:42,733
‫So, basically, a thousand milliseconds.

298
00:17:43,750 --> 00:17:47,670
‫And so that then will put the passwordChangedAt one second

299
00:17:47,670 --> 00:17:50,840
‫in the past, okay, which will then of course,

300
00:17:50,840 --> 00:17:54,500
‫not be 100% accurate, but that's not a problem at all,

301
00:17:54,500 --> 00:17:58,000
‫because one second here doesn't make any difference at all.

302
00:17:58,000 --> 00:18:01,213
‫It's a small hack, but again, it's no problem.

303
00:18:02,190 --> 00:18:06,190
‫So putting this passwordChanged one second in the past,

304
00:18:06,190 --> 00:18:08,920
‫will then ensure that the token is always created

305
00:18:08,920 --> 00:18:11,433
‫after the password has been changed.

306
00:18:13,290 --> 00:18:15,800
‫So, this works now, but as always,

307
00:18:15,800 --> 00:18:18,380
‫let's also quickly test it.

308
00:18:18,380 --> 00:18:21,060
‫Okay, so back to Postman.

309
00:18:21,060 --> 00:18:23,990
‫Let's do a new Reset Password,

310
00:18:23,990 --> 00:18:26,060
‫or actually, that's not what I wanted at all,

311
00:18:26,060 --> 00:18:28,400
‫but it's a great thing to see

312
00:18:28,400 --> 00:18:30,200
‫that the code is actually working.

313
00:18:30,200 --> 00:18:33,610
‫So, The token is invalid or has expired,

314
00:18:33,610 --> 00:18:35,999
‫and that's because, well, 10 minutes have passed

315
00:18:35,999 --> 00:18:38,640
‫since I actually created that token.

316
00:18:38,640 --> 00:18:41,240
‫And I think we hadn't yet tested this,

317
00:18:41,240 --> 00:18:45,043
‫and so it's great that it now accidentally, actually did it.

318
00:18:46,370 --> 00:18:50,160
‫So again, this comes, in case you're wondering

319
00:18:50,160 --> 00:18:51,493
‫what the hell happened,

320
00:18:53,840 --> 00:18:56,500
‫so that's of course this error message here.

321
00:18:56,500 --> 00:18:59,450
‫And so it means, that it didn't find any user

322
00:18:59,450 --> 00:19:03,216
‫which has this token or which has a token that is

323
00:19:03,216 --> 00:19:05,163
‫more than 10 minutes in the past.

324
00:19:06,600 --> 00:19:10,393
‫And so, indeed what I wanted to do, is forget password.

325
00:19:12,700 --> 00:19:14,073
‫So, let's wait for it.

326
00:19:18,000 --> 00:19:19,980
‫So 8.6 seconds,

327
00:19:19,980 --> 00:19:22,820
‫but that might be because of my internet connection.

328
00:19:22,820 --> 00:19:24,520
‫So if you run this on a server,

329
00:19:24,520 --> 00:19:26,373
‫it's probably gonna be a lot faster.

330
00:19:27,440 --> 00:19:31,900
‫So let's grab that here, back to Postman, and now

331
00:19:31,900 --> 00:19:36,740
‫we reset the password, again with this password,

332
00:19:36,740 --> 00:19:39,823
‫doesn't really matter if it's the same as the old one.

333
00:19:40,690 --> 00:19:43,580
‫And, so now we have our success here.

334
00:19:43,580 --> 00:19:45,193
‫And now back to Compass.

335
00:19:46,680 --> 00:19:51,210
‫Let's reload, and indeed, we get the passwordChangedAt.

336
00:19:51,210 --> 00:19:53,290
‫And so that is actually right now.

337
00:19:53,290 --> 00:19:57,220
‫And so, if we now tried to actually use this token,

338
00:19:57,220 --> 00:19:59,870
‫for example, to access this protected route,

339
00:19:59,870 --> 00:20:02,130
‫well then that should work because of that small,

340
00:20:02,130 --> 00:20:04,633
‫one second tag that we did.

341
00:20:06,090 --> 00:20:10,205
‫So, it did and so just like this, we actually now finished

342
00:20:10,205 --> 00:20:12,840
‫our Password Reset Functionality.

343
00:20:12,840 --> 00:20:16,400
‫So that was quite a bit of code, but of course,

344
00:20:16,400 --> 00:20:18,100
‫it's totally worth it.

345
00:20:18,100 --> 00:20:20,470
‫So, you should always offer this functionality

346
00:20:20,470 --> 00:20:22,874
‫in your web application, because otherwise,

347
00:20:22,874 --> 00:20:26,750
‫a user that forgets his password is completely screwed,

348
00:20:26,750 --> 00:20:29,140
‫they can non longer use your application,

349
00:20:29,140 --> 00:20:31,940
‫and so, that's of course a terrible practice.

350
00:20:31,940 --> 00:20:34,020
‫Anyway, this kind of finishes, already,

351
00:20:34,020 --> 00:20:38,520
‫the authentication and authorization part of this section.

352
00:20:38,520 --> 00:20:40,510
‫So again, it's quite complete

353
00:20:40,510 --> 00:20:43,250
‫and I had a lot of fun implementing this.

354
00:20:43,250 --> 00:20:46,341
‫So, this part for me is where web applications

355
00:20:46,341 --> 00:20:48,560
‫really start coming to life.

356
00:20:48,560 --> 00:20:51,280
‫I know that it's not really visible at this point,

357
00:20:51,280 --> 00:20:54,280
‫with all these, just tokens and copying tokens

358
00:20:54,280 --> 00:20:56,300
‫and paste them somewhere else.

359
00:20:56,300 --> 00:20:59,630
‫That's not the usual idea that we have of logging in,

360
00:20:59,630 --> 00:21:02,410
‫I know, but of course again, a bit later,

361
00:21:02,410 --> 00:21:05,430
‫when we finally start building the dynamic website,

362
00:21:05,430 --> 00:21:06,580
‫then we will of course,

363
00:21:06,580 --> 00:21:09,220
‫keep using this authentication that we just built

364
00:21:09,220 --> 00:21:13,350
‫and then it will also become visual on that dynamic website.

365
00:21:13,350 --> 00:21:16,833
‫Next up, we will implement functionality for updating

366
00:21:16,833 --> 00:21:19,620
‫the user and also deleting it,

367
00:21:19,620 --> 00:21:22,990
‫and after that, we will then also talk about security.

368
00:21:22,990 --> 00:21:25,800
‫So that's what's ahead for the rest of the section,

369
00:21:25,800 --> 00:21:28,323
‫so make sure not to miss that.

