Skip to content

Commit

Permalink
Merge branch 'develop' into tadzik/webhook-verification
Browse files Browse the repository at this point in the history
  • Loading branch information
tadzik committed Jun 5, 2024
2 parents 4d312a3 + 55d8e65 commit e6d0359
Show file tree
Hide file tree
Showing 11 changed files with 806 additions and 21 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ jobs:
with:
node-version: "${{ matrix.node_version }}"
- run: yarn --pure-lockfile
- name: Set up PostgreSQL 11
- name: Set up PostgreSQL 13
run: |
docker run --detach --publish 5432:5432 \
--env POSTGRES_PASSWORD=pass \
--env POSTGRES_INITDB_ARGS="--lc-collate C --lc-ctype C --encoding UTF8" \
postgres:11
postgres:13
- run: yarn test:postgres
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ lib-cov

# Coverage directory used by tools like istanbul
coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
Expand Down
1 change: 1 addition & 0 deletions changelog.d/766.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
User correct Matrix accounts when redacting events.
1 change: 1 addition & 0 deletions changelog.d/777.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a way to measure test coverage.
1 change: 1 addition & 0 deletions changelog.d/783.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update integration test to use Postgres 13.
2 changes: 1 addition & 1 deletion docs/puppeting.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ oauth2:
```
You must enable puppeting and RTM support. RTM support means the bridge will
use websockets to communicate with the bridge rather than HTTP pushed events.
use websockets to communicate with Slack rather than using HTTP pushed events.
Finally, you must have OAuth2 configured. OAuth2 is used to authenticate
users with Slack and get the required access tokens in order to puppet
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"build:app": "tsc --build",
"build:widget": "vite build --config widget/vite.config.ts",
"test": "yarn test:unit && yarn test:integration",
"test:coverage": "nyc --reporter=text --reporter=html mocha --exit --reporter list --ui bdd --require ts-node/register --recursive tests/*/*.ts",
"test:unit": "mocha --require ts-node/register --recursive tests/unit/*.ts",
"test:integration": "mocha --exit --reporter list --ui bdd --require ts-node/register --recursive tests/integration/*.ts",
"test:postgres": "SLACKBRIDGE_TEST_ENABLEPG=yes mocha --reporter list --ui bdd --require ts-node/register --recursive tests/integration/PgDatastoreTest.ts",
Expand Down Expand Up @@ -86,6 +87,7 @@
"js-yaml": "^4.1.0",
"mocha": "^10.0.0",
"node-mocks-http": "^1.14.1",
"nyc": "^15.1.0",
"postcss": "^8.4.21",
"prom-client": "^14.0.1",
"source-map-support": "^0.5.19",
Expand Down
1 change: 1 addition & 0 deletions src/BaseSlackHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface ISlackEventMessageAttachment {
}

export interface ISlackMessageEvent extends ISlackEvent {
team?: string;
team_domain?: string;
team_id?: string;
user?: string;
Expand Down
46 changes: 41 additions & 5 deletions src/SlackEventHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { BaseSlackHandler, ISlackEvent, ISlackMessageEvent, ISlackUser } from ".
import { BridgedRoom } from "./BridgedRoom";
import { Main, METRIC_RECEIVED_MESSAGE } from "./Main";
import { Logger } from "matrix-appservice-bridge";
import { TeamEntry } from "./datastore/Models";
const log = new Logger("SlackEventHandler");

/**
Expand Down Expand Up @@ -289,11 +290,10 @@ export class SlackEventHandler extends BaseSlackHandler {
}
}
} else if (msg.subtype === "message_deleted" && msg.deleted_ts) {
const originalEvent = await this.main.datastore.getEventBySlackId(msg.channel, msg.deleted_ts);
if (originalEvent) {
const botClient = this.main.botIntent.matrixClient;
await botClient.redactEvent(originalEvent.roomId, originalEvent.eventId);
return;
try {
await this.deleteMessage(msg, team);
} catch (err) {
log.error(err);
}
// If we don't have the event
throw Error("unknown_message");
Expand All @@ -315,6 +315,42 @@ export class SlackEventHandler extends BaseSlackHandler {
return room.onSlackMessage(msg);
}

private async deleteMessage(msg: ISlackMessageEvent, team: TeamEntry): Promise<void> {
const originalEvent = await this.main.datastore.getEventBySlackId(msg.channel, msg.deleted_ts!);
if (originalEvent) {
const previousMessage = msg.previous_message;
if (!previousMessage) {
throw new Error(`Cannot delete message with no previous_message: ${JSON.stringify(msg)}`);
}

// Try to determine the Matrix user responsible for deleting the message, fallback to our main bot if all else fails
if (!previousMessage.user) {
log.warn("We don't know the original sender of", previousMessage, "will try to remove with our bot");
}

const isOurMessage = previousMessage.subtype === 'bot_message' && (previousMessage.bot_id === team.bot_id);

if (previousMessage.user && !isOurMessage) {
try {
const ghost = await this.main.ghostStore.get(previousMessage.user, previousMessage.team_domain, previousMessage.team);
await ghost.redactEvent(originalEvent.roomId, originalEvent.eventId);
return;
} catch (err) {
log.warn(`Failed to remove message on behalf of ${previousMessage.user}, falling back to our bot`);
}
}

try {
const botClient = this.main.botIntent.matrixClient;
await botClient.redactEvent(originalEvent.roomId, originalEvent.eventId, "Deleted on Slack");
} catch (err) {
throw new Error(
`Failed to remove message ${JSON.stringify(previousMessage)} with our Matrix bot. insufficient power level? Error: ${err}`
);
}
}
}

private async handleReaction(event: ISlackEventReaction, teamId: string) {
// Reactions store the channel in the item
const channel = event.item.channel;
Expand Down
7 changes: 7 additions & 0 deletions src/SlackGhost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,13 @@ export class SlackGhost {
return Slackdown.parse(body);
}

public async redactEvent(roomId: string, eventId: string) {
if (!this._intent) {
throw Error('No intent associated with ghost');
}
await this._intent.matrixClient.redactEvent(roomId, eventId);
}

public async sendInThread(roomId: string, text: string, slackRoomId: string,
slackEventTs: string, replyEvent: IMatrixReplyEvent): Promise<void> {
const content = {
Expand Down
Loading

0 comments on commit e6d0359

Please sign in to comment.