Skip to content

Commit

Permalink
Merge pull request #254 from matrix-org/hs/add-more-intent-calls
Browse files Browse the repository at this point in the history
Add more intent calls
  • Loading branch information
Half-Shot authored Oct 21, 2020
2 parents 4c3538f + 290fb95 commit 2ff23db
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 12 deletions.
1 change: 1 addition & 0 deletions changelog.d/254.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `uploadContent()`, and `setRoomDirectoryVisibility()` intent functions
57 changes: 47 additions & 10 deletions src/components/intent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { unstable } from "../errors";
import BridgeErrorReason = unstable.BridgeErrorReason;
import { APPSERVICE_LOGIN_TYPE, ClientEncryptionSession } from "./encryption";
import Logging from "./logging";
import { ReadStream } from "fs";

const log = Logging.get("Intent");

Expand Down Expand Up @@ -58,6 +59,12 @@ export interface RoomCreationOpts {
options: Record<string, unknown>;
}

export interface FileUploadOpts {
name?: string;
includeFilename?: boolean;
type?: string;
}

/**
* Returns the first parameter that is a number or 0.
*/
Expand All @@ -70,10 +77,6 @@ const returnFirstNumber = (...args: unknown[]) => {
return 0;
}

const STATE_EVENT_TYPES = [
"m.room.name", "m.room.topic", "m.room.power_levels", "m.room.member",
"m.room.join_rules", "m.room.history_visibility"
];
const DEFAULT_CACHE_TTL = 90000;
const DEFAULT_CACHE_SIZE = 1024;

Expand Down Expand Up @@ -316,7 +319,6 @@ export class Intent {
*/
public async sendTyping(roomId: string, isTyping: boolean) {
await this._ensureJoined(roomId);
await this._ensureHasPowerLevelFor(roomId, "m.typing");
return this.client.sendTyping(roomId, isTyping);
}

Expand Down Expand Up @@ -344,7 +346,7 @@ export class Intent {
*/
public async setPowerLevel(roomId: string, target: string, level: number|undefined) {
await this._ensureJoined(roomId);
const event = await this._ensureHasPowerLevelFor(roomId, "m.room.power_levels");
const event = await this._ensureHasPowerLevelFor(roomId, "m.room.power_levels", true);
return this.client.setPowerLevel(roomId, target, level, event);
}

Expand Down Expand Up @@ -378,7 +380,7 @@ export class Intent {
await this.encryption.ensureClientSyncingCallback();
}
await this._ensureJoined(roomId);
await this._ensureHasPowerLevelFor(roomId, type);
await this._ensureHasPowerLevelFor(roomId, type, false);
return this._joinGuard(roomId, async() =>
// eslint-disable-next-line camelcase
this.client.sendEvent(roomId, type, content) as Promise<{event_id: string}>
Expand All @@ -399,7 +401,7 @@ export class Intent {
// eslint-disable-next-line camelcase
): Promise<{event_id: string}> {
await this._ensureJoined(roomId);
await this._ensureHasPowerLevelFor(roomId, type);
await this._ensureHasPowerLevelFor(roomId, type, true);
return this._joinGuard(roomId, async() =>
// eslint-disable-next-line camelcase
this.client.sendStateEvent(roomId, type, content, skey) as Promise<{event_id: string}>
Expand Down Expand Up @@ -697,6 +699,40 @@ export class Intent {
return this.client.getStateEvent(roomId, eventType, stateKey);
}

/**
* Upload a file to the homeserver.
* @param content The file contents
* @param opts Additional options for the upload.
* @returns A MXC URL pointing to the uploaded data.
*/
public async uploadContent(content: Buffer|string|ReadStream, opts: FileUploadOpts = {}): Promise<string> {
await this.ensureRegistered();
return this.client.uploadContent(content, {...opts, onlyContentUri: true});
}

/**
* Set the visibility of a room in the homeserver's room directory.
* @param roomId The room
* @param visibility Should the room be visible
*/
public async setRoomDirectoryVisibility(roomId: string, visibility: "public"|"private") {
await this.ensureRegistered();
return this.client.setRoomDirectoryVisibility(roomId, visibility);
}

/**
* Set the visibility of a room in the appservice's room directory.
* This only works if you have defined the `protocol` in the registration file.
* @param roomId The room
* @param networkId The network (not protocol) that owns this room. E.g. "freenode" (for an IRC bridge)
* @param visibility Should the room be visible
*/
public async setRoomDirectoryVisibilityAppService(roomId: string, networkId: string,
visibility: "public"|"private") {
await this.ensureRegistered();
return this.client.setRoomDirectoryVisibilityAppService(roomId, visibility, networkId);
}

/**
* Inform this Intent class of an incoming event. Various optimisations will be
* done if this is provided. For example, a /join request won't be sent out if
Expand Down Expand Up @@ -838,9 +874,10 @@ export class Intent {
* Ensures that the client has the required power level to post the event type.
* @param roomId Required as power levels exist inside a room.
* @param eventTypes The event type to check the permissions for.
* @param isState Are we checking for state permissions or regular event permissions.
* @return If found, the power level event
*/
private async _ensureHasPowerLevelFor(roomId: string, eventType: string) {
private async _ensureHasPowerLevelFor(roomId: string, eventType: string, isState: boolean) {
if (this.opts.dontCheckPowerLevel && eventType !== "m.room.power_levels") {
return undefined;
}
Expand All @@ -859,7 +896,7 @@ export class Intent {
}
const powerLevelEvent = new MatrixEvent(event);
// What level do we need for this event type?
const defaultLevel = STATE_EVENT_TYPES.includes(eventType)
const defaultLevel = isState
? event.content.state_default
: event.content.events_default;
const requiredLevel = returnFirstNumber(
Expand Down
5 changes: 3 additions & 2 deletions src/components/state-lookup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import PQueue from "p-queue";
import { Intent } from "..";

interface StateLookupOpts {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -48,7 +49,7 @@ const DEFAULT_STATE_CONCURRENCY = 4;

export class StateLookup {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private _client: any;
private _client: any|Intent;
private eventTypes: {[eventType: string]: boolean} = {};
private dict: { [roomId: string]: StateLookupRoom } = {};
private lookupQueue: PQueue;
Expand Down Expand Up @@ -81,7 +82,7 @@ export class StateLookup {

this.retryStateIn = opts.retryStateInMs || RETRY_STATE_IN_MS;

this._client = opts.client;
this._client = opts.client instanceof Intent ? opts.client.client : opts.client;
(opts.eventTypes || []).forEach((t) => {
this.eventTypes[t] = true;
});
Expand Down

0 comments on commit 2ff23db

Please sign in to comment.