mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-12-17 18:37:16 +00:00
478403ef63
* feat(cli): Allow unattended password reset via CLI This commit adds a way to reset the admin password via CLI without any user interaction (unattended operation). It adds an optional `new_password` CLI argument that, when present is used instead of prompting the user for password and password confirmation. It also makes sure the user is informed the password could leak into it's shell history (it's up to him to do some cleaning if needed/wanted). * Change to dash style * Add dry-run * Fix number password issue --------- Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
90 lines
2.8 KiB
JavaScript
90 lines
2.8 KiB
JavaScript
console.log("== Uptime Kuma Reset Password Tool ==");
|
|
|
|
const Database = require("../server/database");
|
|
const { R } = require("redbean-node");
|
|
const readline = require("readline");
|
|
const { initJWTSecret } = require("../server/util-server");
|
|
const User = require("../server/model/user");
|
|
const args = require("args-parser")(process.argv);
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout
|
|
});
|
|
|
|
const main = async () => {
|
|
if ("dry-run" in args) {
|
|
console.log("Dry run mode, no changes will be made.");
|
|
}
|
|
|
|
console.log("Connecting the database");
|
|
Database.initDataDir(args);
|
|
await Database.connect(false, false, true);
|
|
|
|
try {
|
|
// No need to actually reset the password for testing, just make sure no connection problem. It is ok for now.
|
|
if (!process.env.TEST_BACKEND) {
|
|
const user = await R.findOne("user");
|
|
if (! user) {
|
|
throw new Error("user not found, have you installed?");
|
|
}
|
|
|
|
console.log("Found user: " + user.username);
|
|
|
|
while (true) {
|
|
let password;
|
|
let confirmPassword;
|
|
|
|
// When called with "--new-password" argument for unattended modification (e.g. npm run reset-password -- --new_password=secret)
|
|
if ("new-password" in args) {
|
|
console.log("Using password from argument");
|
|
console.warn("\x1b[31m%s\x1b[0m", "Warning: the password might be stored, in plain text, in your shell's history");
|
|
password = confirmPassword = args["new-password"] + "";
|
|
} else {
|
|
password = await question("New Password: ");
|
|
confirmPassword = await question("Confirm New Password: ");
|
|
}
|
|
|
|
if (password === confirmPassword) {
|
|
if (!("dry-run" in args)) {
|
|
await User.resetPassword(user.id, password);
|
|
|
|
// Reset all sessions by reset jwt secret
|
|
await initJWTSecret();
|
|
}
|
|
break;
|
|
} else {
|
|
console.log("Passwords do not match, please try again.");
|
|
}
|
|
}
|
|
console.log("Password reset successfully.");
|
|
}
|
|
} catch (e) {
|
|
console.error("Error: " + e.message);
|
|
}
|
|
|
|
await Database.close();
|
|
rl.close();
|
|
|
|
console.log("Finished.");
|
|
};
|
|
|
|
/**
|
|
* Ask question of user
|
|
* @param {string} question Question to ask
|
|
* @returns {Promise<string>} Users response
|
|
*/
|
|
function question(question) {
|
|
return new Promise((resolve) => {
|
|
rl.question(question, (answer) => {
|
|
resolve(answer);
|
|
});
|
|
});
|
|
}
|
|
|
|
if (!process.env.TEST_BACKEND) {
|
|
main();
|
|
}
|
|
|
|
module.exports = {
|
|
main,
|
|
};
|