Skip to content

Commit 31a20ba

Browse files
committed
new endpoint to update emailVerified from email-handler
1 parent 935b999 commit 31a20ba

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
}
@@ -244,6 +245,13 @@ export async function sendVerificationEmail(
244245
return new MonkeyResponse("Email sent", null);
245246
}
246247

248+
export async function verifyEmail(req: MonkeyRequest): Promise<MonkeyResponse> {
249+
const { uid, email, emailVerified } = req.ctx.decodedToken;
250+
await UserDAL.updateEmail(uid, email, emailVerified);
251+
252+
return new MonkeyResponse("emailVerify updated.", null);
253+
}
254+
247255
export async function sendForgotPasswordEmail(
248256
req: MonkeyRequest<undefined, ForgotPasswordEmailRequest>
249257
): Promise<MonkeyResponse> {
@@ -607,7 +615,7 @@ export async function getUser(req: MonkeyRequest): Promise<GetUserResponse> {
607615
);
608616
delete relevantUserInfo.customThemes;
609617

610-
//update users emailVerified status if it changed
618+
// soft-migrate user.emailVerified for existing users, update status if it has changed
611619
const { email, emailVerified } = req.ctx.decodedToken;
612620
if (emailVerified !== undefined && emailVerified !== userInfo.emailVerified) {
613621
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
@@ -868,6 +868,19 @@ export const usersContract = c.router(
868868
rateLimit: "userRequestVerificationEmail",
869869
}),
870870
},
871+
verifyEmail: {
872+
summary: "verify email",
873+
description: "Verify the user email",
874+
method: "GET",
875+
path: "/verifyEmail",
876+
responses: {
877+
200: MonkeyResponseSchema,
878+
},
879+
metadata: meta({
880+
authenticationOptions: { noCache: true },
881+
rateLimit: "userVerifyEmail",
882+
}),
883+
},
871884
forgotPasswordEmail: {
872885
summary: "send forgot password email",
873886
description: "Send a forgot password email",

0 commit comments

Comments
 (0)