Merge branch 'develop' into sort-imports

Signed-off-by: Aaron Raimist <aaron@raim.ist>
This commit is contained in:
Aaron Raimist 2021-12-09 08:34:20 +00:00
commit 7b94e13a84
642 changed files with 30052 additions and 8035 deletions

View file

@ -15,11 +15,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const request = require('request-promise-native');
const cheerio = require('cheerio');
const url = require("url");
import request = require('request-promise-native');
import * as cheerio from 'cheerio';
import * as url from "url";
module.exports.approveConsent = async function(consentUrl) {
export const approveConsent = async function(consentUrl: string): Promise<void> {
const body = await request.get(consentUrl);
const doc = cheerio.load(body);
const v = doc("input[name=v]").val();

View file

@ -15,13 +15,17 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const { exec } = require('child_process');
const request = require('request-promise-native');
import { exec } from 'child_process';
import request = require('request-promise-native');
import { RestSession } from './session';
import { RestMultiSession } from './multi';
const RestSession = require('./session');
const RestMultiSession = require('./multi');
interface ExecResult {
stdout: string;
stderr: string;
}
function execAsync(command, options) {
function execAsync(command: string, options: Parameters<typeof exec>[1]): Promise<ExecResult> {
return new Promise((resolve, reject) => {
exec(command, options, (error, stdout, stderr) => {
if (error) {
@ -33,27 +37,32 @@ function execAsync(command, options) {
});
}
module.exports = class RestSessionCreator {
constructor(synapseSubdir, hsUrl, cwd) {
this.synapseSubdir = synapseSubdir;
this.hsUrl = hsUrl;
this.cwd = cwd;
}
export interface Credentials {
accessToken: string;
homeServer: string;
userId: string;
deviceId: string;
hsUrl: string;
}
async createSessionRange(usernames, password, groupName) {
export class RestSessionCreator {
constructor(private readonly synapseSubdir: string, private readonly hsUrl: string, private readonly cwd: string) {}
public async createSessionRange(usernames: string[], password: string,
groupName: string): Promise<RestMultiSession> {
const sessionPromises = usernames.map((username) => this.createSession(username, password));
const sessions = await Promise.all(sessionPromises);
return new RestMultiSession(sessions, groupName);
}
async createSession(username, password) {
await this._register(username, password);
public async createSession(username: string, password: string): Promise<RestSession> {
await this.register(username, password);
console.log(` * created REST user ${username} ... done`);
const authResult = await this._authenticate(username, password);
const authResult = await this.authenticate(username, password);
return new RestSession(authResult);
}
async _register(username, password) {
private async register(username: string, password: string): Promise<void> {
const registerArgs = [
'-c homeserver.yaml',
`-u ${username}`,
@ -71,7 +80,7 @@ module.exports = class RestSessionCreator {
await execAsync(allCmds, { cwd: this.cwd, encoding: 'utf-8' });
}
async _authenticate(username, password) {
private async authenticate(username: string, password: string): Promise<Credentials> {
const requestBody = {
"type": "m.login.password",
"identifier": {
@ -90,4 +99,4 @@ module.exports = class RestSessionCreator {
hsUrl: this.hsUrl,
};
}
};
}

View file

@ -15,19 +15,22 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const Logger = require('../logger');
import { Logger } from '../logger';
import { RestSession } from "./session";
import { RestRoom } from "./room";
module.exports = class RestMultiSession {
constructor(sessions, groupName) {
export class RestMultiSession {
readonly log: Logger;
constructor(public readonly sessions: RestSession[], groupName: string) {
this.log = new Logger(groupName);
this.sessions = sessions;
}
slice(groupName, start, end) {
public slice(groupName: string, start: number, end?: number): RestMultiSession {
return new RestMultiSession(this.sessions.slice(start, end), groupName);
}
pop(userName) {
public pop(userName: string): RestSession {
const idx = this.sessions.findIndex((s) => s.userName() === userName);
if (idx === -1) {
throw new Error(`user ${userName} not found`);
@ -36,9 +39,9 @@ module.exports = class RestMultiSession {
return session;
}
async setDisplayName(fn) {
public async setDisplayName(fn: (s: RestSession) => string): Promise<void> {
this.log.step("set their display name");
await Promise.all(this.sessions.map(async (s) => {
await Promise.all(this.sessions.map(async (s: RestSession) => {
s.log.mute();
await s.setDisplayName(fn(s));
s.log.unmute();
@ -46,7 +49,7 @@ module.exports = class RestMultiSession {
this.log.done();
}
async join(roomIdOrAlias) {
public async join(roomIdOrAlias: string): Promise<RestMultiRoom> {
this.log.step(`join ${roomIdOrAlias}`);
const rooms = await Promise.all(this.sessions.map(async (s) => {
s.log.mute();
@ -58,22 +61,19 @@ module.exports = class RestMultiSession {
return new RestMultiRoom(rooms, roomIdOrAlias, this.log);
}
room(roomIdOrAlias) {
public room(roomIdOrAlias: string): RestMultiRoom {
const rooms = this.sessions.map(s => s.room(roomIdOrAlias));
return new RestMultiRoom(rooms, roomIdOrAlias, this.log);
}
};
}
class RestMultiRoom {
constructor(rooms, roomIdOrAlias, log) {
this.rooms = rooms;
this.roomIdOrAlias = roomIdOrAlias;
this.log = log;
}
constructor(public readonly rooms: RestRoom[], private readonly roomIdOrAlias: string,
private readonly log: Logger) {}
async talk(message) {
public async talk(message: string): Promise<void> {
this.log.step(`say "${message}" in ${this.roomIdOrAlias}`);
await Promise.all(this.rooms.map(async (r) => {
await Promise.all(this.rooms.map(async (r: RestRoom) => {
r.log.mute();
await r.talk(message);
r.log.unmute();
@ -81,7 +81,7 @@ class RestMultiRoom {
this.log.done();
}
async leave() {
public async leave() {
this.log.step(`leave ${this.roomIdOrAlias}`);
await Promise.all(this.rooms.map(async (r) => {
r.log.mute();

View file

@ -15,20 +15,18 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const uuidv4 = require('uuid/v4');
import uuidv4 = require('uuid/v4');
import { RestSession } from "./session";
import { Logger } from "../logger";
/* no pun intented */
module.exports = class RestRoom {
constructor(session, roomId, log) {
this.session = session;
this._roomId = roomId;
this.log = log;
}
export class RestRoom {
constructor(readonly session: RestSession, readonly roomId: string, readonly log: Logger) {}
async talk(message) {
this.log.step(`says "${message}" in ${this._roomId}`);
async talk(message: string): Promise<void> {
this.log.step(`says "${message}" in ${this.roomId}`);
const txId = uuidv4();
await this.session._put(`/rooms/${this._roomId}/send/m.room.message/${txId}`, {
await this.session.put(`/rooms/${this.roomId}/send/m.room.message/${txId}`, {
"msgtype": "m.text",
"body": message,
});
@ -36,13 +34,9 @@ module.exports = class RestRoom {
return txId;
}
async leave() {
this.log.step(`leaves ${this._roomId}`);
await this.session._post(`/rooms/${this._roomId}/leave`);
async leave(): Promise<void> {
this.log.step(`leaves ${this.roomId}`);
await this.session.post(`/rooms/${this.roomId}/leave`);
this.log.done();
}
roomId() {
return this._roomId;
}
};
}

View file

@ -0,0 +1,137 @@
/*
Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import request = require('request-promise-native');
import { Logger } from '../logger';
import { RestRoom } from './room';
import { approveConsent } from './consent';
import { Credentials } from "./creator";
interface RoomOptions {
invite: string;
public: boolean;
topic: string;
dm: boolean;
}
export class RestSession {
private _displayName: string = null;
private readonly rooms: Record<string, RestRoom> = {};
readonly log: Logger;
constructor(private readonly credentials: Credentials) {
this.log = new Logger(credentials.userId);
}
userId(): string {
return this.credentials.userId;
}
userName(): string {
return this.credentials.userId.split(":")[0].substr(1);
}
displayName(): string {
return this._displayName;
}
async setDisplayName(displayName: string): Promise<void> {
this.log.step(`sets their display name to ${displayName}`);
this._displayName = displayName;
await this.put(`/profile/${this.credentials.userId}/displayname`, {
displayname: displayName,
});
this.log.done();
}
async join(roomIdOrAlias: string): Promise<RestRoom> {
this.log.step(`joins ${roomIdOrAlias}`);
const roomId = (await this.post(`/join/${encodeURIComponent(roomIdOrAlias)}`)).room_id;
this.log.done();
const room = new RestRoom(this, roomId, this.log);
this.rooms[roomId] = room;
this.rooms[roomIdOrAlias] = room;
return room;
}
room(roomIdOrAlias: string): RestRoom {
if (this.rooms.hasOwnProperty(roomIdOrAlias)) {
return this.rooms[roomIdOrAlias];
} else {
throw new Error(`${this.credentials.userId} is not in ${roomIdOrAlias}`);
}
}
async createRoom(name: string, options: RoomOptions): Promise<RestRoom> {
this.log.step(`creates room ${name}`);
const body = {
name,
};
if (options.invite) {
body['invite'] = options.invite;
}
if (options.public) {
body['visibility'] = "public";
} else {
body['visibility'] = "private";
}
if (options.dm) {
body['is_direct'] = true;
}
if (options.topic) {
body['topic'] = options.topic;
}
const roomId = (await this.post(`/createRoom`, body)).room_id;
this.log.done();
return new RestRoom(this, roomId, this.log);
}
post(csApiPath: string, body?: any): Promise<any> {
return this.request("POST", csApiPath, body);
}
put(csApiPath: string, body?: any): Promise<any> {
return this.request("PUT", csApiPath, body);
}
async request(method: string, csApiPath: string, body?: any): Promise<any> {
try {
return await request({
url: `${this.credentials.hsUrl}/_matrix/client/r0${csApiPath}`,
method,
headers: {
"Authorization": `Bearer ${this.credentials.accessToken}`,
},
json: true,
body,
});
} catch (err) {
if (!err.response) {
throw err;
}
const responseBody = err.response.body;
if (responseBody.errcode === 'M_CONSENT_NOT_GIVEN') {
await approveConsent(responseBody.consent_uri);
return this.request(method, csApiPath, body);
} else if (responseBody && responseBody.error) {
throw new Error(`${method} ${csApiPath}: ${responseBody.error}`);
} else {
throw new Error(`${method} ${csApiPath}: ${err.response.statusCode}`);
}
}
}
}