()
| 2017 | |
| 2018 | @app.route("/vault/settings", methods=["GET", "POST"]) |
| 2019 | def vault_settings(): |
| 2020 | gate = require_vault() |
| 2021 | if gate: |
| 2022 | return gate |
| 2023 | if request.method == "POST": |
| 2024 | oldp = request.form.get("oldp", "") |
| 2025 | newp1 = request.form.get("newp1", "") |
| 2026 | newp2 = request.form.get("newp2", "") |
| 2027 | if not verify_vault_password(oldp): |
| 2028 | flash("Old password is wrong.") |
| 2029 | elif len(newp1) < 8: |
| 2030 | flash("New password must be at least 8 characters.") |
| 2031 | elif newp1 != newp2: |
| 2032 | flash("New passwords do not match.") |
| 2033 | else: |
| 2034 | con = db_connect() |
| 2035 | rows = con.execute("SELECT * FROM entries").fetchall() |
| 2036 | for row in rows: |
| 2037 | try: |
| 2038 | username = vault_decrypt(oldp, row["username_enc"]) |
| 2039 | password = vault_decrypt(oldp, row["password_enc"]) |
| 2040 | notes = vault_decrypt(oldp, row["notes_enc"]) |
| 2041 | except Exception: |
| 2042 | con.close() |
| 2043 | flash("Could not re-encrypt the vault.") |
| 2044 | return redirect(url_for("vault_settings")) |
| 2045 | con.execute( |
| 2046 | "UPDATE entries SET username_enc=?, password_enc=?, notes_enc=?, updated_at=? WHERE id=?", |
| 2047 | (vault_encrypt(newp1, username), vault_encrypt(newp1, password), vault_encrypt(newp1, notes), int(time.time()), row["id"]) |
| 2048 | ) |
| 2049 | con.commit() |
| 2050 | con.close() |
| 2051 | set_vault_password(newp1) |
| 2052 | VAULT_KEYS[get_client_id()] = newp1 |
| 2053 | flash("Vault password changed.") |
| 2054 | return redirect(url_for("vault_settings")) |
| 2055 | body = """ |
| 2056 | <section class='hero stack'> |
| 2057 | <h1 style='margin:0;'>Vault settings</h1> |
| 2058 | <div class='muted'>Change the master password and re-encrypt all entries using the new one.</div> |
| 2059 | <form method='post' class='grid2'> |
| 2060 | <div class='card stack'> |
| 2061 | <div><label>Old password</label><input type='password' name='oldp' required></div> |
| 2062 | <div><label>New password</label><input type='password' name='newp1' required></div> |
| 2063 | <div><label>Confirm new password</label><input type='password' name='newp2' required></div> |
| 2064 | <div class='row'><button class='btn primary' type='submit'>Change password</button><a class='btn' href='{{ url_for("vault_home") }}'>Back</a></div> |
| 2065 | </div> |
| 2066 | <div class='card stack'><h3 style='margin:0;'>Reminder</h3><div class='muted'>Changing the password re-encrypts every stored field, so it may take a moment if you have many entries.</div></div> |
| 2067 | </form> |
| 2068 | </section> |
| 2069 | """ |
| 2070 | return render_page("Vault settings", body) |
| 2071 | |
| 2072 | # ---------------- auto open ---------------- |
| 2073 | def open_in_browser(url: str) -> None: |
nothing calls this directly
no test coverage detected