1
This commit is contained in:
@@ -67,17 +67,20 @@ module.exports = {
|
|||||||
return ctx.fail('密码长度不能少于6位');
|
return ctx.fail('密码长度不能少于6位');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 统一邮箱地址为小写
|
||||||
|
const email_normalized = email.toLowerCase().trim();
|
||||||
|
|
||||||
// 验证验证码
|
// 验证验证码
|
||||||
const emailVerifyResult = await verifyEmailCode(email, email_code);
|
const emailVerifyResult = await verifyEmailCode(email_normalized, email_code);
|
||||||
if (!emailVerifyResult.success) {
|
if (!emailVerifyResult.success) {
|
||||||
return ctx.fail(emailVerifyResult.message || '验证码错误或已过期');
|
return ctx.fail(emailVerifyResult.message || '验证码错误或已过期');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { pla_account } = await Framework.getModels();
|
const { pla_account } = await Framework.getModels();
|
||||||
|
|
||||||
// 检查邮箱是否已注册
|
// 检查邮箱是否已注册(使用统一的小写邮箱)
|
||||||
const existingUser = await pla_account.findOne({
|
const existingUser = await pla_account.findOne({
|
||||||
where: { login_name: email }
|
where: { login_name: email_normalized }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (existingUser) {
|
if (existingUser) {
|
||||||
@@ -87,7 +90,7 @@ module.exports = {
|
|||||||
// 验证邀请码(如果提供了邀请码)
|
// 验证邀请码(如果提供了邀请码)
|
||||||
let inviter = null;
|
let inviter = null;
|
||||||
let inviter_id = null;
|
let inviter_id = null;
|
||||||
|
|
||||||
if (invite_code) {
|
if (invite_code) {
|
||||||
// 解析邀请码,获取邀请人ID
|
// 解析邀请码,获取邀请人ID
|
||||||
// 邀请码格式:INV{user_id}_{timestamp}
|
// 邀请码格式:INV{user_id}_{timestamp}
|
||||||
@@ -111,13 +114,13 @@ module.exports = {
|
|||||||
// 生成设备SN码(基于邮箱和时间戳)
|
// 生成设备SN码(基于邮箱和时间戳)
|
||||||
const sn_code = `SN${Date.now()}${Math.random().toString(36).substr(2, 6).toUpperCase()}`;
|
const sn_code = `SN${Date.now()}${Math.random().toString(36).substr(2, 6).toUpperCase()}`;
|
||||||
|
|
||||||
// 创建新用户
|
// 创建新用户(使用统一的小写邮箱)
|
||||||
const newUser = await pla_account.create({
|
const newUser = await pla_account.create({
|
||||||
name: email.split('@')[0], // 默认使用邮箱用户名作为名称
|
name: email_normalized.split('@')[0], // 默认使用邮箱用户名作为名称
|
||||||
sn_code: sn_code,
|
sn_code: sn_code,
|
||||||
device_id: '', // 设备ID由客户端登录时提供
|
device_id: '', // 设备ID由客户端登录时提供
|
||||||
platform_type: 'boss', // 默认平台类型
|
platform_type: 'boss', // 默认平台类型
|
||||||
login_name: email,
|
login_name: email_normalized,
|
||||||
pwd: password,
|
pwd: password,
|
||||||
keyword: '',
|
keyword: '',
|
||||||
is_enabled: 1,
|
is_enabled: 1,
|
||||||
@@ -173,9 +176,9 @@ module.exports = {
|
|||||||
is_delete: 0
|
is_delete: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`[邀请注册] 用户 ${email} 通过邀请码 ${invite_code} 注册成功,邀请人 ${inviter.sn_code} 获得3天试用期`);
|
console.log(`[邀请注册] 用户 ${email_normalized} 通过邀请码 ${invite_code} 注册成功,邀请人 ${inviter.sn_code} 获得3天试用期`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`[邀请注册] 用户 ${email} 注册成功(无邀请码)`);
|
console.log(`[邀请注册] 用户 ${email_normalized} 注册成功(无邀请码)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.success({
|
return ctx.success({
|
||||||
@@ -231,8 +234,11 @@ module.exports = {
|
|||||||
return ctx.fail('邮箱格式不正确');
|
return ctx.fail('邮箱格式不正确');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 统一邮箱地址为小写
|
||||||
|
const email_normalized = email.toLowerCase().trim();
|
||||||
|
|
||||||
// 发送验证码
|
// 发送验证码
|
||||||
const emailResult = await sendEmailCode(email);
|
const emailResult = await sendEmailCode(email_normalized);
|
||||||
if (!emailResult.success) {
|
if (!emailResult.success) {
|
||||||
return ctx.fail(emailResult.message || '发送验证码失败');
|
return ctx.fail(emailResult.message || '发送验证码失败');
|
||||||
}
|
}
|
||||||
@@ -255,35 +261,57 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
async function sendEmailCode(email) {
|
async function sendEmailCode(email) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
// 获取框架的 Redis 服务
|
||||||
|
const redis_service = Framework.getServices().redisService;
|
||||||
|
|
||||||
|
|
||||||
|
// 统一邮箱地址为小写,避免大小写不一致导致的问题
|
||||||
|
const email_lower = email.toLowerCase().trim();
|
||||||
|
|
||||||
// 生成6位随机验证码
|
// 生成6位随机验证码
|
||||||
const code = Math.floor(100000 + Math.random() * 900000).toString();
|
const code = Math.floor(100000 + Math.random() * 900000).toString();
|
||||||
|
|
||||||
// 将验证码存储到缓存中(可以使用Redis或内存缓存)
|
// Redis key
|
||||||
// 格式:email_code:{email} = {code, expire_time}
|
const redis_key = `email_code:${email_lower}`;
|
||||||
const expire_time = Date.now() + 5 * 60 * 1000; // 5分钟后过期
|
|
||||||
|
// 验证码数据
|
||||||
// 这里应该存储到缓存中,暂时使用全局变量(生产环境应使用Redis)
|
const code_data = {
|
||||||
if (!global.emailCodeCache) {
|
|
||||||
global.emailCodeCache = {};
|
|
||||||
}
|
|
||||||
global.emailCodeCache[email] = {
|
|
||||||
code: code,
|
code: code,
|
||||||
expire_time: expire_time
|
created_at: Date.now()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 存储到 Redis,设置 5 分钟过期时间(300秒)
|
||||||
|
try {
|
||||||
|
await redis_service.set(redis_key, JSON.stringify(code_data), 300);
|
||||||
|
} catch (redis_error) {
|
||||||
|
console.error(`[邮箱验证] Redis 存储失败: ${email_lower}`, redis_error);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: '验证码存储失败,请稍后重试'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[邮箱验证] 生成验证码: ${email_lower} -> ${code}, 已存储到 Redis (5分钟过期)`);
|
||||||
|
|
||||||
// 调用邮件服务发送验证码
|
// 调用邮件服务发送验证码
|
||||||
const email_result = await email_service.send_verification_code(email, code);
|
const email_result = await email_service.send_verification_code(email_lower, code);
|
||||||
|
|
||||||
if (!email_result.success) {
|
if (!email_result.success) {
|
||||||
// 如果邮件发送失败,删除已生成的验证码
|
// 如果邮件发送失败,删除已生成的验证码
|
||||||
delete global.emailCodeCache[email];
|
try {
|
||||||
|
await redis_service.del(redis_key);
|
||||||
|
} catch (del_error) {
|
||||||
|
console.error(`[邮箱验证] 删除验证码失败:`, del_error);
|
||||||
|
}
|
||||||
|
console.error(`[邮箱验证] 邮件发送失败,已删除验证码: ${email_lower}`);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: email_result.message || '发送验证码失败'
|
message: email_result.message || '发送验证码失败'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[邮箱验证] 验证码已发送到 ${email}: ${code} (5分钟内有效)`);
|
console.log(`[邮箱验证] 验证码已发送到 ${email_lower}: ${code} (5分钟内有效)`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
@@ -306,32 +334,56 @@ async function sendEmailCode(email) {
|
|||||||
*/
|
*/
|
||||||
async function verifyEmailCode(email, code) {
|
async function verifyEmailCode(email, code) {
|
||||||
try {
|
try {
|
||||||
if (!global.emailCodeCache) {
|
// 统一邮箱地址为小写,避免大小写不一致导致的问题
|
||||||
|
const email_lower = email.toLowerCase().trim();
|
||||||
|
|
||||||
|
console.log(`[邮箱验证] 开始验证: ${email_lower}, 验证码: ${code}`);
|
||||||
|
|
||||||
|
// Redis key
|
||||||
|
const redis_key = `email_code:${email_lower}`;
|
||||||
|
|
||||||
|
// 从 Redis 获取验证码
|
||||||
|
let cached_str;
|
||||||
|
try {
|
||||||
|
cached_str = await redis_service.get(redis_key);
|
||||||
|
} catch (redis_error) {
|
||||||
|
console.error(`[邮箱验证] Redis 获取失败:`, redis_error);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: '验证码不存在或已过期'
|
message: '验证码获取失败,请稍后重试'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const cached = global.emailCodeCache[email];
|
if (!cached_str) {
|
||||||
if (!cached) {
|
console.log(`[邮箱验证] 未找到该邮箱的验证码: ${email_lower}`);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: '验证码不存在或已过期'
|
message: '验证码不存在或已过期,请重新获取'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否过期
|
// 解析验证码数据
|
||||||
if (Date.now() > cached.expire_time) {
|
let cached;
|
||||||
delete global.emailCodeCache[email];
|
try {
|
||||||
|
cached = JSON.parse(cached_str);
|
||||||
|
} catch (parse_error) {
|
||||||
|
console.error(`[邮箱验证] 解析验证码数据失败:`, parse_error);
|
||||||
|
try {
|
||||||
|
await redis_service.del(redis_key);
|
||||||
|
} catch (del_error) {
|
||||||
|
console.error(`[邮箱验证] 删除异常数据失败:`, del_error);
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: '验证码已过期,请重新获取'
|
message: '验证码数据异常,请重新获取'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`[邮箱验证] 找到验证码,创建时间: ${new Date(cached.created_at).toLocaleString()}`);
|
||||||
|
|
||||||
// 验证码是否正确
|
// 验证码是否正确
|
||||||
if (cached.code !== code) {
|
if (cached.code !== code) {
|
||||||
|
console.log(`[邮箱验证] 验证码错误,期望: ${cached.code}, 实际: ${code}`);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: '验证码错误'
|
message: '验证码错误'
|
||||||
@@ -339,7 +391,12 @@ async function verifyEmailCode(email, code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 验证成功后删除缓存
|
// 验证成功后删除缓存
|
||||||
delete global.emailCodeCache[email];
|
try {
|
||||||
|
await redis_service.del(redis_key);
|
||||||
|
} catch (del_error) {
|
||||||
|
console.error(`[邮箱验证] 删除验证码失败:`, del_error);
|
||||||
|
}
|
||||||
|
console.log(`[邮箱验证] 验证成功: ${email_lower}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true
|
success: true
|
||||||
|
|||||||
Reference in New Issue
Block a user