Socket
Socket
Sign inDemoInstall

mx-puppet-bridge

Package Overview
Dependencies
125
Maintainers
1
Versions
112
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.8 to 0.0.9

3

lib/botprovisioner.js

@@ -175,3 +175,4 @@ "use strict";

default:
yield this.sendMessage(roomId, `Available commands: help, list, link, unlink, setmatrixtoken, listusers, listchannels`);
yield this.sendMessage(roomId, "Available commands: help, list, link, " +
"unlink, setmatrixtoken, listusers, listchannels");
}

@@ -178,0 +179,0 @@ });

@@ -70,106 +70,114 @@ "use strict";

log.info(`Fetching mxid for roomId ${data.roomId} and puppetId ${data.puppetId}`);
if (!client) {
client = this.bridge.botIntent.underlyingClient;
}
let chan = yield this.chanStore.getByRemote(data.puppetId, data.roomId);
log.silly(chan);
const update = {
name: false,
avatar: false,
topic: false,
};
let mxid = "";
let doUpdate = false;
let created = false;
if (!chan) {
if (!doCreate) {
this.mxidLock.release(lockKey);
return {
mxid: "",
created: false,
try {
if (!client) {
client = this.bridge.botIntent.underlyingClient;
}
let chan = yield this.chanStore.getByRemote(data.puppetId, data.roomId);
log.silly(chan);
const update = {
name: false,
avatar: false,
topic: false,
};
let mxid = "";
let doUpdate = false;
let created = false;
if (!chan) {
if (!doCreate) {
this.mxidLock.release(lockKey);
return {
mxid: "",
created: false,
};
}
log.info("Channel doesn't exist yet, creating entry...");
doUpdate = true;
// let's fetch the create data via hook
if (this.bridge.hooks.createChan) {
log.verbose("Fetching new override data...");
const newData = yield this.bridge.hooks.createChan(data);
if (newData && newData.puppetId === data.puppetId && newData.roomId === data.roomId) {
data = newData;
}
else {
log.warn("Override data is malformed! Old data:", data, "New data:", newData);
}
}
log.verbose("Creation data:", data);
log.verbose("Initial invites:", invites);
update.name = data.name ? true : false;
update.avatar = data.avatarUrl ? true : false;
update.topic = data.topic ? true : false;
// ooookay, we need to create this channel
const createParams = {
visibility: "private",
preset: "private_chat",
power_level_content_override: {
notifications: {
room: 0,
},
},
is_direct: data.isDirect,
invite: invites,
};
if (!data.isDirect) {
// we also want to set an alias for later reference
createParams.room_alias_name = this.bridge.AS.getAliasLocalpartForSuffix(`${data.puppetId}_${util_1.Util.str2mxid(data.roomId)}`);
}
mxid = yield client.createRoom(createParams);
yield this.chanStore.setChanOp(mxid, yield client.getUserId());
chan = this.chanStore.newData(mxid, data.roomId, data.puppetId);
created = true;
}
log.info("Channel doesn't exist yet, creating entry...");
doUpdate = true;
// let's fetch the create data via hook
if (this.bridge.hooks.createChan) {
log.verbose("Fetching new override data...");
const newData = yield this.bridge.hooks.createChan(data);
if (newData && newData.puppetId === data.puppetId && newData.roomId === data.roomId) {
data = newData;
else {
update.name = data.name !== undefined && data.name !== chan.name;
update.avatar = data.avatarUrl !== undefined && data.avatarUrl !== chan.avatarUrl;
update.topic = data.topic !== undefined && data.topic !== chan.topic;
mxid = chan.mxid;
// set new client for potential updates
const newClient = yield this.getChanOp(mxid);
if (newClient) {
client = newClient;
}
else {
log.warn("Override data is malformed! Old data:", data, "New data:", newData);
}
if (update.name) {
log.verbose("Updating name");
yield client.sendStateEvent(mxid, "m.room.name", "", { name: data.name });
chan.name = data.name;
}
if (update.avatar || data.avatarBuffer) {
log.verbose("Updating avatar");
const { doUpdate: updateAvatar, mxcUrl, hash } = yield util_1.Util.MaybeUploadFile(client, data, chan.avatarHash);
if (updateAvatar) {
update.avatar = true;
chan.avatarUrl = data.avatarUrl;
chan.avatarHash = hash;
chan.avatarMxc = mxcUrl;
yield client.sendStateEvent(mxid, "m.room.avatar", "", { url: chan.avatarMxc });
}
}
log.verbose("Creation data:", data);
log.verbose("Initial invites:", invites);
update.name = data.name ? true : false;
update.avatar = data.avatarUrl ? true : false;
update.topic = data.topic ? true : false;
// ooookay, we need to create this channel
const createParams = {
visibility: "private",
preset: "private_chat",
power_level_content_override: {
notifications: {
room: 0,
},
},
is_direct: data.isDirect,
invite: invites,
};
if (!data.isDirect) {
// we also want to set an alias for later reference
createParams.room_alias_name = this.bridge.AS.getAliasLocalpartForSuffix(`${data.puppetId}_${util_1.Util.str2mxid(data.roomId)}`);
if (update.topic) {
log.verbose("updating topic");
yield client.sendStateEvent(mxid, "m.room.topic", "", { topic: data.topic });
chan.topic = data.topic;
}
mxid = yield client.createRoom(createParams);
yield this.chanStore.setChanOp(mxid, yield client.getUserId());
chan = this.chanStore.newData(mxid, data.roomId, data.puppetId);
created = true;
}
else {
update.name = data.name !== undefined && data.name !== chan.name;
update.avatar = data.avatarUrl !== undefined && data.avatarUrl !== chan.avatarUrl;
update.topic = data.topic !== undefined && data.topic !== chan.topic;
mxid = chan.mxid;
// set new client for potential updates
const newClient = yield this.getChanOp(mxid);
if (newClient) {
client = newClient;
for (const k of Object.keys(update)) {
if (update[k]) {
doUpdate = true;
break;
}
}
}
if (update.name) {
log.verbose("Updating name");
yield client.sendStateEvent(mxid, "m.room.name", "", { name: data.name });
chan.name = data.name;
}
if (update.avatar || data.avatarBuffer) {
log.verbose("Updating avatar");
const { doUpdate: updateAvatar, mxcUrl, hash } = yield util_1.Util.MaybeUploadFile(client, data, chan.avatarHash);
if (updateAvatar) {
update.avatar = true;
chan.avatarUrl = data.avatarUrl;
chan.avatarHash = hash;
chan.avatarMxc = mxcUrl;
yield client.sendStateEvent(mxid, "m.room.avatar", "", { url: chan.avatarMxc });
if (doUpdate) {
log.verbose("Storing update to DB");
yield this.chanStore.set(chan);
}
this.mxidLock.release(lockKey);
log.verbose("Returning mxid");
return { mxid, created };
}
if (update.topic) {
log.verbose("updating topic");
yield client.sendStateEvent(mxid, "m.room.topic", "", { topic: data.topic });
chan.topic = data.topic;
catch (err) {
log.error("Error fetching mxid:", err);
this.mxidLock.release(lockKey);
throw err;
}
for (const k of Object.keys(update)) {
if (update[k]) {
doUpdate = true;
break;
}
}
if (doUpdate) {
log.verbose("Storing update to DB");
yield this.chanStore.set(chan);
}
this.mxidLock.release(lockKey);
return { mxid, created };
});

@@ -176,0 +184,0 @@ }

@@ -242,2 +242,3 @@ "use strict";

return __awaiter(this, void 0, void 0, function* () {
log.verbose(`Setting user presence for userId=${user.userId} to ${presence}`);
const client = yield this.userSync.getClient(user);

@@ -250,2 +251,3 @@ const userId = yield client.getUserId();

return __awaiter(this, void 0, void 0, function* () {
log.verbose(`Setting user status for userId=${user.userId} to ${status}`);
const client = yield this.userSync.getClient(user);

@@ -258,2 +260,3 @@ const userId = yield client.getUserId();

return __awaiter(this, void 0, void 0, function* () {
log.verbose(`Setting user typing for userId=${params.user.userId} in roomId=${params.chan.roomId} to ${typing}`);
const ret = yield this.maybePrepareSend(params);

@@ -476,3 +479,3 @@ if (!ret) {

return __awaiter(this, void 0, void 0, function* () {
const client = yield this.userSync.getClient(params.user);
log.verbose(`Maybe preparing send parameters`, params);
const mxid = yield this.chanSync.maybeGetMxid(params.chan);

@@ -482,2 +485,3 @@ if (!mxid) {

}
const client = yield this.userSync.getClient(params.user);
return { client, mxid };

@@ -839,6 +843,10 @@ });

log.info(`Got room query for alias ${alias}`);
// get room ID and check if ti is valid
// we deny room creation and then create it later on ourself
yield createRoom(false);
if (!this.hooks.createChan) {
return;
}
// get room ID and check if it is valid
const parts = this.chanSync.getPartsFromMxid(alias);
if (!parts) {
yield createRoom(false);
return;

@@ -849,7 +857,9 @@ }

if (!puppet) {
yield createRoom(false);
return;
}
// reject the lookup and create the room with invite manually instead
yield createRoom(false);
// check if this is a valid room at all
const room = yield this.hooks.createChan(parts);
if (!room || room.puppetId !== parts.puppetId || room.roomId !== parts.roomId || room.isDirect) {
return;
}
// this will also only create the room if it doesn't exist already

@@ -856,0 +866,0 @@ yield this.chanSync.getMxid(parts, undefined, [puppet.puppetMxid]);

@@ -43,2 +43,3 @@ "use strict";

// first we look if we can puppet this user to the matrix side
log.silly("Start of getClient request");
const puppetData = yield this.bridge.provisioner.get(data.puppetId);

@@ -53,70 +54,79 @@ if (puppetData && puppetData.userId === data.userId) {

// now we fetch the ghost client
yield this.clientLock.wait(data.userId);
this.clientLock.set(data.userId);
const lockKey = `${data.puppetId};${data.userId}`;
yield this.clientLock.wait(lockKey);
this.clientLock.set(lockKey);
log.info("Fetching client for " + data.userId);
let user = yield this.userStore.get(data.puppetId, data.userId);
const update = {
name: false,
avatar: false,
};
let doUpdate = false;
if (!user) {
log.info("User doesn't exist yet, creating entry...");
doUpdate = true;
// let's fetch the create data via hook
if (this.bridge.hooks.createUser) {
log.verbose("Fetching new override data...");
const newData = yield this.bridge.hooks.createUser(data);
if (newData && newData.userId === data.userId && newData.puppetId === data.puppetId) {
data = newData;
try {
let user = yield this.userStore.get(data.puppetId, data.userId);
const update = {
name: false,
avatar: false,
};
let doUpdate = false;
if (!user) {
log.info("User doesn't exist yet, creating entry...");
doUpdate = true;
// let's fetch the create data via hook
if (this.bridge.hooks.createUser) {
log.verbose("Fetching new override data...");
const newData = yield this.bridge.hooks.createUser(data);
if (newData && newData.userId === data.userId && newData.puppetId === data.puppetId) {
data = newData;
}
else {
log.warn("Override data is malformed! Old data:", data, "New data:", newData);
}
}
else {
log.warn("Override data is malformed! Old data:", data, "New data:", newData);
}
update.name = data.name ? true : false;
update.avatar = data.avatarUrl ? true : false;
user = this.userStore.newData(data.puppetId, data.userId);
}
update.name = data.name ? true : false;
update.avatar = data.avatarUrl ? true : false;
user = this.userStore.newData(data.puppetId, data.userId);
}
else {
update.name = data.name !== undefined && data.name !== user.name;
update.avatar = data.avatarUrl !== undefined && data.avatarUrl !== user.avatarUrl;
}
const intent = this.bridge.AS.getIntentForSuffix(`${data.puppetId}_${util_1.Util.str2mxid(data.userId)}`);
yield intent.ensureRegistered();
const client = intent.underlyingClient;
if (update.name) {
log.verbose("Updating name");
// we *don't* await here as setting the name might take a
// while due to updating all those m.room.member events, we can do that in the BG
// tslint:disable-next-line:no-floating-promises
client.setDisplayName(data.name || "");
user.name = data.name;
}
if (update.avatar || data.avatarBuffer) {
log.verbose("Updating avatar");
const { doUpdate: updateAvatar, mxcUrl, hash } = yield util_1.Util.MaybeUploadFile(client, data, user.avatarHash);
if (updateAvatar) {
update.avatar = true;
user.avatarUrl = data.avatarUrl;
user.avatarHash = hash;
user.avatarMxc = mxcUrl;
// we *don't* await here as that can take rather long
// and we might as well do this in the background
else {
update.name = data.name !== undefined && data.name !== user.name;
update.avatar = data.avatarUrl !== undefined && data.avatarUrl !== user.avatarUrl;
}
const intent = this.bridge.AS.getIntentForSuffix(`${data.puppetId}_${util_1.Util.str2mxid(data.userId)}`);
yield intent.ensureRegistered();
const client = intent.underlyingClient;
if (update.name) {
log.verbose("Updating name");
// we *don't* await here as setting the name might take a
// while due to updating all those m.room.member events, we can do that in the BG
// tslint:disable-next-line:no-floating-promises
client.setAvatarUrl(user.avatarMxc || "");
client.setDisplayName(data.name || "");
user.name = data.name;
}
}
for (const k of Object.keys(update)) {
if (update[k]) {
doUpdate = true;
break;
if (update.avatar || data.avatarBuffer) {
log.verbose("Updating avatar");
const { doUpdate: updateAvatar, mxcUrl, hash } = yield util_1.Util.MaybeUploadFile(client, data, user.avatarHash);
if (updateAvatar) {
update.avatar = true;
user.avatarUrl = data.avatarUrl;
user.avatarHash = hash;
user.avatarMxc = mxcUrl;
// we *don't* await here as that can take rather long
// and we might as well do this in the background
// tslint:disable-next-line:no-floating-promises
client.setAvatarUrl(user.avatarMxc || "");
}
}
for (const k of Object.keys(update)) {
if (update[k]) {
doUpdate = true;
break;
}
}
if (doUpdate) {
log.verbose("Storing update to DB");
yield this.userStore.set(user);
}
this.clientLock.release(lockKey);
log.verbose("Returning client");
return client;
}
if (doUpdate) {
log.verbose("Storing update to DB");
yield this.userStore.set(user);
catch (err) {
log.error("Error fetching client:", err);
this.clientLock.release(lockKey);
throw err;
}
this.clientLock.release(data.userId);
return client;
});

@@ -123,0 +133,0 @@ }

{
"name": "mx-puppet-bridge",
"version": "0.0.8",
"version": "0.0.9",
"description": "Matrix Puppeting Bridge library",

@@ -5,0 +5,0 @@ "repository": {

@@ -115,3 +115,3 @@ import { PuppetBridge } from "./puppetbridge";

for (const u of users) {
const nameHtml = escapeHtml(u.name);
const nameHtml = escapeHtml(u.name);
if (u.category) {

@@ -152,3 +152,3 @@ reply += `${u.name}:\n`;

for (const c of chans) {
const nameHtml = escapeHtml(c.name);
const nameHtml = escapeHtml(c.name);
if (c.category) {

@@ -173,3 +173,4 @@ reply += `${c.name}:\n`;

default:
await this.sendMessage(roomId, `Available commands: help, list, link, unlink, setmatrixtoken, listusers, listchannels`);
await this.sendMessage(roomId, "Available commands: help, list, link, " +
"unlink, setmatrixtoken, listusers, listchannels");
}

@@ -176,0 +177,0 @@ }

@@ -82,124 +82,132 @@ import { PuppetBridge } from "./puppetbridge";

log.info(`Fetching mxid for roomId ${data.roomId} and puppetId ${data.puppetId}`);
if (!client) {
client = this.bridge.botIntent.underlyingClient;
}
let chan = await this.chanStore.getByRemote(data.puppetId, data.roomId);
log.silly(chan);
const update = {
name: false,
avatar: false,
topic: false,
};
let mxid = "";
let doUpdate = false;
let created = false;
if (!chan) {
if (!doCreate) {
this.mxidLock.release(lockKey);
return {
mxid: "",
created: false,
};
try {
if (!client) {
client = this.bridge.botIntent.underlyingClient;
}
log.info("Channel doesn't exist yet, creating entry...");
doUpdate = true;
// let's fetch the create data via hook
if (this.bridge.hooks.createChan) {
log.verbose("Fetching new override data...");
const newData = await this.bridge.hooks.createChan(data);
if (newData && newData.puppetId === data.puppetId && newData.roomId === data.roomId) {
data = newData;
} else {
log.warn("Override data is malformed! Old data:", data, "New data:", newData);
let chan = await this.chanStore.getByRemote(data.puppetId, data.roomId);
log.silly(chan);
const update = {
name: false,
avatar: false,
topic: false,
};
let mxid = "";
let doUpdate = false;
let created = false;
if (!chan) {
if (!doCreate) {
this.mxidLock.release(lockKey);
return {
mxid: "",
created: false,
};
}
}
log.verbose("Creation data:", data);
log.verbose("Initial invites:", invites);
update.name = data.name ? true : false;
update.avatar = data.avatarUrl ? true : false;
update.topic = data.topic ? true : false;
// ooookay, we need to create this channel
const createParams = {
visibility: "private",
preset: "private_chat",
power_level_content_override: {
notifications: {
room: 0,
log.info("Channel doesn't exist yet, creating entry...");
doUpdate = true;
// let's fetch the create data via hook
if (this.bridge.hooks.createChan) {
log.verbose("Fetching new override data...");
const newData = await this.bridge.hooks.createChan(data);
if (newData && newData.puppetId === data.puppetId && newData.roomId === data.roomId) {
data = newData;
} else {
log.warn("Override data is malformed! Old data:", data, "New data:", newData);
}
}
log.verbose("Creation data:", data);
log.verbose("Initial invites:", invites);
update.name = data.name ? true : false;
update.avatar = data.avatarUrl ? true : false;
update.topic = data.topic ? true : false;
// ooookay, we need to create this channel
const createParams = {
visibility: "private",
preset: "private_chat",
power_level_content_override: {
notifications: {
room: 0,
},
},
},
is_direct: data.isDirect,
invite: invites,
} as any;
if (!data.isDirect) {
// we also want to set an alias for later reference
createParams.room_alias_name = this.bridge.AS.getAliasLocalpartForSuffix(
`${data.puppetId}_${Util.str2mxid(data.roomId)}`);
}
mxid = await client!.createRoom(createParams);
await this.chanStore.setChanOp(mxid, await client!.getUserId());
chan = this.chanStore.newData(mxid, data.roomId, data.puppetId);
created = true;
} else {
update.name = data.name !== undefined && data.name !== chan.name;
update.avatar = data.avatarUrl !== undefined && data.avatarUrl !== chan.avatarUrl;
update.topic = data.topic !== undefined && data.topic !== chan.topic;
mxid = chan.mxid;
is_direct: data.isDirect,
invite: invites,
} as any;
if (!data.isDirect) {
// we also want to set an alias for later reference
createParams.room_alias_name = this.bridge.AS.getAliasLocalpartForSuffix(
`${data.puppetId}_${Util.str2mxid(data.roomId)}`);
}
mxid = await client!.createRoom(createParams);
await this.chanStore.setChanOp(mxid, await client!.getUserId());
chan = this.chanStore.newData(mxid, data.roomId, data.puppetId);
created = true;
} else {
update.name = data.name !== undefined && data.name !== chan.name;
update.avatar = data.avatarUrl !== undefined && data.avatarUrl !== chan.avatarUrl;
update.topic = data.topic !== undefined && data.topic !== chan.topic;
mxid = chan.mxid;
// set new client for potential updates
const newClient = await this.getChanOp(mxid);
if (newClient) {
client = newClient;
// set new client for potential updates
const newClient = await this.getChanOp(mxid);
if (newClient) {
client = newClient;
}
}
}
if (update.name) {
log.verbose("Updating name");
await client!.sendStateEvent(
mxid,
"m.room.name",
"",
{ name: data.name },
);
chan.name = data.name;
}
if (update.avatar || data.avatarBuffer) {
log.verbose("Updating avatar");
const { doUpdate: updateAvatar, mxcUrl, hash } = await Util.MaybeUploadFile(client!, data, chan.avatarHash);
if (updateAvatar) {
update.avatar = true;
chan.avatarUrl = data.avatarUrl;
chan.avatarHash = hash;
chan.avatarMxc = mxcUrl;
if (update.name) {
log.verbose("Updating name");
await client!.sendStateEvent(
mxid,
"m.room.avatar",
"m.room.name",
"",
{ url: chan.avatarMxc },
{ name: data.name },
);
chan.name = data.name;
}
}
if (update.topic) {
log.verbose("updating topic");
await client!.sendStateEvent(
mxid,
"m.room.topic",
"",
{ topic: data.topic },
);
chan.topic = data.topic;
}
if (update.avatar || data.avatarBuffer) {
log.verbose("Updating avatar");
const { doUpdate: updateAvatar, mxcUrl, hash } = await Util.MaybeUploadFile(client!, data, chan.avatarHash);
if (updateAvatar) {
update.avatar = true;
chan.avatarUrl = data.avatarUrl;
chan.avatarHash = hash;
chan.avatarMxc = mxcUrl;
await client!.sendStateEvent(
mxid,
"m.room.avatar",
"",
{ url: chan.avatarMxc },
);
}
}
if (update.topic) {
log.verbose("updating topic");
await client!.sendStateEvent(
mxid,
"m.room.topic",
"",
{ topic: data.topic },
);
chan.topic = data.topic;
}
for (const k of Object.keys(update)) {
if (update[k]) {
doUpdate = true;
break;
for (const k of Object.keys(update)) {
if (update[k]) {
doUpdate = true;
break;
}
}
}
if (doUpdate) {
log.verbose("Storing update to DB");
await this.chanStore.set(chan);
if (doUpdate) {
log.verbose("Storing update to DB");
await this.chanStore.set(chan);
}
this.mxidLock.release(lockKey);
log.verbose("Returning mxid");
return { mxid, created };
} catch (err) {
log.error("Error fetching mxid:", err);
this.mxidLock.release(lockKey);
throw err;
}
this.mxidLock.release(lockKey);
return { mxid, created };
}

@@ -206,0 +214,0 @@

@@ -361,2 +361,3 @@ import * as fs from "fs";

public async setUserPresence(user: IRemoteUser, presence: MatrixPresence) {
log.verbose(`Setting user presence for userId=${user.userId} to ${presence}`);
const client = await this.userSync.getClient(user);

@@ -368,2 +369,3 @@ const userId = await client.getUserId();

public async setUserStatus(user: IRemoteUser, status: string) {
log.verbose(`Setting user status for userId=${user.userId} to ${status}`);
const client = await this.userSync.getClient(user);

@@ -375,2 +377,3 @@ const userId = await client.getUserId();

public async setUserTyping(params: IReceiveParams, typing: boolean) {
log.verbose(`Setting user typing for userId=${params.user.userId} in roomId=${params.chan.roomId} to ${typing}`);
const ret = await this.maybePrepareSend(params);

@@ -578,3 +581,3 @@ if (!ret) {

private async maybePrepareSend(params: IReceiveParams): Promise<ISendInfo | null> {
const client = await this.userSync.getClient(params.user);
log.verbose(`Maybe preparing send parameters`, params);
const mxid = await this.chanSync.maybeGetMxid(params.chan);

@@ -584,2 +587,3 @@ if (!mxid) {

}
const client = await this.userSync.getClient(params.user);
return { client, mxid };

@@ -936,6 +940,10 @@ }

log.info(`Got room query for alias ${alias}`);
// get room ID and check if ti is valid
// we deny room creation and then create it later on ourself
await createRoom(false);
if (!this.hooks.createChan) {
return;
}
// get room ID and check if it is valid
const parts = this.chanSync.getPartsFromMxid(alias);
if (!parts) {
await createRoom(false);
return;

@@ -946,7 +954,11 @@ }

if (!puppet) {
await createRoom(false);
return;
}
// reject the lookup and create the room with invite manually instead
await createRoom(false);
// check if this is a valid room at all
const room = await this.hooks.createChan(parts);
if (!room || room.puppetId !== parts.puppetId || room.roomId !== parts.roomId || room.isDirect) {
return;
}
// this will also only create the room if it doesn't exist already

@@ -953,0 +965,0 @@ await this.chanSync.getMxid(parts, undefined, [puppet.puppetMxid]);

@@ -49,2 +49,3 @@ import { PuppetBridge } from "./puppetbridge";

// first we look if we can puppet this user to the matrix side
log.silly("Start of getClient request");
const puppetData = await this.bridge.provisioner.get(data.puppetId);

@@ -60,71 +61,79 @@ if (puppetData && puppetData.userId === data.userId) {

// now we fetch the ghost client
await this.clientLock.wait(data.userId);
this.clientLock.set(data.userId);
const lockKey = `${data.puppetId};${data.userId}`;
await this.clientLock.wait(lockKey);
this.clientLock.set(lockKey);
log.info("Fetching client for " + data.userId);
let user = await this.userStore.get(data.puppetId, data.userId);
const update = {
name: false,
avatar: false,
};
let doUpdate = false;
if (!user) {
log.info("User doesn't exist yet, creating entry...");
doUpdate = true;
// let's fetch the create data via hook
if (this.bridge.hooks.createUser) {
log.verbose("Fetching new override data...");
const newData = await this.bridge.hooks.createUser(data);
if (newData && newData.userId === data.userId && newData.puppetId === data.puppetId) {
data = newData;
} else {
log.warn("Override data is malformed! Old data:", data, "New data:", newData);
try {
let user = await this.userStore.get(data.puppetId, data.userId);
const update = {
name: false,
avatar: false,
};
let doUpdate = false;
if (!user) {
log.info("User doesn't exist yet, creating entry...");
doUpdate = true;
// let's fetch the create data via hook
if (this.bridge.hooks.createUser) {
log.verbose("Fetching new override data...");
const newData = await this.bridge.hooks.createUser(data);
if (newData && newData.userId === data.userId && newData.puppetId === data.puppetId) {
data = newData;
} else {
log.warn("Override data is malformed! Old data:", data, "New data:", newData);
}
}
update.name = data.name ? true : false;
update.avatar = data.avatarUrl ? true : false;
user = this.userStore.newData(data.puppetId, data.userId);
} else {
update.name = data.name !== undefined && data.name !== user.name;
update.avatar = data.avatarUrl !== undefined && data.avatarUrl !== user.avatarUrl;
}
update.name = data.name ? true : false;
update.avatar = data.avatarUrl ? true : false;
user = this.userStore.newData(data.puppetId, data.userId);
} else {
update.name = data.name !== undefined && data.name !== user.name;
update.avatar = data.avatarUrl !== undefined && data.avatarUrl !== user.avatarUrl;
}
const intent = this.bridge.AS.getIntentForSuffix(`${data.puppetId}_${Util.str2mxid(data.userId)}`);
await intent.ensureRegistered();
const client = intent.underlyingClient;
if (update.name) {
log.verbose("Updating name");
// we *don't* await here as setting the name might take a
// while due to updating all those m.room.member events, we can do that in the BG
// tslint:disable-next-line:no-floating-promises
client.setDisplayName(data.name || "");
user.name = data.name;
}
if (update.avatar || data.avatarBuffer) {
log.verbose("Updating avatar");
const { doUpdate: updateAvatar, mxcUrl, hash } = await Util.MaybeUploadFile(client, data, user.avatarHash);
if (updateAvatar) {
update.avatar = true;
user.avatarUrl = data.avatarUrl;
user.avatarHash = hash;
user.avatarMxc = mxcUrl;
// we *don't* await here as that can take rather long
// and we might as well do this in the background
const intent = this.bridge.AS.getIntentForSuffix(`${data.puppetId}_${Util.str2mxid(data.userId)}`);
await intent.ensureRegistered();
const client = intent.underlyingClient;
if (update.name) {
log.verbose("Updating name");
// we *don't* await here as setting the name might take a
// while due to updating all those m.room.member events, we can do that in the BG
// tslint:disable-next-line:no-floating-promises
client.setAvatarUrl(user.avatarMxc || "");
client.setDisplayName(data.name || "");
user.name = data.name;
}
}
if (update.avatar || data.avatarBuffer) {
log.verbose("Updating avatar");
const { doUpdate: updateAvatar, mxcUrl, hash } = await Util.MaybeUploadFile(client, data, user.avatarHash);
if (updateAvatar) {
update.avatar = true;
user.avatarUrl = data.avatarUrl;
user.avatarHash = hash;
user.avatarMxc = mxcUrl;
// we *don't* await here as that can take rather long
// and we might as well do this in the background
// tslint:disable-next-line:no-floating-promises
client.setAvatarUrl(user.avatarMxc || "");
}
}
for (const k of Object.keys(update)) {
if (update[k]) {
doUpdate = true;
break;
for (const k of Object.keys(update)) {
if (update[k]) {
doUpdate = true;
break;
}
}
}
if (doUpdate) {
log.verbose("Storing update to DB");
await this.userStore.set(user);
}
if (doUpdate) {
log.verbose("Storing update to DB");
await this.userStore.set(user);
}
this.clientLock.release(data.userId);
this.clientLock.release(lockKey);
return client;
log.verbose("Returning client");
return client;
} catch (err) {
log.error("Error fetching client:", err);
this.clientLock.release(lockKey);
throw err;
}
}

@@ -131,0 +140,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc