feat: 支持 OAuth 无密码用户设置密码和查看 API Key
- 新增 POST /auth/set-password 端点(仅限无密码用户) - /auth/me 返回 hasPassword 字段 - SettingsDialog:无密码用户显示"设置密码"表单(无需当前密码) - API Key reveal/copy:无密码时引导用户先设置密码 - 中英双语 i18n 支持 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -90,6 +90,33 @@ router.post('/refresh', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
const setPasswordSchema = z.object({
|
||||
password: z.string().min(8),
|
||||
});
|
||||
|
||||
router.post('/set-password', requireAuth, async (req, res) => {
|
||||
const parsed = setPasswordSchema.safeParse(req.body);
|
||||
if (!parsed.success) {
|
||||
res.status(400).json({ success: false, error: { code: 'VALIDATION', message: parsed.error.issues[0].message } });
|
||||
return;
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { id: req.user!.userId } });
|
||||
if (!user) {
|
||||
res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: 'User not found' } });
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.passwordHash) {
|
||||
res.status(400).json({ success: false, error: { code: 'ALREADY_HAS_PASSWORD', message: 'Password already set. Use change-password instead.' } });
|
||||
return;
|
||||
}
|
||||
|
||||
const passwordHash = await hashPassword(parsed.data.password);
|
||||
await prisma.user.update({ where: { id: user.id }, data: { passwordHash } });
|
||||
res.json({ success: true, data: { message: 'Password set successfully' } });
|
||||
});
|
||||
|
||||
const changePasswordSchema = z.object({
|
||||
currentPassword: z.string(),
|
||||
newPassword: z.string().min(8),
|
||||
@@ -143,13 +170,14 @@ router.put('/profile', requireAuth, async (req, res) => {
|
||||
router.get('/me', requireAuth, async (req, res) => {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: req.user!.userId },
|
||||
select: { id: true, email: true, name: true, avatarUrl: true },
|
||||
select: { id: true, email: true, name: true, avatarUrl: true, passwordHash: true },
|
||||
});
|
||||
if (!user) {
|
||||
res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: 'User not found' } });
|
||||
return;
|
||||
}
|
||||
res.json({ success: true, data: user });
|
||||
const { passwordHash, ...rest } = user;
|
||||
res.json({ success: true, data: { ...rest, hasPassword: !!passwordHash } });
|
||||
});
|
||||
|
||||
// --- API Key Management ---
|
||||
|
||||
Reference in New Issue
Block a user