refactor: SocketIO
- Check request data in middleware - Authenticate each connection before allowing room access - Allow site room access only to System Users, restrict Website User & Guests to their respective user rooms Note: This doesn't check for roles / permissions
This commit is contained in:
parent
5210ea593f
commit
4de9c39bb8
2 changed files with 38 additions and 32 deletions
|
|
@ -122,8 +122,10 @@ def get_user_info():
|
|||
from frappe.sessions import Session
|
||||
|
||||
session = Session(None, resume=True).get_session_data()
|
||||
|
||||
return {
|
||||
"user": session.user,
|
||||
"user_type": session.user_type,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
68
socketio.js
68
socketio.js
|
|
@ -14,47 +14,53 @@ const io = require("socket.io")(conf.socketio_port, {
|
|||
},
|
||||
});
|
||||
|
||||
// on socket connection
|
||||
io.on("connection", function (socket) {
|
||||
io.use((socket, next) => {
|
||||
if (get_hostname(socket.request.headers.host) != get_hostname(socket.request.headers.origin)) {
|
||||
next(new Error("Invalid origin"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!socket.request.headers.cookie) {
|
||||
next(new Error("No cookie transmitted."));
|
||||
return;
|
||||
}
|
||||
|
||||
const sid = cookie.parse(socket.request.headers.cookie).sid;
|
||||
if (!sid) {
|
||||
const cookies = cookie.parse(socket.request.headers.cookie);
|
||||
|
||||
if (!cookies.sid) {
|
||||
next(new Error("No sid transmitted."));
|
||||
return;
|
||||
}
|
||||
socket.sid = cookies.sid;
|
||||
socket.user = cookies.user_id;
|
||||
|
||||
socket.user = cookie.parse(socket.request.headers.cookie).user_id;
|
||||
request
|
||||
.get(get_url(socket, "/api/method/frappe.realtime.get_user_info"))
|
||||
.type("form")
|
||||
.query({
|
||||
sid: socket.sid,
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(`User ${res.body.message.user} found`);
|
||||
socket.user = res.body.message.user;
|
||||
socket.user_type = res.body.message.user_type;
|
||||
})
|
||||
.catch((e) => {
|
||||
next(new Error(`Unauthorized: ${e}`));
|
||||
return;
|
||||
});
|
||||
|
||||
let retries = 0;
|
||||
let join_user_room = () => {
|
||||
request
|
||||
.get(get_url(socket, "/api/method/frappe.realtime.get_user_info"))
|
||||
.type("form")
|
||||
.query({
|
||||
sid: sid,
|
||||
})
|
||||
.then((res) => {
|
||||
const room = get_user_room(socket, res.body.message.user);
|
||||
socket.join(room);
|
||||
socket.join(get_site_room(socket));
|
||||
})
|
||||
.catch((e) => {
|
||||
if (e.code === "ECONNREFUSED" && retries < 5) {
|
||||
// retry after 1s
|
||||
retries += 1;
|
||||
return setTimeout(join_user_room, 1000);
|
||||
}
|
||||
log(`Unable to join user room. ${e}`);
|
||||
});
|
||||
};
|
||||
next();
|
||||
});
|
||||
|
||||
join_user_room();
|
||||
// on socket connection
|
||||
io.on("connection", function (socket) {
|
||||
const room = get_user_room(socket);
|
||||
socket.join(room);
|
||||
|
||||
if (socket.user == "System User") {
|
||||
socket.join(get_site_room(socket));
|
||||
}
|
||||
|
||||
socket.on("task_subscribe", function (task_id) {
|
||||
var room = get_task_room(socket, task_id);
|
||||
|
|
@ -75,7 +81,6 @@ io.on("connection", function (socket) {
|
|||
socket.on("doc_subscribe", function (doctype, docname) {
|
||||
can_subscribe_doc({
|
||||
socket,
|
||||
sid,
|
||||
doctype,
|
||||
docname,
|
||||
callback: () => {
|
||||
|
|
@ -93,7 +98,6 @@ io.on("connection", function (socket) {
|
|||
socket.on("doc_open", function (doctype, docname) {
|
||||
can_subscribe_doc({
|
||||
socket,
|
||||
sid,
|
||||
doctype,
|
||||
docname,
|
||||
callback: () => {
|
||||
|
|
@ -210,7 +214,7 @@ function get_typing_room(socket, doctype, docname) {
|
|||
}
|
||||
|
||||
function get_user_room(socket, user) {
|
||||
return get_site_name(socket) + ":user:" + user;
|
||||
return get_site_name(socket) + ":user:" + user || socket.user;
|
||||
}
|
||||
|
||||
function get_site_room(socket) {
|
||||
|
|
@ -261,7 +265,7 @@ function can_subscribe_doc(args) {
|
|||
.get(get_url(args.socket, "/api/method/frappe.realtime.can_subscribe_doc"))
|
||||
.type("form")
|
||||
.query({
|
||||
sid: args.sid,
|
||||
sid: args.socket.sid,
|
||||
doctype: args.doctype,
|
||||
docname: args.docname,
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue