summary refs log tree commit diff
path: root/src/api
diff options
context:
space:
mode:
authorPuyodead1 <puyodead@proton.me>2023-01-19 11:15:12 -0500
committerPuyodead1 <puyodead@protonmail.com>2023-02-23 21:35:51 -0500
commita47d80b255f1501e39bebd7ad7e80119c8ed1697 (patch)
treeeca3d1ff4a837efb8dfcc1571279c2f72f529e99 /src/api
parentadd missing copyright headers (diff)
downloadserver-a47d80b255f1501e39bebd7ad7e80119c8ed1697.tar.xz
Email verification works
- Added /auth/verify to authenticated route whitelist
- Updated /auth/verify to properly mark a user as verified, return a response, and fix expiration time check
- Implemented /auth/verify/resend
- Moved verification email sending to a helper method
- Fixed VerifyEmailSchema requiring captcha_key
Diffstat (limited to 'src/api')
-rw-r--r--src/api/middlewares/Authentication.ts5
-rw-r--r--src/api/routes/auth/verify/index.ts23
-rw-r--r--src/api/routes/auth/verify/resend.ts49
3 files changed, 72 insertions, 5 deletions
diff --git a/src/api/middlewares/Authentication.ts b/src/api/middlewares/Authentication.ts
index ea0aa312..f4c33963 100644
--- a/src/api/middlewares/Authentication.ts
+++ b/src/api/middlewares/Authentication.ts
@@ -16,10 +16,10 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-import { NextFunction, Request, Response } from "express";
-import { HTTPError } from "lambert-server";
 import { checkToken, Config, Rights } from "@fosscord/util";
 import * as Sentry from "@sentry/node";
+import { NextFunction, Request, Response } from "express";
+import { HTTPError } from "lambert-server";
 
 export const NO_AUTHORIZATION_ROUTES = [
 	// Authentication routes
@@ -28,6 +28,7 @@ export const NO_AUTHORIZATION_ROUTES = [
 	"/auth/location-metadata",
 	"/auth/mfa/totp",
 	"/auth/mfa/webauthn",
+	"/auth/verify",
 	// Routes with a seperate auth system
 	"/webhooks/",
 	// Public information endpoints
diff --git a/src/api/routes/auth/verify/index.ts b/src/api/routes/auth/verify/index.ts
index 4c076d09..d61b8d16 100644
--- a/src/api/routes/auth/verify/index.ts
+++ b/src/api/routes/auth/verify/index.ts
@@ -17,7 +17,11 @@
 */
 
 import { route, verifyCaptcha } from "@fosscord/api";
-import { Config, FieldErrors, verifyToken } from "@fosscord/util";
+import {
+	Config,
+	FieldErrors,
+	verifyTokenEmailVerification,
+} from "@fosscord/util";
 import { Request, Response, Router } from "express";
 import { HTTPError } from "lambert-server";
 const router = Router();
@@ -43,9 +47,13 @@ router.post(
 		try {
 			const { jwtSecret } = Config.get().security;
 
-			const { decoded, user } = await verifyToken(token, jwtSecret);
+			const { decoded, user } = await verifyTokenEmailVerification(
+				token,
+				jwtSecret,
+			);
+
 			// toksn should last for 24 hours from the time they were issued
-			if (decoded.exp < Date.now() / 1000) {
+			if (new Date().getTime() > decoded.iat * 1000 + 86400 * 1000) {
 				throw FieldErrors({
 					token: {
 						code: "TOKEN_INVALID",
@@ -53,7 +61,16 @@ router.post(
 					},
 				});
 			}
+
+			if (user.verified) return res.send(user);
+
+			// verify email
 			user.verified = true;
+			await user.save();
+
+			// TODO: invalidate token after use?
+
+			return res.send(user);
 		} catch (error: any) {
 			throw new HTTPError(error?.toString(), 400);
 		}
diff --git a/src/api/routes/auth/verify/resend.ts b/src/api/routes/auth/verify/resend.ts
new file mode 100644
index 00000000..0c8c4ed9
--- /dev/null
+++ b/src/api/routes/auth/verify/resend.ts
@@ -0,0 +1,49 @@
+/*
+	Fosscord: A FOSS re-implementation and extension of the Discord.com backend.
+	Copyright (C) 2023 Fosscord and Fosscord Contributors
+	
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU Affero General Public License as published
+	by the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+	
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU Affero General Public License for more details.
+	
+	You should have received a copy of the GNU Affero General Public License
+	along with this program.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+import { route } from "@fosscord/api";
+import { Email, User } from "@fosscord/util";
+import { Request, Response, Router } from "express";
+import { HTTPError } from "lambert-server";
+const router = Router();
+
+router.post("/", route({}), async (req: Request, res: Response) => {
+	const user = await User.findOneOrFail({
+		where: { id: req.user_id },
+		select: ["email"],
+	});
+
+	if (!user.email) {
+		// TODO: whats the proper error response for this?
+		throw new HTTPError("User does not have an email address", 400);
+	}
+
+	await Email.sendVerificationEmail(req.user_id, user.email)
+		.then((info) => {
+			console.log("Message sent: %s", info.messageId);
+			return res.sendStatus(204);
+		})
+		.catch((e) => {
+			console.error(
+				`Failed to send verification email to ${user.username}#${user.discriminator}: ${e}`,
+			);
+			throw new HTTPError("Failed to send verification email", 500);
+		});
+});
+
+export default router;