Allow users to change their passwords
caution
SuperTokens does not provide the UI for users to change/update their password, you will need to create the UI and setup a route on your backend to have this functionality.
In this section we will go over how you can create a route on your backend which can update a user's password. Calling this route will check if the old password is valid and update the user's profile with the new password.
Step 1: Creating the /change-password route#
- You will need to create a route on your backend which is protected by the session verification middleware, this will ensure that only a authenticated user can access the protected route.
 - To learn more about how to use the session verfication middleware for other frameworks click here
 
- NodeJS
 - GoLang
 - Python
 
import { verifySession } from "supertokens-node/recipe/session/framework/express";import { SessionRequest } from "supertokens-node/framework/express"import express from "express";
let app = express();
app.post("/change-password", verifySession(), async (req: SessionRequest, res: express.Response) => {    // TODO: see next steps})
import (    "net/http"
    "github.com/supertokens/supertokens-golang/recipe/session")
// the following example uses net/httpfunc main() {    _ = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {        // Wrap the API handler in session.VerifySession        session.VerifySession(nil, changePasswordAPI).ServeHTTP(rw, r)    })}
func changePasswordAPI(w http.ResponseWriter, r *http.Request) {    // TODO: see next steps}
# the following example uses flaskfrom supertokens_python.recipe.session.framework.flask import verify_sessionfrom flask import Flask
app = Flask(__name__)
@app.route('/change-password', methods=['POST']) @verify_session()def change_password():    pass # TODO: see next stepsStep 2: Validate and update the user's password#
- You can now use 
sessionobject to retrive the logged in user'suserId. - Use the recipe's sign in function and check if the old password is valid
 - Update the user's password.
 
- NodeJS
 - GoLang
 - Python
 
// the following example uses expressimport ThirdPartyEmailPassword from "supertokens-node/recipe/thirdpartyemailpassword";import { verifySession } from "supertokens-node/recipe/session/framework/express";import { SessionRequest } from "supertokens-node/framework/express"import express from "express";
let app = express();
app.post("/change-password", verifySession(), async (req: SessionRequest, res: express.Response) => {
    // get the supertokens session object from the req    let session = req.session
    // retrive the old password from the request body    let oldPassword = req.body.oldPassword
    // retrive the new password from the request body    let updatedPassword = req.body.newPassword
    // get the user's Id from the session    let userId = session!.getUserId()
    // get the signed in user's email from the getUserById function    let userInfo = await ThirdPartyEmailPassword.getUserById(userId)
    if (userInfo === undefined) {        throw new Error("Should never come here")    }
    // call signin to check that input password is correct    let isPasswordValid = await ThirdPartyEmailPassword.emailPasswordSignIn(userInfo.email, oldPassword)
    if (isPasswordValid.status !== "OK") {        // TODO: handle incorrect password error        return    }
    // update the user's password using updateEmailOrPassword    let response = await ThirdPartyEmailPassword.updateEmailOrPassword({        userId,        password: updatedPassword    })        // TODO: send successful password update response
})
import (    "encoding/json"    "net/http"
    "github.com/supertokens/supertokens-golang/recipe/session"    "github.com/supertokens/supertokens-golang/recipe/thirdpartyemailpassword")
func main() {    _ = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {        // Wrap the API handler in session.VerifySession        session.VerifySession(nil, changePasswordAPI).ServeHTTP(rw, r)    })}
type RequestBody struct {    OldPassword string    NewPassword string}
func changePasswordAPI(w http.ResponseWriter, r *http.Request) {
    // retrieve the session object as shown below    sessionContainer := session.GetSessionFromRequestContext(r.Context())
    // retrive the old password from the request body    var requestBody RequestBody    err := json.NewDecoder(r.Body).Decode(&requestBody)    if err != nil {        http.Error(w, err.Error(), http.StatusBadRequest)        return    }
    // get the userId from the session    userID := sessionContainer.GetUserID()
    // get the signed in user's email from the getUserById function    userInfo, err := thirdpartyemailpassword.GetUserById(userID)    if err != nil {        // TODO: Handle error        return    }
    // call signin to check that the input is correct    isPasswordValid, err := thirdpartyemailpassword.EmailPasswordSignIn(userInfo.Email, requestBody.OldPassword)    if err != nil {        // TODO: Handle error        return    }
    if isPasswordValid.OK != nil {        // TODO: Handle error        return    }
    _, err = thirdpartyemailpassword.UpdateEmailOrPassword(userID, &userInfo.Email, &requestBody.NewPassword)    if err != nil {        // TODO: Handle error        return    }    // TODO: send successful password update response
}from supertokens_python.recipe.session.framework.flask import verify_sessionfrom supertokens_python.recipe.session import SessionContainerfrom supertokens_python.recipe.thirdpartyemailpassword.syncio import get_user_by_id, emailpassword_sign_in, update_email_or_passwordfrom supertokens_python.recipe.thirdpartyemailpassword.interfaces import EmailPasswordSignInWrongCredentialsErrorfrom flask import g
@app.route('/change-password', methods=['POST']) @verify_session()def change_password():
    session: SessionContainer = g.supertokens         # get the userId from the session object    user_id = session.get_user_id()
    # get the signed in user's email from the getUserById function    users_info = get_user_by_id(user_id)
    if users_info is None:        raise Exception("Should never come here")
    # call signin to check that the input password is correct    isPasswordValid = emailpassword_sign_in(users_info.email, request.json["oldPassword"]) 
    if isinstance(isPasswordValid, EmailPasswordSignInWrongCredentialsError):        # TODO: handle incorrect password error        return        # update the users password    update_email_or_password(user_id, password=request.json["newPassword"]) 
    # TODO: send successful password update responseStep 3: Revoke all sessions associated with the user (optional)#
- Revoking all sessions associated with the user will force them to reauthenticate with their new password.
 
- NodeJS
 - GoLang
 - Python
 
// the following example uses expressimport ThirdPartyEmailPassword from "supertokens-node/recipe/thirdpartyemailpassword";import Session from "supertokens-node/recipe/session";import { verifySession } from "supertokens-node/recipe/session/framework/express";import { SessionRequest } from "supertokens-node/framework/express"import express from "express";
let app = express();
app.post("/change-password", verifySession(), async (req: SessionRequest, res: express.Response) => {
   let userId = req.session!.getUserId();
    /**     *      * ...     * see previous step     * ...     *      *  */
    // revoke all sessions for the user    await Session.revokeAllSessionsForUser(userId)
    // revoke the current user's session, we do this to remove the auth cookies, logging out the user on the frontend.    await req.session!.revokeSession()
    // TODO: send successful password update response
})
import (    "net/http"
    "github.com/supertokens/supertokens-golang/recipe/session")
func main() {    _ = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {        // Wrap the API handler in session.VerifySession        session.VerifySession(nil, changePasswordAPI).ServeHTTP(rw, r)    })}
type ResponseBody struct {    OldPassword string    NewPassword string}
func changePasswordAPI(w http.ResponseWriter, r *http.Request) {
    // retrieve the session object as shown below    sessionContainer := session.GetSessionFromRequestContext(r.Context())    userID := sessionContainer.GetUserID()
    /**     *     * ...     * see previous step     * ...     *     *  */
    // revoke all sessions for the user    _, err := session.RevokeAllSessionsForUser(userID)    if err != nil {        // TODO: Handle error    }
    // revoke the user's current session, we do this to remove the auth cookies, logging out the user on the frontend    err = sessionContainer.RevokeSession()    if err != nil {        // TODO: Handle error    }
    // TODO: send successful password update response}from supertokens_python.recipe.session.framework.flask import verify_sessionfrom supertokens_python.recipe.session.syncio import revoke_all_sessions_for_userfrom flask import Flaskfrom supertokens_python.recipe.session import SessionContainer
app = Flask(__name__)@app.route('/change-password', methods=['POST']) @verify_session()def change_password():        session: SessionContainer = g.supertokens         # get the userId from the session object    user_id = session.get_user_id()
    # TODO: see previous step...
    # revoke all sessions for the user    revoke_all_sessions_for_user(user_id)        # revoke the user's current session, we do this to remove the auth cookies, logging out the user on the frontend    session.sync_revoke_session()
    # TODO: send successful password update response