🚧 save work
This commit is contained in:
+4
-1
@@ -1,4 +1,7 @@
|
|||||||
.idea
|
.idea
|
||||||
node_modules
|
node_modules
|
||||||
package-lock.json
|
package-lock.json
|
||||||
.env
|
.env
|
||||||
|
data.db
|
||||||
|
data.db-journal
|
||||||
|
.vscode
|
||||||
@@ -5,8 +5,9 @@ const logger = require("morgan");
|
|||||||
const http = require("http");
|
const http = require("http");
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
|
|
||||||
const indexRouter = require("./routes");
|
const indexRouter = require("./routers/index");
|
||||||
const requestToken = require("./utils").requestToken;
|
const messageRouter = require("./routers/message");
|
||||||
|
const requestToken = require("./utils/wechat").requestToken;
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ app.use(cookieParser());
|
|||||||
app.use(express.static(path.join(__dirname, "public")));
|
app.use(express.static(path.join(__dirname, "public")));
|
||||||
|
|
||||||
app.use("/", indexRouter);
|
app.use("/", indexRouter);
|
||||||
|
app.use("/message", messageRouter);
|
||||||
|
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
|
|
||||||
|
|||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
module.exports = {
|
||||||
|
development: {
|
||||||
|
client: "sqlite3",
|
||||||
|
connection: {
|
||||||
|
filename: "./data.db",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
staging: {
|
||||||
|
client: "sqlite3",
|
||||||
|
connection: {
|
||||||
|
filename: "./data.db",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
production: {
|
||||||
|
client: "sqlite3",
|
||||||
|
connection: {
|
||||||
|
filename: "./data.db",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
exports.up = function (knex) {
|
||||||
|
return knex.schema.createTable("messages", (tableBuilder) => {
|
||||||
|
tableBuilder.uuid("id").primary();
|
||||||
|
tableBuilder.string("title");
|
||||||
|
tableBuilder.string("status");
|
||||||
|
tableBuilder.string("created_by");
|
||||||
|
tableBuilder.string("created_time");
|
||||||
|
tableBuilder.string("description");
|
||||||
|
tableBuilder.text("content");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = function (knex) {};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const db = require("../utils/database").db;
|
||||||
|
const { v4: uuid } = require("uuid");
|
||||||
|
|
||||||
|
class Message {
|
||||||
|
create(message) {
|
||||||
|
message.id = uuid();
|
||||||
|
return db("messages").insert(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
getById(id) {
|
||||||
|
return db("messages").where("id", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteById(id) {
|
||||||
|
return db("messages").where("id", id).del();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.Message = new Message();
|
||||||
+5
-1
@@ -12,7 +12,11 @@
|
|||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"ejs": "^3.1.5",
|
"ejs": "^3.1.5",
|
||||||
"express": "~4.16.1",
|
"express": "~4.16.1",
|
||||||
"morgan": "~1.9.1"
|
"knex": "^0.21.5",
|
||||||
|
"marked": "^1.1.1",
|
||||||
|
"morgan": "~1.9.1",
|
||||||
|
"sqlite3": "^5.0.0",
|
||||||
|
"uuid": "^8.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^2.1.1"
|
"prettier": "^2.1.1"
|
||||||
|
|||||||
@@ -2,20 +2,14 @@ const express = require("express");
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const pushMessage = require("./utils").pushMessage;
|
|
||||||
|
|
||||||
router.all("/", (req, res, next) => {
|
router.all("/", (req, res, next) => {
|
||||||
fs.promises
|
fs.promises
|
||||||
.access("./.env")
|
.access("./.env")
|
||||||
.then(() => {
|
.then(() => {
|
||||||
res.render("message", {
|
res.render("info", {
|
||||||
message: "服务已在运行,本次访问已被记录。",
|
message: "服务已在运行。",
|
||||||
});
|
});
|
||||||
pushMessage(
|
|
||||||
req,
|
|
||||||
res,
|
|
||||||
`请注意,ip 地址为 ${req.ip} 的用户访问了你的消息通知服务,如果非你本人,则你的私有消息通知服务可能已被泄露,当前版本无法阻止其他用户通过本系统向你发送消息。`
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
res.render("configure");
|
res.render("configure");
|
||||||
@@ -47,7 +41,7 @@ router.post("/configure", (req, res, next) => {
|
|||||||
process.exit();
|
process.exit();
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
res.render("message", {
|
res.render("info", {
|
||||||
message: "在尝试写入 .env 文件时发生错误:" + e,
|
message: "在尝试写入 .env 文件时发生错误:" + e,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -68,14 +62,4 @@ router.all("/verify", (req, res, next) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.all("/push", (req, res, next) => {
|
|
||||||
let content = req.query.content || req.body.content;
|
|
||||||
pushMessage(req, res, content);
|
|
||||||
});
|
|
||||||
|
|
||||||
router.all("/:content", (req, res, next) => {
|
|
||||||
let content = req.params.content;
|
|
||||||
pushMessage(req, res, content);
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
const express = require("express");
|
||||||
|
const lexer = require("marked").lexer;
|
||||||
|
const parser = require("marked").parser;
|
||||||
|
const Message = require("../models/message").Message;
|
||||||
|
const pushWeChatMessage = require("../utils/wechat").pushWeChatMessage;
|
||||||
|
const formatTime = require("../utils/utils").formatTime;
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
function md2html(markdown) {
|
||||||
|
return parser(lexer(markdown));
|
||||||
|
}
|
||||||
|
|
||||||
|
router.get("/:description", (req, res, next) => {
|
||||||
|
req.query.description = req.params.description;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
router.all("/", (req, res) => {
|
||||||
|
let message = {
|
||||||
|
title: req.query.title || req.body.title || "无标题",
|
||||||
|
status: 1,
|
||||||
|
created_by: "系统", // TODO
|
||||||
|
created_time: formatTime(),
|
||||||
|
description: req.query.description || req.body.description,
|
||||||
|
content: md2html(req.query.content || req.body.content),
|
||||||
|
};
|
||||||
|
|
||||||
|
Message.create(message)
|
||||||
|
.then((value) => {
|
||||||
|
console.log(value);
|
||||||
|
pushWeChatMessage(message.description, message.link)
|
||||||
|
.then((response) => {
|
||||||
|
res.json(response);
|
||||||
|
})
|
||||||
|
.catch((reason) => {
|
||||||
|
res.json(reason);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((reason) => {
|
||||||
|
res.json(reason);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/detail/:id", (req, res) => {
|
||||||
|
const id = req.params.id;
|
||||||
|
Message.getById(id)
|
||||||
|
.then((value) => {
|
||||||
|
console.log(value);
|
||||||
|
res.render("message", value[0]);
|
||||||
|
})
|
||||||
|
.catch((reason) => {
|
||||||
|
res.render("info", {
|
||||||
|
message: "获取该消息时发生了错误:" + reason,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
const knex = require("knex");
|
||||||
|
const environment = process.env.NODE_ENV || "development";
|
||||||
|
const configuration = require("../knexfile")[environment];
|
||||||
|
|
||||||
|
const db = knex(configuration);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
db: db,
|
||||||
|
};
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
function formatTime(format) {
|
||||||
|
if (format === undefined) format = "yyyy-MM-dd hh:mm:ss";
|
||||||
|
const date = new Date();
|
||||||
|
const o = {
|
||||||
|
"M+": date.getMonth() + 1,
|
||||||
|
"d+": date.getDate(),
|
||||||
|
"h+": date.getHours(),
|
||||||
|
"m+": date.getMinutes(),
|
||||||
|
"s+": date.getSeconds(),
|
||||||
|
S: date.getMilliseconds(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (/(y+)/.test(format)) {
|
||||||
|
format = format.replace(
|
||||||
|
RegExp.$1,
|
||||||
|
(date.getFullYear() + "").substr(4 - RegExp.$1.length)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let k in o) {
|
||||||
|
if (new RegExp("(" + k + ")").test(format)) {
|
||||||
|
format = format.replace(
|
||||||
|
RegExp.$1,
|
||||||
|
RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
formatTime,
|
||||||
|
};
|
||||||
@@ -12,6 +12,7 @@ module.exports = {
|
|||||||
console.log("Token requested.");
|
console.log("Token requested.");
|
||||||
token = res.data.access_token;
|
token = res.data.access_token;
|
||||||
app.locals.access_token = token;
|
app.locals.access_token = token;
|
||||||
|
process.env.access_token = token;
|
||||||
} else {
|
} else {
|
||||||
console.error(res.data);
|
console.error(res.data);
|
||||||
}
|
}
|
||||||
@@ -19,27 +20,17 @@ module.exports = {
|
|||||||
return token;
|
return token;
|
||||||
},
|
},
|
||||||
|
|
||||||
pushMessage: function (req, res, content) {
|
pushWeChatMessage: function (description, link) {
|
||||||
// Reference: https://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=tmplmsg/faq_tmpl
|
// Reference: https://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=tmplmsg/faq_tmpl
|
||||||
let access_token = req.app.locals.access_token;
|
let access_token = process.env.access_token;
|
||||||
let request_data = {
|
let request_data = {
|
||||||
touser: process.env.OPEN_ID,
|
touser: process.env.OPEN_ID,
|
||||||
template_id: process.env.TEMPLATE_ID,
|
template_id: process.env.TEMPLATE_ID,
|
||||||
};
|
};
|
||||||
request_data.data = { text: { value: content } };
|
request_data.data = { text: { value: description } };
|
||||||
axios
|
return axios.post(
|
||||||
.post(
|
`https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${access_token}`,
|
||||||
`https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${access_token}`,
|
request_data
|
||||||
request_data
|
);
|
||||||
)
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data && response.data.errcode === "40001") {
|
|
||||||
requestToken(req.app);
|
|
||||||
}
|
|
||||||
res.json(response.data);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
res.json(error);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<%- include('./header') %>
|
||||||
|
<article class="message is-primary">
|
||||||
|
<div class="message-header">
|
||||||
|
<p>注意</p>
|
||||||
|
</div>
|
||||||
|
<div class="message-body">
|
||||||
|
<%= message %>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<%- include('./footer') %>
|
||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
<%- include('./header') %>
|
<%- include('./header') %>
|
||||||
<article class="message is-primary">
|
<article class="info is-primary">
|
||||||
<div class="message-header">
|
<div class="message-header">
|
||||||
<p>注意</p>
|
<p>注意</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="message-body">
|
<div class="message-body">
|
||||||
<%= message %>
|
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
<%- include('./footer') %>
|
<%- include('./footer') %>
|
||||||
Reference in New Issue
Block a user