From 41660bc6a2b9bf3e0b4a6a167051be373fdef447 Mon Sep 17 00:00:00 2001 From: jscyo Date: Thu, 27 Jan 2022 18:37:24 +0530 Subject: [PATCH 01/11] adds change password guide --- .../common-customizations/change-password.mdx | 137 ++++++++++++++++++ v2/thirdpartyemailpassword/sidebars.js | 1 + 2 files changed, 138 insertions(+) create mode 100644 v2/thirdpartyemailpassword/common-customizations/change-password.mdx diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx new file mode 100644 index 000000000..dfb88a131 --- /dev/null +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -0,0 +1,137 @@ +--- +id: change-password +title: Change a User's Password +hide_title: true +--- + +import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; +import TabItem from '@theme/TabItem'; + +# Change a User's Password + +In this section we will go over how you can create a route on your backend which can change a user's password. + +The user will have to enter their old password and the password they would like to update it to. If the old password is valid the user's profile will now be updated with the new password. + +## Step 1: Creating the `/change-password` route +- You will first need to create a route on your backend which is protected with the `verifySession` Middleware +- The `verifySession` middleware will ensure that only an authenticated user can access the protected route. +- In this example `/change-password` will be the route on your backend which will be used to update a users password. + + + + +```jsx +// the following example uses express +let ThirdPartyEmailPassword = require("supertokens-node/recipe/thirdpartyemailpassword"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +app.post("/change-password", verifySession(), async (req, res) => { + +}) + +``` + + + + +## Step 2: Use the `session` Object to retrive the user's info and check if the old password is a valid credential + +- You can now use the `getUserId` function exposed by the `session` object to retrive the logged in user's `userId`. +- The user's profile can be retrived using the `getUserById` function. +- You can now call the `signIn` function and check if the old password is a valid credential + + + + +```jsx +// the following example uses express +let ThirdPartyEmailPassword = require("supertokens-node/recipe/thirdpartyemailpassword"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +app.post("/change-password", verifySession(), async (req, res) => { + + // get the supertokens session object from the req + let session = req.session + + // retrive the new password from the request body + let updatedPassword = req.body.password + + // get the users Id from the session + let userId = session.getUserId() + + // call signin to check that input password is correct + + let isPasswordValid = await ThirdPartyEmailPassword.signIn(userInfo.email, oldPassword) + + if (isPasswordValid.status !== "OK") { + res.send({ + status: isPasswordValid.status + }) + + return + } + +}) + +``` + + + +## Step 3: Revoke all sessions associated with the user (optional) + +- You can now revoke all sessions created by the user by calling the `revokeAllSessionsForUser` function. + + + + +```jsx +// the following example uses express +let ThirdPartyEmailPassword = require("supertokens-node/recipe/thirdpartyemailpassword"); +let Session = require("supertokens-node/recipe/session"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +app.get("/change-password", verifySession(), async (req, res) => { + + // get the session information from the req + let session = req.session + + let oldPassword = req.body.oldPassword + let updatedPassword = req.query.newPassword + + // get the users Id from the req.session + let userId = session.getUserId() + + // get the signed in user's email from the getUserById function + let userInfo = await ThirdPartyEmailPassword.getUserById(userId) + + // call signin to check that input password is correct + + let isPasswordValid = await ThirdPartyEmailPassword.signIn(userInfo.email, oldPassword) + + if (isPasswordValid.status !== "OK") { + res.send({ + status: isPasswordValid.status + }) + + return + } + + // update the user's password using updateEmailOrPassword + let response = await ThirdPartyEmailPassword.updateEmailOrPassword({ + userId, + password: updatedPassword + }) + + // revoke all sessions for the user + await Session.revokeAllSessionsForUser(userId) + + res.send({ + response + }) + +}) + +``` + + \ No newline at end of file diff --git a/v2/thirdpartyemailpassword/sidebars.js b/v2/thirdpartyemailpassword/sidebars.js index b93898bf2..63b3cd78a 100644 --- a/v2/thirdpartyemailpassword/sidebars.js +++ b/v2/thirdpartyemailpassword/sidebars.js @@ -84,6 +84,7 @@ module.exports = { "common-customizations/signin-form/custom-providers", ] }, + "common-customizations/change-password", "common-customizations/password-managers", "common-customizations/user-pagination", "common-customizations/delete-user", From 8600b7284071efa951ffd258c917fd1616f282c5 Mon Sep 17 00:00:00 2001 From: jscyo Date: Thu, 27 Jan 2022 18:59:37 +0530 Subject: [PATCH 02/11] fixs --- .../common-customizations/change-password.mdx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx index dfb88a131..006738330 100644 --- a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -9,9 +9,9 @@ import TabItem from '@theme/TabItem'; # Change a User's Password -In this section we will go over how you can create a route on your backend which can change a user's password. +In this section we will go over how you can create a route on your backend which can update a user's password. -The user will have to enter their old password and the password they would like to update it to. If the old password is valid the user's profile will now be updated with the new password. +Calling this API will check if the old password is a valid credential and update the user's profile with the new password. ## Step 1: Creating the `/change-password` route - You will first need to create a route on your backend which is protected with the `verifySession` Middleware @@ -26,10 +26,12 @@ The user will have to enter their old password and the password they would like let ThirdPartyEmailPassword = require("supertokens-node/recipe/thirdpartyemailpassword"); let { verifySession } = require("supertokens-node/recipe/session/framework/express"); +// highlight-start app.post("/change-password", verifySession(), async (req, res) => { }) +// highlight-end ``` @@ -51,6 +53,7 @@ let { verifySession } = require("supertokens-node/recipe/session/framework/expre app.post("/change-password", verifySession(), async (req, res) => { + // highlight-start // get the supertokens session object from the req let session = req.session @@ -71,6 +74,7 @@ app.post("/change-password", verifySession(), async (req, res) => { return } + // highlight-end }) @@ -123,8 +127,10 @@ app.get("/change-password", verifySession(), async (req, res) => { password: updatedPassword }) + // highlight-start // revoke all sessions for the user await Session.revokeAllSessionsForUser(userId) + //highlight-end res.send({ response From 476378f31a57770b67a13c1fd46226fb92a08116 Mon Sep 17 00:00:00 2001 From: jscyo Date: Thu, 27 Jan 2022 19:35:18 +0530 Subject: [PATCH 03/11] adds guide for emailpassword recipe --- .../common-customizations/change-password.mdx | 203 ++++++++++++++++++ v2/emailpassword/sidebars.js | 1 + .../common-customizations/change-password.mdx | 76 ++++++- 3 files changed, 272 insertions(+), 8 deletions(-) create mode 100644 v2/emailpassword/common-customizations/change-password.mdx diff --git a/v2/emailpassword/common-customizations/change-password.mdx b/v2/emailpassword/common-customizations/change-password.mdx new file mode 100644 index 000000000..a558e5e1d --- /dev/null +++ b/v2/emailpassword/common-customizations/change-password.mdx @@ -0,0 +1,203 @@ +--- +id: change-password +title: Change a User's Password +hide_title: true +--- + + + + +import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; +import TabItem from '@theme/TabItem'; + +# Change a User's Password + +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 API will check if the old password is a valid credential and update the user's profile with the new password. + +## Step 1: Creating the `/change-password` route +- You will first need to create a route on your backend which is protected with the `verifySession` Middleware +- The `verifySession` middleware will ensure that only an authenticated user can access the protected route. +- In this example `/change-password` will be the route on your backend which will be used to update a users password. + + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +// highlight-start +app.post("/change-password", verifySession(), async (req, res) => { + +}) + +// highlight-end +``` + + + + +## Step 2: Use the `session` Object to retrive the user's info and check if the old password is a valid credential + +- You can now use the `getUserId` function exposed by the `session` object to retrive the logged in user's `userId`. +- The user's profile can be retrived using the `getUserById` function. +- You can now call the `signIn` function and check if the old password is a valid credential + + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +app.post("/change-password", verifySession(), async (req, res) => { + + // highlight-start + // get the supertokens session object from the req + let session = req.session + + // retrive the new password from the request body + let updatedPassword = req.body.password + + // get the users Id from the session + let userId = session.getUserId() + + // call signin to check that input password is correct + + let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) + + if (isPasswordValid.status !== "OK") { + res.send({ + status: isPasswordValid.status + }) + + return + } + // highlight-end + +}) + +``` + + + +## Step 3: Update the user's password + +- You can now ccall the `updateEmailOrPassword` function to update the user's password. + + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let Session = require("supertokens-node/recipe/session"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +app.get("/change-password", verifySession(), async (req, res) => { + + // get the session information from the req + let session = req.session + + let oldPassword = req.body.oldPassword + let updatedPassword = req.query.newPassword + + // get the users Id from the req.session + let userId = session.getUserId() + + // get the signed in user's email from the getUserById function + let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) + + // call signin to check that input password is correct + + let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) + + if (isPasswordValid.status !== "OK") { + res.send({ + status: isPasswordValid.status + }) + + return + } + + // highlight-start + // update the user's password using updateEmailOrPassword + let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ + userId, + password: updatedPassword + }) + + res.send({ + response + }) + // highlight-end + +}) + +``` + + + +## Step 4: Revoke all sessions associated with the user (optional) + +- You can now revoke all sessions created by the user by calling the `revokeAllSessionsForUser` function. + + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let Session = require("supertokens-node/recipe/session"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +app.get("/change-password", verifySession(), async (req, res) => { + + // get the session information from the req + let session = req.session + + let oldPassword = req.body.oldPassword + let updatedPassword = req.query.newPassword + + // get the users Id from the req.session + let userId = session.getUserId() + + // get the signed in user's email from the getUserById function + let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) + + // call signin to check that input password is correct + + let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) + + if (isPasswordValid.status !== "OK") { + res.send({ + status: isPasswordValid.status + }) + + return + } + + // update the user's password using updateEmailOrPassword + let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ + userId, + password: updatedPassword + }) + + // highlight-start + // revoke all sessions for the user + await Session.revokeAllSessionsForUser(userId) + //highlight-end + + res.send({ + response + }) + +}) + +``` + + \ No newline at end of file diff --git a/v2/emailpassword/sidebars.js b/v2/emailpassword/sidebars.js index 373d1b78a..b1650c749 100644 --- a/v2/emailpassword/sidebars.js +++ b/v2/emailpassword/sidebars.js @@ -72,6 +72,7 @@ module.exports = { "common-customizations/signin-form/field-validators", ] }, + "common-customizations/change-password", "common-customizations/password-managers", "common-customizations/user-pagination", "common-customizations/delete-user", diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx index 006738330..a558e5e1d 100644 --- a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -4,6 +4,9 @@ title: Change a User's Password hide_title: true --- + + + import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; import TabItem from '@theme/TabItem'; @@ -23,7 +26,7 @@ Calling this API will check if the old password is a valid credential and update ```jsx // the following example uses express -let ThirdPartyEmailPassword = require("supertokens-node/recipe/thirdpartyemailpassword"); +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); let { verifySession } = require("supertokens-node/recipe/session/framework/express"); // highlight-start @@ -48,7 +51,7 @@ app.post("/change-password", verifySession(), async (req, res) => { ```jsx // the following example uses express -let ThirdPartyEmailPassword = require("supertokens-node/recipe/thirdpartyemailpassword"); +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); let { verifySession } = require("supertokens-node/recipe/session/framework/express"); app.post("/change-password", verifySession(), async (req, res) => { @@ -65,7 +68,7 @@ app.post("/change-password", verifySession(), async (req, res) => { // call signin to check that input password is correct - let isPasswordValid = await ThirdPartyEmailPassword.signIn(userInfo.email, oldPassword) + let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) if (isPasswordValid.status !== "OK") { res.send({ @@ -82,7 +85,64 @@ app.post("/change-password", verifySession(), async (req, res) => { -## Step 3: Revoke all sessions associated with the user (optional) +## Step 3: Update the user's password + +- You can now ccall the `updateEmailOrPassword` function to update the user's password. + + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let Session = require("supertokens-node/recipe/session"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +app.get("/change-password", verifySession(), async (req, res) => { + + // get the session information from the req + let session = req.session + + let oldPassword = req.body.oldPassword + let updatedPassword = req.query.newPassword + + // get the users Id from the req.session + let userId = session.getUserId() + + // get the signed in user's email from the getUserById function + let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) + + // call signin to check that input password is correct + + let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) + + if (isPasswordValid.status !== "OK") { + res.send({ + status: isPasswordValid.status + }) + + return + } + + // highlight-start + // update the user's password using updateEmailOrPassword + let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ + userId, + password: updatedPassword + }) + + res.send({ + response + }) + // highlight-end + +}) + +``` + + + +## Step 4: Revoke all sessions associated with the user (optional) - You can now revoke all sessions created by the user by calling the `revokeAllSessionsForUser` function. @@ -91,7 +151,7 @@ app.post("/change-password", verifySession(), async (req, res) => { ```jsx // the following example uses express -let ThirdPartyEmailPassword = require("supertokens-node/recipe/thirdpartyemailpassword"); +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); let Session = require("supertokens-node/recipe/session"); let { verifySession } = require("supertokens-node/recipe/session/framework/express"); @@ -107,11 +167,11 @@ app.get("/change-password", verifySession(), async (req, res) => { let userId = session.getUserId() // get the signed in user's email from the getUserById function - let userInfo = await ThirdPartyEmailPassword.getUserById(userId) + let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) // call signin to check that input password is correct - let isPasswordValid = await ThirdPartyEmailPassword.signIn(userInfo.email, oldPassword) + let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) if (isPasswordValid.status !== "OK") { res.send({ @@ -122,7 +182,7 @@ app.get("/change-password", verifySession(), async (req, res) => { } // update the user's password using updateEmailOrPassword - let response = await ThirdPartyEmailPassword.updateEmailOrPassword({ + let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ userId, password: updatedPassword }) From 73ccbb8289c0b877d84d906df25aa95e114cfa69 Mon Sep 17 00:00:00 2001 From: jscyo Date: Mon, 31 Jan 2022 13:55:08 +0530 Subject: [PATCH 04/11] adds golang code snipptets --- .../common-customizations/change-password.mdx | 216 +++++++++++++++++- .../common-customizations/change-password.mdx | 214 ++++++++++++++++- 2 files changed, 421 insertions(+), 9 deletions(-) diff --git a/v2/emailpassword/common-customizations/change-password.mdx b/v2/emailpassword/common-customizations/change-password.mdx index a558e5e1d..2e1f4fe37 100644 --- a/v2/emailpassword/common-customizations/change-password.mdx +++ b/v2/emailpassword/common-customizations/change-password.mdx @@ -36,6 +36,24 @@ app.post("/change-password", verifySession(), async (req, res) => { // highlight-end ``` + + + + +```go +// highlight-start +// the following example uses net/http +func main() { + // Wrap the API handler in session.VerifySession + session.VerifySession(nil, changePasswordAPI).ServeHTTP(rw, r) +} + +func changePasswordAPI(w http.ResponseWriter, r *http.Request) { + +} +// highlight-end +``` + @@ -60,12 +78,15 @@ app.post("/change-password", verifySession(), async (req, res) => { // get the supertokens session object from the req let session = req.session - // retrive the new password from the request body - let updatedPassword = req.body.password + // retrive the old password from the request body + let oldPassword = req.body.oldPassword - // get the users Id from the session + // 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 ^{recipeNameCapitalLetters}.getUserById(userId) + // call signin to check that input password is correct let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) @@ -81,13 +102,68 @@ app.post("/change-password", verifySession(), async (req, res) => { }) +``` + + + + +```go + +func main() { + // 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) { + // highlight-start + // retrieve the session object as shown below + sessionContainer := session.GetSessionFromRequestContext(r.Context()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}d.GetUserById(userId) + if err != nil { + // TODO: Handle error + return + } + + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: Invalid oldPassword + return + } + // highlight-end +} + ``` ## Step 3: Update the user's password -- You can now ccall the `updateEmailOrPassword` function to update the user's password. +- You can now call the `updateEmailOrPassword` function to update the user's password. @@ -138,6 +214,68 @@ app.get("/change-password", verifySession(), async (req, res) => { }) +``` + + + + +```go + +func main() { + // 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()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}d.GetUserById(userId) + if err != nil { + // TODO: Handle error + return + } + + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: Invalid oldPassword + return + } + + // highlight-start + _, err := ^{rid}.UpdateEmailOrPassword(userID, userInfo.email, response.NewPassword) + + if err != nil { + // TODO: Handle error + } + // highlight-end +} + ``` @@ -200,4 +338,72 @@ app.get("/change-password", verifySession(), async (req, res) => { ``` - \ No newline at end of file + + + +```go + +func main() { + // 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()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}d.GetUserById(userId) + if err != nil { + // TODO: Handle error + return + } + + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: Invalid oldPassword + return + } + + _, err := ^{rid}.UpdateEmailOrPassword(userID, userInfo.email, response.NewPassword) + + if err != nil { + // TODO: Handle error + } + + // highlight-start + _, err := session.RevokeAllSessionsForUser(userID) + if err != nil { + // TODO: Handle error + } + // highlight-end +} + +``` + + + diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx index a558e5e1d..8566d5fac 100644 --- a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -36,6 +36,24 @@ app.post("/change-password", verifySession(), async (req, res) => { // highlight-end ``` + + + + +```go +// highlight-start +// the following example uses net/http +func main() { + // Wrap the API handler in session.VerifySession + session.VerifySession(nil, changePasswordAPI).ServeHTTP(rw, r) +} + +func changePasswordAPI(w http.ResponseWriter, r *http.Request) { + +} +// highlight-end +``` + @@ -60,12 +78,15 @@ app.post("/change-password", verifySession(), async (req, res) => { // get the supertokens session object from the req let session = req.session - // retrive the new password from the request body - let updatedPassword = req.body.password + // retrive the old password from the request body + let oldPassword = req.body.oldPassword - // get the users Id from the session + // 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 ^{recipeNameCapitalLetters}.getUserById(userId) + // call signin to check that input password is correct let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) @@ -81,13 +102,68 @@ app.post("/change-password", verifySession(), async (req, res) => { }) +``` + + + + +```go + +func main() { + // 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) { + // highlight-start + // retrieve the session object as shown below + sessionContainer := session.GetSessionFromRequestContext(r.Context()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}d.GetUserById(userId) + if err != nil { + // TODO: Handle error + return + } + + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: Invalid oldPassword + return + } + // highlight-end +} + ``` ## Step 3: Update the user's password -- You can now ccall the `updateEmailOrPassword` function to update the user's password. +- You can now call the `updateEmailOrPassword` function to update the user's password. @@ -138,6 +214,68 @@ app.get("/change-password", verifySession(), async (req, res) => { }) +``` + + + + +```go + +func main() { + // 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()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}d.GetUserById(userId) + if err != nil { + // TODO: Handle error + return + } + + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: Invalid oldPassword + return + } + + // highlight-start + _, err := ^{rid}.UpdateEmailOrPassword(userID, userInfo.email, response.NewPassword) + + if err != nil { + // TODO: Handle error + } + // highlight-end +} + ``` @@ -200,4 +338,72 @@ app.get("/change-password", verifySession(), async (req, res) => { ``` + + + +```go + +func main() { + // 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()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}d.GetUserById(userId) + if err != nil { + // TODO: Handle error + return + } + + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: Invalid oldPassword + return + } + + _, err := ^{rid}.UpdateEmailOrPassword(userID, userInfo.email, response.NewPassword) + + if err != nil { + // TODO: Handle error + } + + // highlight-start + _, err := session.RevokeAllSessionsForUser(userID) + if err != nil { + // TODO: Handle error + } + // highlight-end +} + +``` + + \ No newline at end of file From 1f62710cc1b5a11317070da478ab8ebaddb8d215 Mon Sep 17 00:00:00 2001 From: jscyo Date: Tue, 1 Feb 2022 14:24:49 +0530 Subject: [PATCH 05/11] adds python snippets --- .../common-customizations/change-password.mdx | 116 ++++++++++++++++++ .../common-customizations/change-password.mdx | 116 ++++++++++++++++++ 2 files changed, 232 insertions(+) diff --git a/v2/emailpassword/common-customizations/change-password.mdx b/v2/emailpassword/common-customizations/change-password.mdx index 2e1f4fe37..6c635c8c0 100644 --- a/v2/emailpassword/common-customizations/change-password.mdx +++ b/v2/emailpassword/common-customizations/change-password.mdx @@ -55,6 +55,22 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ``` + + + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session + +# highlight-start +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): +# highlight-end +``` + + + @@ -157,6 +173,35 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { // highlight-end } +``` + + + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in + +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + + # highlight-start + session_ = 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) + + # call signin to check that the input password is correct + isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) + + if isPasswordValid.status != "OK": + return isPasswordValid.status + # highlight-end + ``` @@ -278,6 +323,40 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ``` + + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password + +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + session_ = 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) + + # call signin to check that the input password is correct + isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) + + if isPasswordValid.status != "OK": + return isPasswordValid.status + + # highlight-start + # update the users password + response = update_email_or_password(user_id, password=request.json["newPassword"]) + # highlight-start + + return response.status + +``` + + ## Step 4: Revoke all sessions associated with the user (optional) @@ -406,4 +485,41 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ``` + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password +from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user + +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + session_ = 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) + + # call signin to check that the input password is correct + isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) + + if isPasswordValid.status != "OK": + return isPasswordValid.status + + # update the users password + response = update_email_or_password(user_id, password=request.json["newPassword"]) + + # highlight-start + # revoke all sessions for the user + revoke_all_sessions_for_user(user_id) + # highlight-end + + return response.status + +``` + + diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx index 8566d5fac..3a78533bf 100644 --- a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -55,6 +55,22 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ``` + + + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session + +# highlight-start +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): +# highlight-end +``` + + + @@ -157,6 +173,35 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { // highlight-end } +``` + + + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in + +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + + # highlight-start + session_ = 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) + + # call signin to check that the input password is correct + isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) + + if isPasswordValid.status != "OK": + return isPasswordValid.status + # highlight-end + ``` @@ -278,6 +323,40 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ``` + + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password + +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + session_ = 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) + + # call signin to check that the input password is correct + isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) + + if isPasswordValid.status != "OK": + return isPasswordValid.status + + # highlight-start + # update the users password + response = update_email_or_password(user_id, password=request.json["newPassword"]) + # highlight-start + + return response.status + +``` + + ## Step 4: Revoke all sessions associated with the user (optional) @@ -406,4 +485,41 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ``` + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password +from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user + +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + session_ = 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) + + # call signin to check that the input password is correct + isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) + + if isPasswordValid.status != "OK": + return isPasswordValid.status + + # update the users password + response = update_email_or_password(user_id, password=request.json["newPassword"]) + + # highlight-start + # revoke all sessions for the user + revoke_all_sessions_for_user(user_id) + # highlight-end + + return response.status + +``` + + \ No newline at end of file From 35624d7bbdffc91792292189195e20a1ef8b8504 Mon Sep 17 00:00:00 2001 From: jscyo Date: Tue, 1 Feb 2022 14:42:30 +0530 Subject: [PATCH 06/11] fixs --- .../common-customizations/change-password.mdx | 233 +++++++++--------- .../common-customizations/change-password.mdx | 233 +++++++++--------- 2 files changed, 240 insertions(+), 226 deletions(-) diff --git a/v2/emailpassword/common-customizations/change-password.mdx b/v2/emailpassword/common-customizations/change-password.mdx index 6c635c8c0..f4b08a586 100644 --- a/v2/emailpassword/common-customizations/change-password.mdx +++ b/v2/emailpassword/common-customizations/change-password.mdx @@ -60,6 +60,7 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ```python +# the following example uses flask from supertokens_python.recipe.session.framework.flask import verify_session # highlight-start @@ -136,40 +137,40 @@ type ResponseBody struct { } func changePasswordAPI(w http.ResponseWriter, r *http.Request) { - // highlight-start - // retrieve the session object as shown below - sessionContainer := session.GetSessionFromRequestContext(r.Context()) - - // retrive the old password from the request body - var response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}d.GetUserById(userId) - if err != nil { - // TODO: Handle error - return - } + // retrieve the session object as shown below + sessionContainer := session.GetSessionFromRequestContext(r.Context()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}.GetUserById(userID) + if err != nil { + // TODO: Handle error + return + } + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - if isPasswordValid.OK == nil { - // TODO: Invalid oldPassword - return - } + // highlight-start + if isPasswordValid.OK == nil { + // TODO: Handle error + return + } // highlight-end } @@ -278,46 +279,45 @@ type ResponseBody struct { 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 response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}d.GetUserById(userId) - if err != nil { - // TODO: Handle error - return - } - - - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - if isPasswordValid.OK == nil { - // TODO: Invalid oldPassword - return - } + // retrieve the session object as shown below + sessionContainer := session.GetSessionFromRequestContext(r.Context()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}.GetUserById(userID) + if err != nil { + // TODO: Handle error + return + } + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: Handle error + return + } // highlight-start - _, err := ^{rid}.UpdateEmailOrPassword(userID, userInfo.email, response.NewPassword) - - if err != nil { - // TODO: Handle error - } + _, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) + if err != nil { + // TODO: Handle error + return + } // highlight-end } @@ -434,52 +434,59 @@ type ResponseBody struct { 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 response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}d.GetUserById(userId) - if err != nil { - // TODO: Handle error - return - } - - - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - if isPasswordValid.OK == nil { - // TODO: Invalid oldPassword - return - } - - _, err := ^{rid}.UpdateEmailOrPassword(userID, userInfo.email, response.NewPassword) - - if err != nil { - // TODO: Handle error - } + // retrieve the session object as shown below + sessionContainer := session.GetSessionFromRequestContext(r.Context()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}.GetUserById(userID) + if err != nil { + // TODO: Handle error + return + } + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: IHandle nvalid oldPassword + return + } + + _, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) + if err != nil { + // TODO: Handle error + return + } // highlight-start - _, err := session.RevokeAllSessionsForUser(userID) - if err != nil { - // TODO: Handle error - } + _, err = session.RevokeAllSessionsForUser(userID) + if err != nil { + // TODO: Handle error + } // highlight-end + + resp := make(map[string]string) + resp["message"] = "Password Changed" + jsonResp, err := json.Marshal(resp) + if err != nil { + log.Fatalf("Error happened in JSON marshal. Err: %s", err) + } + w.Write(jsonResp) } ``` diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx index 3a78533bf..e77d5e37e 100644 --- a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -60,6 +60,7 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ```python +# the following example uses flask from supertokens_python.recipe.session.framework.flask import verify_session # highlight-start @@ -136,40 +137,40 @@ type ResponseBody struct { } func changePasswordAPI(w http.ResponseWriter, r *http.Request) { - // highlight-start - // retrieve the session object as shown below - sessionContainer := session.GetSessionFromRequestContext(r.Context()) - - // retrive the old password from the request body - var response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}d.GetUserById(userId) - if err != nil { - // TODO: Handle error - return - } + // retrieve the session object as shown below + sessionContainer := session.GetSessionFromRequestContext(r.Context()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}.GetUserById(userID) + if err != nil { + // TODO: Handle error + return + } + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - if isPasswordValid.OK == nil { - // TODO: Invalid oldPassword - return - } + // highlight-start + if isPasswordValid.OK == nil { + // TODO: Handle error + return + } // highlight-end } @@ -278,46 +279,45 @@ type ResponseBody struct { 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 response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}d.GetUserById(userId) - if err != nil { - // TODO: Handle error - return - } - - - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - if isPasswordValid.OK == nil { - // TODO: Invalid oldPassword - return - } + // retrieve the session object as shown below + sessionContainer := session.GetSessionFromRequestContext(r.Context()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}.GetUserById(userID) + if err != nil { + // TODO: Handle error + return + } + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: Handle error + return + } // highlight-start - _, err := ^{rid}.UpdateEmailOrPassword(userID, userInfo.email, response.NewPassword) - - if err != nil { - // TODO: Handle error - } + _, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) + if err != nil { + // TODO: Handle error + return + } // highlight-end } @@ -434,52 +434,59 @@ type ResponseBody struct { 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 response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}d.GetUserById(userId) - if err != nil { - // TODO: Handle error - return - } - - - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - if isPasswordValid.OK == nil { - // TODO: Invalid oldPassword - return - } - - _, err := ^{rid}.UpdateEmailOrPassword(userID, userInfo.email, response.NewPassword) - - if err != nil { - // TODO: Handle error - } + // retrieve the session object as shown below + sessionContainer := session.GetSessionFromRequestContext(r.Context()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}.GetUserById(userID) + if err != nil { + // TODO: Handle error + return + } + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: IHandle nvalid oldPassword + return + } + + _, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) + if err != nil { + // TODO: Handle error + return + } // highlight-start - _, err := session.RevokeAllSessionsForUser(userID) - if err != nil { - // TODO: Handle error - } + _, err = session.RevokeAllSessionsForUser(userID) + if err != nil { + // TODO: Handle error + } // highlight-end + + resp := make(map[string]string) + resp["message"] = "Password Changed" + jsonResp, err := json.Marshal(resp) + if err != nil { + log.Fatalf("Error happened in JSON marshal. Err: %s", err) + } + w.Write(jsonResp) } ``` From af9e423a2bad7a583ea12719ee2df9d453788d2b Mon Sep 17 00:00:00 2001 From: jscyo Date: Mon, 7 Feb 2022 12:31:06 +0530 Subject: [PATCH 07/11] fixs --- .../common-customizations/change-password.mdx | 206 +++++------------- v2/emailpassword/sidebars.js | 2 +- .../common-customizations/change-password.mdx | 206 +++++------------- v2/thirdpartyemailpassword/sidebars.js | 2 +- 4 files changed, 110 insertions(+), 306 deletions(-) diff --git a/v2/emailpassword/common-customizations/change-password.mdx b/v2/emailpassword/common-customizations/change-password.mdx index f4b08a586..f0473aaa3 100644 --- a/v2/emailpassword/common-customizations/change-password.mdx +++ b/v2/emailpassword/common-customizations/change-password.mdx @@ -8,20 +8,23 @@ hide_title: true import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; +import BackendSDKCasing from "/src/components/BackendSDKCasing" import TabItem from '@theme/TabItem'; # Change a User's Password -In this section we will go over how you can create a route on your backend which can update a user's password. +:::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. +::: -Calling this API will check if the old password is a valid credential and update the user's profile with the new password. +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 first need to create a route on your backend which is protected with the `verifySession` Middleware -- The `verifySession` middleware will ensure that only an authenticated user can access the protected route. -- In this example `/change-password` will be the route on your backend which will be used to update a users password. +- 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](verify-session) + ```jsx @@ -75,11 +78,12 @@ def change_password(): -## Step 2: Use the `session` Object to retrive the user's info and check if the old password is a valid credential +## Step 2: Validate and update the user's password - You can now use the `getUserId` function exposed by the `session` object to retrive the logged in user's `userId`. - The user's profile can be retrived using the `getUserById` function. -- You can now call the `signIn` function and check if the old password is a valid credential +- Use `signIn` function and check if the old password is valid +- You can update the user's password with the `updateEmailOrPassword` function. @@ -105,137 +109,6 @@ app.post("/change-password", verifySession(), async (req, res) => { let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) // call signin to check that input password is correct - - let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) - - if (isPasswordValid.status !== "OK") { - res.send({ - status: isPasswordValid.status - }) - - return - } - // highlight-end - -}) - -``` - - - - -```go - -func main() { - // 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()) - - // retrive the old password from the request body - var response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}.GetUserById(userID) - if err != nil { - // TODO: Handle error - return - } - - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - // highlight-start - if isPasswordValid.OK == nil { - // TODO: Handle error - return - } - // highlight-end -} - -``` - - - - -```python -from supertokens_python.recipe.session.framework.flask import verify_session -from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in - -@app.route('/change-password', methods=['POST']) -@verify_session() -def change_password(): - - # highlight-start - session_ = 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) - - # call signin to check that the input password is correct - isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) - - if isPasswordValid.status != "OK": - return isPasswordValid.status - # highlight-end - -``` - - - -## Step 3: Update the user's password - -- You can now call the `updateEmailOrPassword` function to update the user's password. - - - - -```jsx -// the following example uses express -let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); -let Session = require("supertokens-node/recipe/session"); -let { verifySession } = require("supertokens-node/recipe/session/framework/express"); - -app.get("/change-password", verifySession(), async (req, res) => { - - // get the session information from the req - let session = req.session - - let oldPassword = req.body.oldPassword - let updatedPassword = req.query.newPassword - - // get the users Id from the req.session - let userId = session.getUserId() - - // get the signed in user's email from the getUserById function - let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) - - // call signin to check that input password is correct - let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) if (isPasswordValid.status !== "OK") { @@ -246,15 +119,15 @@ app.get("/change-password", verifySession(), async (req, res) => { return } - // highlight-start // update the user's password using updateEmailOrPassword + let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ userId, password: updatedPassword }) res.send({ - response + status: response.status }) // highlight-end @@ -307,18 +180,30 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { return } + // highlight-start if isPasswordValid.OK == nil { // TODO: Handle error return } - // highlight-start - _, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) + response, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) if err != nil { // TODO: Handle error return } // highlight-end + + resp := make(map[string]string) + if response.OK != nil { + resp["status"] = "OK" + } else { + resp["status"] = "Could not update" + } + jsonResp, err := json.Marshal(resp) + if err != nil { + log.Fatalf("Error happened in JSON marshal. Err: %s", err) + } + w.Write(jsonResp) } ``` @@ -328,11 +213,13 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ```python from supertokens_python.recipe.session.framework.flask import verify_session -from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in @app.route('/change-password', methods=['POST']) @verify_session() def change_password(): + + # highlight-start session_ = g.supertokens # get the userId from the session object @@ -347,19 +234,16 @@ def change_password(): if isPasswordValid.status != "OK": return isPasswordValid.status - # highlight-start # update the users password response = update_email_or_password(user_id, password=request.json["newPassword"]) - # highlight-start - return response.status + # highlight-end ``` - -## Step 4: Revoke all sessions associated with the user (optional) +## Step 3: Revoke all sessions associated with the user (optional) - You can now revoke all sessions created by the user by calling the `revokeAllSessionsForUser` function. @@ -407,10 +291,13 @@ app.get("/change-password", verifySession(), async (req, res) => { // highlight-start // 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 Session.revokeSession(session.getHandle()) //highlight-end res.send({ - response + status: response.status }) }) @@ -474,14 +361,27 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { } // highlight-start + + // 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 = session.RevokeSession(userID) + if err != nil { + // TODO: Handle error + } + // highlight-end resp := make(map[string]string) - resp["message"] = "Password Changed" + if response.OK != nil { + resp["status"] = "OK" + } else { + resp["status"] = "Could not update" + } jsonResp, err := json.Marshal(resp) if err != nil { log.Fatalf("Error happened in JSON marshal. Err: %s", err) @@ -497,7 +397,7 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ```python from supertokens_python.recipe.session.framework.flask import verify_session from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password -from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user +from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user, revoke_session @app.route('/change-password', methods=['POST']) @verify_session() @@ -522,8 +422,10 @@ def change_password(): # highlight-start # 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 + revoke_session(session_.get_handle()) # highlight-end - return response.status ``` diff --git a/v2/emailpassword/sidebars.js b/v2/emailpassword/sidebars.js index b1650c749..66f8f64f5 100644 --- a/v2/emailpassword/sidebars.js +++ b/v2/emailpassword/sidebars.js @@ -72,11 +72,11 @@ module.exports = { "common-customizations/signin-form/field-validators", ] }, - "common-customizations/change-password", "common-customizations/password-managers", "common-customizations/user-pagination", "common-customizations/delete-user", "common-customizations/embed-sign-in-up-form", + "common-customizations/change-password", { type: "category", label: "User Roles", diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx index e77d5e37e..639f438ca 100644 --- a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -8,20 +8,23 @@ hide_title: true import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; +import BackendSDKCasing from "/src/components/BackendSDKCasing" import TabItem from '@theme/TabItem'; # Change a User's Password -In this section we will go over how you can create a route on your backend which can update a user's password. +:::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. +::: -Calling this API will check if the old password is a valid credential and update the user's profile with the new password. +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 first need to create a route on your backend which is protected with the `verifySession` Middleware -- The `verifySession` middleware will ensure that only an authenticated user can access the protected route. -- In this example `/change-password` will be the route on your backend which will be used to update a users password. +- 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](verify-session) + ```jsx @@ -75,11 +78,12 @@ def change_password(): -## Step 2: Use the `session` Object to retrive the user's info and check if the old password is a valid credential +## Step 2: Validate and update the user's password - You can now use the `getUserId` function exposed by the `session` object to retrive the logged in user's `userId`. - The user's profile can be retrived using the `getUserById` function. -- You can now call the `signIn` function and check if the old password is a valid credential +- Use `signIn` function and check if the old password is valid +- You can update the user's password with the `updateEmailOrPassword` function. @@ -105,137 +109,6 @@ app.post("/change-password", verifySession(), async (req, res) => { let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) // call signin to check that input password is correct - - let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) - - if (isPasswordValid.status !== "OK") { - res.send({ - status: isPasswordValid.status - }) - - return - } - // highlight-end - -}) - -``` - - - - -```go - -func main() { - // 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()) - - // retrive the old password from the request body - var response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}.GetUserById(userID) - if err != nil { - // TODO: Handle error - return - } - - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - // highlight-start - if isPasswordValid.OK == nil { - // TODO: Handle error - return - } - // highlight-end -} - -``` - - - - -```python -from supertokens_python.recipe.session.framework.flask import verify_session -from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in - -@app.route('/change-password', methods=['POST']) -@verify_session() -def change_password(): - - # highlight-start - session_ = 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) - - # call signin to check that the input password is correct - isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) - - if isPasswordValid.status != "OK": - return isPasswordValid.status - # highlight-end - -``` - - - -## Step 3: Update the user's password - -- You can now call the `updateEmailOrPassword` function to update the user's password. - - - - -```jsx -// the following example uses express -let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); -let Session = require("supertokens-node/recipe/session"); -let { verifySession } = require("supertokens-node/recipe/session/framework/express"); - -app.get("/change-password", verifySession(), async (req, res) => { - - // get the session information from the req - let session = req.session - - let oldPassword = req.body.oldPassword - let updatedPassword = req.query.newPassword - - // get the users Id from the req.session - let userId = session.getUserId() - - // get the signed in user's email from the getUserById function - let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) - - // call signin to check that input password is correct - let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) if (isPasswordValid.status !== "OK") { @@ -246,15 +119,15 @@ app.get("/change-password", verifySession(), async (req, res) => { return } - // highlight-start // update the user's password using updateEmailOrPassword + let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ userId, password: updatedPassword }) res.send({ - response + status: response.status }) // highlight-end @@ -307,18 +180,30 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { return } + // highlight-start if isPasswordValid.OK == nil { // TODO: Handle error return } - // highlight-start - _, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) + response, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) if err != nil { // TODO: Handle error return } // highlight-end + + resp := make(map[string]string) + if response.OK != nil { + resp["status"] = "OK" + } else { + resp["status"] = "Could not update" + } + jsonResp, err := json.Marshal(resp) + if err != nil { + log.Fatalf("Error happened in JSON marshal. Err: %s", err) + } + w.Write(jsonResp) } ``` @@ -328,11 +213,13 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ```python from supertokens_python.recipe.session.framework.flask import verify_session -from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in @app.route('/change-password', methods=['POST']) @verify_session() def change_password(): + + # highlight-start session_ = g.supertokens # get the userId from the session object @@ -347,19 +234,16 @@ def change_password(): if isPasswordValid.status != "OK": return isPasswordValid.status - # highlight-start # update the users password response = update_email_or_password(user_id, password=request.json["newPassword"]) - # highlight-start - return response.status + # highlight-end ``` - -## Step 4: Revoke all sessions associated with the user (optional) +## Step 3: Revoke all sessions associated with the user (optional) - You can now revoke all sessions created by the user by calling the `revokeAllSessionsForUser` function. @@ -407,10 +291,13 @@ app.get("/change-password", verifySession(), async (req, res) => { // highlight-start // 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 Session.revokeSession(session.getHandle()) //highlight-end res.send({ - response + status: response.status }) }) @@ -474,14 +361,27 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { } // highlight-start + + // 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 = session.RevokeSession(userID) + if err != nil { + // TODO: Handle error + } + // highlight-end resp := make(map[string]string) - resp["message"] = "Password Changed" + if response.OK != nil { + resp["status"] = "OK" + } else { + resp["status"] = "Could not update" + } jsonResp, err := json.Marshal(resp) if err != nil { log.Fatalf("Error happened in JSON marshal. Err: %s", err) @@ -497,7 +397,7 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { ```python from supertokens_python.recipe.session.framework.flask import verify_session from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password -from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user +from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user, revoke_session @app.route('/change-password', methods=['POST']) @verify_session() @@ -522,8 +422,10 @@ def change_password(): # highlight-start # 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 + revoke_session(session_.get_handle()) # highlight-end - return response.status ``` diff --git a/v2/thirdpartyemailpassword/sidebars.js b/v2/thirdpartyemailpassword/sidebars.js index 63b3cd78a..466184f19 100644 --- a/v2/thirdpartyemailpassword/sidebars.js +++ b/v2/thirdpartyemailpassword/sidebars.js @@ -84,12 +84,12 @@ module.exports = { "common-customizations/signin-form/custom-providers", ] }, - "common-customizations/change-password", "common-customizations/password-managers", "common-customizations/user-pagination", "common-customizations/delete-user", "common-customizations/embed-sign-in-up-form", "common-customizations/account-linking", + "common-customizations/change-password", { type: "category", label: "User Roles", From 0e7100168525a890ea384f7ceba14bb2f075fe4d Mon Sep 17 00:00:00 2001 From: jscyo Date: Mon, 7 Feb 2022 13:55:34 +0530 Subject: [PATCH 08/11] adds remaining feedback --- .../common-customizations/change-password.mdx | 257 +--------------- .../_change-password-ending-snippet.mdx | 191 ++++++++++++ .../_change-password-introduction-snippet.mdx | 60 ++++ .../common-customizations/change-password.mdx | 288 +++--------------- 4 files changed, 298 insertions(+), 498 deletions(-) create mode 100644 v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx create mode 100644 v2/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx diff --git a/v2/emailpassword/common-customizations/change-password.mdx b/v2/emailpassword/common-customizations/change-password.mdx index f0473aaa3..b5a5a0a7e 100644 --- a/v2/emailpassword/common-customizations/change-password.mdx +++ b/v2/emailpassword/common-customizations/change-password.mdx @@ -1,17 +1,16 @@ --- id: change-password -title: Change a User's Password +title: Allow users to change their passwords hide_title: true --- - - - import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; import BackendSDKCasing from "/src/components/BackendSDKCasing" +import IntroductionSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx" +import EndingSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx" import TabItem from '@theme/TabItem'; -# Change a User's Password +# 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. @@ -23,66 +22,12 @@ In this section we will go over how you can create a route on your backend which - 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](verify-session) - - - - -```jsx -// the following example uses express -let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); -let { verifySession } = require("supertokens-node/recipe/session/framework/express"); - -// highlight-start -app.post("/change-password", verifySession(), async (req, res) => { - -}) - -// highlight-end -``` - - - - -```go -// highlight-start -// the following example uses net/http -func main() { - // Wrap the API handler in session.VerifySession - session.VerifySession(nil, changePasswordAPI).ServeHTTP(rw, r) -} - -func changePasswordAPI(w http.ResponseWriter, r *http.Request) { - -} -// highlight-end -``` - - - - - - -```python -# the following example uses flask -from supertokens_python.recipe.session.framework.flask import verify_session - -# highlight-start -@app.route('/change-password', methods=['POST']) -@verify_session() -def change_password(): -# highlight-end -``` - - - - - + ## Step 2: Validate and update the user's password -- You can now use the `getUserId` function exposed by the `session` object to retrive the logged in user's `userId`. -- The user's profile can be retrived using the `getUserById` function. -- Use `signIn` function and check if the old password is valid +- You can now use `session` object to retrive the logged in user's `userId`. +- Use the recipe's `signIn`function and check if the old password is valid - You can update the user's password with the `updateEmailOrPassword` function. @@ -245,190 +190,6 @@ def change_password(): ## Step 3: Revoke all sessions associated with the user (optional) -- You can now revoke all sessions created by the user by calling the `revokeAllSessionsForUser` function. +- You can now invalidate all sessions associated with the user so they can login with their new password. - - - -```jsx -// the following example uses express -let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); -let Session = require("supertokens-node/recipe/session"); -let { verifySession } = require("supertokens-node/recipe/session/framework/express"); - -app.get("/change-password", verifySession(), async (req, res) => { - - // get the session information from the req - let session = req.session - - let oldPassword = req.body.oldPassword - let updatedPassword = req.query.newPassword - - // get the users Id from the req.session - let userId = session.getUserId() - - // get the signed in user's email from the getUserById function - let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) - - // call signin to check that input password is correct - - let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) - - if (isPasswordValid.status !== "OK") { - res.send({ - status: isPasswordValid.status - }) - - return - } - - // update the user's password using updateEmailOrPassword - let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ - userId, - password: updatedPassword - }) - - // highlight-start - // 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 Session.revokeSession(session.getHandle()) - //highlight-end - - res.send({ - status: response.status - }) - -}) - -``` - - - - -```go - -func main() { - // 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()) - - // retrive the old password from the request body - var response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}.GetUserById(userID) - if err != nil { - // TODO: Handle error - return - } - - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - if isPasswordValid.OK == nil { - // TODO: IHandle nvalid oldPassword - return - } - - _, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) - if err != nil { - // TODO: Handle error - return - } - - // highlight-start - - // 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 = session.RevokeSession(userID) - if err != nil { - // TODO: Handle error - } - - // highlight-end - - resp := make(map[string]string) - if response.OK != nil { - resp["status"] = "OK" - } else { - resp["status"] = "Could not update" - } - jsonResp, err := json.Marshal(resp) - if err != nil { - log.Fatalf("Error happened in JSON marshal. Err: %s", err) - } - w.Write(jsonResp) -} - -``` - - - - -```python -from supertokens_python.recipe.session.framework.flask import verify_session -from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password -from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user, revoke_session - -@app.route('/change-password', methods=['POST']) -@verify_session() -def change_password(): - session_ = 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) - - # call signin to check that the input password is correct - isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) - - if isPasswordValid.status != "OK": - return isPasswordValid.status - - # update the users password - response = update_email_or_password(user_id, password=request.json["newPassword"]) - - # highlight-start - # 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 - revoke_session(session_.get_handle()) - # highlight-end - return response.status - -``` - - - + diff --git a/v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx b/v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx new file mode 100644 index 000000000..17ee4e61a --- /dev/null +++ b/v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx @@ -0,0 +1,191 @@ +import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; +import BackendSDKCasing from "/src/components/BackendSDKCasing" +import IntroductionSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx" +import EndingSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx" +import TabItem from '@theme/TabItem'; + + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let Session = require("supertokens-node/recipe/session"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +app.get("/change-password", verifySession(), async (req, res) => { + + // get the session information from the req + let session = req.session + + let oldPassword = req.body.oldPassword + let updatedPassword = req.query.newPassword + + // get the users Id from the req.session + let userId = session.getUserId() + + // get the signed in user's email from the getUserById function + let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) + + // call signin to check that input password is correct + + let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) + + if (isPasswordValid.status !== "OK") { + res.send({ + status: isPasswordValid.status + }) + + return + } + + // update the user's password using updateEmailOrPassword + let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ + userId, + password: updatedPassword + }) + + // highlight-start + // 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 Session.revokeSession(session.getHandle()) + //highlight-end + + res.send({ + status: response.status + }) + +}) + +``` + + + + +```go + +func main() { + // 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()) + + // retrive the old password from the request body + var response ResponseBody + err := json.NewDecoder(r.Body).Decode(&response) + 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 := ^{rid}.GetUserById(userID) + if err != nil { + // TODO: Handle error + return + } + + // call signin to check that the input is correct + isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) + if err != nil { + // TODO: Handle error + return + } + + if isPasswordValid.OK == nil { + // TODO: IHandle nvalid oldPassword + return + } + + _, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) + if err != nil { + // TODO: Handle error + return + } + + // highlight-start + + // 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 = session.RevokeSession(userID) + if err != nil { + // TODO: Handle error + } + + // highlight-end + + resp := make(map[string]string) + if response.OK != nil { + resp["status"] = "OK" + } else { + resp["status"] = "Could not update" + } + jsonResp, err := json.Marshal(resp) + if err != nil { + log.Fatalf("Error happened in JSON marshal. Err: %s", err) + } + w.Write(jsonResp) +} + +``` + + + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password +from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user, revoke_session + +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + session_ = 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) + + # call signin to check that the input password is correct + isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) + + if isPasswordValid.status != "OK": + return isPasswordValid.status + + # update the users password + response = update_email_or_password(user_id, password=request.json["newPassword"]) + + # highlight-start + # 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 + revoke_session(session_.get_handle()) + # highlight-end + return response.status + +``` + + + \ No newline at end of file diff --git a/v2/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx b/v2/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx new file mode 100644 index 000000000..e52f5b2a3 --- /dev/null +++ b/v2/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx @@ -0,0 +1,60 @@ +import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; +import BackendSDKCasing from "/src/components/BackendSDKCasing" +import IntroductionSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx" +import EndingSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx" +import TabItem from '@theme/TabItem'; + + + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +// highlight-start +app.post("/change-password", verifySession(), async (req, res) => { + // TODO: see next steps +}) + +// highlight-end +``` + + + + +```go +// highlight-start +// the following example uses net/http +func main() { + // 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 +} +// highlight-end +``` + + + + + + +```python +# the following example uses flask +from supertokens_python.recipe.session.framework.flask import verify_session + +# highlight-start +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + # TODO: see next steps +# highlight-end +``` + + + + diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx index 639f438ca..4328a9810 100644 --- a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -1,17 +1,16 @@ --- id: change-password -title: Change a User's Password +title: Allow users to change their passwords hide_title: true --- - - - import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; import BackendSDKCasing from "/src/components/BackendSDKCasing" import TabItem from '@theme/TabItem'; +import IntroductionSnippet from "./_change-password-introduction-snippet.mdx" +import EndingSnippet from "./_change-password-ending-snippet.mdx" -# Change a User's Password +# 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. @@ -23,67 +22,13 @@ In this section we will go over how you can create a route on your backend which - 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](verify-session) - - - - -```jsx -// the following example uses express -let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); -let { verifySession } = require("supertokens-node/recipe/session/framework/express"); - -// highlight-start -app.post("/change-password", verifySession(), async (req, res) => { - -}) - -// highlight-end -``` - - - - -```go -// highlight-start -// the following example uses net/http -func main() { - // Wrap the API handler in session.VerifySession - session.VerifySession(nil, changePasswordAPI).ServeHTTP(rw, r) -} - -func changePasswordAPI(w http.ResponseWriter, r *http.Request) { - -} -// highlight-end -``` - - - - - - -```python -# the following example uses flask -from supertokens_python.recipe.session.framework.flask import verify_session - -# highlight-start -@app.route('/change-password', methods=['POST']) -@verify_session() -def change_password(): -# highlight-end -``` - - - - - + ## Step 2: Validate and update the user's password -- You can now use the `getUserId` function exposed by the `session` object to retrive the logged in user's `userId`. -- The user's profile can be retrived using the `getUserById` function. -- Use `signIn` function and check if the old password is valid -- You can update the user's password with the `updateEmailOrPassword` function. +- You can now use `session` object to retrive the logged in user's `userId`. +- Use the recipe's sign in function and check if the old password is valid +- You can update the user's password. @@ -108,6 +53,16 @@ app.post("/change-password", verifySession(), async (req, res) => { // get the signed in user's email from the getUserById function let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) + // check that the user is not a social account + if userInfo.thirdParty !== undefined { + + res.send({ + status: "Cannot change password for social accounts" + }) + + return + } + // call signin to check that input password is correct let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) @@ -120,7 +75,6 @@ app.post("/change-password", verifySession(), async (req, res) => { } // update the user's password using updateEmailOrPassword - let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ userId, password: updatedPassword @@ -172,6 +126,19 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { // TODO: Handle error return } + + // check that the user is not a social account + if userInfo.ThirdParty != nil { + + resp := make(map[string]string) + resp["status"] = "Cannot change password for social account" + jsonResp, err := json.Marshal(resp) + if err != nil { + log.Fatalf("Error happened in JSON marshal. Err: %s", err) + } + w.Write(jsonResp) + return + } // call signin to check that the input is correct isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) @@ -227,6 +194,11 @@ def change_password(): # get the signed in user's email from the getUserById function users_info = get_user_by_id(user_id) + + # check that the user is not a social account + if user_info.thirdParty is None { + return + } # call signin to check that the input password is correct isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) @@ -245,190 +217,6 @@ def change_password(): ## Step 3: Revoke all sessions associated with the user (optional) -- You can now revoke all sessions created by the user by calling the `revokeAllSessionsForUser` function. - - - - -```jsx -// the following example uses express -let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); -let Session = require("supertokens-node/recipe/session"); -let { verifySession } = require("supertokens-node/recipe/session/framework/express"); - -app.get("/change-password", verifySession(), async (req, res) => { - - // get the session information from the req - let session = req.session - - let oldPassword = req.body.oldPassword - let updatedPassword = req.query.newPassword - - // get the users Id from the req.session - let userId = session.getUserId() - - // get the signed in user's email from the getUserById function - let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) - - // call signin to check that input password is correct - - let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) - - if (isPasswordValid.status !== "OK") { - res.send({ - status: isPasswordValid.status - }) - - return - } - - // update the user's password using updateEmailOrPassword - let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ - userId, - password: updatedPassword - }) - - // highlight-start - // 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 Session.revokeSession(session.getHandle()) - //highlight-end - - res.send({ - status: response.status - }) - -}) - -``` - - - - -```go - -func main() { - // 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()) - - // retrive the old password from the request body - var response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}.GetUserById(userID) - if err != nil { - // TODO: Handle error - return - } - - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - if isPasswordValid.OK == nil { - // TODO: IHandle nvalid oldPassword - return - } - - _, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) - if err != nil { - // TODO: Handle error - return - } - - // highlight-start - - // 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 = session.RevokeSession(userID) - if err != nil { - // TODO: Handle error - } - - // highlight-end - - resp := make(map[string]string) - if response.OK != nil { - resp["status"] = "OK" - } else { - resp["status"] = "Could not update" - } - jsonResp, err := json.Marshal(resp) - if err != nil { - log.Fatalf("Error happened in JSON marshal. Err: %s", err) - } - w.Write(jsonResp) -} - -``` - - - - -```python -from supertokens_python.recipe.session.framework.flask import verify_session -from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password -from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user, revoke_session - -@app.route('/change-password', methods=['POST']) -@verify_session() -def change_password(): - session_ = 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) - - # call signin to check that the input password is correct - isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) - - if isPasswordValid.status != "OK": - return isPasswordValid.status - - # update the users password - response = update_email_or_password(user_id, password=request.json["newPassword"]) - - # highlight-start - # 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 - revoke_session(session_.get_handle()) - # highlight-end - return response.status - -``` - +- You can now invalidate all sessions associated with the user so they can login with their new password. - \ No newline at end of file + \ No newline at end of file From 262e163ee092b39f4eba77211ecc01c0fdea7649 Mon Sep 17 00:00:00 2001 From: jscyo Date: Mon, 7 Feb 2022 14:04:51 +0530 Subject: [PATCH 09/11] fixs --- .../common-customizations/change-password.mdx | 6 +- .../_change-password-ending-snippet.mdx | 85 +------------------ .../common-customizations/change-password.mdx | 4 +- 3 files changed, 8 insertions(+), 87 deletions(-) diff --git a/v2/emailpassword/common-customizations/change-password.mdx b/v2/emailpassword/common-customizations/change-password.mdx index b5a5a0a7e..5cfca7d93 100644 --- a/v2/emailpassword/common-customizations/change-password.mdx +++ b/v2/emailpassword/common-customizations/change-password.mdx @@ -27,8 +27,8 @@ In this section we will go over how you can create a route on your backend which ## Step 2: Validate and update the user's password - You can now use `session` object to retrive the logged in user's `userId`. -- Use the recipe's `signIn`function and check if the old password is valid -- You can update the user's password with the `updateEmailOrPassword` function. +- Use the recipe's sign in function and check if the old password is valid +- Update the user's password. @@ -190,6 +190,6 @@ def change_password(): ## Step 3: Revoke all sessions associated with the user (optional) -- You can now invalidate all sessions associated with the user so they can login with their new password. +- Revoking all sessions associated with the user will force them to reauthenticate with their new password. diff --git a/v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx b/v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx index 17ee4e61a..7870082a3 100644 --- a/v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx @@ -15,35 +15,7 @@ let { verifySession } = require("supertokens-node/recipe/session/framework/expre app.get("/change-password", verifySession(), async (req, res) => { - // get the session information from the req - let session = req.session - - let oldPassword = req.body.oldPassword - let updatedPassword = req.query.newPassword - - // get the users Id from the req.session - let userId = session.getUserId() - - // get the signed in user's email from the getUserById function - let userInfo = await ^{recipeNameCapitalLetters}.getUserById(userId) - - // call signin to check that input password is correct - - let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) - - if (isPasswordValid.status !== "OK") { - res.send({ - status: isPasswordValid.status - }) - - return - } - - // update the user's password using updateEmailOrPassword - let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ - userId, - password: updatedPassword - }) + // TODO: see previous step // highlight-start // revoke all sessions for the user @@ -78,44 +50,7 @@ type ResponseBody struct { 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 response ResponseBody - err := json.NewDecoder(r.Body).Decode(&response) - 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 := ^{rid}.GetUserById(userID) - if err != nil { - // TODO: Handle error - return - } - - // call signin to check that the input is correct - isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) - if err != nil { - // TODO: Handle error - return - } - - if isPasswordValid.OK == nil { - // TODO: IHandle nvalid oldPassword - return - } - - _, err = ^{rid}.UpdateEmailOrPassword(userID, &userInfo.Email, &response.NewPassword) - if err != nil { - // TODO: Handle error - return - } + // TODO: see previous step // highlight-start @@ -159,22 +94,8 @@ from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_use @app.route('/change-password', methods=['POST']) @verify_session() def change_password(): - session_ = 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) - - # call signin to check that the input password is correct - isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) - - if isPasswordValid.status != "OK": - return isPasswordValid.status - # update the users password - response = update_email_or_password(user_id, password=request.json["newPassword"]) + # TODO: see previous step # highlight-start # revoke all sessions for the user diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx index 4328a9810..faf4ba6a3 100644 --- a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -28,7 +28,7 @@ In this section we will go over how you can create a route on your backend which - You can now use `session` object to retrive the logged in user's `userId`. - Use the recipe's sign in function and check if the old password is valid -- You can update the user's password. +- Update the user's password. @@ -217,6 +217,6 @@ def change_password(): ## Step 3: Revoke all sessions associated with the user (optional) -- You can now invalidate all sessions associated with the user so they can login with their new password. +- Revoking all sessions associated with the user will force them to reauthenticate with their new password. \ No newline at end of file From e5edab9f2cf028759649126c33fba5287d48601b Mon Sep 17 00:00:00 2001 From: jscyo Date: Tue, 8 Feb 2022 12:05:07 +0530 Subject: [PATCH 10/11] feedback changes --- .../common-customizations/change-password.mdx | 193 +++++++++++++--- .../_change-password-ending-snippet.mdx | 112 --------- .../_change-password-introduction-snippet.mdx | 60 ----- .../common-customizations/change-password.mdx | 216 +++++++++++++----- 4 files changed, 328 insertions(+), 253 deletions(-) delete mode 100644 v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx delete mode 100644 v2/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx diff --git a/v2/emailpassword/common-customizations/change-password.mdx b/v2/emailpassword/common-customizations/change-password.mdx index 5cfca7d93..51749bfa2 100644 --- a/v2/emailpassword/common-customizations/change-password.mdx +++ b/v2/emailpassword/common-customizations/change-password.mdx @@ -4,10 +4,11 @@ title: Allow users to change their passwords hide_title: true --- + + + import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; import BackendSDKCasing from "/src/components/BackendSDKCasing" -import IntroductionSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx" -import EndingSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx" import TabItem from '@theme/TabItem'; # Allow users to change their passwords @@ -22,7 +23,60 @@ In this section we will go over how you can create a route on your backend which - 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](verify-session) - + + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +// highlight-start +app.post("/change-password", verifySession(), async (req, res) => { + // TODO: see next steps +}) + +// highlight-end +``` + + + + +```go +// highlight-start +// the following example uses net/http +func main() { + // 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 +} +// highlight-end +``` + + + + + + +```python +# the following example uses flask +from supertokens_python.recipe.session.framework.flask import verify_session + +# highlight-start +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + # TODO: see next steps +# highlight-end +``` + + + + ## Step 2: Validate and update the user's password @@ -47,6 +101,9 @@ app.post("/change-password", verifySession(), async (req, res) => { // 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() @@ -57,23 +114,17 @@ app.post("/change-password", verifySession(), async (req, res) => { let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) if (isPasswordValid.status !== "OK") { - res.send({ - status: isPasswordValid.status - }) - + // TODO: handle incorrect password error return } // update the user's password using updateEmailOrPassword - let response = await ^{recipeNameCapitalLetters}.updateEmailOrPassword({ userId, password: updatedPassword }) - res.send({ - status: response.status - }) + // TODO: send successful password update response // highlight-end }) @@ -117,7 +168,7 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { // TODO: Handle error return } - + // call signin to check that the input is correct isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) if err != nil { @@ -126,7 +177,7 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { } // highlight-start - if isPasswordValid.OK == nil { + if isPasswordValid.OK != nil { // TODO: Handle error return } @@ -136,19 +187,9 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { // TODO: Handle error return } + // TODO: send successful password update response // highlight-end - resp := make(map[string]string) - if response.OK != nil { - resp["status"] = "OK" - } else { - resp["status"] = "Could not update" - } - jsonResp, err := json.Marshal(resp) - if err != nil { - log.Fatalf("Error happened in JSON marshal. Err: %s", err) - } - w.Write(jsonResp) } ``` @@ -172,16 +213,18 @@ def change_password(): # get the signed in user's email from the getUserById function users_info = get_user_by_id(user_id) - + # call signin to check that the input password is correct isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) if isPasswordValid.status != "OK": - return isPasswordValid.status + # TODO: handle incorrect password error + return # update the users password response = update_email_or_password(user_id, password=request.json["newPassword"]) - return response.status + + # TODO: send successful password update response # highlight-end ``` @@ -192,4 +235,98 @@ def change_password(): - Revoking all sessions associated with the user will force them to reauthenticate with their new password. - + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let Session = require("supertokens-node/recipe/session"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +app.get("/change-password", verifySession(), async (req, res) => { + + // TODO: see previous step + + // highlight-start + // 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(session.getHandle()) + //highlight-end + + // TODO: send successful password update response + +}) + +``` + + + + +```go + +func main() { + // 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) { + + // TODO: see previous step + + // highlight-start + + // 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 = session.GetSessionFromRequestContext(r.Context()).RevokeSession() + if err != nil { + // TODO: Handle error + } + + // highlight-end + + // TODO: send successful password update response +} + +``` + + + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password +from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user, revoke_session + +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + + # TODO: see previous step + + # highlight-start + # 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 + g.supertokens.revoke_session() + # highlight-end + + # TODO: send successful password update response + +``` + + + diff --git a/v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx b/v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx deleted file mode 100644 index 7870082a3..000000000 --- a/v2/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx +++ /dev/null @@ -1,112 +0,0 @@ -import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; -import BackendSDKCasing from "/src/components/BackendSDKCasing" -import IntroductionSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx" -import EndingSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx" -import TabItem from '@theme/TabItem'; - - - - -```jsx -// the following example uses express -let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); -let Session = require("supertokens-node/recipe/session"); -let { verifySession } = require("supertokens-node/recipe/session/framework/express"); - -app.get("/change-password", verifySession(), async (req, res) => { - - // TODO: see previous step - - // highlight-start - // 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 Session.revokeSession(session.getHandle()) - //highlight-end - - res.send({ - status: response.status - }) - -}) - -``` - - - - -```go - -func main() { - // 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) { - - // TODO: see previous step - - // highlight-start - - // 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 = session.RevokeSession(userID) - if err != nil { - // TODO: Handle error - } - - // highlight-end - - resp := make(map[string]string) - if response.OK != nil { - resp["status"] = "OK" - } else { - resp["status"] = "Could not update" - } - jsonResp, err := json.Marshal(resp) - if err != nil { - log.Fatalf("Error happened in JSON marshal. Err: %s", err) - } - w.Write(jsonResp) -} - -``` - - - - -```python -from supertokens_python.recipe.session.framework.flask import verify_session -from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password -from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user, revoke_session - -@app.route('/change-password', methods=['POST']) -@verify_session() -def change_password(): - - # TODO: see previous step - - # highlight-start - # 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 - revoke_session(session_.get_handle()) - # highlight-end - return response.status - -``` - - - \ No newline at end of file diff --git a/v2/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx b/v2/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx deleted file mode 100644 index e52f5b2a3..000000000 --- a/v2/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx +++ /dev/null @@ -1,60 +0,0 @@ -import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; -import BackendSDKCasing from "/src/components/BackendSDKCasing" -import IntroductionSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-introduction-snippet.mdx" -import EndingSnippet from "/thirdpartyemailpassword/common-customizations/_change-password-ending-snippet.mdx" -import TabItem from '@theme/TabItem'; - - - - - -```jsx -// the following example uses express -let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); -let { verifySession } = require("supertokens-node/recipe/session/framework/express"); - -// highlight-start -app.post("/change-password", verifySession(), async (req, res) => { - // TODO: see next steps -}) - -// highlight-end -``` - - - - -```go -// highlight-start -// the following example uses net/http -func main() { - // 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 -} -// highlight-end -``` - - - - - - -```python -# the following example uses flask -from supertokens_python.recipe.session.framework.flask import verify_session - -# highlight-start -@app.route('/change-password', methods=['POST']) -@verify_session() -def change_password(): - # TODO: see next steps -# highlight-end -``` - - - - diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx index faf4ba6a3..06ab18d98 100644 --- a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -4,11 +4,12 @@ title: Allow users to change their passwords hide_title: true --- + + + import BackendSDKTabs from "/src/components/tabs/BackendSDKTabs"; import BackendSDKCasing from "/src/components/BackendSDKCasing" import TabItem from '@theme/TabItem'; -import IntroductionSnippet from "./_change-password-introduction-snippet.mdx" -import EndingSnippet from "./_change-password-ending-snippet.mdx" # Allow users to change their passwords @@ -22,7 +23,60 @@ In this section we will go over how you can create a route on your backend which - 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](verify-session) - + + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +// highlight-start +app.post("/change-password", verifySession(), async (req, res) => { + // TODO: see next steps +}) + +// highlight-end +``` + + + + +```go +// highlight-start +// the following example uses net/http +func main() { + // 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 +} +// highlight-end +``` + + + + + + +```python +# the following example uses flask +from supertokens_python.recipe.session.framework.flask import verify_session + +# highlight-start +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + # TODO: see next steps +# highlight-end +``` + + + + ## Step 2: Validate and update the user's password @@ -47,30 +101,20 @@ app.post("/change-password", verifySession(), async (req, res) => { // 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 ^{recipeNameCapitalLetters}.getUserById(userId) - // check that the user is not a social account - if userInfo.thirdParty !== undefined { - - res.send({ - status: "Cannot change password for social accounts" - }) - - return - } - // call signin to check that input password is correct let isPasswordValid = await ^{recipeNameCapitalLetters}.signIn(userInfo.email, oldPassword) if (isPasswordValid.status !== "OK") { - res.send({ - status: isPasswordValid.status - }) - + // TODO: handle incorrect password error return } @@ -80,9 +124,7 @@ app.post("/change-password", verifySession(), async (req, res) => { password: updatedPassword }) - res.send({ - status: response.status - }) + // TODO: send successful password update response // highlight-end }) @@ -127,19 +169,6 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { return } - // check that the user is not a social account - if userInfo.ThirdParty != nil { - - resp := make(map[string]string) - resp["status"] = "Cannot change password for social account" - jsonResp, err := json.Marshal(resp) - if err != nil { - log.Fatalf("Error happened in JSON marshal. Err: %s", err) - } - w.Write(jsonResp) - return - } - // call signin to check that the input is correct isPasswordValid, err := ^{rid}.SignIn(userInfo.Email, response.OldPassword) if err != nil { @@ -148,7 +177,7 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { } // highlight-start - if isPasswordValid.OK == nil { + if isPasswordValid.OK != nil { // TODO: Handle error return } @@ -158,19 +187,9 @@ func changePasswordAPI(w http.ResponseWriter, r *http.Request) { // TODO: Handle error return } + // TODO: send successful password update response // highlight-end - resp := make(map[string]string) - if response.OK != nil { - resp["status"] = "OK" - } else { - resp["status"] = "Could not update" - } - jsonResp, err := json.Marshal(resp) - if err != nil { - log.Fatalf("Error happened in JSON marshal. Err: %s", err) - } - w.Write(jsonResp) } ``` @@ -195,20 +214,17 @@ def change_password(): # get the signed in user's email from the getUserById function users_info = get_user_by_id(user_id) - # check that the user is not a social account - if user_info.thirdParty is None { - return - } - # call signin to check that the input password is correct isPasswordValid = sign_in(users_info.email, request.json["oldPassword"]) if isPasswordValid.status != "OK": - return isPasswordValid.status + # TODO: handle incorrect password error + return # update the users password response = update_email_or_password(user_id, password=request.json["newPassword"]) - return response.status + + # TODO: send successful password update response # highlight-end ``` @@ -219,4 +235,98 @@ def change_password(): - Revoking all sessions associated with the user will force them to reauthenticate with their new password. - \ No newline at end of file + + + +```jsx +// the following example uses express +let ^{recipeNameCapitalLetters} = require("supertokens-node/recipe/^{codeImportRecipeName}"); +let Session = require("supertokens-node/recipe/session"); +let { verifySession } = require("supertokens-node/recipe/session/framework/express"); + +app.get("/change-password", verifySession(), async (req, res) => { + + // TODO: see previous step + + // highlight-start + // 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(session.getHandle()) + //highlight-end + + // TODO: send successful password update response + +}) + +``` + + + + +```go + +func main() { + // 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) { + + // TODO: see previous step + + // highlight-start + + // 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 = session.GetSessionFromRequestContext(r.Context()).RevokeSession() + if err != nil { + // TODO: Handle error + } + + // highlight-end + + // TODO: send successful password update response +} + +``` + + + + +```python +from supertokens_python.recipe.session.framework.flask import verify_session +from supertokens_python.recipe.^{rid}.syncio import get_user_by_id, sign_in, update_email_or_password +from supertokens_python.recipe.session.syncio import revoke_all_sessions_for_user, revoke_session + +@app.route('/change-password', methods=['POST']) +@verify_session() +def change_password(): + + # TODO: see previous step + + # highlight-start + # 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 + g.supertokens.revoke_session() + # highlight-end + + # TODO: send successful password update response + +``` + + + \ No newline at end of file From fa9c84fbfff26b1ec31d96789efbf6db08677592 Mon Sep 17 00:00:00 2001 From: jscyo Date: Tue, 8 Feb 2022 12:07:29 +0530 Subject: [PATCH 11/11] fix typo --- v2/emailpassword/common-customizations/change-password.mdx | 2 +- .../common-customizations/change-password.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/v2/emailpassword/common-customizations/change-password.mdx b/v2/emailpassword/common-customizations/change-password.mdx index 51749bfa2..7759050ee 100644 --- a/v2/emailpassword/common-customizations/change-password.mdx +++ b/v2/emailpassword/common-customizations/change-password.mdx @@ -253,7 +253,7 @@ app.get("/change-password", verifySession(), async (req, res) => { 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(session.getHandle()) + await req.session.revokeSession() //highlight-end // TODO: send successful password update response diff --git a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx index 06ab18d98..a0868b3a7 100644 --- a/v2/thirdpartyemailpassword/common-customizations/change-password.mdx +++ b/v2/thirdpartyemailpassword/common-customizations/change-password.mdx @@ -253,7 +253,7 @@ app.get("/change-password", verifySession(), async (req, res) => { 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(session.getHandle()) + await req.session.revokeSession() //highlight-end // TODO: send successful password update response