diff --git a/.gitignore b/.gitignore index f85d509..20d47b9 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,7 @@ coverage # files created with miaoShare service temp miaoShare.db +addUser.js + +# JWT SK +*.key \ No newline at end of file diff --git a/miaoShareConfig.json b/miaoShareConfig.json index 3f33f53..2c993b2 100644 --- a/miaoShareConfig.json +++ b/miaoShareConfig.json @@ -1,3 +1,11 @@ { - "PORT":17057 + "PORT":17057, + "userGroupSetting":{ + "admin":{ + "cloudCapacity":2147483648 + }, + "guest":{ + "cloudCapacity":2147483648 + } + } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b389250..7023e6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "express": "^4.18.2", "file-saver": "^2.0.5", "js-base64": "^3.7.7", + "jsonwebtoken": "^9.0.2", + "node-cron": "^3.0.3", "pinia": "^2.1.7", "sm-crypto": "^0.3.13", "uuid": "^9.0.1", @@ -24,12 +26,13 @@ "ws": "^8.16.0" }, "devDependencies": { + "@vicons/fluent": "^0.12.0", "@vicons/ionicons5": "^0.12.0", "@vitejs/plugin-vue": "^5.0.3", "better-sqlite3": "^8.7.0", "concurrently": "^8.2.2", "cors": "^2.8.5", - "naive-ui": "^2.37.3", + "naive-ui": "^2.38.1", "vfonts": "^0.0.3", "vite": "^5.0.11" } @@ -656,6 +659,12 @@ "@types/lodash": "*" } }, + "node_modules/@vicons/fluent": { + "version": "0.12.0", + "resolved": "https://registry.npmmirror.com/@vicons/fluent/-/fluent-0.12.0.tgz", + "integrity": "sha512-ATCiqPuiJ6RI5GBlD3BIpZ9Xw4MsCA4RpI5oR6MCti4quS4mX1Gp6N74FCzw7lgOj+80rV4HMKhZTVInwimpVQ==", + "dev": true + }, "node_modules/@vicons/ionicons5": { "version": "0.12.0", "resolved": "https://registry.npmmirror.com/@vicons/ionicons5/-/ionicons5-0.12.0.tgz", @@ -889,6 +898,11 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz", @@ -1174,6 +1188,14 @@ "node": ">=8" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz", @@ -1577,6 +1599,51 @@ "resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmmirror.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", @@ -1589,11 +1656,45 @@ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", "dev": true }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmmirror.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -1690,9 +1791,9 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/naive-ui": { - "version": "2.37.3", - "resolved": "https://registry.npmmirror.com/naive-ui/-/naive-ui-2.37.3.tgz", - "integrity": "sha512-aUkHFXVIluSi8Me+npbcsdv1NYhVMj5t9YaruoCESlqmfqspj+R2QHEVXkTtUI1kQwVrABMCtAGq/wountqjZA==", + "version": "2.38.1", + "resolved": "https://registry.npmmirror.com/naive-ui/-/naive-ui-2.38.1.tgz", + "integrity": "sha512-AnU1FQ7K/CbhguAX++V4kCFjk7h7RvWt4nvZPRjORMpq+fUIlzD+EcQ5Cv1VqDloNF8+eMv4Akc2Ogacc9S+5A==", "dev": true, "dependencies": { "@css-render/plugin-bem": "^0.15.12", @@ -1756,6 +1857,25 @@ "node": ">=10" } }, + "node_modules/node-cron": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/node-cron/-/node-cron-3.0.3.tgz", + "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", + "dependencies": { + "uuid": "8.3.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/node-cron/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", @@ -2056,7 +2176,6 @@ "version": "7.6.0", "resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.0.tgz", "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -2581,8 +2700,7 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yargs": { "version": "17.7.2", diff --git a/package.json b/package.json index 17af1a2..967c93d 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,8 @@ "express": "^4.18.2", "file-saver": "^2.0.5", "js-base64": "^3.7.7", + "jsonwebtoken": "^9.0.2", + "node-cron": "^3.0.3", "pinia": "^2.1.7", "sm-crypto": "^0.3.13", "uuid": "^9.0.1", @@ -28,12 +30,13 @@ "ws": "^8.16.0" }, "devDependencies": { + "@vicons/fluent": "^0.12.0", "@vicons/ionicons5": "^0.12.0", "@vitejs/plugin-vue": "^5.0.3", "better-sqlite3": "^8.7.0", "concurrently": "^8.2.2", "cors": "^2.8.5", - "naive-ui": "^2.37.3", + "naive-ui": "^2.38.1", "vfonts": "^0.0.3", "vite": "^5.0.11" } diff --git a/public/111.ico b/public/111.ico new file mode 100644 index 0000000..df36fcf Binary files /dev/null and b/public/111.ico differ diff --git a/public/favicon.ico b/public/favicon.ico index df36fcf..7e0c56b 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/server.js b/server.js index 8603fc3..70076f4 100644 --- a/server.js +++ b/server.js @@ -5,15 +5,23 @@ import fs from "fs"; import { WebSocketServer } from "ws"; import http from "http"; import { v4 as uuid4 } from "uuid"; -// import Config from "./miaoShareConfig.json" +import jwt from "jsonwebtoken"; +import sha256 from "crypto-js/sha256.js"; +import Config from './miaoShareConfig.json' assert { type: 'json' }; +// function loadJSON(path){ +// return JSON.parse(fs.readFileSync(path).toString()); +// } +// const Config = loadJSON("./miaoShareConfig.json"); const HOST = "0.0.0.0"; -// const PORT = Config.PORT -const PORT = 17057; +const PORT = Config.PORT +// const PORT = 17057; const fileDir = "./temp"; const dbPath = "./miaoShare.db"; const PATH = "./dist"; +const JWT_SK = fs.readFileSync("JWT_SK.key").toString(); + // 上传文件最大大小:200MB const uploadMaxSize = 200 * 1024 * 1024; // 一天的毫秒数 @@ -24,27 +32,43 @@ const LifeOfFile = millisecondsOfOneDay * 3; // 数据库相关 const db = new Database(dbPath, { verbose: null }); -db.prepare( +db.exec( `CREATE TABLE IF NOT EXISTS id2fileName ( id CHAR(8) PRIMARY KEY NOT NULL UNIQUE, fileName TEXT NOT NULL, timestamp INT NOT NULL, freeze tinyint(1) NOT NULL, - downloadCredit INT NOT NULL + downloadCredit INT NOT NULL, + fileSize INT NOT NULL, + sender_id CHAR(32) NOT NULL );` -).run(); +); +db.exec(` +CREATE TABLE IF NOT EXISTS USERS( + user_id CHAR(32) PRIMARY KEY UNIQUE, + password_hash CHAR(32) NOT NULL, + user_group VARCHAR(32) NOT NULL, + uploadFilesSizeCount BIGINT NOT NULL, + email CHAR(64) +);`); +const stmt_getPermissionGroup = db.prepare("SELECT user_group FROM USERS WHERE user_id = ? AND password_hash = ?"); const stmt_getFileName = db.prepare(`SELECT fileName FROM id2fileName WHERE id = ?`); +const stmt_getUserUploadFilesSizeCount = db.prepare("SELECT uploadFilesSizeCount FROM USERS WHERE user_id = ?"); +const stmt_getUserGroup = db.prepare("SELECT user_group FROM USERS WHERE user_id = ?"); const stmt_getTimestamp = db.prepare(`SELECT timestamp FROM id2fileName WHERE id = ?`); +const stmt_getFileSize = db.prepare(`SELECT fileSize FROM id2fileName WHERE id = ?`); const stmt_getFreeze = db.prepare(`SELECT freeze FROM id2fileName WHERE id = ?`); const stmt_getDownloadCredit = db.prepare(`SELECT downloadCredit FROM id2fileName WHERE id = ?`); -const stmt_getFreezenIDs = db.prepare(`SELECT id FROM id2fileName WHERE freeze = 1`); -const stmt_insertId2FileName = db.prepare(`INSERT INTO id2fileName (id, fileName, timestamp, freeze, downloadCredit) VALUES (?, ?, ?, ?, ?)`); +const stmt_getFreezenIDs = db.prepare(`SELECT id,fileSize,sender_id FROM id2fileName WHERE freeze = 1`); +const stmt_insertId2FileName = db.prepare(`INSERT INTO id2fileName (id, fileName, timestamp, freeze, downloadCredit, fileSize, sender_id) VALUES (?, ?, ?, ?, ?, ?, ?)`); const stmt_deleteExpireData = db.prepare(`DELETE FROM id2fileName WHERE freeze=1`); const stmt_freezeExpireData = db.prepare(`UPDATE id2fileName SET freeze=1 WHERE timestamp < ? OR downloadCredit < 1`); const stmt_updateDownloadCredit = db.prepare(`UPDATE id2fileName SET downloadCredit=downloadCredit-1 WHERE id = ?`); +const stmt_updateUserUploadFilesSizeCount = db.prepare(`UPDATE USERS SET uploadFilesSizeCount=uploadFilesSizeCount+? WHERE user_id = ?`); +const stmt_updateUserUploadFilesSizeCount_d = db.prepare(`UPDATE USERS SET uploadFilesSizeCount=uploadFilesSizeCount-? WHERE user_id = ?`); -const db_insert = (id, fileName, downloadCredit) => { - stmt_insertId2FileName.run(id, fileName, parseInt(Date.now()), 0, downloadCredit); +const db_insert = (id, fileName, downloadCredit, fileSize, senderId) => { + stmt_insertId2FileName.run(id, fileName, parseInt(Date.now()), 0, downloadCredit, fileSize, senderId); }; const db_getFileName = id => { try { @@ -78,6 +102,22 @@ const db_getTimestamp = id => { return stmt_getTimestamp.get(id)["timestamp"]; }; +const db_getFileSize = id => { + return stmt_getFileSize.get(id)["fileSize"]; +}; +const db_getUserUploadFilesSizeCount = id => { + return stmt_getUserUploadFilesSizeCount.get(id)["uploadFilesSizeCount"]; +}; + +function db_updateUserUploadFilesSizeCount(id,size){ + return stmt_updateUserUploadFilesSizeCount.run(size,id) +} + +// 减 +function db_updateUserUploadFilesSizeCount_d(id,size){ + return stmt_updateUserUploadFilesSizeCount_d.run(size,id) +} + // 更新存储的文件,删除已经被冻结的文件以及相关记录,然后冻结过期文件 const updateDBAndFiles = () => { try { @@ -85,6 +125,9 @@ const updateDBAndFiles = () => { stmt_deleteExpireData.run(); for (let row of rows) { let fileName = row["id"]; + let sid = row['sender_id'] + let fsize = row['fileSize'] + db_updateUserUploadFilesSizeCount_d(sid,fsize) let path = fileDir + "/" + fileName; try { fs.unlink(path, e => { @@ -117,6 +160,15 @@ if (!fs.existsSync(fileDir)) { fs.mkdirSync(fileDir); } +function db_getPermissionGroup(id, pwdH) { + let res = stmt_getPermissionGroup.get(id, pwdH); + // console.log(id,pwdH,res) + if (res && res.user_group) { + return res.user_group; + } + return null; +} + function generateId(isGID) { var returnStr = "", range = 8, @@ -134,10 +186,11 @@ function generateId(isGID) { } // 上传文件接口 -function uploadFile(req, res, fileName, downloadCredit) { +function uploadFile(req, res, fileName, downloadCredit, fileSize) { let id = generateId(); const fileStream = fs.createWriteStream(fileDir + "/" + id); - db_insert(id, fileName, downloadCredit); + db_insert(id, fileName, downloadCredit, fileSize, req.sender_id); + db_updateUserUploadFilesSizeCount(req.sender_id,fileSize) // tempMap[id] = fileName; // console.log(tempMap); req.pipe(fileStream); @@ -184,9 +237,54 @@ function downloadFile(req, res, fileId) { } } +const getUserGroup = (function(){ + const cache = {} + return function(userId){ + if(!cache[userId]){ + cache[userId]= stmt_getUserGroup.get(userId)['user_group'] + } + return cache[userId] + } +})() + +// 验证token +const verifyToken = (req, res, next) => { + try { + const token = req.headers.authorization.split(" ")[1]; // 从Authorization头中提取JWT + console.log(req.headers.authorization,token) + let verifyData = jwt.verify(token, JWT_SK); + if (verifyData.exp > parseInt(Date.now())) { + throw "token has expired"; + } + req.sender_id = verifyData.id + next(); + } catch (err) { + console.log(err) + return res.status(401).json({ message: "Invalid token", err }); + } +}; + app.use(express.static(PATH)); +app.post("/user/login", express.json(),function (req, res) { + res.header("Access-Control-Allow-Origin", "*"); + res.header("Access-Control-Allow-Headers", "*"); + res.header("Access-Control-Allow-Methods", "POST"); + // console.log(req.body) + let { id, pwd } = req.body; + console.log(req.body) + let pwdH = sha256(id + pwd).toString(); + let userGroup = db_getPermissionGroup(id, pwdH); + if (userGroup !== null) { + res.writeHead(200); + let token = jwt.sign({ id, pwd }, JWT_SK, { expiresIn: "168h" }); + res.end(JSON.stringify({ status: "Success", userGroup, token })); + } else { + res.end(JSON.stringify({ status: "Error" })); + } + // console.log(req) +}); // app.all() -app.post("/file/upload", function (req, res) { +app.post("/file/upload", verifyToken, function (req, res) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "*"); res.header("Access-Control-Allow-Methods", "POST"); @@ -198,15 +296,15 @@ app.post("/file/upload", function (req, res) { if (!fileName) { res.statusCode = 500; res.end("FileName Not Found"); - } else if (fileSize > uploadMaxSize) { + } else if (fileSize > uploadMaxSize || db_getUserUploadFilesSizeCount(req.sender_id) + fileSize > Config.userGroupSetting[getUserGroup(req.sender_id)].cloudCapacity) { res.statusCode = 500; res.end("Maximum size limit exceeded"); } else { - uploadFile(req, res, fileName, downloadCredit); + uploadFile(req, res, fileName, downloadCredit, fileSize); } }); -app.get("/file/download", function (req, res) { +app.get("/file/download", verifyToken, function (req, res) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "*"); res.header("Access-Control-Allow-Methods", "GET"); @@ -234,29 +332,29 @@ const groupsMap = {}; const LifeOfGroup = millisecondsOfOneDay * 1; // const LifeOfGroup = 0; // 根据uuid查询加入的群组 -const uuid2Groups={} +const uuid2Groups = {}; db.exec( - `CREATE TABLE IF NOT EXISTS GROUPS ( + `CREATE TABLE IF NOT EXISTS CHATGROUPS ( gID CHAR(8) PRIMARY KEY UNIQUE NOT NULL, verify TEXT NOT NULL, activeTimestamp INT NOT NULL );` ); -const stmt_getExpiredGroups = db.prepare(`SELECT gID FROM GROUPS WHERE activeTimestamp < ? `); +const stmt_getExpiredGroups = db.prepare(`SELECT gID FROM CHATGROUPS WHERE activeTimestamp < ? `); -const stmt_getGroupVerify = db.prepare(`SELECT verify FROM GROUPS WHERE gID = ? `); +const stmt_getGroupVerify = db.prepare(`SELECT verify FROM CHATGROUPS WHERE gID = ? `); -const stmt_insertGROUPS = db.prepare(`INSERT INTO GROUPS (gID,verify, activeTimestamp) VALUES (?, ?, ?)`); +const stmt_insertCHATGROUPS = db.prepare(`INSERT INTO CHATGROUPS (gID,verify, activeTimestamp) VALUES (?, ?, ?)`); -const stmt_updateGROUPS_ActiveTimestamp = db.prepare(`UPDATE GROUPS SET activeTimestamp=? WHERE gID=?`); +const stmt_updateCHATGROUPS_ActiveTimestamp = db.prepare(`UPDATE CHATGROUPS SET activeTimestamp=? WHERE gID=?`); -const stmt_deleteGroup = db.prepare(`DELETE FROM GROUPS WHERE gID=?`); +const stmt_deleteGroup = db.prepare(`DELETE FROM CHATGROUPS WHERE gID=?`); const generateStmt_insertMessage_map = {}; -const updateGROUPS = () => { +const updateCHATGROUPS = () => { // console.log(1) try { let gIDs = stmt_getExpiredGroups.all(parseInt(Date.now()) - LifeOfGroup); @@ -270,8 +368,8 @@ const updateGROUPS = () => { return; } }; -updateGROUPS(); -setInterval(updateGROUPS, 1000 * 3600 * 3); +updateCHATGROUPS(); +setInterval(updateCHATGROUPS, 1000 * 3600 * 3); // 创建群组的数据库 function createGroupTableDB(gID, verify) { @@ -283,7 +381,7 @@ function createGroupTableDB(gID, verify) { timestamp INT NOT NULL );` ); - stmt_insertGROUPS.run(gID, verify, parseInt(Date.now())); + stmt_insertCHATGROUPS.run(gID, verify, parseInt(Date.now())); } // 插入信息 @@ -295,7 +393,7 @@ function insertMessageByGID(gID, msg, from, timestamp) { } function updateActiveTimestamp(gID) { - stmt_updateGROUPS_ActiveTimestamp.run(parseInt(Date.now()), gID); + stmt_updateCHATGROUPS_ActiveTimestamp.run(parseInt(Date.now()), gID); } function createGroup(verify) { @@ -307,13 +405,13 @@ function createGroup(verify) { } function getGroupVerify(gID) { - initMsgHistory(gID) + initMsgHistory(gID); return groupsMap[gID].verify; } // 正式加入群组 function joinGroup(socket, gID, callback) { - initMsgHistory(gID) + initMsgHistory(gID); groupsMap[gID].member.push(socket); updateActiveTimestamp(gID); callback(); @@ -321,13 +419,13 @@ function joinGroup(socket, gID, callback) { // 暂时这么写 function getHistory(gID) { - initMsgHistory(gID) + initMsgHistory(gID); return groupsMap[gID].msgHistory; } function broadcastMsg(gID, msg, from) { - const timestamp = parseInt(Date.now()) - initMsgHistory(gID) + const timestamp = parseInt(Date.now()); + initMsgHistory(gID); updateActiveTimestamp(gID); insertMessageByGID(gID, msg, from, timestamp); @@ -338,7 +436,7 @@ function broadcastMsg(gID, msg, from) { } } -function initMsgHistory(gID){ +function initMsgHistory(gID) { if (!groupsMap[gID]) { let verify = stmt_getGroupVerify.get(gID).verify; // 暂时这么写 @@ -346,7 +444,7 @@ function initMsgHistory(gID){ .prepare(`SELECT message,type,sender,timestamp FROM ${gID}`) .all() .map(v => { - return { type: v.type, msg: v.message,from:v.sender,timestamp:v.timestamp }; + return { type: v.type, msg: v.message, from: v.sender, timestamp: v.timestamp }; }); // console.log(msgHistory) groupsMap[gID] = { verify, member: [], msgHistory }; @@ -359,8 +457,8 @@ wss.on("connection", socket => { const no = wss.clients.size; const joinedGroup = []; var uuid = uuid4(); - function setUuid(new_uuid){ - uuid = new_uuid + function setUuid(new_uuid) { + uuid = new_uuid; } socket.on("message", message => { try { @@ -392,14 +490,14 @@ wss.on("connection", socket => { } } else if (type === "message") { let gID = msg.gID; - broadcastMsg(gID, msg.msg,uuid); + broadcastMsg(gID, msg.msg, uuid); } else if (type === "heartbeat") { socket.send(JSON.stringify({ type: "sMsg", type1: "heartbeat" })); } else if (type === "uuid") { if (msg.type1 === "get") { socket.send(JSON.stringify({ type: "sMsg", type1: "uuid", uuid })); } else if (msg.type1 === "set") { - uuid = msg.uuid + uuid = msg.uuid; } } } diff --git a/src/App.vue b/src/App.vue index c8acd07..39d6cc8 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,85 +3,121 @@ import upload from "./views/uploadFileMiao.vue"; import download from "./views/downloadFileMiao.vue"; import setting from "./views/setting.vue"; import chat from "./views/chat.vue"; -import { NNotificationProvider, NMessageProvider, NCard, NMenu, NIcon } from 'naive-ui' -import { ref, watch, h ,shallowRef} from "vue"; -// import { RouterView, useRouter } from "vue-router"; +import login from "./views/login.vue"; +import account from "./views/accountInfo.vue"; +import getQueryString from '@/func/getQuery' +import { NNotificationProvider, NMessageProvider, NCard, NMenu, NIcon,NModalProvider } from 'naive-ui' +import { ref, watch, h ,shallowRef, onMounted, computed} from "vue"; +// import { useRoute } from "vue-router"; import { ArrowUpCircleOutline as uploadIcon, ArrowDownCircleOutline as downloadIcon, ChatboxEllipsesOutline as chatIcon, - SettingsOutline as settingIcon + SettingsOutline as settingIcon, + PersonOutline as AccountIcon } from '@vicons/ionicons5' +import { useSettingStore } from "@/pinia/store"; + +const settingData = useSettingStore(); const activePage = ref('upload') const isComponent = shallowRef(upload) watch(activePage, () => { - isComponent.value={upload,download,setting,chat}[activePage.value] + isComponent.value={upload,download,setting,chat,login,account}[activePage.value] }) function renderIcon(icon) { return () => h(NIcon, null, { default: () => h(icon) }) } -const menuOptions = [ +const menuOptions = ref([ { label: '上传', key: 'upload', icon: renderIcon(uploadIcon), + disabled:computed(()=>{ + // console.log(settingData) + return settingData.token === null + }) }, { label: '下载', key: 'download', icon: renderIcon(downloadIcon), + disabled:computed(()=>{ + return settingData.token === null + }) }, { label: 'Chat', key: 'chat', icon: renderIcon(chatIcon), + disabled:computed(()=>{ + return settingData.token === null + }) }, { label: '设置', key: 'setting', icon: renderIcon(settingIcon), + disabled:computed(()=>{ + return settingData.token === null + }) + }, + { + label:'账户', + key:'account', + icon: renderIcon(AccountIcon), + disabled:computed(()=>{ + return settingData.token === null + }) } -] +]) +// function getQueryString(key) { +// var reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)', 'i'); +// var r = window.location.search.substr(1).match(reg); +// if (r != null) { +// return unescape(r[2]); +// } +// return null; +// } +onMounted(()=>{ + let aP = getQueryString('aP') + // console.log(aP) + if(aP){ + activePage.value = aP + } + if(settingData.token === null){ + aP = activePage.value + activePage.value = 'login' + // 登录后跳原来的activePage + const w = watch(()=>settingData.token,()=>{ + activePage.value = aP + w() + }) + } +}) \ No newline at end of file diff --git a/src/views/uploadFileMiao.vue b/src/views/uploadFileMiao.vue index f6c598d..783f39f 100644 --- a/src/views/uploadFileMiao.vue +++ b/src/views/uploadFileMiao.vue @@ -37,7 +37,7 @@