Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
public GetIntentFromDiscordMember(member: Discord.GuildMember | Discord.User, webhookID?: string): Intent {
if (webhookID) {
// webhookID and user IDs are the same, they are unique, so no need to prefix _webhook_
const name = member instanceof Discord.User ? member.username : member.user.username;
const nameId = new MatrixUser(`@${name}`).localpart;
return this.bridge.getIntentFromLocalpart(`_discord_${webhookID}_${nameId}`);
}
return this.bridge.getIntentFromLocalpart(`_discord_${member.id}`);
}
public async setUserAccessToken(userId: string, teamId: string, slackId: string, accessToken: string, puppeting: boolean) {
let matrixUser = await this.datastore.getMatrixUser(userId);
matrixUser = matrixUser ? matrixUser : new BridgeMatrixUser(userId);
const accounts = matrixUser.get("accounts") || {};
accounts[slackId] = {
access_token: accessToken,
team_id: teamId,
};
matrixUser.set("accounts", accounts);
await this.datastore.storeMatrixUser(matrixUser);
if (puppeting) {
// Store it here too for puppeting.
await this.datastore.setPuppetToken(teamId, slackId, userId, accessToken);
await this.slackRtm!.startUserClient({
teamId,
slackId,
matrixId: userId,
token: accessToken,
});
if (relatesTo && relatesTo["m.in_reply_to"]) {
eventId = relatesTo["m.in_reply_to"].event_id;
} else {
return;
}
const intent = this.bridge.getIntent();
// Try to get the event.
try {
const sourceEvent = await intent.getEvent(event.room_id, eventId);
sourceEvent.content.body = sourceEvent.content.body || "Reply with unknown content";
const replyEmbed = (await this.EventToEmbed(sourceEvent, channel, false)).messageEmbed;
// if we reply to a discord member, ping them!
if (this.bridge.getBot().isRemoteUser(sourceEvent.sender)) {
const uid = new MatrixUser(sourceEvent.sender.replace("@", "")).localpart.substring("_discord".length);
replyEmbed.addField("ping", `<@${uid}>`);
}
replyEmbed.setTimestamp(new Date(sourceEvent.origin_server_ts));
if (this.HasAttachment(sourceEvent)) {
const mxClient = this.bridge.getClientFactory().getClientAs();
const url = mxClient.mxcUrlToHttp(sourceEvent.content.url);
if (["m.image", "m.sticker"].includes(sourceEvent.content.msgtype as string)
|| sourceEvent.type === "m.sticker") {
// we have an image reply
replyEmbed.setImage(url);
} else {
const name = this.GetFilenameForMediaEvent(sourceEvent.content);
replyEmbed.description = `[${name}](${url})`;
}
public async storeGhost(
userId: string, protocol: BifrostProtocol, username: string,
): Promise<{remote: BifrostRemoteUser, matrix: MatrixUser}> {
const acctProps = {
user_id: userId,
sender_name: username,
protocol_id: protocol.id,
// tslint:disable-next-line: no-any
} as any;
const statement = PgDataStore.BuildUpsertStatement("remote_users", "(user_id)", Object.keys(acctProps));
await this.pgPool.query(statement, Object.values(acctProps));
return {
matrix: new MatrixUser(userId),
remote: new BifrostRemoteUser(userId, username, protocol.id, true),
};
}
public async GetUserUpdateState(discordUser: User, webhookID?: string): Promise {
log.verbose(`State update requested for ${discordUser.id}`);
let mxidExtra = "";
if (webhookID) {
// no need to escape as this mxid is only used to create an intent
mxidExtra = `_${new MatrixUser(`@${webhookID}`).localpart}`;
}
const userState: IUserState = Object.assign({}, DEFAULT_USER_STATE, {
id: discordUser.id,
mxUserId: `@_discord_${discordUser.id}${mxidExtra}:${this.config.bridge.domain}`,
});
const displayName = Util.ApplyPatternString(this.config.ghosts.usernamePattern, {
id: discordUser.id,
tag: discordUser.discriminator,
username: discordUser.username,
});
// Determine if the user exists.
const remoteId = discordUser.id + mxidExtra;
const remoteUser = await this.userStore.getRemoteUser(remoteId);
if (remoteUser === null) {
log.verbose(`Could not find user in remote user store.`);
userState.createUser = true;
public getMxIdForProtocol(
senderId: string,
domain: string,
prefix: string = "",
isGroupChat: boolean = false): MatrixUser {
// This is a little bad, but we drop the prpl- because it's a bit ugly.
const protocolName = this.id.startsWith("prpl-") ? this.id.substr("prpl-".length) : this.id;
// senderId containing : can mess things up
senderId = senderId.replace(/\:/g, "=3a");
return new MatrixUser(`@${prefix}${protocolName}_${senderId}:${domain}`);
}
}
public async GetUserStateForDiscordUser(
user: User,
webhookID?: string,
): Promise {
let mxidExtra = "";
if (webhookID) {
// no need to escape as this mxid is only used to create an Intent
mxidExtra = `_${new MatrixUser(`@${user.username}`).localpart}`;
}
const guildState: IGuildMemberState = Object.assign({}, DEFAULT_GUILD_STATE, {
bot: user.bot,
displayName: user.username,
id: user.id,
mxUserId: `@_discord_${user.id}${mxidExtra}:${this.config.bridge.domain}`,
roles: [],
username: user.tag,
});
return guildState;
}
public generateParameters(parameters: {[key: string]: string}, mxId: string, profile: any = {})
: {[key: string]: string} {
const body = {};
const mxUser = new MatrixUser(mxId);
for (const key of Object.keys(parameters)) {
let val = parameters[key];
val = val.replace("", mxUser.getId());
val = val.replace("", this.getSaneMxId(mxUser.getId()));
val = val.replace("", mxUser.localpart);
val = val.replace("", mxUser.host);
val = val.replace("", profile.displayname || mxUser.localpart);
val = val.replace("", Util.passwordGen(32));
val = val.replace("", profile.avatar_url || "");
body[key] = val;
}
return body;
}
return store.getMatrixUser(user_id).then((matrixUser) => {
matrixUser = matrixUser ? matrixUser : new BridgeLib.MatrixUser(userId);
const accounts = matrixUser.get("accounts") || {};
delete accounts[slack_id];
matrixUser.set("accounts", accounts);
store.setMatrixUser(matrixUser);
log.info(`Removed accoun ${slack_id} from ${userId}`);
});
}