feat: 完成用户鉴权相关api

This commit is contained in:
539943419 committed 2025-01-13 17:22:52 +08:00
1 parent 79cc9c34d6
commit 4c69f57aaa
22 files changed
+903 -68

No files matched your search

-4
View File
@@ -1,4 +0,0 @@
export default defineEventHandler(async (event) => {
const body = await readBody(event)
return
})
+84
View File
@@ -0,0 +1,84 @@
// editPost.ts
import DB from 'better-sqlite3';
import cacheResult from '~/server/utils/cacheRes';
function prepareDB() {
const db = new DB('./userData/db/posts.db');
const updatePostStmt = db.prepare(`
UPDATE posts
SET title = ?, summary = ?, type = ?, url = ?, date = ?, tag_id = ?
WHERE id = ?
`);
const updateContentStmt = db.prepare(`
UPDATE postContent
SET content = ?
WHERE id = ?
`);
const updateTagsStmt = db.prepare(`
UPDATE tags
SET tag1 = ?, tag2 = ?, tag3 = ?, tag4 = ?, tag5 = ?,
tag6 = ?, tag7 = ?, tag8 = ?, tag9 = ?, tag10 = ?,
tag11 = ?, tag12 = ?, tag13 = ?, tag14 = ?, tag15 = ?
WHERE id = ?
`);
const insertTagsStmt = db.prepare(`
INSERT INTO tags (tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9, tag10, tag11, tag12, tag13, tag14, tag15)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
return { updatePostStmt, updateContentStmt, updateTagsStmt, insertTagsStmt, db };
}
export default defineEventHandler(async (event) => {
const { updatePostStmt, updateContentStmt, updateTagsStmt, insertTagsStmt, db } = cacheResult(prepareDB)();
const body = await readBody(event);
const { id, title, summary, tags: _tags, type, url, date, content } = body;
if ([id, title, summary, _tags, type, url, date, content].some(item => item === undefined)) {
return {
code: 400,
msg: '参数错误',
body
}
}
const tagsArray = Array.isArray(_tags) ? _tags : [_tags];
const tags = tagsArray.slice(0, 15).concat(new Array(15 - tagsArray.length).fill(null));
try {
db.transaction(() => {
// 检查是否存在tag_id,如果不存在则插入新标签
const tagRow: any = db.prepare(`SELECT tag_id FROM posts WHERE id = ?`).get(id);
if (tagRow.tag_id) {
// 更新现有标签
updateTagsStmt.run(...tags, tagRow.tag_id);
} else {
// 插入新标签并获取tag_id
const tagResult = insertTagsStmt.run(...tags);
const tagId = tagResult.lastInsertRowid;
// 更新posts表中的tag_id
updatePostStmt.run(title, summary, type, url, date, tagId, id);
}
// 更新posts表
updatePostStmt.run(title, summary, type, url, date, tagRow.tag_id, id);
// 更新postContent表
updateContentStmt.run(content, id);
})();
return {
code: 200,
msg: '更新成功'
};
} catch (error) {
console.error('更新数据时出错:', error);
return {
code: 500,
msg: '服务器内部错误'
};
}
});
+33 -2
View File
@@ -1,8 +1,39 @@
// @ts-ignore
import testData from "~/public/testData/test.md"
import DB from 'better-sqlite3';
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const data = testData
return { data, title: `测试标题::{${body.id}}` }
const id = body.id;
if (!id || isNaN(Number(id))) {
return {
code: 400,
msg: '无效的id'
};
}
const db = new DB('./userData/db/posts.db');
const post: any = db.prepare('SELECT * FROM posts WHERE id = ?').get(Number(id));
const content: any = db.prepare('SELECT content FROM postContent WHERE id = ?').get(Number(id));
db.close();
if (!post) {
return {
code: 404,
msg: '文章不存在'
};
}
if (!content) {
return {
code: 404,
msg: '文章内容不存在'
};
}
return {
code: 200,
data: content.content,
title: post.title
};
})
+33 -20
View File
@@ -1,22 +1,35 @@
import type { postItem } from "~/types/post";
import { defineEventHandler } from 'h3';
import DB from 'better-sqlite3';
function generateFakeData(length: number) {
const data: postItem[] = [];
for (let i = 0; i < length; i++) {
data.push({
id: i,
title: `测试标题`,
summary: `测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要`,
type: 'markdown',
tags: ['test', 'test1'],
url: '',
date: parseInt(new Date().getTime().toFixed()),
});
}
return data;
}
export default defineEventHandler(async (event) => {
const db = new DB('./userData/db/posts.db');
export default defineEventHandler((event) => {
const data = generateFakeData(50)
return data
})
// 获取所有标签
const tagsMap = new Map<number, string[]>();
const tagsRows = db.prepare('SELECT id, tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9, tag10, tag11, tag12, tag13, tag14, tag15 FROM tags').all();
tagsRows.forEach((row: any) => {
const tags = [];
for (let i = 1; i <= 15; i++) {
const tag = row[`tag${i}`];
if (tag) {
tags.push(tag);
}
}
tagsMap.set(row.id, tags);
});
// 获取所有文章
const posts = db.prepare('SELECT id, title, summary, type, tag_id, url, date FROM posts').all();
// 替换tag_id为标签数组
posts.forEach((post: any) => {
post.tags = tagsMap.get(post.tag_id) || [];
});
db.close();
return {
code: 200,
data: posts
};
});
+69
View File
@@ -0,0 +1,69 @@
import DB from 'better-sqlite3';
import cacheResult from '~/server/utils/cacheRes';
function prepareDB() {
const db = new DB('./userData/db/posts.db');
const insertPostStmt = db.prepare(`
INSERT INTO posts (title, summary, type, url, date, tag_id)
VALUES (?, ?, ?, ?, ?, ?)
`);
const insertContentStmt = db.prepare(`
INSERT INTO postContent (id, content)
VALUES (?, ?)
`);
const insertTagsStmt = db.prepare(`
INSERT INTO tags (tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9, tag10, tag11, tag12, tag13, tag14, tag15)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
return { db, insertPostStmt, insertContentStmt, insertTagsStmt };
}
export default defineEventHandler(async (event) => {
const { db, insertPostStmt, insertContentStmt, insertTagsStmt } = cacheResult(prepareDB)();
const body = await readBody(event);
const { title, summary, tags: _tags, type, url, date, content } = body;
if([title, summary, _tags, type, url, date, content].some(item => item === undefined)){
return {
code: 400,
msg: '参数错误',
body
}
}
// 确保_tags是一个数组
const tagsArray = Array.isArray(_tags) ? _tags : [_tags];
// 填充或截取前15个标签
const tags = tagsArray.slice(0, 15).concat(new Array(15 - tagsArray.length).fill(null));
try {
db.transaction(() => {
// 插入tags表
const tagResult = insertTagsStmt.run(...tags);
const tagId = tagResult.lastInsertRowid;
// 插入posts表
const postResult = insertPostStmt.run(title, summary, type, url, date, tagId);
const postId = postResult.lastInsertRowid;
// 插入postContent表
insertContentStmt.run(postId, content);
})();
return {
code: 200,
msg: '插入成功'
};
} catch (error) {
console.error('插入数据时出错:', error);
return {
code: 500,
msg: '服务器内部错误'
};
}
});
+1 -1
View File
@@ -1,5 +1,5 @@
import fs from 'fs';
import checkUserData from '~/server/utils/checkUserData';
import checkUserData from '~/server/utils/initUserData';
export default defineEventHandler((event) => {
checkUserData()
+27
View File
@@ -0,0 +1,27 @@
// import { defineEventHandler, readBody, createError } from 'h3';
import bcrypt from 'bcryptjs';
import BetterSqlite3 from 'better-sqlite3';
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { username, password } = body;
// 查询用户
const userDB = BetterSqlite3('./userData/db/user.db');
const user: any = userDB.prepare('SELECT * FROM user WHERE username = ?').get(username);
if (!user || password !== user.password) {
userDB.close();
throw createError({ statusCode: 401, statusMessage: 'Invalid username or password' });
}
// 更新最后登录时间
userDB.prepare('UPDATE user SET lastLoginTime = ? WHERE id = ?').run(Date.now(), user.id);
// 生成 JWT
const token = createToken(user.id);
userDB.close();
return { token , expiresIn: Date.now() + 168 * 60 * 60 * 1000 };
});
+20
View File
@@ -0,0 +1,20 @@
import { defineEventHandler, readBody, createError } from 'h3';
import jwt from 'jsonwebtoken';
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { token } = body;
const jwtSecret = getKey();
try {
// 验证旧的 Token
const decoded = jwt.verify(token, jwtSecret) as { userId: number };
// 生成新的 Token
const newToken = jwt.sign({ userId: decoded.userId }, jwtSecret, { expiresIn: '168h' });
return { token: newToken, expiresIn: Date.now() + 168 * 60 * 60 * 1000 };
} catch (err) {
throw createError({ statusCode: 401, statusMessage: 'Token invalid or expired', data: { err, token } });
}
});
+34
View File
@@ -0,0 +1,34 @@
import bcrypt from 'bcryptjs';
import BetterSqlite3 from 'better-sqlite3';
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { username, password } = body;
// 检查用户名是否已存在
const userDB = BetterSqlite3('./userData/db/user.db');
const existingUser = userDB.prepare('SELECT * FROM user WHERE username = ?').get(username);
if (existingUser) {
userDB.close();
throw createError({ statusCode: 400, statusMessage: 'Username already exists' });
}
// 哈希密码
// const salt = getKey().substring(0, 10);
// const hashedPassword = bcrypt.hashSync(password, salt);
const hashedPassword = password
// 插入新用户
const createTime = Date.now();
const lastLoginTime = createTime;
const stmt = userDB.prepare('INSERT INTO user (username, password, createTime, lastLoginTime) VALUES (?, ?, ?, ?)');
const result = stmt.run(username, hashedPassword, createTime, lastLoginTime);
// 生成 JWT
const userId = result.lastInsertRowid as number;
const token = createToken(userId);
userDB.close();
return { token, expiresIn: Date.now() + 168 * 60 * 60 * 1000 };
});
+31
View File
@@ -0,0 +1,31 @@
// import { defineEventHandler, readBody, createError } from 'h3';
import bcrypt from 'bcryptjs';
import BetterSqlite3 from 'better-sqlite3';
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { oldPassword, newPassword } = body;
const userId = event.context.user.id;
// 查询用户
const userDB = new BetterSqlite3('./userData/db/user.db');
const user: any = userDB.prepare('SELECT * FROM user WHERE id = ?').get(userId);
if (!user || !bcrypt.compareSync(oldPassword, user.password)) {
userDB.close();
throw createError({ statusCode: 401, statusMessage: 'Invalid old password' });
}
// 哈希新密码
const salt = bcrypt.genSaltSync(10);
const hashedPassword = bcrypt.hashSync(newPassword, salt);
// 更新密码
userDB.prepare('UPDATE user SET password = ? WHERE id = ?').run(hashedPassword, userId);
// 生成新的 JWT
const token = createToken(userId);
userDB.close();
return { token , expiresIn: Date.now() + 168 * 60 * 60 * 1000 };
});