Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/next/pages/api/v2/auth/password-reset.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Password reset works as follows:781. Query the database to make sure there is a user with the given email address.92. If a password reset was already sent within the last XX minutes,10return an error -- we don't want people to spam other people with11password resets.123. Generate password reset token and write to database.134. Send email.145. Send response to user that email has been sent (or there was an error).15*/1617import isAccountAvailable from "@cocalc/server/auth/is-account-available";18import {19recentAttempts,20createReset,21} from "@cocalc/server/auth/password-reset";22import sendPasswordResetEmail from "@cocalc/server/email/password-reset";23import getParams from "lib/api/get-params";2425export default async function passwordReset(req, res) {26const { email } = getParams(req);27let result;28try {29result = await handle(email?.toLowerCase(), req.ip);30} catch (err) {31result = { error: err.message };32}33res.json(result);34}3536async function handle(email: string, ip: string): Promise<object> {37if (await isAccountAvailable(email)) {38// Bad -- email is *available*, which means no way to reset39// the password for it, since it doesn't exist.40return { error: `There is no account with email "${email}".` };41}42// Check that user isn't spamming email.4344const n = await recentAttempts(email, ip);45if (n > 3) {46return {47error: `We recently sent multiple password resets for "${email}". Check your email or wait a while and try later.`,48};49}5051const id = await createReset(email, ip, 60 * 60 * 4); // 4 hour ttl seems reasonable for this.52// TODO:53// - Send email with the id and link54// - Link should be back to next.js server (i.e., a new password reset target)55// - Implement that target and backend handling of it.56try {57await sendPasswordResetEmail(email, id);58} catch (err) {59console.trace(err);60return {61error: `Sending password reset email failed -- ${err.message}`,62};63}6465return {66success: `Password reset email successfully sent to ${email}.`,67};68}697071