diff --git a/apps/wizarr-backend/wizarr_backend/api/routes/accounts_api.py b/apps/wizarr-backend/wizarr_backend/api/routes/accounts_api.py index fa2976e3..0c7dca6a 100644 --- a/apps/wizarr-backend/wizarr_backend/api/routes/accounts_api.py +++ b/apps/wizarr-backend/wizarr_backend/api/routes/accounts_api.py @@ -1,3 +1,4 @@ +from app.models.wizarr.accounts import AccountsModel from flask import request from flask_jwt_extended import jwt_required, current_user from flask_restx import Namespace, Resource @@ -120,3 +121,19 @@ def delete(self, account_id: str) -> tuple[dict[str, str], int]: """Delete an account""" delete_account(account_id) return {"message": "Account deleted"}, 200 + +@api.route("/change_password") +@api.route("/change_password/", doc=False) +class ChangePassword(Resource): + """API resource for changing the user's password""" + + method_decorators = [jwt_required()] + + @api.doc(description="Change the user's password") + @api.response(200, "Password changed") + @api.response(401, "Invalid password") + @api.response(500, "Internal server error") + def post(self): + """Change the user's password""" + #get the current user's id + return AccountsModel.change_password(request), 200 diff --git a/apps/wizarr-backend/wizarr_backend/api/routes/authentication_api.py b/apps/wizarr-backend/wizarr_backend/api/routes/authentication_api.py index 9303d6f1..d47bd23c 100644 --- a/apps/wizarr-backend/wizarr_backend/api/routes/authentication_api.py +++ b/apps/wizarr-backend/wizarr_backend/api/routes/authentication_api.py @@ -74,19 +74,4 @@ class Logout(Resource): @api.response(500, "Internal server error") def post(self): """Logout the currently logged in user""" - return AuthenticationModel.logout_user() - -@api.route("/change_password") -@api.route("/change_password/", doc=False) -class ChangePassword(Resource): - """API resource for changing the user's password""" - - method_decorators = [jwt_required()] - - @api.doc(description="Change the user's password") - @api.response(200, "Password changed") - @api.response(401, "Invalid password") - @api.response(500, "Internal server error") - def post(self): - """Change the user's password""" - return AuthenticationModel.change_password(request.form) + return AuthenticationModel.logout_user() \ No newline at end of file diff --git a/apps/wizarr-backend/wizarr_backend/app/models/wizarr/accounts.py b/apps/wizarr-backend/wizarr_backend/app/models/wizarr/accounts.py index 77a88bed..71233389 100644 --- a/apps/wizarr-backend/wizarr_backend/app/models/wizarr/accounts.py +++ b/apps/wizarr-backend/wizarr_backend/app/models/wizarr/accounts.py @@ -5,7 +5,7 @@ from schematics.exceptions import DataError, ValidationError from schematics.models import Model from schematics.types import DateTimeType, EmailType, StringType, BooleanType -from werkzeug.security import generate_password_hash +from werkzeug.security import generate_password_hash, check_password_hash from app.models.database.accounts import Accounts @@ -108,3 +108,22 @@ def update_account(self, account: Accounts): # Set the attributes of the updated account to the model for key, value in model_to_dict(account).items(): setattr(self, key, value) + + + # ANCHOR - Perform migration of old passwords + def change_password(self): + old_password = self.form.get("old_password") + new_password = self.form.get("new_password") + username = self.form.get("username") + # get account by username + account = Accounts.get_or_none(Accounts.username == username) + + # First, check if the old_password matches the account's current password + if not check_password_hash(account.password, old_password): + raise ValidationError("Old password does not match.") + + # Next update the password on account + account.password = generate_password_hash(new_password, method="scrypt") + account.save() + return True + diff --git a/apps/wizarr-backend/wizarr_backend/app/models/wizarr/authentication.py b/apps/wizarr-backend/wizarr_backend/app/models/wizarr/authentication.py index 061f4822..ff2fa521 100644 --- a/apps/wizarr-backend/wizarr_backend/app/models/wizarr/authentication.py +++ b/apps/wizarr-backend/wizarr_backend/app/models/wizarr/authentication.py @@ -236,17 +236,6 @@ def login_user(self): info(f"Account {self._user.username} successfully logged in") return resp - # ANCHOR - Perform migration of old passwords - def change_password(self): - # verify the old password id the same as the current password - - # if it is, then update the password - - # else, return an error message - - pass - - # ANCHOR - Logout User @staticmethod def logout_user(): diff --git a/apps/wizarr-frontend/src/api/authentication.ts b/apps/wizarr-frontend/src/api/authentication.ts index 6c42d384..8cb0c164 100644 --- a/apps/wizarr-frontend/src/api/authentication.ts +++ b/apps/wizarr-frontend/src/api/authentication.ts @@ -241,17 +241,26 @@ class Auth { } // check if old assword is correct - const username = userStore.user?.display_name || userStore.user?.username; + const username = userStore.user?.username; + + if (old_password) this.old_password = old_password; + if (new_password) this.new_password = new_password; + if (username) this.username = username; + + // Create a form data object + const formData = new FormData(); + + // Add the username, password and remember_me to the form data + formData.append("old_password", this.old_password); + formData.append("new_password", this.new_password); + formData.append("username", this.username); // send request to server to change password await this.axios - .post("/api/auth/change_password", { - old_password: old_password, - new_password: new_password, - username: username, - }) - .then((response) => { - return response; + .post("/api/accounts/change_password", formData) + .then((res) => { + this.successToast("Password changed successfully"); + return res; }) .catch(() => { this.errorToast("Failed to change password, please try again"); diff --git a/apps/wizarr-frontend/src/modules/settings/pages/Password.vue b/apps/wizarr-frontend/src/modules/settings/pages/Password.vue index 82f971a7..741df7db 100644 --- a/apps/wizarr-frontend/src/modules/settings/pages/Password.vue +++ b/apps/wizarr-frontend/src/modules/settings/pages/Password.vue @@ -49,11 +49,8 @@ export default defineComponent({ return; } await this.auth.changePassword(old_password, new_password).then((res) => { - if (res !== undefined) { - this.$toast.success("Password changed successfully"); - } + this.resetForm(); }); - this.resetForm(); }, }, });