commit 861a689759c7f552b5cc83e81ef9ea0836ee10b6 Author: CancerAi Date: Sun Oct 11 18:01:11 2026 +0800 add: 用户鉴权和查询所有用户接口 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a14702c --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# dependencies (bun install) +node_modules + +# output +out +dist +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +_.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..c74b939 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# user-auth + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.ts +``` + +This project was created using `bun init` in bun v1.4.2. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime. diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..3f3fc49 --- /dev/null +++ b/bun.lock @@ -0,0 +1,71 @@ +{ + "lockfileVersion": 2, + "configVersion": 1, + "workspaces": { + "": { + "name": "user-auth", + "dependencies": { + "hono": "^4.13.13", + }, + "devDependencies": { + "@types/bun": "latest", + }, + "peerDependencies": { + "typescript": "^7", + }, + }, + }, + "packages": { + "@types/bun": ["@types/bun@1.4.2", "", { "dependencies": { "bun-types": "1.4.2" } }, "sha512-GimotNn7+ZV0uVArItBbriZsR1oNf0+WTzPkdcFrzShI7k2norL0uzEaJT8T33dWr7O/c9ZDuAFQrctKCi72oQ=="], + + "@types/node": ["@types/node@26.6.5", "", { "dependencies": { "undici-types": "~8.9.0" } }, "sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg=="], + + "@typescript/typescript-aix-ppc64": ["@typescript/typescript-aix-ppc64@7.0.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ=="], + + "@typescript/typescript-darwin-arm64": ["@typescript/typescript-darwin-arm64@7.0.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA=="], + + "@typescript/typescript-darwin-x64": ["@typescript/typescript-darwin-x64@7.0.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA=="], + + "@typescript/typescript-freebsd-arm64": ["@typescript/typescript-freebsd-arm64@7.0.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ=="], + + "@typescript/typescript-freebsd-x64": ["@typescript/typescript-freebsd-x64@7.0.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw=="], + + "@typescript/typescript-linux-arm": ["@typescript/typescript-linux-arm@7.0.2", "", { "os": "linux", "cpu": "arm" }, "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ=="], + + "@typescript/typescript-linux-arm64": ["@typescript/typescript-linux-arm64@7.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ=="], + + "@typescript/typescript-linux-loong64": ["@typescript/typescript-linux-loong64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ=="], + + "@typescript/typescript-linux-mips64el": ["@typescript/typescript-linux-mips64el@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA=="], + + "@typescript/typescript-linux-ppc64": ["@typescript/typescript-linux-ppc64@7.0.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA=="], + + "@typescript/typescript-linux-riscv64": ["@typescript/typescript-linux-riscv64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ=="], + + "@typescript/typescript-linux-s390x": ["@typescript/typescript-linux-s390x@7.0.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw=="], + + "@typescript/typescript-linux-x64": ["@typescript/typescript-linux-x64@7.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A=="], + + "@typescript/typescript-netbsd-arm64": ["@typescript/typescript-netbsd-arm64@7.0.2", "", { "os": "none", "cpu": "arm64" }, "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA=="], + + "@typescript/typescript-netbsd-x64": ["@typescript/typescript-netbsd-x64@7.0.2", "", { "os": "none", "cpu": "x64" }, "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA=="], + + "@typescript/typescript-openbsd-arm64": ["@typescript/typescript-openbsd-arm64@7.0.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ=="], + + "@typescript/typescript-openbsd-x64": ["@typescript/typescript-openbsd-x64@7.0.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg=="], + + "@typescript/typescript-sunos-x64": ["@typescript/typescript-sunos-x64@7.0.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g=="], + + "@typescript/typescript-win32-arm64": ["@typescript/typescript-win32-arm64@7.0.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ=="], + + "@typescript/typescript-win32-x64": ["@typescript/typescript-win32-x64@7.0.2", "", { "os": "win32", "cpu": "x64" }, "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g=="], + + "bun-types": ["bun-types@1.4.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-bxV1FgK7yBIzjRe5zBozIM4Bem11ZJcCXSrjWRG3YWLt8yFDePu4cLjpebO8OvPeIE9trbyPF4fuj3Cia4Fj3w=="], + + "hono": ["hono@4.13.13", "", {}, "sha512-CQ46U0ZkAGmbT/4UxdzzGJpacP2IeKgY4a5/tOI9AABbpOMfK739wfDXmv1usCk+3RkKj1hQy4/fjhiwa2xlrA=="], + + "typescript": ["typescript@7.0.2", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.2", "@typescript/typescript-darwin-arm64": "7.0.2", "@typescript/typescript-darwin-x64": "7.0.2", "@typescript/typescript-freebsd-arm64": "7.0.2", "@typescript/typescript-freebsd-x64": "7.0.2", "@typescript/typescript-linux-arm": "7.0.2", "@typescript/typescript-linux-arm64": "7.0.2", "@typescript/typescript-linux-loong64": "7.0.2", "@typescript/typescript-linux-mips64el": "7.0.2", "@typescript/typescript-linux-ppc64": "7.0.2", "@typescript/typescript-linux-riscv64": "7.0.2", "@typescript/typescript-linux-s390x": "7.0.2", "@typescript/typescript-linux-x64": "7.0.2", "@typescript/typescript-netbsd-arm64": "7.0.2", "@typescript/typescript-netbsd-x64": "7.0.2", "@typescript/typescript-openbsd-arm64": "7.0.2", "@typescript/typescript-openbsd-x64": "7.0.2", "@typescript/typescript-sunos-x64": "7.0.2", "@typescript/typescript-win32-arm64": "7.0.2", "@typescript/typescript-win32-x64": "7.0.2" }, "bin": { "tsc": "bin/tsc" } }, "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA=="], + + "undici-types": ["undici-types@8.9.0", "", {}, "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg=="], + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..e4eb7e4 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "user-auth", + "module": "index.ts", + "type": "module", + "private": true, + "scripts": { + "dev": "bun run --hot src/index.js" + }, + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^7" + }, + "dependencies": { + "hono": "^4.13.13" + } +} diff --git a/sql/init_mock_data.sql b/sql/init_mock_data.sql new file mode 100644 index 0000000..6f5511c --- /dev/null +++ b/sql/init_mock_data.sql @@ -0,0 +1,9 @@ +-- 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 new file mode 100644 index 0000000..75d8306 --- /dev/null +++ b/sql/init_table.sql @@ -0,0 +1,16 @@ +drop table if exists user; +drop table if exists admin; + +create table user( + id varchar(100) primary key not null, + name varchar(50) not null, + passwd varchar(120), + create_time datetime not null, + update_time datetime +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; -- 大小写敏感 + +create table admin( + id integer primary key auto_increment, + name varchar(50) not null, + passwd varchar(120) not null +); diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..61e089c --- /dev/null +++ b/src/index.ts @@ -0,0 +1,129 @@ +import { sql, SQL } from "bun"; +import { Hono } from "hono"; +import { validator } from "hono/validator"; +import { checkAdmin } from "./utils/admin"; +import { checkUser } from "./utils/user"; + +const appTmp = new Hono() +const app = appTmp.basePath("/auth") +const db = new SQL({ + "adapter": "mariadb", + "host": "localhost", + "user": "root", + "password": "root", + "database": "user_auth", + "allowPublicKeyRetrieval": true +}) + +// 鉴权 +app.get( + "/", + validator("query", async (val, c) => { + const name = val.name ?? "" + const passwd = val.passwd ?? "" + // 判空 + if (name == null || + name == "" || + passwd == null || + passwd == "" + ) { + 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": "用户验证失败" + }) + } + }), + (c) => { + return c.json({ + "code": 200, + "msg": "ok" + }) + }) + +// 查询所有用户 +app.get( + "/user", + validator("query", async (val, c) => { + const adminName = val.admin_name ?? "" + const adminPasswd = val.admin_passwd ?? "" + // 判空 + if (adminName == null || + adminName == "" || + adminPasswd == null || + adminPasswd == "" + ) { + c.status(401) + return c.json({ + "msg": "需要提供管理员信息字段: admin_name, admin_passwd" + }) + } + + // 验证是否是合法管理员 + const re = await checkAdmin(db, adminName.toString(), adminPasswd.toString()) + if (re) { + return val + } else { + c.status(401) + return c.json({ + "msg": "管理员验证失败" + }) + } + }), + 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"], + }) + }); + 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 + +// await db`` +// return c.json({}) +// }) + +export default { + port: 8080, + fetch: app.fetch +} \ No newline at end of file diff --git a/src/utils/admin.ts b/src/utils/admin.ts new file mode 100644 index 0000000..11d8b00 --- /dev/null +++ b/src/utils/admin.ts @@ -0,0 +1,14 @@ +import type { SQL } from "bun"; + +export async function checkAdmin( + db: SQL, + name: String, + passwd: String +): Promise { + interface adminDTO { + name: String, + passwd: String + } + const rows: adminDTO[] = await db`select * from admin where name = ${name} and passwd = ${passwd}` + return rows.length == 0 ? false : true +} \ No newline at end of file diff --git a/src/utils/user.ts b/src/utils/user.ts new file mode 100644 index 0000000..d84dd01 --- /dev/null +++ b/src/utils/user.ts @@ -0,0 +1,13 @@ +import type { SQL } from "bun"; + +export async function checkUser( + db: SQL, + name: String, + passwd: String +) { + interface userDTO { + name: String, + } + const rows: userDTO[] = await db`select name from user where name = ${name} and passwd = ${passwd}` + return rows.length == 0 ? false : true +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..b2e7497 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + // Environment setup & latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "Preserve", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + "types": ["bun"], + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +}