Refactor private chat creation
This commit is contained in:
+32
-1
@@ -5,7 +5,7 @@ const assert = require("assert").strict
|
|||||||
const streamWeb = require("stream/web")
|
const streamWeb = require("stream/web")
|
||||||
|
|
||||||
const passthrough = require("../passthrough")
|
const passthrough = require("../passthrough")
|
||||||
const {sync} = passthrough
|
const {sync, db, select} = passthrough
|
||||||
/** @type {import("./mreq")} */
|
/** @type {import("./mreq")} */
|
||||||
const mreq = sync.require("./mreq")
|
const mreq = sync.require("./mreq")
|
||||||
/** @type {import("./txnid")} */
|
/** @type {import("./txnid")} */
|
||||||
@@ -513,6 +513,36 @@ function versions() {
|
|||||||
return mreq.mreq("GET", "/client/versions")
|
return mreq.mreq("GET", "/client/versions")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} mxid
|
||||||
|
*/
|
||||||
|
async function usePrivateChat(mxid) {
|
||||||
|
// Check if we have an existing DM
|
||||||
|
let roomID = select("direct", "room_id", {mxid}).pluck().get()
|
||||||
|
if (roomID) {
|
||||||
|
// Check that the person is/still in the room
|
||||||
|
try {
|
||||||
|
var member = await getStateEvent(roomID, "m.room.member", mxid)
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
// Invite them back to the room if needed
|
||||||
|
if (!member || member.membership === "leave") {
|
||||||
|
await inviteToRoom(roomID, mxid)
|
||||||
|
}
|
||||||
|
return roomID
|
||||||
|
}
|
||||||
|
|
||||||
|
// No existing DM, create a new room and invite
|
||||||
|
roomID = await createRoom({
|
||||||
|
invite: [mxid],
|
||||||
|
is_direct: true,
|
||||||
|
preset: "trusted_private_chat"
|
||||||
|
})
|
||||||
|
// Store the newly created room in the database (not using account data due to awkward bugs with misaligned state)
|
||||||
|
db.prepare("REPLACE INTO direct (mxid, room_id) VALUES (?, ?)").run(mxid, roomID)
|
||||||
|
return roomID
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.path = path
|
module.exports.path = path
|
||||||
module.exports.register = register
|
module.exports.register = register
|
||||||
module.exports.createRoom = createRoom
|
module.exports.createRoom = createRoom
|
||||||
@@ -550,3 +580,4 @@ module.exports.setAccountData = setAccountData
|
|||||||
module.exports.setPresence = setPresence
|
module.exports.setPresence = setPresence
|
||||||
module.exports.getProfile = getProfile
|
module.exports.getProfile = getProfile
|
||||||
module.exports.versions = versions
|
module.exports.versions = versions
|
||||||
|
module.exports.usePrivateChat = usePrivateChat
|
||||||
|
|||||||
@@ -79,30 +79,7 @@ as.router.post("/api/log-in-with-matrix", defineEventHandler(async event => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have an existing DM
|
const roomID = await api.usePrivateChat(mxid)
|
||||||
let roomID = select("direct", "room_id", {mxid}).pluck().get()
|
|
||||||
if (roomID) {
|
|
||||||
// Check that the person is/still in the room
|
|
||||||
try {
|
|
||||||
var member = await api.getStateEvent(roomID, "m.room.member", mxid)
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
// Invite them back to the room if needed
|
|
||||||
if (!member || member.membership === "leave") {
|
|
||||||
await api.inviteToRoom(roomID, mxid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No existing DM, create a new room and invite
|
|
||||||
else {
|
|
||||||
roomID = await api.createRoom({
|
|
||||||
invite: [mxid],
|
|
||||||
is_direct: true,
|
|
||||||
preset: "trusted_private_chat"
|
|
||||||
})
|
|
||||||
// Store the newly created room in account data (Matrix doesn't do this for us automatically, sigh...)
|
|
||||||
db.prepare("REPLACE INTO direct (mxid, room_id) VALUES (?, ?)").run(mxid, roomID)
|
|
||||||
}
|
|
||||||
|
|
||||||
const token = randomUUID()
|
const token = randomUUID()
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ test("log in with matrix: checks if mxid domain format looks valid", async t =>
|
|||||||
t.match(error.data.fieldErrors.mxid, /must match pattern/)
|
t.match(error.data.fieldErrors.mxid, /must match pattern/)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("log in with matrix: sends message when there is no existing dm room", async t => {
|
test("log in with matrix: sends message to log in", async t => {
|
||||||
const event = {}
|
const event = {}
|
||||||
let called = 0
|
let called = 0
|
||||||
await router.test("post", "/api/log-in-with-matrix", {
|
await router.test("post", "/api/log-in-with-matrix", {
|
||||||
@@ -42,8 +42,9 @@ test("log in with matrix: sends message when there is no existing dm room", asyn
|
|||||||
mxid: "@cadence:cadence.moe"
|
mxid: "@cadence:cadence.moe"
|
||||||
},
|
},
|
||||||
api: {
|
api: {
|
||||||
async createRoom() {
|
async usePrivateChat(mxid) {
|
||||||
called++
|
called++
|
||||||
|
t.equal(mxid, "@cadence:cadence.moe")
|
||||||
return "!created:cadence.moe"
|
return "!created:cadence.moe"
|
||||||
},
|
},
|
||||||
async sendEvent(roomID, type, content) {
|
async sendEvent(roomID, type, content) {
|
||||||
@@ -72,65 +73,6 @@ test("log in with matrix: does not send another message when a log in is in prog
|
|||||||
t.match(event.node.res.getHeader("location"), /We already sent you a link on Matrix/)
|
t.match(event.node.res.getHeader("location"), /We already sent you a link on Matrix/)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("log in with matrix: reuses room from direct", async t => {
|
|
||||||
const event = {}
|
|
||||||
let called = 0
|
|
||||||
await router.test("post", "/api/log-in-with-matrix", {
|
|
||||||
body: {
|
|
||||||
mxid: "@user1:example.org"
|
|
||||||
},
|
|
||||||
api: {
|
|
||||||
async getStateEvent(roomID, type, key) {
|
|
||||||
called++
|
|
||||||
t.equal(roomID, "!existing:cadence.moe")
|
|
||||||
t.equal(type, "m.room.member")
|
|
||||||
t.equal(key, "@user1:example.org")
|
|
||||||
return {membership: "join"}
|
|
||||||
},
|
|
||||||
async sendEvent(roomID) {
|
|
||||||
called++
|
|
||||||
t.equal(roomID, "!existing:cadence.moe")
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
event
|
|
||||||
})
|
|
||||||
t.match(event.node.res.getHeader("location"), /Please check your inbox on Matrix/)
|
|
||||||
t.equal(called, 2)
|
|
||||||
})
|
|
||||||
|
|
||||||
test("log in with matrix: reuses room from direct, reinviting if user has left", async t => {
|
|
||||||
const event = {}
|
|
||||||
let called = 0
|
|
||||||
await router.test("post", "/api/log-in-with-matrix", {
|
|
||||||
body: {
|
|
||||||
mxid: "@user2:example.org"
|
|
||||||
},
|
|
||||||
api: {
|
|
||||||
async getStateEvent(roomID, type, key) {
|
|
||||||
called++
|
|
||||||
t.equal(roomID, "!existing:cadence.moe")
|
|
||||||
t.equal(type, "m.room.member")
|
|
||||||
t.equal(key, "@user2:example.org")
|
|
||||||
throw new MatrixServerError({errcode: "M_NOT_FOUND"})
|
|
||||||
},
|
|
||||||
async inviteToRoom(roomID, mxid) {
|
|
||||||
called++
|
|
||||||
t.equal(roomID, "!existing:cadence.moe")
|
|
||||||
t.equal(mxid, "@user2:example.org")
|
|
||||||
},
|
|
||||||
async sendEvent(roomID) {
|
|
||||||
called++
|
|
||||||
t.equal(roomID, "!existing:cadence.moe")
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
event
|
|
||||||
})
|
|
||||||
t.match(event.node.res.getHeader("location"), /Please check your inbox on Matrix/)
|
|
||||||
t.equal(called, 3)
|
|
||||||
})
|
|
||||||
|
|
||||||
// ***** third request *****
|
// ***** third request *****
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user