mirror of
https://github.com/matrix-org/matrix-hookshot.git
synced 2025-03-10 13:17:08 +00:00
Minor grammar corrections in code and documentation (#267)
* setupWidget -> setUpWidget * setup -> (to) set up; add full stops * setupAdminRoom -> setUpAdminRoom * it's -> its * Create 267.feature * log in to; Currently, ; full stops * Improve copy of error messages * Update 267.feature * Rename 267.feature to 267.misc Co-authored-by: Will Hunt <will@half-shot.uk>
This commit is contained in:
parent
14abb011b6
commit
4060ded7f8
2
.github/workflows/docker-hub-latest.yml
vendored
2
.github/workflows/docker-hub-latest.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Login to Docker Hub
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
|
2
.github/workflows/docker-hub-release.yml
vendored
2
.github/workflows/docker-hub-release.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
- name: Get release tag
|
||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
- name: Login to Docker Hub
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
|
@ -65,7 +65,7 @@ Bugfixes
|
||||
- Fix a bug which caused GitHub "ready for review" events to be unhandled. ([\#149](https://github.com/matrix-org/matrix-hookshot/issues/149))
|
||||
- Fix a bug preventing `!hookshot jira project` from working ([\#166](https://github.com/matrix-org/matrix-hookshot/issues/166))
|
||||
- Fix a few issues preventing GitHub notifications from working ([\#173](https://github.com/matrix-org/matrix-hookshot/issues/173))
|
||||
- Fixed an issue where the bridge bot would change it's displayname if a webhook event is handled while `generic.userIdPrefix` is not set in the config. ([\#215](https://github.com/matrix-org/matrix-hookshot/issues/215))
|
||||
- Fixed an issue where the bridge bot would change its displayname if a webhook event is handled while `generic.userIdPrefix` is not set in the config. ([\#215](https://github.com/matrix-org/matrix-hookshot/issues/215))
|
||||
- Remove nonfunctional `gitlab notifications toggle` command. ([\#226](https://github.com/matrix-org/matrix-hookshot/issues/226))
|
||||
|
||||
|
||||
|
1
changelog.d/267.misc
Normal file
1
changelog.d/267.misc
Normal file
@ -0,0 +1 @@
|
||||
Make some grammar corrections in code, chat notices and documentation.
|
@ -108,11 +108,11 @@ Each permission set can have a services. The `service` field can be:
|
||||
- `*`, for any service.
|
||||
|
||||
The `level` can be:
|
||||
- `commands` Can run commands within connected rooms, but NOT log into the bridge.
|
||||
- `login` All the above, and can also log into the bridge.
|
||||
- `commands` Can run commands within connected rooms, but NOT log in to the bridge.
|
||||
- `login` All the above, and can also log in to the bridge.
|
||||
- `notifications` All the above, and can also bridge their notifications.
|
||||
- `manageConnections` All the above, and can create and delete connections (either via the provisioner, setup commands, or state events).
|
||||
- `admin` All permissions. Currently there are no admin features so this exists as a placeholder.
|
||||
- `admin` All permissions. Currently, there are no admin features so this exists as a placeholder.
|
||||
|
||||
When permissions are checked, if a user matches any of the permission set and one
|
||||
of those grants the right level for a service, they are allowed access. If none of the
|
||||
@ -134,7 +134,7 @@ permissions:
|
||||
services:
|
||||
- service: github
|
||||
level: manageConnections
|
||||
# Allow users on this domain to login to jira and github.
|
||||
# Allow users on this domain to log in to jira and github.
|
||||
- actor: support.example.com
|
||||
services:
|
||||
- service: jira
|
||||
|
@ -29,7 +29,7 @@ The `accessToken` should be the personal access token for your account.
|
||||
|
||||
The `passcode` should be a randomly generated code which is used to authenticate requests from Figma.
|
||||
|
||||
The bridge will automatically setup a webhook on Figma for you upon startup, and will automatically reconfigure that webhook if the `publicUrl` or `passcode` changes.
|
||||
The bridge will automatically set up a webhook on Figma for you upon startup, and will automatically reconfigure that webhook if the `publicUrl` or `passcode` changes.
|
||||
|
||||
## Next steps
|
||||
|
||||
|
@ -25,7 +25,7 @@ jira:
|
||||
... # See below
|
||||
```
|
||||
|
||||
You can omit the `oauth` section if you are not planning to allow users to login and use interactive features (i.e. webhook only mode).
|
||||
You can omit the `oauth` section if you are not planning to allow users to log in and use interactive features (i.e. webhook only mode).
|
||||
|
||||
## Connecting Matrix users to JIRA
|
||||
|
||||
@ -85,7 +85,7 @@ jira:
|
||||
# The path to your webhooks listener on the "/jira/oauth" path.
|
||||
redirect_uri: http://localhost:5065/jira/oauth
|
||||
```
|
||||
To start with, setup your JIRA instance to support OAuth.
|
||||
To start with, set up your JIRA instance to support OAuth.
|
||||
|
||||
|
||||
1. Open the **Administration** page for your JIRA instance.
|
||||
@ -104,7 +104,7 @@ To start with, setup your JIRA instance to support OAuth.
|
||||
1. Enter your `consumerKey` from the config file above.
|
||||
2. The `consumerName` can be anything, but will be visible to users of your app. You could use something like `Matrix`, `Hookshot` or anything else.
|
||||
3. The `publicKey` can be generated by running `openssl rsa -in jira_privatekey.pem -pubout` on the key you created earlier.
|
||||
7. Congratulations, you now have OAuth setup.
|
||||
7. Congratulations, you now have OAuth set up.
|
||||
|
||||
## Next steps
|
||||
|
||||
|
@ -38,7 +38,7 @@ To authenticate with a personal access token:
|
||||
You can authenticate with GitLab by supplying a Personal Access Token. OAuth-style authentication isn't supported
|
||||
yet.
|
||||
|
||||
- You will need to have configured a GitLab instance in your config.yml for the instance you want to login to.
|
||||
- You will need to have configured a GitLab instance in your config.yml for the instance you want to log in to.
|
||||
- Open https://%instance%/-/profile/personal_access_tokens (GitLab > User Settings > Access Tokens), where instance is your GitLab instance address.
|
||||
- For the public GitLab server, this would be "gitlab.com"
|
||||
- Give it a good name, and a sensible expiration date. For scopes you will need to tick `api`.
|
||||
@ -49,7 +49,7 @@ yet.
|
||||
|
||||
## JIRA
|
||||
|
||||
You can login to JIRA via OAuth. This means you will need to have configured OAuth support in your `config.yml`, and
|
||||
You can log in to JIRA via OAuth. This means you will need to have configured OAuth support in your `config.yml`, and
|
||||
have the endpoints required accessible from the internet. Authentication is required when trying to bridge JIRA resources into rooms.
|
||||
|
||||
- Say `jira login` to get the URL to authenticate via.
|
||||
|
@ -160,7 +160,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
private async setGitHubNotificationsStateParticipating() {
|
||||
const newData = await this.saveAccountData((data) => {
|
||||
if (!data.github?.notifications?.enabled) {
|
||||
throw Error('Notifications are not enabled')
|
||||
throw Error('Notifications are not enabled.')
|
||||
}
|
||||
const oldState = data.github?.notifications?.participating ?? false;
|
||||
return {
|
||||
@ -174,17 +174,17 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
};
|
||||
});
|
||||
if (newData.github?.notifications?.participating) {
|
||||
return this.sendNotice(`Filtering for events you are participating in`);
|
||||
return this.sendNotice(`Filtering for events you are participating in.`);
|
||||
}
|
||||
return this.sendNotice(`Showing all events`);
|
||||
return this.sendNotice(`Showing all events.`);
|
||||
}
|
||||
|
||||
@botCommand("github notifications", {help: "Show the current notification settings", category: "github"})
|
||||
public async getGitHubNotificationsState() {
|
||||
if (!this.notificationsEnabled("github")) {
|
||||
return this.sendNotice(`Notifications are disabled`);
|
||||
return this.sendNotice(`Notifications are disabled.`);
|
||||
}
|
||||
return this.sendNotice(`Notifications are enabled, ${this.notificationsParticipating("github") ? "Showing only events you are particiapting in" : "Showing all events"}`);
|
||||
return this.sendNotice(`Notifications are enabled, ${this.notificationsParticipating("github") ? "Showing only events you are particiapting in." : "Showing all events."}`);
|
||||
}
|
||||
|
||||
|
||||
@ -192,7 +192,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
// @ts-ignore - property is used
|
||||
private async listProjects(username?: string, repo?: string) {
|
||||
if (!this.config.github) {
|
||||
return this.sendNotice("The bridge is not configured with GitHub support");
|
||||
return this.sendNotice("The bridge is not configured with GitHub support.");
|
||||
}
|
||||
const octokit = await this.tokenStore.getOctokitForUser(this.userId);
|
||||
if (!octokit) {
|
||||
@ -218,7 +218,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
})).data;
|
||||
} catch (ex) {
|
||||
log.warn(`Failed to fetch projects:`, ex);
|
||||
return this.sendNotice(`Failed to fetch projects due to an error. See logs for details`);
|
||||
return this.sendNotice(`Failed to fetch projects due to an error. See logs for details.`);
|
||||
}
|
||||
|
||||
const content = `Projects for ${username}:\n${FormatUtil.projectListing(res)}\n`;
|
||||
@ -234,7 +234,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
// @ts-ignore - property is used
|
||||
private async listProjects(org: string, repo?: string) {
|
||||
if (!this.config.github) {
|
||||
return this.sendNotice("The bridge is not configured with GitHub support");
|
||||
return this.sendNotice("The bridge is not configured with GitHub support.");
|
||||
}
|
||||
const octokit = await this.tokenStore.getOctokitForUser(this.userId);
|
||||
if (!octokit) {
|
||||
@ -254,10 +254,10 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
}));
|
||||
} catch (ex) {
|
||||
if (ex.status === 404) {
|
||||
return this.sendNotice('Not found');
|
||||
return this.sendNotice(`${repo ? "Repository" : "Org"} does not exist.`);
|
||||
}
|
||||
log.warn(`Failed to fetch projects:`, ex);
|
||||
return this.sendNotice(`Failed to fetch projects due to an error. See logs for details`);
|
||||
return this.sendNotice(`Failed to fetch projects due to an error. See logs for details.`);
|
||||
}
|
||||
|
||||
const content = `Projects for ${org}:\n` + res.data.map(r => ` - ${FormatUtil.projectListing([r])}\n`).join("\n");
|
||||
@ -273,7 +273,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
// @ts-ignore - property is used
|
||||
private async openProject(projectId: string) {
|
||||
if (!this.config.github) {
|
||||
return this.sendNotice("The bridge is not configured with GitHub support");
|
||||
return this.sendNotice("The bridge is not configured with GitHub support.");
|
||||
}
|
||||
const octokit = await this.tokenStore.getOctokitForUser(this.userId);
|
||||
if (!octokit) {
|
||||
@ -287,10 +287,10 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
this.emit('open.project', project.data);
|
||||
} catch (ex) {
|
||||
if (ex.status === 404) {
|
||||
return this.sendNotice('Not found');
|
||||
return this.sendNotice('Project does not exist.');
|
||||
}
|
||||
log.warn(`Failed to fetch project:`, ex);
|
||||
return this.sendNotice(`Failed to fetch project due to an error. See logs for details`);
|
||||
return this.sendNotice(`Failed to fetch project due to an error. See logs for details.`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,7 +299,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
private async listDiscussions(owner: string, repo: string, numberStr: string) {
|
||||
const number = parseInt(numberStr);
|
||||
if (!this.config.github) {
|
||||
return this.sendNotice("The bridge is not configured with GitHub support");
|
||||
return this.sendNotice("The bridge is not configured with GitHub support.");
|
||||
}
|
||||
const octokit = await this.tokenStore.getOctokitForUser(this.userId);
|
||||
if (!octokit) {
|
||||
@ -311,10 +311,10 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
this.emit('open.discussion', owner, repo, discussions);
|
||||
} catch (ex) {
|
||||
if (ex.status === 404) {
|
||||
return this.sendNotice('Not found');
|
||||
return this.sendNotice('Discussion does not exist.');
|
||||
}
|
||||
log.warn(`Failed to fetch discussions:`, ex);
|
||||
return this.sendNotice(`Failed to fetch discussions due to an error. See logs for details`);
|
||||
return this.sendNotice(`Failed to fetch discussions due to an error. See logs for details.`);
|
||||
}
|
||||
|
||||
}
|
||||
@ -325,7 +325,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
// @ts-ignore - property is used
|
||||
private async gitLabOpenIssue(url: string) {
|
||||
if (!this.config.gitlab) {
|
||||
return this.sendNotice("The bridge is not configured with GitLab support");
|
||||
return this.sendNotice("The bridge is not configured with GitLab support.");
|
||||
}
|
||||
|
||||
const urlResult = GitLabClient.splitUrlIntoParts(this.config.gitlab.instances, url);
|
||||
@ -336,7 +336,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
const instance = this.config.gitlab.instances[instanceName];
|
||||
const client = await this.tokenStore.getGitLabForUser(this.userId, instance.url);
|
||||
if (!client) {
|
||||
return this.sendNotice("You have not added a personal access token for GitLab");
|
||||
return this.sendNotice("You have not added a personal access token for GitLab.");
|
||||
}
|
||||
const getIssueOpts = {
|
||||
issue: parseInt(parts[parts.length-1]),
|
||||
@ -351,11 +351,11 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
public async setGitLabPersonalAccessToken(instanceName: string, accessToken: string) {
|
||||
let me: GetUserResponse;
|
||||
if (!this.config.gitlab) {
|
||||
return this.sendNotice("The bridge is not configured with GitLab support");
|
||||
return this.sendNotice("The bridge is not configured with GitLab support.");
|
||||
}
|
||||
const instance = this.config.gitlab.instances[instanceName];
|
||||
if (!instance) {
|
||||
return this.sendNotice("The bridge is not configured for this GitLab instance");
|
||||
return this.sendNotice("The bridge is not configured for this GitLab instance.");
|
||||
}
|
||||
try {
|
||||
const client = new GitLabClient(instance.url, accessToken);
|
||||
@ -365,22 +365,22 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
log.error("Gitlab auth error:", ex);
|
||||
return this.sendNotice("Could not authenticate with GitLab. Is your token correct?");
|
||||
}
|
||||
await this.sendNotice(`Connected as ${me.username}. Token stored`);
|
||||
await this.sendNotice(`Connected as ${me.username}. Token stored.`);
|
||||
return this.tokenStore.storeUserToken("gitlab", this.userId, accessToken, instance.url);
|
||||
}
|
||||
|
||||
@botCommand("gitlab hastoken", {help: "Check if you have a token stored for GitLab", requiredArgs: ["instanceName"], category: "gitlab"})
|
||||
public async gitlabHasPersonalToken(instanceName: string) {
|
||||
if (!this.config.gitlab) {
|
||||
return this.sendNotice("The bridge is not configured with GitLab support");
|
||||
return this.sendNotice("The bridge is not configured with GitLab support.");
|
||||
}
|
||||
const instance = this.config.gitlab.instances[instanceName];
|
||||
if (!instance) {
|
||||
return this.sendNotice("The bridge is not configured for this GitLab instance");
|
||||
return this.sendNotice("The bridge is not configured for this GitLab instance.");
|
||||
}
|
||||
const result = await this.tokenStore.getUserToken("gitlab", this.userId, instance.url);
|
||||
if (result === null) {
|
||||
return this.sendNotice("You do not currently have a token stored");
|
||||
return this.sendNotice("You do not currently have a token stored.");
|
||||
}
|
||||
return this.sendNotice("A token is stored for your GitLab account.");
|
||||
}
|
||||
@ -388,7 +388,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
@botCommand("filters list", "List your saved filters")
|
||||
public async getFilters() {
|
||||
if (this.notifFilter.empty) {
|
||||
return this.sendNotice("You do not currently have any filters");
|
||||
return this.sendNotice("You do not currently have any filters.");
|
||||
}
|
||||
const filterText = Object.entries(this.notifFilter.filters).map(([name, value]) => {
|
||||
const userText = value.users.length ? `users: ${value.users.join("|")}` : '';
|
||||
@ -407,7 +407,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
const users = parameters.filter(param => param.toLowerCase().startsWith("users:")).map(param => param.toLowerCase().substring("users:".length).split(",")).flat();
|
||||
const repos = parameters.filter(param => param.toLowerCase().startsWith("repos:")).map(param => param.toLowerCase().substring("repos:".length).split(",")).flat();
|
||||
if (orgs.length + users.length + repos.length === 0) {
|
||||
return this.sendNotice("You must specify some filter options like 'orgs:matrix-org,half-shot', 'users:Half-Shot' or 'repos:matrix-hookshot'");
|
||||
return this.sendNotice("You must specify some filter options like 'orgs:matrix-org,half-shot', 'users:Half-Shot' or 'repos:matrix-hookshot'.");
|
||||
}
|
||||
this.notifFilter.setFilter(name, {
|
||||
orgs,
|
||||
@ -415,20 +415,20 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
repos,
|
||||
});
|
||||
await this.botIntent.underlyingClient.sendStateEvent(this.roomId, NotifFilter.StateType, "", this.notifFilter.getStateContent());
|
||||
return this.sendNotice(`Stored new filter "${name}". You can now apply the filter by saying 'filters notifications toggle $name'`);
|
||||
return this.sendNotice(`Stored new filter "${name}". You can now apply the filter by saying 'filters notifications toggle $name'.`);
|
||||
}
|
||||
|
||||
@botCommand("filters notifications toggle", "Apply a filter as a whitelist to your notifications", ["name"])
|
||||
public async setFiltersNotificationsToggle(name: string) {
|
||||
if (!this.notifFilter.filters[name]) {
|
||||
return this.sendNotice(`Filter "${name}" doesn't exist'`);
|
||||
return this.sendNotice(`Filter "${name}" doesn't exist.`);
|
||||
}
|
||||
if (this.notifFilter.forNotifications.has(name)) {
|
||||
this.notifFilter.forNotifications.delete(name);
|
||||
await this.sendNotice(`Filter "${name}" disabled for notifications`);
|
||||
await this.sendNotice(`Filter "${name}" disabled for notifications.`);
|
||||
} else {
|
||||
this.notifFilter.forNotifications.add(name);
|
||||
await this.sendNotice(`Filter "${name}" enabled for notifications`);
|
||||
await this.sendNotice(`Filter "${name}" enabled for notifications.`);
|
||||
}
|
||||
return this.botIntent.underlyingClient.sendStateEvent(this.roomId, NotifFilter.StateType, "", this.notifFilter.getStateContent());
|
||||
}
|
||||
@ -449,7 +449,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
const checkPermission = (service: string, level: BridgePermissionLevel) => this.config.checkPermission(this.userId, service, level);
|
||||
const result = await handleCommand(this.userId, command, AdminRoom.botCommands, this, checkPermission);
|
||||
if (!result.handled) {
|
||||
return this.sendNotice("Command not understood");
|
||||
return this.sendNotice("Command not understood.");
|
||||
}
|
||||
|
||||
if ("error" in result) {
|
||||
@ -488,7 +488,7 @@ export class AdminRoom extends AdminRoomCommandHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public async setupWidget() {
|
||||
public async setUpWidget() {
|
||||
try {
|
||||
const res = await this.botIntent.underlyingClient.getRoomStateEvent(this.roomId, "im.vector.modular.widgets", "bridge_control");
|
||||
if (res) {
|
||||
|
@ -106,10 +106,10 @@ export async function handleCommand(
|
||||
if (command) {
|
||||
const permissionService = command.permissionService || defaultPermissionService;
|
||||
if (permissionService && !permissionCheckFn(permissionService, command.permissionLevel || BridgePermissionLevel.commands)) {
|
||||
return {handled: true, error: "You do not have permission to use this command"};
|
||||
return {handled: true, error: "You do not have permission to use this command."};
|
||||
}
|
||||
if (command.requiredArgs && command.requiredArgs.length > parts.length - i) {
|
||||
return {handled: true, error: "Missing args"};
|
||||
return {handled: true, error: "Missing at least one required parameter."};
|
||||
}
|
||||
const args = parts.slice(i);
|
||||
if (command.includeUserId) {
|
||||
|
@ -109,7 +109,7 @@ export class Bridge {
|
||||
}
|
||||
|
||||
if (this.config.figma) {
|
||||
// Ensure webhooks are setup
|
||||
// Ensure webhooks are set up
|
||||
await ensureFigmaWebhooks(this.config.figma, this.as.botClient);
|
||||
}
|
||||
|
||||
@ -621,12 +621,12 @@ export class Bridge {
|
||||
// No state yet
|
||||
}
|
||||
}
|
||||
const adminRoom = await this.setupAdminRoom(roomId, accountData, notifContent || NotifFilter.getDefaultContent());
|
||||
const adminRoom = await this.setUpAdminRoom(roomId, accountData, notifContent || NotifFilter.getDefaultContent());
|
||||
// Call this on startup to set the state
|
||||
await this.onAdminRoomSettingsChanged(adminRoom, accountData, { admin_user: accountData.admin_user });
|
||||
log.debug(`Room ${roomId} is connected to: ${adminRoom.toString()}`);
|
||||
} catch (ex) {
|
||||
log.error(`Failed to setup admin room ${roomId}:`, ex);
|
||||
log.error(`Failed to set up admin room ${roomId}:`, ex);
|
||||
}
|
||||
}));
|
||||
|
||||
@ -678,7 +678,7 @@ export class Bridge {
|
||||
}
|
||||
await retry(() => this.as.botIntent.joinRoom(roomId), 5);
|
||||
if (event.content.is_direct) {
|
||||
const room = await this.setupAdminRoom(roomId, {admin_user: event.sender}, NotifFilter.getDefaultContent());
|
||||
const room = await this.setUpAdminRoom(roomId, {admin_user: event.sender}, NotifFilter.getDefaultContent());
|
||||
await this.as.botIntent.underlyingClient.setRoomAccountData(
|
||||
BRIDGE_ROOM_TYPE, roomId, room.accountData,
|
||||
);
|
||||
@ -1016,10 +1016,10 @@ export class Bridge {
|
||||
is_direct: true,
|
||||
preset: "trusted_private_chat",
|
||||
});
|
||||
return this.setupAdminRoom(roomId, {admin_user: userId}, NotifFilter.getDefaultContent());
|
||||
return this.setUpAdminRoom(roomId, {admin_user: userId}, NotifFilter.getDefaultContent());
|
||||
}
|
||||
|
||||
private async setupAdminRoom(roomId: string, accountData: AdminAccountData, notifContent: NotificationFilterStateContent) {
|
||||
private async setUpAdminRoom(roomId: string, accountData: AdminAccountData, notifContent: NotificationFilterStateContent) {
|
||||
const adminRoom = new AdminRoom(
|
||||
roomId, accountData, notifContent, this.as.botIntent, this.tokenStore, this.config,
|
||||
);
|
||||
@ -1053,9 +1053,9 @@ export class Bridge {
|
||||
});
|
||||
this.adminRooms.set(roomId, adminRoom);
|
||||
if (this.config.widgets?.addToAdminRooms && this.config.widgets.publicUrl) {
|
||||
await adminRoom.setupWidget();
|
||||
await adminRoom.setUpWidget();
|
||||
}
|
||||
log.debug(`Setup ${roomId} as an admin room for ${adminRoom.userId}`);
|
||||
log.debug(`Set up ${roomId} as an admin room for ${adminRoom.userId}`);
|
||||
return adminRoom;
|
||||
}
|
||||
}
|
@ -48,7 +48,7 @@ export abstract class CommandConnection extends BaseConnection {
|
||||
});
|
||||
await this.botClient.sendEvent(this.roomId, 'm.room.message', {
|
||||
msgtype: "m.notice",
|
||||
body: humanError ? `Failed to handle command: ${humanError}` : "Failed to handle command",
|
||||
body: humanError ? `Failed to handle command: ${humanError}` : "Failed to handle command.",
|
||||
});
|
||||
log.warn(`Failed to handle command:`, error);
|
||||
return true;
|
||||
|
@ -514,7 +514,7 @@ export class GitHubRepoConnection extends CommandConnection implements IConnecti
|
||||
const workflow = workflows.data.workflows.find(w => w.name.toLowerCase().trim() === name.toLowerCase().trim());
|
||||
if (!workflow) {
|
||||
const workflowNames = workflows.data.workflows.map(w => w.name).join(', ');
|
||||
await this.as.botIntent.sendText(this.roomId, `Could not find a workflow by the name of "${name}". The workflows on this repository are ${workflowNames}`, "m.notice");
|
||||
await this.as.botIntent.sendText(this.roomId, `Could not find a workflow by the name of "${name}". The workflows on this repository are ${workflowNames}.`, "m.notice");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@ -544,7 +544,7 @@ export class GitHubRepoConnection extends CommandConnection implements IConnecti
|
||||
throw ex;
|
||||
}
|
||||
|
||||
await this.as.botIntent.sendText(this.roomId, `Workflow started`, "m.notice");
|
||||
await this.as.botIntent.sendText(this.roomId, `Workflow started.`, "m.notice");
|
||||
}
|
||||
|
||||
public async onIssueCreated(event: IssuesOpenedEvent) {
|
||||
|
@ -76,7 +76,7 @@ export class GitLabRepoConnection extends CommandConnection {
|
||||
public async onCreateIssue(userId: string, title: string, description?: string, labels?: string) {
|
||||
const client = await this.tokenStore.getGitLabForUser(userId, this.instance.url);
|
||||
if (!client) {
|
||||
await this.as.botIntent.sendText(this.roomId, "You must login to create an issue", "m.notice");
|
||||
await this.as.botIntent.sendText(this.roomId, "You must be logged in to create an issue.", "m.notice");
|
||||
throw Error('Not logged in');
|
||||
}
|
||||
const res = await client.issues.create({
|
||||
@ -99,7 +99,7 @@ export class GitLabRepoConnection extends CommandConnection {
|
||||
public async onClose(userId: string, number: string) {
|
||||
const client = await this.tokenStore.getGitLabForUser(userId, this.instance.url);
|
||||
if (!client) {
|
||||
await this.as.botIntent.sendText(this.roomId, "You must login to create an issue", "m.notice");
|
||||
await this.as.botIntent.sendText(this.roomId, "You must be logged in to create an issue.", "m.notice");
|
||||
throw Error('Not logged in');
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ export interface IConnection {
|
||||
*/
|
||||
get connectionId(): string;
|
||||
/**
|
||||
* When a room gets an update to it's state.
|
||||
* When a room gets an update to its state.
|
||||
*/
|
||||
onStateUpdate?: (ev: MatrixEvent<unknown>) => Promise<void>;
|
||||
/**
|
||||
|
@ -41,19 +41,19 @@ export class SetupConnection extends CommandConnection {
|
||||
)
|
||||
}
|
||||
|
||||
@botCommand("github repo", "Create a connection for a GitHub repository. (You must be logged in with GitHub to do this)", ["url"], [], true)
|
||||
@botCommand("github repo", "Create a connection for a GitHub repository. (You must be logged in with GitHub to do this.)", ["url"], [], true)
|
||||
public async onGitHubRepo(userId: string, url: string) {
|
||||
if (!this.githubInstance || !this.config.github) {
|
||||
throw new CommandError("not-configured", "The bridge is not configured to support GitHub");
|
||||
throw new CommandError("not-configured", "The bridge is not configured to support GitHub.");
|
||||
}
|
||||
if (!this.config.checkPermission(userId, "github", BridgePermissionLevel.manageConnections)) {
|
||||
throw new CommandError('You are not permitted to provision connections for GitHub');
|
||||
throw new CommandError('You are not permitted to provision connections for GitHub.');
|
||||
}
|
||||
if (!await this.as.botClient.userHasPowerLevelFor(userId, this.roomId, "", true)) {
|
||||
throw new CommandError("not-configured", "You must be able to set state in a room ('Change settings') in order to setup new integrations.");
|
||||
throw new CommandError("not-configured", "You must be able to set state in a room ('Change settings') in order to set up new integrations.");
|
||||
}
|
||||
if (!await this.as.botClient.userHasPowerLevelFor(this.as.botUserId, this.roomId, GitHubRepoConnection.CanonicalEventType, true)) {
|
||||
throw new CommandError("Bot lacks power level to set room state", "I do not have permission to setup a bridge in this room. Please promote me to an Admin/Moderator");
|
||||
throw new CommandError("Bot lacks power level to set room state", "I do not have permission to set up a bridge in this room. Please promote me to an Admin/Moderator.");
|
||||
}
|
||||
const octokit = await this.tokenStore.getOctokitForUser(userId);
|
||||
if (!octokit) {
|
||||
@ -61,7 +61,7 @@ export class SetupConnection extends CommandConnection {
|
||||
}
|
||||
const urlParts = /^https:\/\/github\.com\/([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)$/.exec(url.trim().toLowerCase());
|
||||
if (!urlParts) {
|
||||
throw new CommandError("Invalid GitHub url", "The GitHub url you entered was not valid");
|
||||
throw new CommandError("Invalid GitHub url", "The GitHub url you entered was not valid.");
|
||||
}
|
||||
const [, org, repo] = urlParts;
|
||||
const res = await GitHubRepoConnection.provisionConnection(this.roomId, userId, {org, repo}, this.as, this.tokenStore, this.githubInstance, this.config.github);
|
||||
@ -69,20 +69,20 @@ export class SetupConnection extends CommandConnection {
|
||||
await this.as.botClient.sendNotice(this.roomId, `Room configured to bridge ${org}/${repo}`);
|
||||
}
|
||||
|
||||
@botCommand("jira project", "Create a connection for a JIRA project. (You must be logged in with JIRA to do this)", ["url"], [], true)
|
||||
@botCommand("jira project", "Create a connection for a JIRA project. (You must be logged in with JIRA to do this.)", ["url"], [], true)
|
||||
public async onJiraProject(userId: string, urlStr: string) {
|
||||
const url = new URL(urlStr);
|
||||
if (!this.config.jira) {
|
||||
throw new CommandError("not-configured", "The bridge is not configured to support Jira");
|
||||
throw new CommandError("not-configured", "The bridge is not configured to support Jira.");
|
||||
}
|
||||
if (!this.config.checkPermission(userId, "jira", BridgePermissionLevel.manageConnections)) {
|
||||
throw new CommandError('You are not permitted to provision connections for Jira');
|
||||
throw new CommandError('You are not permitted to provision connections for Jira.');
|
||||
}
|
||||
if (!await this.as.botClient.userHasPowerLevelFor(userId, this.roomId, "", true)) {
|
||||
throw new CommandError("not-configured", "You must be able to set state in a room ('Change settings') in order to setup new integrations.");
|
||||
throw new CommandError("not-configured", "You must be able to set state in a room ('Change settings') in order to set up new integrations.");
|
||||
}
|
||||
if (!await this.as.botClient.userHasPowerLevelFor(this.as.botUserId, this.roomId, GitHubRepoConnection.CanonicalEventType, true)) {
|
||||
throw new CommandError("Bot lacks power level to set room state", "I do not have permission to setup a bridge in this room. Please promote me to an Admin/Moderator");
|
||||
throw new CommandError("Bot lacks power level to set room state", "I do not have permission to set up a bridge in this room. Please promote me to an Admin/Moderator.");
|
||||
}
|
||||
const jiraClient = await this.tokenStore.getJiraForUser(userId, urlStr);
|
||||
if (!jiraClient) {
|
||||
@ -91,57 +91,57 @@ export class SetupConnection extends CommandConnection {
|
||||
const urlParts = /.+\/projects\/(\w+)\/?(\w+\/?)*$/.exec(url.pathname.toLowerCase());
|
||||
const projectKey = urlParts?.[1] || url.searchParams.get('projectKey');
|
||||
if (!projectKey) {
|
||||
throw new CommandError("Invalid Jira url", "The JIRA project url you entered was not valid. It should be in the format of `https://jira-instance/.../projects/PROJECTKEY/...` or `.../RapidBoard.jspa?projectKey=TEST`");
|
||||
throw new CommandError("Invalid Jira url", "The JIRA project url you entered was not valid. It should be in the format of `https://jira-instance/.../projects/PROJECTKEY/...` or `.../RapidBoard.jspa?projectKey=TEST`.");
|
||||
}
|
||||
const safeUrl = `https://${url.host}/projects/${projectKey}`;
|
||||
const res = await JiraProjectConnection.provisionConnection(this.roomId, userId, { url: safeUrl }, this.as, this.tokenStore);
|
||||
await this.as.botClient.sendStateEvent(this.roomId, JiraProjectConnection.CanonicalEventType, safeUrl, res.stateEventContent);
|
||||
await this.as.botClient.sendNotice(this.roomId, `Room configured to bridge Jira project ${res.connection.projectKey}`);
|
||||
await this.as.botClient.sendNotice(this.roomId, `Room configured to bridge Jira project ${res.connection.projectKey}.`);
|
||||
}
|
||||
|
||||
@botCommand("webhook", "Create an inbound webhook", ["name"], [], true)
|
||||
@botCommand("webhook", "Create an inbound webhook.", ["name"], [], true)
|
||||
public async onWebhook(userId: string, name: string) {
|
||||
if (!this.config.generic?.enabled) {
|
||||
throw new CommandError("not-configured", "The bridge is not configured to support webhooks");
|
||||
throw new CommandError("not-configured", "The bridge is not configured to support webhooks.");
|
||||
}
|
||||
if (!this.config.checkPermission(userId, "webhooks", BridgePermissionLevel.manageConnections)) {
|
||||
throw new CommandError('You are not permitted to provision connections for generic webhooks');
|
||||
throw new CommandError('You are not permitted to provision connections for generic webhooks.');
|
||||
}
|
||||
if (!await this.as.botClient.userHasPowerLevelFor(userId, this.roomId, "", true)) {
|
||||
throw new CommandError("not-configured", "You must be able to set state in a room ('Change settings') in order to setup new integrations.");
|
||||
throw new CommandError("not-configured", "You must be able to set state in a room ('Change settings') in order to set up new integrations.");
|
||||
}
|
||||
if (!await this.as.botClient.userHasPowerLevelFor(this.as.botUserId, this.roomId, GitHubRepoConnection.CanonicalEventType, true)) {
|
||||
throw new CommandError("Bot lacks power level to set room state", "I do not have permission to setup a bridge in this room. Please promote me to an Admin/Moderator");
|
||||
throw new CommandError("Bot lacks power level to set room state", "I do not have permission to set up a bridge in this room. Please promote me to an Admin/Moderator.");
|
||||
}
|
||||
if (!name || name.length < 3 || name.length > 64) {
|
||||
throw new CommandError("Bad webhook name", "A webhook name must be between 3-64 characters");
|
||||
throw new CommandError("Bad webhook name", "A webhook name must be between 3-64 characters.");
|
||||
}
|
||||
const hookId = uuid();
|
||||
const url = `${this.config.generic.urlPrefix}${this.config.generic.urlPrefix.endsWith('/') ? '' : '/'}${hookId}`;
|
||||
await GenericHookConnection.ensureRoomAccountData(this.roomId, this.as, hookId, name);
|
||||
await this.as.botClient.sendStateEvent(this.roomId, GenericHookConnection.CanonicalEventType, name, {hookId, name});
|
||||
const adminRoom = await this.getOrCreateAdminRoom(userId);
|
||||
await adminRoom.sendNotice(`You have bridged a webhook. Please configure your webhook source to use \`${url}\``);
|
||||
await adminRoom.sendNotice(`You have bridged a webhook. Please configure your webhook source to use \`${url}\`.`);
|
||||
return this.as.botClient.sendHtmlNotice(this.roomId, md.renderInline(`Room configured to bridge webhooks. See admin room for secret url.`));
|
||||
}
|
||||
|
||||
@botCommand("figma file", "Bridge a Figma file to the room", ["url"], [], true)
|
||||
@botCommand("figma file", "Bridge a Figma file to the room.", ["url"], [], true)
|
||||
public async onFigma(userId: string, url: string) {
|
||||
if (!this.config.figma) {
|
||||
throw new CommandError("not-configured", "The bridge is not configured to support Figma");
|
||||
throw new CommandError("not-configured", "The bridge is not configured to support Figma.");
|
||||
}
|
||||
if (!this.config.checkPermission(userId, "figma", BridgePermissionLevel.manageConnections)) {
|
||||
throw new CommandError('You are not permitted to provision connections for Figma');
|
||||
throw new CommandError('You are not permitted to provision connections for Figma.');
|
||||
}
|
||||
if (!await this.as.botClient.userHasPowerLevelFor(userId, this.roomId, "", true)) {
|
||||
throw new CommandError("not-configured", "You must be able to set state in a room ('Change settings') in order to setup new integrations.");
|
||||
throw new CommandError("not-configured", "You must be able to set state in a room ('Change settings') in order to set up new integrations.");
|
||||
}
|
||||
if (!await this.as.botClient.userHasPowerLevelFor(this.as.botUserId, this.roomId, GitHubRepoConnection.CanonicalEventType, true)) {
|
||||
throw new CommandError("Bot lacks power level to set room state", "I do not have permission to setup a bridge in this room. Please promote me to an Admin/Moderator");
|
||||
throw new CommandError("Bot lacks power level to set room state", "I do not have permission to set up a bridge in this room. Please promote me to an Admin/Moderator.");
|
||||
}
|
||||
const res = /https:\/\/www\.figma\.com\/file\/(\w+).+/.exec(url);
|
||||
if (!res) {
|
||||
throw new CommandError("Invalid Figma url", "The Figma file url you entered was not valid. It should be in the format of `https://figma.com/file/FILEID/...`");
|
||||
throw new CommandError("Invalid Figma url", "The Figma file url you entered was not valid. It should be in the format of `https://figma.com/file/FILEID/...`.");
|
||||
}
|
||||
const [, fileId] = res;
|
||||
await this.as.botClient.sendStateEvent(this.roomId, FigmaFileConnection.CanonicalEventType, fileId, {fileId});
|
||||
|
@ -20,22 +20,22 @@ export function generateGitHubOAuthUrl(clientId: string, redirectUri: string, st
|
||||
}
|
||||
|
||||
export class GitHubBotCommands extends AdminRoomCommandHandler {
|
||||
@botCommand("github login", {help: "Login to GitHub", category: "github"})
|
||||
@botCommand("github login", {help: "Log in to GitHub", category: "github"})
|
||||
public async loginCommand() {
|
||||
if (!this.config.github) {
|
||||
throw new CommandError("no-github-support", "The bridge is not configured with GitHub support");
|
||||
throw new CommandError("no-github-support", "The bridge is not configured with GitHub support.");
|
||||
}
|
||||
if (!this.config.github.oauth) {
|
||||
throw new CommandError("no-github-support", "The bridge is not configured with GitHub OAuth support");
|
||||
throw new CommandError("no-github-support", "The bridge is not configured with GitHub OAuth support.");
|
||||
}
|
||||
const state = this.tokenStore.createStateForOAuth(this.userId);
|
||||
return this.sendNotice(`To login, open ${generateGitHubOAuthUrl(this.config.github.oauth.client_id, this.config.github.oauth.redirect_uri, state)} to link your account to the bridge`);
|
||||
return this.sendNotice(`Open ${generateGitHubOAuthUrl(this.config.github.oauth.client_id, this.config.github.oauth.redirect_uri, state)} to link your account to the bridge.`);
|
||||
}
|
||||
|
||||
@botCommand("github setpersonaltoken", {help: "Set your personal access token for GitHub", requiredArgs: ['accessToken'], category: "github"})
|
||||
public async setGHPersonalAccessToken(accessToken: string) {
|
||||
if (!this.config.github) {
|
||||
throw new CommandError("no-github-support", "The bridge is not configured with GitHub support");
|
||||
throw new CommandError("no-github-support", "The bridge is not configured with GitHub support.");
|
||||
}
|
||||
let me;
|
||||
try {
|
||||
@ -46,18 +46,18 @@ export class GitHubBotCommands extends AdminRoomCommandHandler {
|
||||
await this.sendNotice("Could not authenticate with GitHub. Is your token correct?");
|
||||
return;
|
||||
}
|
||||
await this.sendNotice(`Connected as ${me.data.login}. Token stored`);
|
||||
await this.sendNotice(`Connected as ${me.data.login}. Token stored.`);
|
||||
await this.tokenStore.storeUserToken("github", this.userId, JSON.stringify({access_token: accessToken, token_type: 'pat'} as GitHubOAuthToken));
|
||||
}
|
||||
|
||||
@botCommand("github hastoken", {help: "Check if you have a token stored for GitHub", category: "github"})
|
||||
public async hasPersonalToken() {
|
||||
if (!this.config.github) {
|
||||
throw new CommandError("no-github-support", "The bridge is not configured with GitHub support");
|
||||
throw new CommandError("no-github-support", "The bridge is not configured with GitHub support.");
|
||||
}
|
||||
const result = await this.tokenStore.getUserToken("github", this.userId);
|
||||
if (result === null) {
|
||||
await this.sendNotice("You do not currently have a token stored");
|
||||
await this.sendNotice("You do not currently have a token stored.");
|
||||
return;
|
||||
}
|
||||
await this.sendNotice("A token is stored for your GitHub account.");
|
||||
|
@ -7,22 +7,22 @@ import { CLOUD_INSTANCE } from "./Client";
|
||||
const log = new LogWrapper('JiraBotCommands');
|
||||
|
||||
export class JiraBotCommands extends AdminRoomCommandHandler {
|
||||
@botCommand("jira login", {help: "Login to JIRA", category: "jira"})
|
||||
@botCommand("jira login", {help: "Log in to JIRA", category: "jira"})
|
||||
public async loginCommand() {
|
||||
if (!this.config.jira?.oauth || !this.tokenStore.jiraOAuth) {
|
||||
this.sendNotice(`Bot is not configured with JIRA OAuth support`);
|
||||
this.sendNotice(`Bot is not configured with JIRA OAuth support.`);
|
||||
return;
|
||||
}
|
||||
const state = this.tokenStore.createStateForOAuth(this.userId);
|
||||
const url = await this.tokenStore.jiraOAuth?.getAuthUrl(state);
|
||||
await this.sendNotice(`To login, open ${url} to link your account to the bridge`);
|
||||
await this.sendNotice(`Open ${url} to link your account to the bridge.`);
|
||||
}
|
||||
|
||||
|
||||
@botCommand("jira logout", {help: "Clear any login information", category: "jira"})
|
||||
public async logout() {
|
||||
if (!this.config.jira?.oauth || !this.tokenStore.jiraOAuth) {
|
||||
this.sendNotice(`Bot is not configured with JIRA OAuth support`);
|
||||
this.sendNotice(`Bot is not configured with JIRA OAuth support.`);
|
||||
return;
|
||||
}
|
||||
if (await this.tokenStore.clearUserToken("jira", this.userId, this.config.jira.url || CLOUD_INSTANCE)) {
|
||||
@ -34,13 +34,13 @@ export class JiraBotCommands extends AdminRoomCommandHandler {
|
||||
@botCommand("jira whoami", {help: "Determine JIRA identity", category: "jira"})
|
||||
public async whoami() {
|
||||
if (!this.config.jira) {
|
||||
await this.sendNotice(`Bot is not configured with JIRA OAuth support`);
|
||||
await this.sendNotice(`Bot is not configured with JIRA OAuth support.`);
|
||||
return;
|
||||
}
|
||||
const client = await this.tokenStore.getJiraForUser(this.userId, this.config.jira.url);
|
||||
|
||||
if (!client) {
|
||||
await this.sendNotice(`You are not logged into JIRA`);
|
||||
await this.sendNotice(`You are not logged into JIRA.`);
|
||||
return;
|
||||
}
|
||||
// Get all resources for user
|
||||
@ -49,10 +49,10 @@ export class JiraBotCommands extends AdminRoomCommandHandler {
|
||||
resources = await client.getAccessibleResources();
|
||||
} catch (ex) {
|
||||
log.warn(`Could not request resources from JIRA API: `, ex);
|
||||
await this.sendNotice(`Could not request JIRA resources due to an error`);
|
||||
await this.sendNotice(`Could not request JIRA resources due to an error.`);
|
||||
return;
|
||||
}
|
||||
let response = resources.length === 0 ? `You do not have any instances authorised with this bot` : 'You have access to the following instances:';
|
||||
let response = resources.length === 0 ? `You do not have any instances authorised with this bot.` : 'You have access to the following instances:';
|
||||
for (const resource of resources) {
|
||||
const clientForResource = await client.getClientForResource(resource);
|
||||
if (!clientForResource) {
|
||||
|
@ -134,7 +134,7 @@ export class JiraProvisionerRouter {
|
||||
|
||||
private async onOAuth(req: Request<undefined, undefined, undefined, {userId: string}>, res: Response<{url: string}>) {
|
||||
if (!this.tokenStore.jiraOAuth) {
|
||||
throw new ApiError('JIRA OAuth is disabled', ErrCode.DisabledFeature);
|
||||
throw new ApiError('JIRA OAuth is disabled.', ErrCode.DisabledFeature);
|
||||
}
|
||||
const url = await this.tokenStore.jiraOAuth.getAuthUrl(this.tokenStore.createStateForOAuth(req.query.userId));
|
||||
res.send({ url });
|
||||
@ -157,7 +157,7 @@ export class JiraProvisionerRouter {
|
||||
}
|
||||
} catch (ex) {
|
||||
log.warn(`Failed to fetch accessible resources for ${req.query.userId}`, ex);
|
||||
return next( new ApiError("Could not fetch accessible resources for JIRA user", ErrCode.Unknown));
|
||||
return next( new ApiError("Could not fetch accessible resources for JIRA user.", ErrCode.Unknown));
|
||||
}
|
||||
return res.send({
|
||||
loggedIn: true,
|
||||
@ -177,10 +177,10 @@ export class JiraProvisionerRouter {
|
||||
resClient = await jiraUser.getClientForName(req.params.instanceName);
|
||||
} catch (ex) {
|
||||
log.warn(`Failed to fetch client for ${req.params.instanceName} for ${req.query.userId}`, ex);
|
||||
return next( new ApiError("Could not fetch accessible resources for JIRA user", ErrCode.Unknown));
|
||||
return next( new ApiError("Could not fetch accessible resources for JIRA user.", ErrCode.Unknown));
|
||||
}
|
||||
if (!resClient) {
|
||||
return next( new ApiError("Instance not known or not accessible to this user", ErrCode.ForbiddenUser));
|
||||
return next( new ApiError("Instance not known or not accessible to this user.", ErrCode.ForbiddenUser));
|
||||
}
|
||||
|
||||
const projects = [];
|
||||
@ -195,7 +195,7 @@ export class JiraProvisionerRouter {
|
||||
}
|
||||
} catch (ex) {
|
||||
log.warn(`Failed to fetch accessible projects for ${req.params.instanceName} / ${req.query.userId}`, ex);
|
||||
return next( new ApiError("Could not fetch accessible projects for JIRA user", ErrCode.Unknown));
|
||||
return next( new ApiError("Could not fetch accessible projects for JIRA user.", ErrCode.Unknown));
|
||||
}
|
||||
|
||||
return res.send(projects);
|
||||
|
@ -76,7 +76,7 @@ export class UserTokenStore {
|
||||
|
||||
public async storeUserToken(type: TokenType, userId: string, token: string, instanceUrl?: string): Promise<void> {
|
||||
if (!this.config.checkPermission(userId, type, BridgePermissionLevel.login)) {
|
||||
throw new ApiError('User does not have permission to login to service', ErrCode.ForbiddenUser);
|
||||
throw new ApiError('User does not have permission to log in to service', ErrCode.ForbiddenUser);
|
||||
}
|
||||
const key = tokenKey(type, userId, false, instanceUrl);
|
||||
const tokenParts: string[] = [];
|
||||
|
@ -55,7 +55,7 @@ export async function ensureFigmaWebhooks(figmaConfig: BridgeConfigFigma, matrix
|
||||
webhookDefinition = res.data as FigmaWebhookDefinition;
|
||||
await matrixClient.setAccountData(accountDataKey, {webhookId: webhookDefinition.id});
|
||||
}
|
||||
// Webhook is ready and setup
|
||||
// Webhook is ready and set up
|
||||
}
|
||||
|
||||
}
|
@ -45,7 +45,7 @@ Request the connection types enabled for this bridge.
|
||||
"type": "JiraProject", // The name of the connection
|
||||
"eventType": "uk.half-shot.matrix-hookshot.jira.project", // Corresponds to the state type for the connection
|
||||
"service": "jira", // or github, webhook. A human-readable service name to make things look pretty
|
||||
"botUserId": "@hookshot:yourdomain.com", // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
|
||||
"botUserId": "@hookshot:yourdomain.com", // The bot mxid for the service. Currently, this is the sender_localpart, but may change in the future.
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -62,7 +62,7 @@ Request the connections for a given room. The `{roomId}` parameter is the target
|
||||
"eventType": "uk.half-shot.matrix-hookshot.jira.project", // Corresponds to the state type in the connection
|
||||
"id": "opaque-unique-id", // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
|
||||
"service": "jira", // or github, webhook. A human-readable service name to make things look pretty
|
||||
"botUserId": "@hookshot:yourdomain.com", // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
|
||||
"botUserId": "@hookshot:yourdomain.com", // The bot mxid for the service. Currently, this is the sender_localpart, but may change in the future.
|
||||
"config": {
|
||||
// ... connection specific details, can be configured.
|
||||
}
|
||||
@ -82,7 +82,7 @@ Request details of a single connection. The `{roomId}` parameter is the target M
|
||||
"eventType": "uk.half-shot.matrix-hookshot.jira.project", // Corresponds to the state type in the connection
|
||||
"id": "opaque-unique-id", // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
|
||||
"service": "jira", // or github, webhook. A human-readable service name to make things look pretty
|
||||
"botUserId": "@hookshot:yourdomain.com", // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
|
||||
"botUserId": "@hookshot:yourdomain.com", // The bot mxid for the service. Currently, this is the sender_localpart, but may change in the future.
|
||||
"config": {
|
||||
// ... connection specific details, can be configured.
|
||||
}
|
||||
@ -110,7 +110,7 @@ The body of the request is the configuration for the connection, which will be t
|
||||
"eventType": "uk.half-shot.matrix-hookshot.jira.project", // Corresponds to the state type in the connection
|
||||
"id": "opaque-unique-id", // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
|
||||
"service": "jira", // or github, webhook. A human-readable service name to make things look pretty
|
||||
"botUserId": "@hookshot:yourdomain.com", // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
|
||||
"botUserId": "@hookshot:yourdomain.com", // The bot mxid for the service. Currently, this is the sender_localpart, but may change in the future.
|
||||
"config": {
|
||||
// ... connection specific details, can be configured.
|
||||
}
|
||||
@ -138,7 +138,7 @@ The body of the request is the configuration for the connection, which will be t
|
||||
"eventType": "uk.half-shot.matrix-hookshot.jira.project", // Corresponds to the state type in the connection
|
||||
"id": "opaque-unique-id", // An opaque ID used to refer to this connection. Should **NOT** be assumed to be stable.
|
||||
"service": "jira", // or github, webhook. A human-readable service name to make things look pretty
|
||||
"botUserId": "@hookshot:yourdomain.com", // The bot mxid for the service. Currently this is the sender_localpart, but may change in the future.
|
||||
"botUserId": "@hookshot:yourdomain.com", // The bot mxid for the service. Currently, this is the sender_localpart, but may change in the future.
|
||||
"config": {
|
||||
// ... connection specific details, can be configured.
|
||||
}
|
||||
|
@ -185,10 +185,10 @@ export class Provisioner {
|
||||
private getConnection(req: Request<{roomId: string, connectionId: string}>, res: Response<GetConnectionsResponseItem>) {
|
||||
const connection = this.connMan.getConnectionById(req.params.roomId, req.params.connectionId);
|
||||
if (!connection) {
|
||||
throw new ApiError("Connection does not exist", ErrCode.NotFound);
|
||||
throw new ApiError("Connection does not exist.", ErrCode.NotFound);
|
||||
}
|
||||
if (!connection.getProvisionerDetails) {
|
||||
throw new ApiError("Connection type does not support updates", ErrCode.UnsupportedOperation);
|
||||
throw new ApiError("Connection type does not support updates.", ErrCode.UnsupportedOperation);
|
||||
}
|
||||
return res.send(connection.getProvisionerDetails());
|
||||
}
|
||||
@ -197,15 +197,15 @@ export class Provisioner {
|
||||
// Need to figure out which connections are available
|
||||
try {
|
||||
if (!req.body || typeof req.body !== "object") {
|
||||
throw new ApiError("A JSON body must be provided", ErrCode.BadValue);
|
||||
throw new ApiError("A JSON body must be provided.", ErrCode.BadValue);
|
||||
}
|
||||
const connection = await this.connMan.provisionConnection(req.params.roomId, req.query.userId, req.params.type, req.body);
|
||||
if (!connection.getProvisionerDetails) {
|
||||
throw new Error('Connection supported provisioning but not getProvisionerDetails');
|
||||
throw new Error('Connection supported provisioning but not getProvisionerDetails.');
|
||||
}
|
||||
res.send(connection.getProvisionerDetails());
|
||||
} catch (ex) {
|
||||
log.warn(`Failed to create connection for ${req.params.roomId}`, ex);
|
||||
log.warn(`Failed to create connection for ${req.params.roomId}.`, ex);
|
||||
return next(ex);
|
||||
}
|
||||
}
|
||||
@ -214,10 +214,10 @@ export class Provisioner {
|
||||
try {
|
||||
const connection = this.connMan.getConnectionById(req.params.roomId, req.params.connectionId);
|
||||
if (!connection) {
|
||||
return next(new ApiError("Connection does not exist", ErrCode.NotFound));
|
||||
return next(new ApiError("Connection does not exist.", ErrCode.NotFound));
|
||||
}
|
||||
if (!connection.provisionerUpdateConfig || !connection.getProvisionerDetails) {
|
||||
return next(new ApiError("Connection type does not support updates", ErrCode.UnsupportedOperation));
|
||||
return next(new ApiError("Connection type does not support updates.", ErrCode.UnsupportedOperation));
|
||||
}
|
||||
await connection.provisionerUpdateConfig(req.query.userId, req.body);
|
||||
res.send(connection.getProvisionerDetails());
|
||||
@ -230,10 +230,10 @@ export class Provisioner {
|
||||
try {
|
||||
const connection = this.connMan.getConnectionById(req.params.roomId, req.params.connectionId);
|
||||
if (!connection) {
|
||||
return next(new ApiError("Connection does not exist", ErrCode.NotFound));
|
||||
return next(new ApiError("Connection does not exist.", ErrCode.NotFound));
|
||||
}
|
||||
if (!connection.onRemove) {
|
||||
return next(new ApiError("Connection does not support removal", ErrCode.UnsupportedOperation));
|
||||
return next(new ApiError("Connection does not support removal.", ErrCode.UnsupportedOperation));
|
||||
}
|
||||
await this.connMan.purgeConnection(req.params.roomId, req.params.connectionId);
|
||||
res.send({ok: true});
|
||||
|
Loading…
x
Reference in New Issue
Block a user