diff --git a/README.md b/README.md index 6bfd707..250b8a7 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ All features marked with an **E** are extended features, and are not a part of t - [X] List emails - [X] **E** View individual user details - [X] **E** Create email from file -- [ ] Change password +- [X] Change password - [ ] Delete email - [ ] Restrict email diff --git a/package.json b/package.json index 70072bf..2a33c5b 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,9 @@ "type": "module", "devDependencies": { "@types/bun": "latest", - "@types/dockerode": "^3.3.34", + "@types/dockerode": "^3.3.35", "@types/express": "^5.0.0", - "@types/node": "^22.13.4", + "@types/node": "^22.13.5", "@types/validator": "^13.12.2", "drizzle-kit": "^0.30.4" }, diff --git a/src/server.ts b/src/server.ts index e35a3c9..1bde13c 100644 --- a/src/server.ts +++ b/src/server.ts @@ -143,15 +143,55 @@ app.post("/accounts/user", async (req: Request, res: Response): Promise => } }); +app.post("/accounts/update/password", async (req: Request, res: Response): Promise => { + const { email, password } = req.body; + + if (!validateEmail(email)) { + console.log("Error updating password: Invalid email format"); + res.status(400).json({ error: "Invalid email format" }); + return; + } + + const exec = await container.exec({ + Cmd: ["setup", "email", "update", email, password], + AttachStdout: true, + AttachStderr: true, + }); + const stream = await new Promise((resolve, reject) => { + exec.start({}, (err, stream) => { + if (err || !stream) { + reject(err || new Error("Exec stream is undefined")); + } else { + resolve(stream); + } + }); + }); + let output = ""; + stream.on("data", (chunk: Buffer) => { + output += chunk.toString(); + }); + await new Promise((resolve) => stream.on("end", resolve)); + console.log("Docker output (update password):\n", output); + // detect errors + if (/ERROR/i.test(output)) { + console.log(`Error during migration: Password reset failed`); + res.status(500).json({ error: "Error during reset" }); + return; + } else { + console.log(`Reset password for account: ${email}`); + res.json({ success: true }); + return; + } +}); + // TODO: The wait upon account creation needs to be more adaptive app.post("/accounts/add", async (req: Request, res: Response): Promise => { const { email, password, migrate } = req.body; let failureReason = ""; if (!validateEmail(email)) { - failureReason = "Invalid email format"; - console.log(`Error adding account: ${failureReason}`); - res.status(400).json({ error: failureReason }); + console.log("Error adding account: Invalid email format"); + res.status(400).json({ error: "Invalid email format" }); return; }