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()
+ })
+ }
+})
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/func/download.js b/src/func/download.js
index 796e532..070abaf 100644
--- a/src/func/download.js
+++ b/src/func/download.js
@@ -72,7 +72,7 @@ const decryptString = (key, str) => {
const downloadFromUint8Array = (data, fileName) => {
let uint8Array = data;
- let blob = new Blob([uint8Array], { type: "text/plain" });
+ let blob = new Blob([uint8Array], { type: "application/octet-stream" });
// 使用file-saver.js
saveAs(blob, fileName);
};
diff --git a/src/func/getQuery.js b/src/func/getQuery.js
new file mode 100644
index 0000000..ad98bd4
--- /dev/null
+++ b/src/func/getQuery.js
@@ -0,0 +1,8 @@
+export default function getQueryString(key) {
+ var reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)', 'i');
+ var r = window.location.search.substring(1).match(reg);
+ if (r != null) {
+ return decodeURI(r[2]);
+ }
+ return null;
+}
\ No newline at end of file
diff --git a/src/pinia/store.js b/src/pinia/store.js
index f85f566..e5da747 100644
--- a/src/pinia/store.js
+++ b/src/pinia/store.js
@@ -1,6 +1,11 @@
import { defineStore } from "pinia";
import config from "../../miaoShareConfig.json"
+const userID = localStorage.getItem('userID');
+const userGroup = localStorage.getItem('userGroup');
+
+const token = localStorage.getItem('token');
+// console.log(token)
var activeFuctionLocal = localStorage.getItem('activeFuction')
if (activeFuctionLocal == null){
@@ -18,12 +23,28 @@ export const useSettingStore = defineStore("setting", {
state: () => ({
activeFuction: activeFuctionLocal,
activeKeyMap:JSON.parse(activeKeyMap),
- serverPort:config.PORT
+ serverPort:config.PORT,
+ token,userID,userGroup
}),
getters: {
// double: state => state.count * 2
},
actions: {
+ setJWT( token,keepTokenLocal ){
+ this.token = token
+ if(keepTokenLocal)
+ localStorage.setItem('token',token)
+ },
+ setUserID( id,keepTokenLocal ){
+ this.userID = id
+ if(keepTokenLocal)
+ localStorage.setItem('userID',id)
+ },
+ setUserGroup( g,keepTokenLocal ){
+ this.userGroup = g
+ if(keepTokenLocal)
+ localStorage.setItem('userGroup',g)
+ }
// increment() {
// this.count++;
// }
diff --git a/src/views/accountInfo.vue b/src/views/accountInfo.vue
new file mode 100644
index 0000000..c4f88ef
--- /dev/null
+++ b/src/views/accountInfo.vue
@@ -0,0 +1,18 @@
+
+
+ 退出登录
+
+
+
+
\ No newline at end of file
diff --git a/src/views/chat.vue b/src/views/chat.vue
index 67240ce..7e72414 100644
--- a/src/views/chat.vue
+++ b/src/views/chat.vue
@@ -1,15 +1,17 @@
-
+
-
+
创建群组
-
+
加入群组
@@ -23,54 +25,65 @@
joinTest
-->
-
+
-
-
+
+
发送消息
+
+ 分享群组
+
-
+
+
+
+
+ size="huge"
+ role="dialog"
+ aria-modal="true"
+ >
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/views/downloadFileMiao.vue b/src/views/downloadFileMiao.vue
index 58d0cf7..baf3888 100644
--- a/src/views/downloadFileMiao.vue
+++ b/src/views/downloadFileMiao.vue
@@ -28,7 +28,7 @@
\ 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 @@