diff --git a/src/App.js b/src/App.js
index a436f4b870033218137b4d0b70e3e375b398b1fa..6b2514c80a9d5ccc92b51c4a5d09a61f5564b9a6 100644
--- a/src/App.js
+++ b/src/App.js
@@ -3,6 +3,7 @@ import { BrowserRouter, Switch, Route } from "react-router-dom";
 import MemberList from "./MemberList";
 import ProductList from "./ProductList";
 import Dashboard from "./Dashboard";
+import OwnPassword from "./Password";
 import Purchase from "./purchase/Purchase";
 import Topup from "./Topup";
 import ShowTransaction from "./ShowTransaction";
@@ -27,6 +28,9 @@ function Panel(props) {
           <Route path="/transaction/:id">
             <ShowTransaction />
           </Route>
+          <Route path="/password">
+            <OwnPassword />
+          </Route>
           <Route path="/purchase">
             <Purchase />
           </Route>
diff --git a/src/Head.js b/src/Head.js
index 63d458216bc4cb6d7c7f691cadf9b3a1d52de926..740778cf1d21dc11051a39cbee88ec2e9184810c 100644
--- a/src/Head.js
+++ b/src/Head.js
@@ -35,6 +35,11 @@ function Head(props) {
           <Nav.Link href="/purchase">Comprar</Nav.Link>
           <Nav.Link href="/order/create">Abrir pedido</Nav.Link>
         </Nav>
+
+        <NavDropdown title="Ajustes" id="ajustes">
+          <Nav.Link href="/password">Cambiar contraseña</Nav.Link>
+        </NavDropdown>
+
         {adminNav}
         <Form inline>
           <Button variant="outline-success" onClick={props.onLogout}>
diff --git a/src/Password.js b/src/Password.js
new file mode 100644
index 0000000000000000000000000000000000000000..ef0a7f376655e27468a3d4122a84e72a42dddf0e
--- /dev/null
+++ b/src/Password.js
@@ -0,0 +1,166 @@
+import React from "react";
+import { Container, Form, Col, Row, Button, Alert } from "react-bootstrap";
+import AuthContext from "./AuthContext";
+
+class OwnPassword extends React.Component {
+  static contextType = AuthContext;
+
+  constructor(props) {
+    super(props);
+    this.state = {
+      newPassword: "",
+      newPassword2: "",
+      formErrors: "",
+      isNewPasswordValid: false,
+      isNewPassword2Valid: false,
+      isFormValid: false,
+      error: null,
+      passwordChanged: false,
+    };
+    this.handleSubmit = this.handleSubmit.bind(this);
+  }
+
+  /** Check whether the new password is valid, and matches with its confirmation. */
+  checkNewPassword() {
+    let isNewPasswordValid = this.state.newPassword.length >= 6;
+    let isNewPassword2Valid =
+      this.state.newPassword === this.state.newPassword2;
+
+    let formErrors = isNewPasswordValid
+      ? isNewPassword2Valid
+        ? ""
+        : "Las contraseñas no coinciden."
+      : "La contraseña es demasiado corta.";
+
+    this.setState(
+      {
+        formErrors: formErrors,
+        isNewPasswordValid: isNewPasswordValid,
+        isNewPassword2Valid: isNewPassword2Valid,
+      },
+      this.validateForm
+    );
+  }
+
+  /** Check all the fields are valid, so the form may be submitted. */
+  validateForm() {
+    this.setState({
+      isFormValid:
+        this.state.isNewPasswordValid && this.state.isNewPassword2Valid,
+    });
+  }
+
+  handleSubmit(event) {
+    event.preventDefault();
+
+    this.setState({ isLoading: true, error: null });
+    const body = JSON.stringify({
+      password: this.state.newPassword,
+    });
+    fetch("/api/member/me", {
+      headers: { "x-authentication": this.context.token },
+      method: "PUT",
+      body,
+    })
+      .then((response) => {
+        if (!response.ok) {
+          throw new Error(
+            response.status.toString() + " " + response.statusText
+          );
+        }
+        return response.json();
+      })
+      .then((json) => {
+        // console.log(json);
+        this.setState({
+          isLoading: false,
+          passwordChanged: true,
+        });
+      })
+      .catch((error) => {
+        this.setState({ isLoading: false, error: error.message });
+      });
+  }
+
+  render() {
+    let alert;
+
+    if (this.state.formErrors) {
+      alert = <Alert variant="warning">{this.state.formErrors}</Alert>;
+    }
+
+    if (this.state.error) {
+      alert = (
+        <Alert variant="danger">
+          Se produjo un error al intentar cambiar la contraseña:{" "}
+          {this.state.error}
+        </Alert>
+      );
+    }
+
+    if (this.state.passwordChanged) {
+      alert = (
+        <Alert variant="success">La contraseña se ha cambiado con éxito.</Alert>
+      );
+      this.state.passwordChanged = false;
+    }
+
+    return (
+      <Container>
+        <h2>Cambio de contraseña</h2>
+
+        {alert}
+
+        <Form onSubmit={this.handleSubmit}>
+          <Form.Group as={Row}>
+            <Form.Label as="legend" column sm={4}>
+              Nueva contraseña
+            </Form.Label>
+            <Col sm={8}>
+              <Form.Control
+                placeholder="Nueva contraseña"
+                type="password"
+                onChange={(e) =>
+                  this.setState({ newPassword: e.target.value }, () => {
+                    this.checkNewPassword();
+                  })
+                }
+              />
+            </Col>
+          </Form.Group>
+
+          <Form.Group as={Row}>
+            <Form.Label as="legend" column sm={4}>
+              Confirme la nueva contraseña
+            </Form.Label>
+            <Col sm={8}>
+              <Form.Control
+                placeholder="Repita la nueva contraseña"
+                type="password"
+                onChange={(e) =>
+                  this.setState({ newPassword2: e.target.value }, () => {
+                    this.checkNewPassword();
+                  })
+                }
+              />
+            </Col>
+          </Form.Group>
+
+          <Form.Group as={Row}>
+            <Col sm={{ offset: 4, span: 8 }}>
+              <Button
+                type="submit"
+                variant="primary"
+                disabled={!this.state.isFormValid}
+              >
+                Cambiar la contraseña
+              </Button>
+            </Col>
+          </Form.Group>
+        </Form>
+      </Container>
+    );
+  }
+}
+
+export default OwnPassword;