添加登录功能

This commit is contained in:
539943419 committed 2024-03-27 22:05:00 +08:00
1 parent 20e9f4940e
commit 530e54a596
17 files changed
+632 -160

No files matched your search

+137 -39
View File
@@ -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;
}
}
}