feat: password changing and user deleting

This commit is contained in:
shinya
2025-07-13 17:07:50 +08:00
parent b24a67625c
commit 8c4c467845
6 changed files with 288 additions and 9 deletions

View File

@@ -36,10 +36,17 @@ export function getAuthInfoFromBrowserCookie(): {
try {
// 解析 document.cookie
const cookies = document.cookie.split(';').reduce((acc, cookie) => {
const [key, value] = cookie.trim().split('=');
if (key && value) {
acc[key] = value;
const trimmed = cookie.trim();
const firstEqualIndex = trimmed.indexOf('=');
if (firstEqualIndex > 0) {
const key = trimmed.substring(0, firstEqualIndex);
const value = trimmed.substring(firstEqualIndex + 1);
if (key && value) {
acc[key] = value;
}
}
return acc;
}, {} as Record<string, string>);
@@ -48,7 +55,14 @@ export function getAuthInfoFromBrowserCookie(): {
return null;
}
const decoded = decodeURIComponent(authCookie);
// 处理可能的双重编码
let decoded = decodeURIComponent(authCookie);
// 如果解码后仍然包含 %,说明是双重编码,需要再次解码
if (decoded.includes('%')) {
decoded = decodeURIComponent(decoded);
}
const authData = JSON.parse(decoded);
return authData;
} catch (error) {

View File

@@ -180,6 +180,41 @@ export class RedisStorage implements IStorage {
return exists === 1;
}
// 修改用户密码
async changePassword(userName: string, newPassword: string): Promise<void> {
// 简单存储明文密码,生产环境应加密
await withRetry(() =>
this.client.set(this.userPwdKey(userName), newPassword)
);
}
// 删除用户及其所有数据
async deleteUser(userName: string): Promise<void> {
// 删除用户密码
await withRetry(() => this.client.del(this.userPwdKey(userName)));
// 删除搜索历史
await withRetry(() => this.client.del(this.shKey(userName)));
// 删除播放记录
const playRecordPattern = `u:${userName}:pr:*`;
const playRecordKeys = await withRetry(() =>
this.client.keys(playRecordPattern)
);
if (playRecordKeys.length > 0) {
await withRetry(() => this.client.del(playRecordKeys));
}
// 删除收藏夹
const favoritePattern = `u:${userName}:fav:*`;
const favoriteKeys = await withRetry(() =>
this.client.keys(favoritePattern)
);
if (favoriteKeys.length > 0) {
await withRetry(() => this.client.del(favoriteKeys));
}
}
// ---------- 搜索历史 ----------
private shKey(user: string) {
return `u:${user}:sh`; // u:username:sh

View File

@@ -48,6 +48,10 @@ export interface IStorage {
verifyUser(userName: string, password: string): Promise<boolean>;
// 检查用户是否存在(无需密码)
checkUserExist(userName: string): Promise<boolean>;
// 修改用户密码
changePassword(userName: string, newPassword: string): Promise<void>;
// 删除用户(包括密码、搜索历史、播放记录、收藏夹)
deleteUser(userName: string): Promise<void>;
// 搜索历史相关
getSearchHistory(userName: string): Promise<string[]>;