mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-06-29 03:12:12 +08:00
feat: implement address password authentication feature (#731)
* feat: implement address password authentication feature - Add password field to address table for storing hashed passwords - Implement address authentication APIs (login, change password) - Add automatic password generation for new addresses - Support password login alongside credential login in frontend - Add password management in account settings and admin panel - Add ENABLE_ADDRESS_PASSWORD environment variable for feature control - Update documentation and i18n support - Enhance security with SHA-256 password hashing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: upgrade dependencies --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
79
worker/src/mails_api/address_auth.ts
Normal file
79
worker/src/mails_api/address_auth.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { Context } from 'hono';
|
||||
import i18n from '../i18n';
|
||||
import { getBooleanValue, hashPassword } from '../utils';
|
||||
import { Jwt } from 'hono/utils/jwt';
|
||||
|
||||
export default {
|
||||
// 修改地址密码
|
||||
changePassword: async (c: Context<HonoCustomType>) => {
|
||||
const { new_password } = await c.req.json();
|
||||
const lang = c.get("lang") || c.env.DEFAULT_LANG;
|
||||
const msgs = i18n.getMessages(lang);
|
||||
const { address, address_id } = c.get("jwtPayload");
|
||||
|
||||
// 检查功能是否启用
|
||||
if (!getBooleanValue(c.env.ENABLE_ADDRESS_PASSWORD)) {
|
||||
return c.text(msgs.PasswordChangeDisabledMsg, 403);
|
||||
}
|
||||
|
||||
if (!new_password) {
|
||||
return c.text(msgs.NewPasswordRequiredMsg, 400);
|
||||
}
|
||||
|
||||
if (!address || !address_id) {
|
||||
return c.text(msgs.InvalidAddressTokenMsg, 400);
|
||||
}
|
||||
|
||||
// 更新密码
|
||||
const { success } = await c.env.DB.prepare(
|
||||
`UPDATE address SET password = ?, updated_at = datetime('now') WHERE id = ?`
|
||||
).bind(new_password, address_id).run();
|
||||
|
||||
if (!success) {
|
||||
return c.text(msgs.FailedUpdatePasswordMsg, 500);
|
||||
}
|
||||
|
||||
return c.json({ success: true });
|
||||
},
|
||||
|
||||
// 地址密码登录
|
||||
login: async (c: Context<HonoCustomType>) => {
|
||||
const { email, password, cf_token } = await c.req.json();
|
||||
const lang = c.get("lang") || c.env.DEFAULT_LANG;
|
||||
const msgs = i18n.getMessages(lang);
|
||||
|
||||
// 检查功能是否启用
|
||||
if (!getBooleanValue(c.env.ENABLE_ADDRESS_PASSWORD)) {
|
||||
return c.text(msgs.PasswordLoginDisabledMsg, 403);
|
||||
}
|
||||
|
||||
if (!email || !password) {
|
||||
return c.text(msgs.EmailPasswordRequiredMsg, 400);
|
||||
}
|
||||
|
||||
// 查找地址
|
||||
const address = await c.env.DB.prepare(
|
||||
`SELECT * FROM address WHERE name = ?`
|
||||
).bind(email).first();
|
||||
|
||||
if (!address) {
|
||||
return c.text(msgs.AddressNotFoundMsg, 404);
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
if (address.password !== password) {
|
||||
return c.text(msgs.InvalidEmailOrPasswordMsg, 401);
|
||||
}
|
||||
|
||||
// 创建JWT
|
||||
const jwt = await Jwt.sign({
|
||||
address: address.name,
|
||||
address_id: address.id
|
||||
}, c.env.JWT_SECRET, "HS256");
|
||||
|
||||
return c.json({
|
||||
jwt: jwt,
|
||||
address: address.name
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -7,6 +7,7 @@ import { CONSTANTS } from '../constants'
|
||||
import auto_reply from './auto_reply'
|
||||
import webhook_settings from './webhook_settings';
|
||||
import s3_attachment from './s3_attachment';
|
||||
import address_auth from './address_auth';
|
||||
|
||||
export const api = new Hono<HonoCustomType>()
|
||||
|
||||
@@ -198,3 +199,6 @@ api.delete('/api/clear_sent_items', async (c) => {
|
||||
success: success
|
||||
})
|
||||
})
|
||||
|
||||
api.post('/api/address_change_password', address_auth.changePassword)
|
||||
api.post('/api/address_login', address_auth.login)
|
||||
|
||||
Reference in New Issue
Block a user