Skip to content

Commit 0f1d5ce

Browse files
committed
Add uid and reset token validation
1 parent 87c9962 commit 0f1d5ce

4 files changed

Lines changed: 95 additions & 21 deletions

File tree

client/pages/login.vue

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
field-type="password"
2121
/>
2222
<NuxtLink
23-
to="/reset/reset-password"
23+
to="/reset-password"
2424
class="self-end text-xs font-semibold text-white underline underline-offset-2"
2525
>
2626
forgot password?
@@ -30,7 +30,7 @@
3030
Don't have an account?
3131
<NuxtLink
3232
to="/sign-up"
33-
class="text-blue font-semibold underline underline-offset-2"
33+
class="font-semibold underline text-blue underline-offset-2"
3434
>
3535
Sign up!
3636
</NuxtLink>
@@ -61,7 +61,10 @@ export default {
6161
await this.$auth
6262
.login({ data })
6363
.then((resp) => this.$auth.setUserToken(resp.data))
64-
.catch((error) => (this.errors = error.response.data));
64+
.catch((error) => {
65+
this.errors = error.response.data;
66+
console.log(error.response.data);
67+
});
6568
},
6669
},
6770
};

client/pages/reset-password.vue

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<AuthForm
3-
v-if="!$route.query.token"
3+
v-if="!emailSentSuccess && !$route.query.uid"
44
v-slot="{ invalid }"
55
error-header="Error sending reset link, please fix the following errors:"
66
:errors="errors"
@@ -23,6 +23,18 @@
2323
<AuthSubmit :disabled="invalid">Send Reset Link</AuthSubmit>
2424
</AuthForm>
2525

26+
<AuthForm
27+
v-else-if="emailSentSuccess"
28+
class="gap-5 text-2xl font-bold text-white place-items-center"
29+
>
30+
<h1 class="text-3xl">Reset Link Has Been Sent!</h1>
31+
<p>Please check your spam folder if you cannot find the email.</p>
32+
<font-awesome-icon
33+
:icon="['fas', 'fa-face-smile-beam']"
34+
class="text-[10rem] my-10"
35+
/>
36+
</AuthForm>
37+
2638
<AuthForm
2739
v-else-if="!passwordResetSuccess"
2840
v-slot="{ invalid }"
@@ -31,6 +43,9 @@
3143
@submit="resetPassword"
3244
>
3345
<div class="mt-1 mb-3">
46+
<p v-if="uid !== ''" class="text-center text-white">
47+
Resetting password for {{ uid }}
48+
</p>
3449
<p class="text-center text-white">Please enter <wbr />a new password.</p>
3550
</div>
3651
<InputField
@@ -48,12 +63,12 @@
4863

4964
<AuthForm
5065
v-else
51-
class="place-items-center gap-5 font-bold text-2xl text-white"
66+
class="gap-5 text-2xl font-bold text-white place-items-center"
5267
>
5368
<h1 class="text-3xl">Congratulations!</h1>
5469
<p>
5570
Your password has been reset. Now you <wbr />can login with your new
56-
password
71+
password!
5772
</p>
5873
<font-awesome-icon
5974
:icon="['fas', 'fa-face-smile-beam']"
@@ -77,10 +92,12 @@ export default {
7792
data: () => ({
7893
title: 'Reset Password',
7994
passwordResetSuccess: false,
95+
emailSentSuccess: false,
96+
uid: '',
8097
errors: [],
8198
8299
emailField: {
83-
name: 'email',
100+
name: 'Email',
84101
type: 'email',
85102
index: 0,
86103
id: 'email',
@@ -89,32 +106,84 @@ export default {
89106
90107
fields: [
91108
{
92-
name: 'password',
109+
name: 'Password',
93110
type: 'password',
94111
index: count++,
95112
id: 'password',
96113
rules: 'required|min:6',
97114
},
98115
{
99-
name: 'confirm password',
116+
name: 'Confirm Password',
100117
type: 'password',
101118
index: count++,
102119
id: 'confirm',
103120
rules: 'required|password:@password',
104121
},
105122
],
106123
}),
124+
107125
head() {
108126
return {
109127
title: this.title,
110128
};
111129
},
130+
131+
async mounted() {
132+
const rawUid = this.$route.query.uid;
133+
const rawToken = this.$route.query.token;
134+
135+
if (!rawUid) {
136+
return;
137+
}
138+
139+
const formattedUid =
140+
rawUid.charAt(rawUid.length - 1) === '/'
141+
? rawUid.substring(0, rawUid.length - 1)
142+
: rawUid;
143+
144+
const formattedToken =
145+
rawUid.charAt(rawUid.length - 1) === '/'
146+
? rawUid.substring(0, rawUid.length - 1)
147+
: rawUid;
148+
149+
const url =
150+
'auth/reset/' + `?token=${this.formattedToken}&uid=${this.formattedUid}/`;
151+
152+
try {
153+
this.uid = atob(formattedUid);
154+
console.log(this.uid);
155+
} catch (err) {
156+
console.log(err);
157+
this.errors = { Errors: ['email UID is invalid'] };
158+
return;
159+
}
160+
161+
await this.$axios
162+
.$get(url)
163+
.then((resp) => (this.emailSentSuccess = true))
164+
.catch((error) => {
165+
this.errors = error.response.data;
166+
console.log(error.response.data);
167+
});
168+
},
169+
112170
methods: {
113-
onSubmit() {
114-
alert('submitted');
171+
async sendResetLink(e) {
172+
const elements = e.target.elements;
173+
const data = {
174+
email: elements.Email.value,
175+
};
176+
177+
const url = 'auth/reset/email/';
178+
await this.$axios
179+
.$post(url, data)
180+
.then((resp) => (this.passwordResetSuccess = true))
181+
.catch((error) => {
182+
this.errors = error.response.data;
183+
console.log(error.response.data);
184+
});
115185
},
116186
117-
sendResetLink() {},
118187
resetPassword() {},
119188
},
120189
};

client/pages/sign-up.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
</AuthForm>
2525
<AuthForm
2626
v-else
27-
class="place-items-center gap-5 font-bold text-2xl text-white"
27+
class="gap-5 text-2xl font-bold text-white place-items-center"
2828
>
2929
<h1 class="text-3xl">Congratulations {{ name }}!</h1>
3030
<p>

server/api/apps/auth/reset_password/views.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ def get(self, request, *args, **kwargs):
4242
if not is_valid_token:
4343
return Response(
4444
{
45-
"message": (
45+
"Errors": [
4646
"the password reset token is invalid or has expired."
47-
)
47+
]
4848
},
4949
status=status.HTTP_400_BAD_REQUEST,
5050
)
5151

5252
return Response(
53-
{"message": "the password reset token is valid"},
53+
{"Errors": ["the password reset token is valid"]},
5454
status=status.HTTP_200_OK,
5555
)
5656

@@ -59,9 +59,9 @@ def update(self, request, *args, **kwargs):
5959
if not is_valid_token:
6060
return Response(
6161
{
62-
"message": (
62+
"Errors": [
6363
"the password reset token is invalid or has expired."
64-
)
64+
]
6565
},
6666
status=status.HTTP_400_BAD_REQUEST,
6767
)
@@ -75,7 +75,7 @@ def update(self, request, *args, **kwargs):
7575

7676
if not user:
7777
return Response(
78-
{"message": "Email does not exist"},
78+
{"Errors": ["Email does not exist"]},
7979
status=status.HTTP_400_BAD_REQUEST,
8080
)
8181

@@ -107,14 +107,16 @@ def post(self, request):
107107

108108
if not user:
109109
return Response(
110-
{"message": "Email does not exist"},
110+
{"Errors": ["Email does not exist"]},
111111
status=status.HTTP_400_BAD_REQUEST,
112112
)
113113

114114
token = PasswordResetTokenGenerator().make_token(user)
115115
uid = urlsafe_base64_encode(force_bytes(user.email))
116116

117-
reset_url = f"{settings.FRONTEND_URL}/reset/?token={token}&uid={uid}/"
117+
reset_url = (
118+
f"{settings.FRONTEND_URL}/reset-password/?token={token}&uid={uid}/"
119+
)
118120

119121
try:
120122
send_mail(

0 commit comments

Comments
 (0)