From b43c31a12b6412e2a668248c72b7f9afd755380d Mon Sep 17 00:00:00 2001 From: CancerAi Date: Sun, 11 Oct 2026 21:58:58 +0800 Subject: [PATCH] =?UTF-8?q?fea:=20=E5=AE=8C=E6=88=90=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=94=A8=E6=88=B7=EF=BC=8C=E6=9F=A5=E8=AF=A2=E7=94=A8=E6=88=B7?= =?UTF-8?q?=EF=BC=8C=E9=89=B4=E6=9D=83=EF=BC=8C=E5=92=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/init_mock_data.sql | 9 -- sql/init_table.sql | 6 +- src/const/response_str.ts | 13 +++ src/index.ts | 197 ++++++++++++++++++++++++++++---------- src/utils/admin.ts | 15 +-- src/utils/user.ts | 70 ++++++++++++-- 6 files changed, 236 insertions(+), 74 deletions(-) delete mode 100644 sql/init_mock_data.sql create mode 100644 src/const/response_str.ts diff --git a/sql/init_mock_data.sql b/sql/init_mock_data.sql deleted file mode 100644 index 6f5511c..0000000 --- a/sql/init_mock_data.sql +++ /dev/null @@ -1,9 +0,0 @@ --- insert normal user -insert into user(id, name, passwd, create_time, update_time) -values -("01", "XiaoAi", "abcd", "2026-01-01", "2026-01-01"), -("02", "XiaoMing", "abce", "2026-01-02", "2026-01-02"), -("03", "CancerAi", "abcf", "2026-01-02", "2026-01-02"); - --- insert admin user -insert into admin(name, passwd) values ("admin", "admin"); diff --git a/sql/init_table.sql b/sql/init_table.sql index 75d8306..ac27c17 100644 --- a/sql/init_table.sql +++ b/sql/init_table.sql @@ -2,7 +2,7 @@ drop table if exists user; drop table if exists admin; create table user( - id varchar(100) primary key not null, + id integer primary key not null auto_increment, name varchar(50) not null, passwd varchar(120), create_time datetime not null, @@ -14,3 +14,7 @@ create table admin( name varchar(50) not null, passwd varchar(120) not null ); + +-- 默认管理员账号 "admin",密码 "admin" +-- 仅开发,测试环境用 +-- insert into admin(name, passwd) values("admin", "$argon2id$v=19$m=65536,t=2,p=1$B7OnAywQYuZSYvu8twgQOo0VRrZjJBIMqezakOjkWgU$+0wIE/FR4rDBVQzAp+l7u1REi8/+tneNzSHhs2dd+n4"); diff --git a/src/const/response_str.ts b/src/const/response_str.ts new file mode 100644 index 0000000..e75db79 --- /dev/null +++ b/src/const/response_str.ts @@ -0,0 +1,13 @@ +export class responseStr { + static REQ_PARAM_ERR = '请求参数错误' + + static ADMIN_INVALID = "管理员验证失败" + + static USER_INVALID = "用户验证失败" + static USER_NAME_LENGTH_LIMIT = "用户名长度应在1~10之间" + static USER_PASSWORD_LENGTH_LIMIT = "用户密码长度应在1~30之间" + static USER_EXISTS = "用户已存在" + static USER_ADD_OK = "用户添加成功" + + static SERVER_INTERNAL_ERR = "服务器内部错误" +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 61e089c..dc58183 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,7 +2,8 @@ import { sql, SQL } from "bun"; import { Hono } from "hono"; import { validator } from "hono/validator"; import { checkAdmin } from "./utils/admin"; -import { checkUser } from "./utils/user"; +import { addUser, checkUser, getAllUser } from "./utils/user"; +import { responseStr } from "./const/response_str"; const appTmp = new Hono() const app = appTmp.basePath("/auth") @@ -29,27 +30,28 @@ app.get( ) { c.status(401) return c.json({ - "msg": "需要提供用户信息字段: name, passwd" - }) - } - - // 验证是否是合法用户 - const re = await checkUser(db, name.toString(), passwd.toString()) - if (re) { - return val - } else { - c.status(401) - return c.json({ - "msg": "用户验证失败" + "msg": responseStr.REQ_PARAM_ERR }) } }), - (c) => { + async (c) => { + const req = c.req.query() + const name = req.name ?? "" + const passwd = req.passwd ?? "" + const re = await checkUser(db, name.toString(), passwd.toString()) + if (!re) { + c.status(401) + return c.json({ + "msg": responseStr.USER_INVALID + }) + } + return c.json({ "code": 200, "msg": "ok" }) - }) + } +) // 查询所有用户 app.get( @@ -65,7 +67,7 @@ app.get( ) { c.status(401) return c.json({ - "msg": "需要提供管理员信息字段: admin_name, admin_passwd" + "msg": responseStr.REQ_PARAM_ERR }) } @@ -76,52 +78,145 @@ app.get( } else { c.status(401) return c.json({ - "msg": "管理员验证失败" + "msg": responseStr.ADMIN_INVALID }) } }), async (c) => { - const rows = await db`select name, token, create_time, update_time from user` - interface userDTO { - name: String, - token: String, - create_time: Date, - update_time: Date, - } - let re: userDTO[] = [] - rows.forEach((ele: { [x: string]: any; }) => { - re.push({ - "name": ele["name"], - "token": ele["token"], - "create_time": ele["create_time"], - "update_time": ele["update_time"], - }) - }); + const re = await getAllUser(db) return c.json({ "msg": "ok", "data": re }) - }) + } +) // 添加用户 -// app.post("/user", -// validator("json", (val, c) => { -// if (val.auth_name == null || val.auth_passwd == null) { -// c.status(400) -// return c.json({ -// "code": 400, -// "msg": "Parameter is invalid" -// }) -// } -// }), -// async (c) => { -// const req = await c.req.json() -// const auth_name = req.auth_name -// const auth_passwd = req.auth_passwd +app.post( + "/user", + validator("json", (val, c) => { + if ( + val.name == null || + val.name == "" || + val.passwd == null || + val.passwd == "" + ) { + c.status(400) + c.status(400) + return c.json({ + "code": 400, + "msg": responseStr.REQ_PARAM_ERR + }) + } else { + return val + } + }), + async (c) => { + const reqHeader = c.req.query() + const adminName = reqHeader.admin_name ?? "" + const adminPasswd = reqHeader.admin_passwd ?? "" + if (!(await checkAdmin(db, adminName, adminPasswd))) { + c.status(401) + return c.json({ + "code": 401, + "msg": responseStr.ADMIN_INVALID + }) + } -// await db`` -// return c.json({}) -// }) + const req = await c.req.json() + const name: string = req.name ?? "" + const passwd: string = req.passwd ?? "" + + + if (name.length <= 0 || name.length >= 11) { + c.status(400) + return c.json({ + "code": 400, + "msg": responseStr.USER_NAME_LENGTH_LIMIT + }) + } + + if (passwd.length <= 0 || passwd.length >= 31) { + c.status(400) + return c.json({ + "code": 400, + "msg": responseStr.USER_NAME_LENGTH_LIMIT + }) + } + + const re = await addUser(db, name, passwd) + if (re.state != 0) { + c.status(500) + return c.json({ + "code": 500, + "msg": re.msg + }) + } + return c.json({ + "code": 200, + "msg": "ok" + }) + } +) + + +// 添加管理员 +app.post( + "/admin", + validator("json", (val, c) => { + if ( + val.name == null || + val.name == "" || + val.passwd == null || + val.passwd == "" + ) { + c.status(400) + c.status(400) + return c.json({ + "code": 400, + "msg": responseStr.REQ_PARAM_ERR + }) + } else { + return val + } + }), + async (c) => { + const req = await c.req.json() + const name: string = req.name ?? "" + const passwd: string = req.passwd ?? "" + + if (name.length <= 0 || name.length >= 11) { + c.status(400) + return c.json({ + "code": 400, + "msg": responseStr.USER_NAME_LENGTH_LIMIT + }) + } + + if (passwd.length <= 0 || passwd.length >= 31) { + c.status(400) + return c.json({ + "code": 400, + "msg": responseStr.USER_NAME_LENGTH_LIMIT + }) + } + + const encryptPasswd = await Bun.password.hash(passwd) + try { + await db`insert into admin(name, passwd) values(${name}, ${encryptPasswd})` + } catch (e) { + c.status(500) + return c.json({ + "code": 500, + "msg": responseStr.SERVER_INTERNAL_ERR + }) + } + return c.json({ + "code": 200, + "msg": "ok" + }) + } +) export default { port: 8080, diff --git a/src/utils/admin.ts b/src/utils/admin.ts index 11d8b00..95fc76f 100644 --- a/src/utils/admin.ts +++ b/src/utils/admin.ts @@ -2,13 +2,16 @@ import type { SQL } from "bun"; export async function checkAdmin( db: SQL, - name: String, - passwd: String + name: string, + passwd: string ): Promise { interface adminDTO { - name: String, - passwd: String + name: string, + passwd: string } - const rows: adminDTO[] = await db`select * from admin where name = ${name} and passwd = ${passwd}` - return rows.length == 0 ? false : true + const rows: adminDTO[] = await db`select passwd from admin where name = ${name}` + if (rows.length == 0) { + return false + } + return await Bun.password.verify(passwd, rows[0]!["passwd"]) } \ No newline at end of file diff --git a/src/utils/user.ts b/src/utils/user.ts index d84dd01..001e903 100644 --- a/src/utils/user.ts +++ b/src/utils/user.ts @@ -1,13 +1,69 @@ -import type { SQL } from "bun"; +import type { BlobOrStringOrBuffer, SQL } from "bun"; +import { responseStr } from "../const/response_str"; + +async function checkUserIfExists(db: SQL, name: string): Promise { + const rows = await db`select name from user where name = ${name}` + return rows.length == 0 ? false : true +} + +// 返回state为0添加成功,非0添加失败 +export async function addUser(db: SQL, name: string, passwd: string): Promise<{ state: number, msg: string }> { + // 检查用户是否存在 + if (await checkUserIfExists(db, name)) { + return { + "state": -1, + "msg": responseStr.USER_EXISTS + } + } + + const encryptPasswd = await Bun.password.hash(passwd) + await db`insert into user(name, passwd, create_time) values(${name}, ${encryptPasswd}, NOW())` + return { + "state": 0, + "msg": responseStr.USER_ADD_OK + } +} export async function checkUser( db: SQL, - name: String, - passwd: String -) { + name: string, + passwd: string +): Promise { interface userDTO { - name: String, + name: string, + passwd: string } - const rows: userDTO[] = await db`select name from user where name = ${name} and passwd = ${passwd}` - return rows.length == 0 ? false : true + + if (!await checkUserIfExists(db, name)) { + return false; + } + + const queryPasswd = (await db`select passwd from user where name = ${name}`)[0]["passwd"] + if (!await Bun.password.verify(passwd, queryPasswd)) { + return false + } + return true +} + +export async function getAllUser( + db: SQL +) { + const rows = await db`select name, passwd, create_time, update_time from user` + interface userDTO { + name: string, + passwd: string, + create_time: Date, + update_time: Date, + } + let re: userDTO[] = [] + rows.forEach((ele: { [x: string]: any; }) => { + re.push({ + "name": ele["name"], + "passwd": ele["passwd"], + "create_time": ele["create_time"], + "update_time": ele["update_time"], + }) + }); + + return re } \ No newline at end of file