diff --git a/Server/src/APIs/Console/SetBlogPasswd.ts b/Server/src/APIs/Console/SetBlogPasswd.ts new file mode 100644 index 0000000..42e7a86 --- /dev/null +++ b/Server/src/APIs/Console/SetBlogPasswd.ts @@ -0,0 +1,24 @@ +import { API } from "../../Plugs/API/API"; +import ServerStdResponse from "../../ServerStdResponse"; +import MySQLConnection from '../../Plugs/MySQLConnection' +import Auth from "../../Plugs/Middleware/Auth"; +import crypto from 'crypto' + +// 设置博客密码 +class SetBlogPasswd extends API { + constructor() { + super('POST', '/console/setBlogPasswd', Auth); + } + + public async onRequset(data: any, res: any) { + let { uuid, passwd } = data; + if (!uuid || !passwd) { + return res.json(ServerStdResponse.PARAMS_MISSING); + } + const encrypt_p = crypto.createHash('sha256').update(passwd).digest('hex'); + MySQLConnection.execute('UPDATE blog SET encrypt_p = ? WHERE uuid = ?', [encrypt_p, uuid]); + return res.json({ ...ServerStdResponse.OK }); + } +} + +export default SetBlogPasswd; \ No newline at end of file diff --git a/Server/src/APIs/GetBlogContent.ts b/Server/src/APIs/GetBlogContent.ts index cc5e67c..45999ce 100644 --- a/Server/src/APIs/GetBlogContent.ts +++ b/Server/src/APIs/GetBlogContent.ts @@ -3,29 +3,52 @@ import ServerStdResponse from "../ServerStdResponse"; import MySQLConnection from '../Plugs/MySQLConnection' import { Buffer } from 'buffer'; import axios from "axios"; - +import crypto from 'crypto' +import MountIP from "../Plugs/Middleware/MountIP"; // 获取博客内容 class GetBlogContent extends API { constructor() { - super('GET', '/blogContent'); + super('GET', '/blogContent', MountIP); } - private defaultAccessLevel = 6; + private AccessLevelRule = { + allow: [8, 10], + encrypt_allow: [7, 9] + }; public async onRequset(data: any, res: any) { - let { bloguuid } = data; + let { bloguuid, passwd } = data; if (!bloguuid || bloguuid.length != 32) { return res.json(ServerStdResponse.INVALID_PARAMS); } - let blogContentRes = await MySQLConnection.execute('SELECT * from blog WHERE access_level > ? AND uuid = ? ', [this.defaultAccessLevel, bloguuid]); + let blogContentRes = await MySQLConnection.execute(`SELECT * from blog WHERE access_level in (${this.AccessLevelRule.allow.join(',')}) AND uuid = ? `, [bloguuid]); if (!blogContentRes) { this.logger.error('查询时数据库发生错误'); return res.json(ServerStdResponse.SERVER_ERROR); } - if (blogContentRes.length != 1) { - this.logger.warn('查询的博客不存在或不可见', bloguuid); - return res.json(ServerStdResponse.BLOG.NOTFOUND); + if (blogContentRes.length == 0) { + // 公开范围不可见,查询允许无连接加密查看的数据 + blogContentRes = await MySQLConnection.execute(`SELECT * from blog WHERE access_level in (${this.AccessLevelRule.encrypt_allow.join(',')}) AND uuid = ? `, [bloguuid]); + if (!blogContentRes) { + this.logger.error('查询时数据库发生错误'); + return res.json(ServerStdResponse.SERVER_ERROR); + } + if (blogContentRes.length != 1) { + this.logger.warn('查询的博客不存在或不可见', bloguuid); + return res.json(ServerStdResponse.BLOG.NOTFOUND); + } + + // 验证密码是否存在和正确 + if (!passwd) { + this.logger.warn(`客户端[${data._ip}]尝试访问受限制的博客,但并未提供密码`) + return res.json(ServerStdResponse.BLOG.PROTECT_FLAG) + } + if (crypto.createHash('sha256').update(passwd).digest('hex') != blogContentRes[0].encrypt_p){ + this.logger.warn(`客户端[${data._ip}]尝试访问受限制的博客,并提供了错误的密码:${passwd}`) + return res.json(ServerStdResponse.BLOG.PASSWD_ERROR) + } + this.logger.info(`客户端[${data._ip}]访问了受限制的博客`) } // 返回处理后的数据 try { @@ -33,7 +56,8 @@ class GetBlogContent extends API { const response = await axios.get(markdownUrl); const base64Content = Buffer.from(response.data, 'utf-8').toString('base64'); - MySQLConnection.execute('UPDATE blog SET visit_count = visit_count + 1 WHERE uuid = ?', [bloguuid]); + // 访问次数+1 + // MySQLConnection.execute('UPDATE blog SET visit_count = visit_count + 1 WHERE uuid = ?', [bloguuid]); return res.json({ ...ServerStdResponse.OK, data: { data: base64Content, diff --git a/Server/src/APIs/GetBlogList.ts b/Server/src/APIs/GetBlogList.ts index 0b07917..39d9b3b 100644 --- a/Server/src/APIs/GetBlogList.ts +++ b/Server/src/APIs/GetBlogList.ts @@ -7,10 +7,10 @@ class GetBlogList extends API { constructor() { super('GET', '/blogList'); } - private defaultAccessLevel = 6; + private defaultAccessLevel = 9; public async onRequset(data: any, res: any) { - let blogListRes = await MySQLConnection.execute('SELECT uuid, title, description, publish_time, visit_count, like_count from blog WHERE access_level > ? ORDER BY publish_time DESC',[this.defaultAccessLevel]); + let blogListRes = await MySQLConnection.execute('SELECT uuid, title, description, publish_time, visit_count, like_count from blog WHERE access_level >= ? ORDER BY publish_time DESC',[this.defaultAccessLevel]); if(!blogListRes){ this.logger.error('查询时数据库发生错误'); return res.json(ServerStdResponse.SERVER_ERROR); diff --git a/Server/src/Plugs/Middleware/MountIP.ts b/Server/src/Plugs/Middleware/MountIP.ts index 9040031..838d488 100644 --- a/Server/src/Plugs/Middleware/MountIP.ts +++ b/Server/src/Plugs/Middleware/MountIP.ts @@ -4,7 +4,7 @@ const logger = new Logger('MountIP') let MountIP = (req: Request, res: Response, next: NextFunction) => { req.body._ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.ip; - logger.info(`[${req.method}][${req.url.split('?')[0]}] IP解析成功:${req.body._ip}`); + // logger.info(`[${req.method}][${req.url.split('?')[0]}] IP解析成功:${req.body._ip}`); next(); } diff --git a/Server/src/Server/Server.ts b/Server/src/Server/Server.ts index 61d2b49..305aaac 100644 --- a/Server/src/Server/Server.ts +++ b/Server/src/Server/Server.ts @@ -19,6 +19,7 @@ import CheckCaptcha from "../APIs/CheckCaptcha"; import Login from "../APIs/Console/Login"; import GetResources from "../APIs/Console/GetResources"; import GetBlogs from '../APIs/Console/GetBlogs' +import SetBlogPasswd from "../APIs/Console/SetBlogPasswd"; import SaveResource from '../APIs/Console/SaveResource' import DelResource from '../APIs/Console/DelResource' import SaveBlog from '../APIs/Console/SaveBlog' @@ -52,6 +53,7 @@ class Server { this.apiLoader.add(DelResource); this.apiLoader.add(GetBlogs) this.apiLoader.add(SaveBlog); + this.apiLoader.add(SetBlogPasswd); this.apiLoader.add(DelBlog); this.apiLoader.add(GetOSSToken); diff --git a/Server/src/ServerStdResponse.ts b/Server/src/ServerStdResponse.ts index 810d09c..af478b4 100644 --- a/Server/src/ServerStdResponse.ts +++ b/Server/src/ServerStdResponse.ts @@ -27,6 +27,14 @@ const ServerStdResponse = { NOTFOUND: { code: -4001, message: 'Blog not found' + }, + PROTECT_FLAG: { + code: -4002, + message: 'Blog is protected, need password' + }, + PASSWD_ERROR: { + code: -4003, + message: 'Blog is protected, and password is not right' } }, CAPTCHA: { @@ -48,7 +56,7 @@ const ServerStdResponse = { code: -6000, message: 'user is not found' }, - PASSWORD_ERROR:{ + PASSWORD_ERROR: { code: -6001, message: 'user password is error' } diff --git a/tonecn/components.d.ts b/tonecn/components.d.ts index 432f4bf..6a224d7 100644 --- a/tonecn/components.d.ts +++ b/tonecn/components.d.ts @@ -36,6 +36,7 @@ declare module 'vue' { ElTable: typeof import('element-plus/es')['ElTable'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] ElText: typeof import('element-plus/es')['ElText'] + ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElUpload: typeof import('element-plus/es')['ElUpload'] FileOnline: typeof import('./src/components/Console/FileOnline.vue')['default'] Footer: typeof import('./src/components/Common/Footer.vue')['default'] diff --git a/tonecn/src/components/Console/Blogs.vue b/tonecn/src/components/Console/Blogs.vue index 74bb191..b5b1d9e 100644 --- a/tonecn/src/components/Console/Blogs.vue +++ b/tonecn/src/components/Console/Blogs.vue @@ -1,7 +1,7 @@