From 1c0e1b99ed21bdafd025d48d8d8595564012f86b Mon Sep 17 00:00:00 2001 From: Alexandre Bodin Date: Mon, 30 Mar 2020 14:49:41 +0200 Subject: [PATCH 01/11] Add docker-compose.dev file to easily work with different databases in dev mode Signed-off-by: Alexandre Bodin Remove old files not used anymore Signed-off-by: Alexandre Bodin Added info about conflict with local db instances and how to change port configurations Signed-off-by: Alexandre Bodin Fix typos Signed-off-by: Alexandre Bodin Signed-off-by: ScottAgirs --- CONTRIBUTING.md | 11 +---- Makefile | 17 -------- docker-compose.dev.yml | 45 ++++++++++++++++++++ examples/getstarted/README.md | 79 +++++++++++++++++++++++++++++++++-- mkdocs.yml | 74 -------------------------------- 5 files changed, 123 insertions(+), 103 deletions(-) delete mode 100644 Makefile create mode 100644 docker-compose.dev.yml delete mode 100644 mkdocs.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 91655fd219..4ee6472512 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -79,16 +79,9 @@ cd strapi && yarn setup #### 4. Start the example application -**Go to the getstarted application** +Read the `getstarted` application README [here](./examples/getstarted/README.md). -```bash -cd strapi/examples/getstarted -yarn develop -``` - -The server (API) is available at http://localhost:1337 - -The built administration panel is available at http://localhost:1337/admin +#### 5. Running the administration panel in development mode **Start the administration panel server for development** diff --git a/Makefile b/Makefile deleted file mode 100644 index 57201cf075..0000000000 --- a/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -MAKEFLAGS = -j1 - -export NODE_ENV = test - -.PHONY: test - -lint: - ./node_modules/.bin/eslint **/*.js - -test: lint - ./scripts/test.sh - -docs: - mkdocs build --clean - -setup: - ./scripts/setup.sh diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000000..95d925fbf9 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,45 @@ +version: '3' + +services: + postgres: + image: postgres + restart: always + volumes: + - pgdata:/var/lib/postgresql/data + environment: + POSTGRES_USER: strapi + POSTGRES_PASSWORD: strapi + POSTGRES_DB: strapi + ports: + - '5432:5432' + + mongo: + image: mongo + restart: always + environment: + MONGO_INITDB_ROOT_USERNAME: root + MONGO_INITDB_ROOT_PASSWORD: strapi + volumes: + - mongodata:/data/db + ports: + - '27017:27017' + + mysql: + image: mysql + restart: always + command: --default-authentication-plugin=mysql_native_password + environment: + MYSQL_DATABASE: strapi + MYSQL_USER: strapi + MYSQL_PASSWORD: strapi + MYSQL_ROOT_HOST: '%' + MYSQL_ROOT_PASSWORD: strapi + volumes: + - mysqldata:/var/lib/mysql + ports: + - '3306:3306' + +volumes: + pgdata: + mongodata: + mysqldata: diff --git a/examples/getstarted/README.md b/examples/getstarted/README.md index ad3c63bfcb..eb80ad304e 100644 --- a/examples/getstarted/README.md +++ b/examples/getstarted/README.md @@ -1,7 +1,80 @@ # getstarted -A quick description of getstarted. +This is an example app you can run to test your changes quickly. -Start the app with mongo +## Requirements -`DB=mongo yarn develop` +- Docker +- Docker compose +- Node + +## Installation + +By default once you have setup the monorepo you will be able to run the getstarted app with a sqlite DB directly. + +If you wish to run the getstarted app with another database you can use the `docker-compose.dev.yml` file at the root of the directory. + +### start the databases + +Run the following command at the root of the monorepo + +``` +docker-compose -f docker-compose.dev.yml up -d +``` + +If you need to stop the running databases you can stop them with the following command: + +``` +docker-compose -f docker-compose.dev.yml stop +``` + +### run the getstarted app with a specific database + +``` +DB={dbName} yarn develop +``` + +The way it works is that the `getstarted` app has a specific `database.js` config file that will use the `DB` environment variable to setup the right database connection. You can look at the code [here](./config/environments/development/database.js) + +**Warning** + +You might have some errors while connecting to the databases. +They might be coming from a conflict between a locally running database instance and the docker instance. To avoid the errors either shutdown your local database instance or change the ports in the `./config/environments/development/database.js` and the `docker-compose.dev.yml` file. + +**Example**: + +`database.js` + +```js +module.exports = { + connections: { + default: { + connector: 'mongoose', + settings: { + // host: 'localhost', + // database: 'strapi', + // username: 'root', + // password: 'strapi', + port: 27099, + }, + options: {}, + }, + }, +}; +``` + +`docker-compose.dev.yml` + +```yml +services: + mongo: + # image: mongo + # restart: always + # environment: + # MONGO_INITDB_ROOT_USERNAME: root + # MONGO_INITDB_ROOT_PASSWORD: strapi + # volumes: + # - mongodata:/data/db + ports: + - '27099:27017' +``` diff --git a/mkdocs.yml b/mkdocs.yml deleted file mode 100644 index 97f097ef49..0000000000 --- a/mkdocs.yml +++ /dev/null @@ -1,74 +0,0 @@ -theme: "readthedocs" - -docs_dir: ./website -site_dir: ./packages/strapi-generate-new/files/public -theme_dir: ./website/theme - -site_name: "Strapi" -site_description: "Node.js framework powering API-driven web and mobile applications." -site_author: "Strapi" -site_url: "http://strapi.io/" - -repo_name: "Strapi" -repo_url: "https://github.com/strapi/strapi" - -markdown_extensions: - - admonition - - smarty - - sane_lists - - toc: - permalink: "#" - -extra: - command: "$ npm install strapi-cli -g" - baseline: "Powering API-driven web and mobile applications." - start: "Get started" - current_version: "Current version" - version: "2.0.0" - -pages: - - Home: ./index.md - - Prologue: - - Introduction: ./documentation/prologue/why.md - - Install Strapi: ./documentation/prologue/installation.md - - How it works: ./documentation/prologue/start.md - - Architecture foundations: - - Configuration: ./documentation/architecture/configuration.md - - Router: ./documentation/architecture/router.md - - Context: ./documentation/architecture/context.md - - Request: ./documentation/architecture/request.md - - Response: ./documentation/architecture/response.md - - Databases: ./documentation/architecture/databases.md - - Views: ./documentation/architecture/views.md - - Logging: ./documentation/architecture/logging.md - - Concepts: - - Authentication: ./documentation/concepts/authentication.md - - GraphQL: ./documentation/concepts/graphql.md - - JSON API: ./documentation/concepts/jsonapi.md - - WebSockets: ./documentation/concepts/websockets.md - - Internationalization: ./documentation/concepts/internationalization.md - - Scheduled tasks: ./documentation/concepts/cron.md - - Services: ./documentation/concepts/services.md - - Policies: ./documentation/concepts/policies.md - - Sessions: ./documentation/concepts/sessions.md - - SQL databases: - - Models: ./documentation/sql/models.md - - Migrations: ./documentation/sql/migrations.md - - Query builder: ./documentation/sql/queries.md - - Raw: ./documentation/sql/raw.md - - Interfaces: ./documentation/sql/interfaces.md - - SQL ORM: ./documentation/sql/orm.md - - Advanced usage: - - Security: ./documentation/advanced/security.md - - Lifecycle events: ./documentation/advanced/events.md - - Error handling: ./documentation/advanced/errors.md - - Custom generators: ./documentation/advanced/generators.md - - Custom hooks: ./documentation/advanced/hooks.md - - Legal Info: - - Governance: ./info/governance.md - - Code Of Conduct: ./info/conduct.md - - Releases: ./info/releases.md - - Security: ./info/security.md - - Trademarks: ./info/trademarks.md - - Licenses: ./info/licenses.md - - Support: ./info/support.md From 801224f2d9545da9122cf283a46d4a720757c803 Mon Sep 17 00:00:00 2001 From: ScottAgirs Date: Mon, 30 Mar 2020 15:13:27 -0400 Subject: [PATCH 02/11] [rename] changePassword > resetPassword for accuracy Signed-off-by: ScottAgirs --- packages/strapi-admin/config/routes.json | 2 +- packages/strapi-admin/controllers/Auth.js | 2 +- packages/strapi-plugin-users-permissions/config/routes.json | 4 ++-- packages/strapi-plugin-users-permissions/controllers/Auth.js | 2 +- .../services/UsersPermissions.js | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/strapi-admin/config/routes.json b/packages/strapi-admin/config/routes.json index 686239cde3..9963242794 100644 --- a/packages/strapi-admin/config/routes.json +++ b/packages/strapi-admin/config/routes.json @@ -72,7 +72,7 @@ { "method": "POST", "path": "/auth/reset-password", - "handler": "Auth.changePassword" + "handler": "Auth.resetPassword" }, { "method": "GET", diff --git a/packages/strapi-admin/controllers/Auth.js b/packages/strapi-admin/controllers/Auth.js index eff1d77af9..6ed9bfc835 100644 --- a/packages/strapi-admin/controllers/Auth.js +++ b/packages/strapi-admin/controllers/Auth.js @@ -199,7 +199,7 @@ module.exports = { } }, - async changePassword(ctx) { + async resetPassword(ctx) { const { password, passwordConfirmation, code } = { ...ctx.request.body, ...ctx.params, diff --git a/packages/strapi-plugin-users-permissions/config/routes.json b/packages/strapi-plugin-users-permissions/config/routes.json index 2491f37359..a06e65ff71 100644 --- a/packages/strapi-plugin-users-permissions/config/routes.json +++ b/packages/strapi-plugin-users-permissions/config/routes.json @@ -260,11 +260,11 @@ { "method": "POST", "path": "/auth/reset-password", - "handler": "Auth.changePassword", + "handler": "Auth.resetPassword", "config": { "policies": ["plugins::users-permissions.ratelimit"], "prefix": "", - "description": "Change a user's password", + "description": "Reset a user's password with a code (resetToken)", "tag": { "plugin": "users-permissions", "name": "User" diff --git a/packages/strapi-plugin-users-permissions/controllers/Auth.js b/packages/strapi-plugin-users-permissions/controllers/Auth.js index cb0b5f1a4a..eeb729d4d5 100644 --- a/packages/strapi-plugin-users-permissions/controllers/Auth.js +++ b/packages/strapi-plugin-users-permissions/controllers/Auth.js @@ -177,7 +177,7 @@ module.exports = { } }, - async changePassword(ctx) { + async resetPassword(ctx) { const params = _.assign({}, ctx.request.body, ctx.params); if ( diff --git a/packages/strapi-plugin-users-permissions/services/UsersPermissions.js b/packages/strapi-plugin-users-permissions/services/UsersPermissions.js index 788c4ae134..4bfe1b818b 100644 --- a/packages/strapi-plugin-users-permissions/services/UsersPermissions.js +++ b/packages/strapi-plugin-users-permissions/services/UsersPermissions.js @@ -362,7 +362,7 @@ module.exports = { obj.type === 'users-permissions' && role.type === 'public'; const isNewPassword = - obj.action === 'changepassword' && + obj.action === 'resetpassword' && obj.controller === 'auth' && obj.type === 'users-permissions' && role.type === 'public'; From 8e322285d61b4d7df4506d5137fe28a2d96b19f8 Mon Sep 17 00:00:00 2001 From: ScottAgirs Date: Tue, 31 Mar 2020 00:51:15 -0400 Subject: [PATCH 03/11] [add] changePassword mutation Signed-off-by: ScottAgirs --- packages/strapi-admin/config/routes.json | 5 ++ packages/strapi-admin/controllers/Auth.js | 84 +++++++++++++++++++ .../config/routes.json | 14 ++++ .../controllers/Auth.js | 77 ++++++++++++++++- 4 files changed, 176 insertions(+), 4 deletions(-) diff --git a/packages/strapi-admin/config/routes.json b/packages/strapi-admin/config/routes.json index 9963242794..185c86d731 100644 --- a/packages/strapi-admin/config/routes.json +++ b/packages/strapi-admin/config/routes.json @@ -69,6 +69,11 @@ "path": "/auth/forgot-password", "handler": "Auth.forgotPassword" }, + { + "method": "POST", + "path": "/auth/change-password", + "handler": "Auth.changePassword" + }, { "method": "POST", "path": "/auth/reset-password", diff --git a/packages/strapi-admin/controllers/Auth.js b/packages/strapi-admin/controllers/Auth.js index 6ed9bfc835..02d5629659 100644 --- a/packages/strapi-admin/controllers/Auth.js +++ b/packages/strapi-admin/controllers/Auth.js @@ -199,6 +199,90 @@ module.exports = { } }, + async changePassword(ctx) { + const id = ctx.state.user && ctx.state.user.id; + if (!id) { + return ctx.badRequest( + null, + formatError({ + id: 'Auth.form.error.user.not-exist', + message: 'Must be logged in.', + }) + ); + } + + const admin = await strapi.query('administrator', 'admin').findOne({ id }); + + const { password, passwordConfirmation, currentPassword } = { + ...ctx.request.body, + ...ctx.params, + }; + + if (!password) { + return ctx.badRequest( + null, + formatError({ + id: 'missing.password', + message: 'Missing password', + }) + ); + } + + if (!passwordConfirmation) { + return ctx.badRequest( + formatError({ + id: 'missing.passwordConfirmation', + message: 'Missing passwordConfirmation', + }) + ); + } + + if (!currentPassword) { + return ctx.badRequest( + null, + formatError({ + id: 'missing.currentPassword', + message: 'Missing current password', + }) + ); + } + + if (password !== passwordConfirmation) { + return ctx.badRequest( + null, + formatError({ + id: 'Auth.form.error.password.matching', + message: 'Passwords do not match.', + }) + ); + } + + const validPassword = await strapi.plugins['users-permissions'].services.user.validatePassword( + currentPassword, + admin.password + ); + + if (!validPassword) { + return ctx.badRequest( + null, + formatError({ + id: 'Auth.form.error.invalid', + message: 'Identifier or password invalid.', + }) + ); + } + + const data = { + password: await strapi.admin.services.auth.hashPassword(currentPassword), + }; + + await strapi.query('administrator', 'admin').update({ id: admin.id }, data); + + return ctx.send({ + ok: true, + }); + }, + async resetPassword(ctx) { const { password, passwordConfirmation, code } = { ...ctx.request.body, diff --git a/packages/strapi-plugin-users-permissions/config/routes.json b/packages/strapi-plugin-users-permissions/config/routes.json index a06e65ff71..2e31f96f63 100644 --- a/packages/strapi-plugin-users-permissions/config/routes.json +++ b/packages/strapi-plugin-users-permissions/config/routes.json @@ -257,6 +257,20 @@ } } }, + { + "method": "POST", + "path": "/auth/change-password", + "handler": "Auth.changePassword", + "config": { + "policies": ["plugins::users-permissions.ratelimit"], + "prefix": "", + "description": "Change user password. Verifies with current password", + "tag": { + "plugin": "users-permissions", + "name": "User" + } + } + }, { "method": "POST", "path": "/auth/reset-password", diff --git a/packages/strapi-plugin-users-permissions/controllers/Auth.js b/packages/strapi-plugin-users-permissions/controllers/Auth.js index eeb729d4d5..362059ed36 100644 --- a/packages/strapi-plugin-users-permissions/controllers/Auth.js +++ b/packages/strapi-plugin-users-permissions/controllers/Auth.js @@ -177,6 +177,75 @@ module.exports = { } }, + async changePassword(ctx) { + const params = _.assign({}, ctx.request.body, ctx.params); + + if ( + params.password && + params.passwordConfirmation && + params.password === params.passwordConfirmation && + params.currentPassword + ) { + const id = ctx.state.user && ctx.state.user.id; + if (!id) { + return ctx.badRequest( + null, + formatError({ + id: 'Auth.form.error.user.not-exist', + message: 'Must be logged in.', + }) + ); + } + + const user = await strapi.plugins['users-permissions'].services.user.fetch({ id }); + + const validPassword = await strapi.plugins[ + 'users-permissions' + ].services.user.validatePassword(params.currentPassword, user.password); + + if (!validPassword) { + return ctx.badRequest( + null, + formatError({ + id: 'Auth.form.error.invalid', + message: 'Identifier or password invalid.', + }) + ); + } else { + // Hash and Replace current password with the new one in the user object. + user.password = await strapi.plugins['users-permissions'].services.user.hashPassword({ + password: params.password, + }); + + // Update the user. + await strapi.query('user', 'users-permissions').update({ id: user.id }, user); + + ctx.send({ + ok: true, + }); + } + } else if ( + params.password && + params.passwordConfirmation && + params.password !== params.passwordConfirmation + ) { + return ctx.badRequest( + null, + formatError({ + id: 'Auth.form.error.password.matching', + message: 'Passwords do not match.', + }) + ); + } else { + return ctx.badRequest( + null, + formatError({ + id: 'Auth.form.error.params.provide', + message: 'Incorrect params provided.', + }) + ); + } + }, async resetPassword(ctx) { const params = _.assign({}, ctx.request.body, ctx.params); @@ -580,14 +649,14 @@ module.exports = { { confirmed: true } ); - if(returnUser) { + if (returnUser) { ctx.send({ jwt: strapi.plugins['users-permissions'].services.jwt.issue({ - id: user.id + id: user.id, }), user: sanitizeEntity(user.toJSON ? user.toJSON() : user, { - model: strapi.query('user', 'users-permissions').model - }) + model: strapi.query('user', 'users-permissions').model, + }), }); } else { const settings = await strapi From 10667395e2d62bef268b344d61ed04f9bfcaf07a Mon Sep 17 00:00:00 2001 From: ScottAgirs Date: Tue, 31 Mar 2020 00:52:49 -0400 Subject: [PATCH 04/11] [rename] ForgotPassword > UserPersmissionsPasswordPayload Signed-off-by: ScottAgirs --- .../config/schema.graphql.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/strapi-plugin-users-permissions/config/schema.graphql.js b/packages/strapi-plugin-users-permissions/config/schema.graphql.js index d046a172b2..e18d3894be 100644 --- a/packages/strapi-plugin-users-permissions/config/schema.graphql.js +++ b/packages/strapi-plugin-users-permissions/config/schema.graphql.js @@ -47,8 +47,8 @@ module.exports = { user: UsersPermissionsMe! } - type ForgotPassword { - ok: Boolean + type UserPersmissionsPasswordPayload { + ok: Boolean! } `, query: ` @@ -57,8 +57,8 @@ module.exports = { mutation: ` login(input: UsersPermissionsLoginInput!): UsersPermissionsLoginPayload! register(input: UserInput!): UsersPermissionsLoginPayload! - forgotPassword(email: String!): ForgotPassword - changePassword(password: String!, passwordConfirmation: String!, code: String!): UsersPermissionsLoginPayload + forgotPassword(email: String!): UserPersmissionsPasswordPayload + changePassword(password: String!, passwordConfirmation: String!, currentPassword: String!): UserPersmissionsPasswordPayload emailConfirmation(confirmation: String!): UsersPermissionsLoginPayload `, resolver: { From 7305a2e20c5b83c014027dcb2c9b20335596ec1b Mon Sep 17 00:00:00 2001 From: ScottAgirs Date: Tue, 31 Mar 2020 00:53:06 -0400 Subject: [PATCH 05/11] [add] changePassword [refactor] changePassword > resetPassword Signed-off-by: ScottAgirs --- .../config/schema.graphql.js | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/strapi-plugin-users-permissions/config/schema.graphql.js b/packages/strapi-plugin-users-permissions/config/schema.graphql.js index e18d3894be..4389d928e2 100644 --- a/packages/strapi-plugin-users-permissions/config/schema.graphql.js +++ b/packages/strapi-plugin-users-permissions/config/schema.graphql.js @@ -59,6 +59,7 @@ module.exports = { register(input: UserInput!): UsersPermissionsLoginPayload! forgotPassword(email: String!): UserPersmissionsPasswordPayload changePassword(password: String!, passwordConfirmation: String!, currentPassword: String!): UserPersmissionsPasswordPayload + resetPassword(password: String!, passwordConfirmation: String!, code: String!): UsersPermissionsLoginPayload emailConfirmation(confirmation: String!): UsersPermissionsLoginPayload `, resolver: { @@ -224,8 +225,25 @@ module.exports = { }; }, }, + resetPassword: { + description: 'Reset user password. Confirm with a code (resetToken from forgotPassword)', + resolverOf: 'plugins::users-permissions.auth.resetPassword', + resolver: async (obj, options, { context }) => { + context.request.body = _.toPlainObject(options); + + await strapi.plugins['users-permissions'].controllers.auth.resetPassword(context); + let output = context.body.toJSON ? context.body.toJSON() : context.body; + + checkBadRequest(output); + + return { + user: output.user || output, + jwt: output.jwt, + }; + }, + }, changePassword: { - description: 'Change your password based on a code', + description: 'Change your password. Verified by current password.', resolverOf: 'plugins::users-permissions.auth.changePassword', resolver: async (obj, options, { context }) => { context.request.body = _.toPlainObject(options); @@ -236,8 +254,7 @@ module.exports = { checkBadRequest(output); return { - user: output.user || output, - jwt: output.jwt, + ok: output.ok, }; }, }, From 3a1b5dbe7d34526a7a0ecc5293a58ff1399483fc Mon Sep 17 00:00:00 2001 From: ScottAgirs Date: Tue, 31 Mar 2020 00:53:29 -0400 Subject: [PATCH 06/11] [add] documentation for password mutations Signed-off-by: ScottAgirs --- .../3.0.0-beta.x/plugins/users-permissions.md | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/3.0.0-beta.x/plugins/users-permissions.md b/docs/3.0.0-beta.x/plugins/users-permissions.md index 8782b12074..b84ea4d156 100644 --- a/docs/3.0.0-beta.x/plugins/users-permissions.md +++ b/docs/3.0.0-beta.x/plugins/users-permissions.md @@ -490,14 +490,15 @@ axios }); ``` -This action will send the user an email that contains a URL with the needed code for the [reset password](#password-reset). +This action will send the user an email that contains a URL with the needed code for the [reset password](#reset-password). The URL must link to your reset password form in your frontend application. To configure it you will have to go in the Roles & Permissions settings and navigate to the Advanced Settings tab. -### Password reset +### Reset Password This action will reset the user password. +Also works with the [GraphQL Plugin](https://strapi.io/documentation/3.0.0-beta.x/plugins/graphql.html), exposes `resetPassword` mutation. #### Usage @@ -513,6 +514,35 @@ axios password: 'myNewPassword', passwordConfirmation: 'myNewPassword', }) + .then(response => { + // Handle success. + console.log("Your user's password has been reset."); + }) + .catch(error => { + // Handle error. + console.log('An error occurred:', error); + }); +``` + +### Change Password + +This action will change the user's password. +Also works with the [GraphQL Plugin](https://strapi.io/documentation/3.0.0-beta.x/plugins/graphql.html), exposes `changePassword` mutation. + +#### Usage + +- `currentPassword` is the user's current password to confirm the action + +```js +import axios from 'axios'; + +// Request API. +axios + .post('http://localhost:1337/auth/change-password', { + currentPassword: 'myCurrentPassword', + password: 'myNewPassword', + passwordConfirmation: 'myNewPassword', + }) .then(response => { // Handle success. console.log("Your user's password has been changed."); From 823acf47774b32c5ba6ae5e99ca8d14756651f57 Mon Sep 17 00:00:00 2001 From: ScottAgirs Date: Sat, 11 Apr 2020 13:41:09 -0400 Subject: [PATCH 07/11] [deprecate] change-password in favour of reset-password Signed-off-by: ScottAgirs --- .../3.0.0-beta.x/plugins/users-permissions.md | 27 ------ packages/strapi-admin/config/routes.json | 5 -- packages/strapi-admin/controllers/Auth.js | 84 ------------------- .../config/routes.json | 14 ---- .../config/schema.graphql.js | 17 ---- .../controllers/Auth.js | 71 +--------------- 6 files changed, 1 insertion(+), 217 deletions(-) diff --git a/docs/3.0.0-beta.x/plugins/users-permissions.md b/docs/3.0.0-beta.x/plugins/users-permissions.md index b84ea4d156..da85186fbd 100644 --- a/docs/3.0.0-beta.x/plugins/users-permissions.md +++ b/docs/3.0.0-beta.x/plugins/users-permissions.md @@ -524,34 +524,7 @@ axios }); ``` -### Change Password -This action will change the user's password. -Also works with the [GraphQL Plugin](https://strapi.io/documentation/3.0.0-beta.x/plugins/graphql.html), exposes `changePassword` mutation. - -#### Usage - -- `currentPassword` is the user's current password to confirm the action - -```js -import axios from 'axios'; - -// Request API. -axios - .post('http://localhost:1337/auth/change-password', { - currentPassword: 'myCurrentPassword', - password: 'myNewPassword', - passwordConfirmation: 'myNewPassword', - }) - .then(response => { - // Handle success. - console.log("Your user's password has been changed."); - }) - .catch(error => { - // Handle error. - console.log('An error occurred:', error); - }); -``` ### Email validation diff --git a/packages/strapi-admin/config/routes.json b/packages/strapi-admin/config/routes.json index 185c86d731..9963242794 100644 --- a/packages/strapi-admin/config/routes.json +++ b/packages/strapi-admin/config/routes.json @@ -69,11 +69,6 @@ "path": "/auth/forgot-password", "handler": "Auth.forgotPassword" }, - { - "method": "POST", - "path": "/auth/change-password", - "handler": "Auth.changePassword" - }, { "method": "POST", "path": "/auth/reset-password", diff --git a/packages/strapi-admin/controllers/Auth.js b/packages/strapi-admin/controllers/Auth.js index 02d5629659..6ed9bfc835 100644 --- a/packages/strapi-admin/controllers/Auth.js +++ b/packages/strapi-admin/controllers/Auth.js @@ -199,90 +199,6 @@ module.exports = { } }, - async changePassword(ctx) { - const id = ctx.state.user && ctx.state.user.id; - if (!id) { - return ctx.badRequest( - null, - formatError({ - id: 'Auth.form.error.user.not-exist', - message: 'Must be logged in.', - }) - ); - } - - const admin = await strapi.query('administrator', 'admin').findOne({ id }); - - const { password, passwordConfirmation, currentPassword } = { - ...ctx.request.body, - ...ctx.params, - }; - - if (!password) { - return ctx.badRequest( - null, - formatError({ - id: 'missing.password', - message: 'Missing password', - }) - ); - } - - if (!passwordConfirmation) { - return ctx.badRequest( - formatError({ - id: 'missing.passwordConfirmation', - message: 'Missing passwordConfirmation', - }) - ); - } - - if (!currentPassword) { - return ctx.badRequest( - null, - formatError({ - id: 'missing.currentPassword', - message: 'Missing current password', - }) - ); - } - - if (password !== passwordConfirmation) { - return ctx.badRequest( - null, - formatError({ - id: 'Auth.form.error.password.matching', - message: 'Passwords do not match.', - }) - ); - } - - const validPassword = await strapi.plugins['users-permissions'].services.user.validatePassword( - currentPassword, - admin.password - ); - - if (!validPassword) { - return ctx.badRequest( - null, - formatError({ - id: 'Auth.form.error.invalid', - message: 'Identifier or password invalid.', - }) - ); - } - - const data = { - password: await strapi.admin.services.auth.hashPassword(currentPassword), - }; - - await strapi.query('administrator', 'admin').update({ id: admin.id }, data); - - return ctx.send({ - ok: true, - }); - }, - async resetPassword(ctx) { const { password, passwordConfirmation, code } = { ...ctx.request.body, diff --git a/packages/strapi-plugin-users-permissions/config/routes.json b/packages/strapi-plugin-users-permissions/config/routes.json index 2e31f96f63..a06e65ff71 100644 --- a/packages/strapi-plugin-users-permissions/config/routes.json +++ b/packages/strapi-plugin-users-permissions/config/routes.json @@ -257,20 +257,6 @@ } } }, - { - "method": "POST", - "path": "/auth/change-password", - "handler": "Auth.changePassword", - "config": { - "policies": ["plugins::users-permissions.ratelimit"], - "prefix": "", - "description": "Change user password. Verifies with current password", - "tag": { - "plugin": "users-permissions", - "name": "User" - } - } - }, { "method": "POST", "path": "/auth/reset-password", diff --git a/packages/strapi-plugin-users-permissions/config/schema.graphql.js b/packages/strapi-plugin-users-permissions/config/schema.graphql.js index 4389d928e2..124da0eff2 100644 --- a/packages/strapi-plugin-users-permissions/config/schema.graphql.js +++ b/packages/strapi-plugin-users-permissions/config/schema.graphql.js @@ -58,7 +58,6 @@ module.exports = { login(input: UsersPermissionsLoginInput!): UsersPermissionsLoginPayload! register(input: UserInput!): UsersPermissionsLoginPayload! forgotPassword(email: String!): UserPersmissionsPasswordPayload - changePassword(password: String!, passwordConfirmation: String!, currentPassword: String!): UserPersmissionsPasswordPayload resetPassword(password: String!, passwordConfirmation: String!, code: String!): UsersPermissionsLoginPayload emailConfirmation(confirmation: String!): UsersPermissionsLoginPayload `, @@ -242,22 +241,6 @@ module.exports = { }; }, }, - changePassword: { - description: 'Change your password. Verified by current password.', - resolverOf: 'plugins::users-permissions.auth.changePassword', - resolver: async (obj, options, { context }) => { - context.request.body = _.toPlainObject(options); - - await strapi.plugins['users-permissions'].controllers.auth.changePassword(context); - let output = context.body.toJSON ? context.body.toJSON() : context.body; - - checkBadRequest(output); - - return { - ok: output.ok, - }; - }, - }, emailConfirmation: { description: 'Confirm an email users email address', resolverOf: 'plugins::users-permissions.auth.emailConfirmation', diff --git a/packages/strapi-plugin-users-permissions/controllers/Auth.js b/packages/strapi-plugin-users-permissions/controllers/Auth.js index 362059ed36..4971da40c8 100644 --- a/packages/strapi-plugin-users-permissions/controllers/Auth.js +++ b/packages/strapi-plugin-users-permissions/controllers/Auth.js @@ -176,76 +176,7 @@ module.exports = { }); } }, - - async changePassword(ctx) { - const params = _.assign({}, ctx.request.body, ctx.params); - - if ( - params.password && - params.passwordConfirmation && - params.password === params.passwordConfirmation && - params.currentPassword - ) { - const id = ctx.state.user && ctx.state.user.id; - if (!id) { - return ctx.badRequest( - null, - formatError({ - id: 'Auth.form.error.user.not-exist', - message: 'Must be logged in.', - }) - ); - } - - const user = await strapi.plugins['users-permissions'].services.user.fetch({ id }); - - const validPassword = await strapi.plugins[ - 'users-permissions' - ].services.user.validatePassword(params.currentPassword, user.password); - - if (!validPassword) { - return ctx.badRequest( - null, - formatError({ - id: 'Auth.form.error.invalid', - message: 'Identifier or password invalid.', - }) - ); - } else { - // Hash and Replace current password with the new one in the user object. - user.password = await strapi.plugins['users-permissions'].services.user.hashPassword({ - password: params.password, - }); - - // Update the user. - await strapi.query('user', 'users-permissions').update({ id: user.id }, user); - - ctx.send({ - ok: true, - }); - } - } else if ( - params.password && - params.passwordConfirmation && - params.password !== params.passwordConfirmation - ) { - return ctx.badRequest( - null, - formatError({ - id: 'Auth.form.error.password.matching', - message: 'Passwords do not match.', - }) - ); - } else { - return ctx.badRequest( - null, - formatError({ - id: 'Auth.form.error.params.provide', - message: 'Incorrect params provided.', - }) - ); - } - }, + async resetPassword(ctx) { const params = _.assign({}, ctx.request.body, ctx.params); From 40fbe530c16858b9f43037100d38f7c67a4a72d7 Mon Sep 17 00:00:00 2001 From: ScottAgirs Date: Sat, 11 Apr 2020 13:46:45 -0400 Subject: [PATCH 08/11] [minor] console log text tweak Signed-off-by: ScottAgirs --- packages/strapi-plugin-users-permissions/config/routes.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/strapi-plugin-users-permissions/config/routes.json b/packages/strapi-plugin-users-permissions/config/routes.json index a06e65ff71..80d8264a95 100644 --- a/packages/strapi-plugin-users-permissions/config/routes.json +++ b/packages/strapi-plugin-users-permissions/config/routes.json @@ -264,7 +264,7 @@ "config": { "policies": ["plugins::users-permissions.ratelimit"], "prefix": "", - "description": "Reset a user's password with a code (resetToken)", + "description": "Reset user password with a code (resetToken)", "tag": { "plugin": "users-permissions", "name": "User" From 13b379128d101a916b1233d4c2a1bb4cd79ad6ee Mon Sep 17 00:00:00 2001 From: ScottAgirs Date: Mon, 18 May 2020 15:49:00 -0400 Subject: [PATCH 09/11] [bugfix] put back UsersPermissionsRegisterInput on register() Signed-off-by: ScottAgirs --- .../strapi-plugin-users-permissions/config/schema.graphql.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/strapi-plugin-users-permissions/config/schema.graphql.js b/packages/strapi-plugin-users-permissions/config/schema.graphql.js index 253c9cbc95..27e63e0395 100644 --- a/packages/strapi-plugin-users-permissions/config/schema.graphql.js +++ b/packages/strapi-plugin-users-permissions/config/schema.graphql.js @@ -62,7 +62,7 @@ module.exports = { `, mutation: ` login(input: UsersPermissionsLoginInput!): UsersPermissionsLoginPayload! - register(input: UserInput!): UsersPermissionsLoginPayload! + register(input: UserInput!): UsersPermissionsRegisterInput! forgotPassword(email: String!): UserPersmissionsPasswordPayload resetPassword(password: String!, passwordConfirmation: String!, code: String!): UsersPermissionsLoginPayload emailConfirmation(confirmation: String!): UsersPermissionsLoginPayload From ebed726d7bb63e77c3232819183d3484314610d9 Mon Sep 17 00:00:00 2001 From: ScottAgirs Date: Tue, 19 May 2020 11:58:36 -0400 Subject: [PATCH 10/11] [bugfix] register(input: UsersPermissionsRegisterInput) Signed-off-by: ScottAgirs --- .../strapi-plugin-users-permissions/config/schema.graphql.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/strapi-plugin-users-permissions/config/schema.graphql.js b/packages/strapi-plugin-users-permissions/config/schema.graphql.js index 27e63e0395..901938120d 100644 --- a/packages/strapi-plugin-users-permissions/config/schema.graphql.js +++ b/packages/strapi-plugin-users-permissions/config/schema.graphql.js @@ -62,7 +62,7 @@ module.exports = { `, mutation: ` login(input: UsersPermissionsLoginInput!): UsersPermissionsLoginPayload! - register(input: UserInput!): UsersPermissionsRegisterInput! + register(input: UsersPermissionsRegisterInput!): UsersPermissionsRegisterInput! forgotPassword(email: String!): UserPersmissionsPasswordPayload resetPassword(password: String!, passwordConfirmation: String!, code: String!): UsersPermissionsLoginPayload emailConfirmation(confirmation: String!): UsersPermissionsLoginPayload From ef861f19ff318d4d00e2b788863e22259f8e1218 Mon Sep 17 00:00:00 2001 From: ScottAgirs Date: Tue, 19 May 2020 12:03:31 -0400 Subject: [PATCH 11/11] [bugfix] register() input, payload Signed-off-by: ScottAgirs --- .../strapi-plugin-users-permissions/config/schema.graphql.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/strapi-plugin-users-permissions/config/schema.graphql.js b/packages/strapi-plugin-users-permissions/config/schema.graphql.js index 901938120d..64f1172661 100644 --- a/packages/strapi-plugin-users-permissions/config/schema.graphql.js +++ b/packages/strapi-plugin-users-permissions/config/schema.graphql.js @@ -62,7 +62,7 @@ module.exports = { `, mutation: ` login(input: UsersPermissionsLoginInput!): UsersPermissionsLoginPayload! - register(input: UsersPermissionsRegisterInput!): UsersPermissionsRegisterInput! + register(input: UsersPermissionsRegisterInput!): UsersPermissionsLoginPayload! forgotPassword(email: String!): UserPersmissionsPasswordPayload resetPassword(password: String!, passwordConfirmation: String!, code: String!): UsersPermissionsLoginPayload emailConfirmation(confirmation: String!): UsersPermissionsLoginPayload