Skip to content

Commit 995af2b

Browse files
committed
new endpoint to update emailVerified from email-handler
1 parent e04a7e6 commit 995af2b

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed

backend/src/api/controllers/user.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ export async function sendVerificationEmail(
158158
);
159159
})
160160
).emailVerified;
161+
161162
if (isVerified) {
162163
throw new MonkeyError(400, "Email already verified");
163164
}
@@ -240,6 +241,13 @@ export async function sendVerificationEmail(
240241
return new MonkeyResponse("Email sent", null);
241242
}
242243

244+
export async function verifyEmail(req: MonkeyRequest): Promise<MonkeyResponse> {
245+
const { uid, email, emailVerified } = req.ctx.decodedToken;
246+
await UserDAL.updateEmail(uid, email, emailVerified);
247+
248+
return new MonkeyResponse("emailVerify updated.", null);
249+
}
250+
243251
export async function sendForgotPasswordEmail(
244252
req: MonkeyRequest<undefined, ForgotPasswordEmailRequest>
245253
): Promise<MonkeyResponse> {
@@ -605,7 +613,7 @@ export async function getUser(req: MonkeyRequest): Promise<GetUserResponse> {
605613
);
606614
delete relevantUserInfo.customThemes;
607615

608-
//update users emailVerified status if it changed
616+
// soft-migrate user.emailVerified for existing users, update status if it has changed
609617
const { email, emailVerified } = req.ctx.decodedToken;
610618
if (emailVerified !== undefined && emailVerified !== userInfo.emailVerified) {
611619
void addImportantLog(

backend/src/api/routes/users.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ export default s.router(usersContract, {
120120
handler: async (r) =>
121121
callController(UserController.sendVerificationEmail)(r),
122122
},
123+
verifyEmail: {
124+
handler: async (r) => callController(UserController.verifyEmail)(r),
125+
},
123126
forgotPasswordEmail: {
124127
handler: async (r) =>
125128
callController(UserController.sendForgotPasswordEmail)(r),

frontend/src/email-handler.html

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@
176176
signInWithEmailAndPassword,
177177
} from "firebase/auth";
178178

179+
import { envConfig } from "./ts/constants/env-config";
180+
179181
function isPasswordStrong(password) {
180182
const hasCapital = !!password.match(/[A-Z]/);
181183
const hasNumber = !!password.match(/[\d]/);
@@ -189,8 +191,21 @@
189191

190192
function handleVerifyEmail(actionCode, continueUrl) {
191193
applyActionCode(Auth, actionCode)
192-
.then((resp) => {
194+
.then(async (resp) => {
193195
// Email address has been verified.
196+
const token =
197+
Auth.currentUser !== undefined
198+
? await Auth.currentUser.getIdToken(true)
199+
: undefined;
200+
const url = envConfig.backendUrl + "/users/verifyEmail";
201+
202+
await fetch(url, {
203+
method: "GET",
204+
headers: {
205+
"Content-Type": "application/json",
206+
Authorization: `Bearer ${token}`,
207+
},
208+
});
194209

195210
$("main .preloader .icon").html(`<i class="fas fa-fw fa-check"></i>`);
196211
$("main .preloader .text").text(

packages/contracts/src/rate-limit/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ export const limits = {
301301
max: 1,
302302
},
303303

304+
userVerifyEmail: {
305+
window: 15 * 60 * 1000, //15 minutes
306+
max: 1,
307+
},
308+
304309
userForgotPasswordEmail: {
305310
window: "minute",
306311
max: 1,

packages/contracts/src/users.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,19 @@ export const usersContract = c.router(
872872
rateLimit: "userRequestVerificationEmail",
873873
}),
874874
},
875+
verifyEmail: {
876+
summary: "verify email",
877+
description: "Verify the user email",
878+
method: "GET",
879+
path: "/verifyEmail",
880+
responses: {
881+
200: MonkeyResponseSchema,
882+
},
883+
metadata: meta({
884+
authenticationOptions: { noCache: true },
885+
rateLimit: "userVerifyEmail",
886+
}),
887+
},
875888
forgotPasswordEmail: {
876889
summary: "send forgot password email",
877890
description: "Send a forgot password email",

0 commit comments

Comments
 (0)