mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-10-01 01:05:53 -04:00
Show the appservice configuration after saving; Make the show config button work
Includes the ability to 'test' the appservice. This doesn't bother checking if the URL is set up correctly because we don't actually care about the transactions.
This commit is contained in:
parent
656d208059
commit
62d81ed842
@ -4,6 +4,9 @@ import AppService from "../../db/models/AppService";
|
||||
import { AppserviceStore } from "../../db/AppserviceStore";
|
||||
import { ApiError } from "../ApiError";
|
||||
import AppServiceUser from "../../db/models/AppServiceUser";
|
||||
import { MatrixAppserviceClient } from "../../matrix/MatrixAppserviceClient";
|
||||
import config from "../../config";
|
||||
import { LogService } from "matrix-js-snippets";
|
||||
|
||||
interface AppserviceResponse {
|
||||
id: string;
|
||||
@ -37,6 +40,20 @@ export class AdminAppserviceService {
|
||||
return (await AppService.findAll()).map(a => this.mapAppservice(a));
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path(":appserviceId")
|
||||
public async getAppservice(@QueryParam("scalar_token") scalarToken: string, @PathParam("appserviceId") asId: string): Promise<AppserviceResponse> {
|
||||
await AdminService.validateAndGetAdminTokenOwner(scalarToken);
|
||||
|
||||
try {
|
||||
const appservice = await AppserviceStore.getAppservice(asId);
|
||||
return this.mapAppservice(appservice);
|
||||
} catch (err) {
|
||||
LogService.error("AdminAppserviceService", err);
|
||||
throw new ApiError(404, "Appservice not found");
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("new")
|
||||
public async createAppservice(@QueryParam("scalar_token") scalarToken: string, request: AppserviceCreateRequest): Promise<AppserviceResponse> {
|
||||
@ -72,6 +89,19 @@ export class AdminAppserviceService {
|
||||
return this.mapUser(user);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path(":appserviceId/test")
|
||||
public async test(@QueryParam("scalar_token") scalarToken: string, @PathParam("appserviceId") asId: string): Promise<any> {
|
||||
await AdminService.validateAndGetAdminTokenOwner(scalarToken);
|
||||
|
||||
const appservice = await AppserviceStore.getAppservice(asId);
|
||||
const client = new MatrixAppserviceClient(config.homeserver.name, appservice);
|
||||
const userId = await client.whoAmI();
|
||||
|
||||
if (userId.startsWith("@" + appservice.userPrefix)) return {}; // 200 OK
|
||||
throw new ApiError(500, "User ID does not match the application service");
|
||||
}
|
||||
|
||||
private mapAppservice(as: AppService): AppserviceResponse {
|
||||
return {
|
||||
id: as.id,
|
||||
|
@ -62,6 +62,12 @@ export class AppserviceStore {
|
||||
});
|
||||
}
|
||||
|
||||
public static async getAppservice(id: string): Promise<AppService> {
|
||||
const appservice = await AppService.findByPrimary(id);
|
||||
if (!appservice) throw new Error("Appservice not found");
|
||||
return appservice;
|
||||
}
|
||||
|
||||
private constructor() {
|
||||
}
|
||||
}
|
@ -22,4 +22,14 @@ export class MatrixAppserviceClient {
|
||||
{type: "m.login.application_service", username: localpart},
|
||||
);
|
||||
}
|
||||
|
||||
public async whoAmI(): Promise<string> {
|
||||
const response = await doFederatedApiCall(
|
||||
"GET",
|
||||
this.homeserverName,
|
||||
"/_matrix/client/r0/account/whoami",
|
||||
{access_token: this.appservice.asToken},
|
||||
);
|
||||
return response['user_id'];
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,11 @@ import { AdminAppserviceApiService } from "../../../shared/services/admin/admin-
|
||||
import { AdminNebApiService } from "../../../shared/services/admin/admin-neb-api.service";
|
||||
import { ToasterService } from "angular2-toaster";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
||||
import {
|
||||
AdminNebAppserviceConfigComponent,
|
||||
AppserviceConfigDialogContext
|
||||
} from "../appservice-config/appservice-config.component";
|
||||
|
||||
|
||||
@Component({
|
||||
@ -19,16 +24,23 @@ export class AdminAddSelfhostedNebComponent {
|
||||
private nebApi: AdminNebApiService,
|
||||
private toaster: ToasterService,
|
||||
private router: Router,
|
||||
private activatedRoute: ActivatedRoute) {
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private modal: Modal) {
|
||||
}
|
||||
|
||||
public save(): void {
|
||||
this.isSaving = true;
|
||||
this.asApi.createAppservice(this.userPrefix).then(appservice => {
|
||||
return this.nebApi.newAppserviceConfiguration(this.adminUrl, appservice);
|
||||
}).then(() => {
|
||||
}).then(neb => {
|
||||
this.toaster.pop("success", "New go-neb created");
|
||||
this.router.navigate(["../.."], {relativeTo: this.activatedRoute});
|
||||
|
||||
this.modal.open(AdminNebAppserviceConfigComponent, overlayConfigFactory({
|
||||
neb: neb,
|
||||
|
||||
isBlocking: true,
|
||||
size: 'lg',
|
||||
}, AppserviceConfigDialogContext)).result.then(() => this.router.navigate(["../.."], {relativeTo: this.activatedRoute}));
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
this.isSaving = false;
|
||||
|
@ -0,0 +1,22 @@
|
||||
<div class="dialog">
|
||||
<div class="dialog-header">
|
||||
<h4>go-neb appservice configuration</h4>
|
||||
</div>
|
||||
<div class="dialog-content" *ngIf="isLoading">
|
||||
<my-spinner></my-spinner>
|
||||
</div>
|
||||
<div class="dialog-content" *ngIf="!isLoading">
|
||||
Copy and paste this configuration to <code>appservice-{{appservice.id}}.yaml</code> on your homeserver and
|
||||
register it as an application service.
|
||||
<br/>
|
||||
<pre>{{appserviceConfig}}</pre>
|
||||
</div>
|
||||
<div class="dialog-footer" *ngIf="!isLoading">
|
||||
<button type="button" (click)="dialog.close()" title="save" class="btn btn-primary btn-sm">
|
||||
<i class="far fa-times-circle"></i> Close
|
||||
</button>
|
||||
<button type="button" (click)="test()" title="close" class="btn btn-secondary btn-sm">
|
||||
<i class="fa fa-exchange-alt"></i> Test Configuration
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,6 @@
|
||||
pre {
|
||||
margin-top: 10px;
|
||||
padding: 5px;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #eee;
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { ToasterService } from "angular2-toaster";
|
||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
||||
import { FE_Appservice, FE_NebConfiguration } from "../../../shared/models/admin_responses";
|
||||
import { AdminAppserviceApiService } from "../../../shared/services/admin/admin-appservice-api.service";
|
||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
||||
|
||||
export class AppserviceConfigDialogContext extends BSModalContext {
|
||||
public neb: FE_NebConfiguration;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: "./appservice-config.component.html",
|
||||
styleUrls: ["./appservice-config.component.scss"],
|
||||
})
|
||||
export class AdminNebAppserviceConfigComponent implements ModalComponent<AppserviceConfigDialogContext> {
|
||||
|
||||
public isLoading = true;
|
||||
public neb: FE_NebConfiguration;
|
||||
public appservice: FE_Appservice;
|
||||
|
||||
constructor(public dialog: DialogRef<AppserviceConfigDialogContext>, private adminAppserviceApi: AdminAppserviceApiService, private toaster: ToasterService) {
|
||||
this.neb = dialog.context.neb;
|
||||
|
||||
this.adminAppserviceApi.getAppservice(this.neb.appserviceId).then(appservice => {
|
||||
this.appservice = appservice;
|
||||
this.isLoading = false;
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
this.toaster.pop("error", "Could not load appservice configuration");
|
||||
});
|
||||
}
|
||||
|
||||
public get appserviceConfig(): string {
|
||||
return `` +
|
||||
`id: ${this.appservice.id}\n` +
|
||||
`url: ${window.location.origin}/_matrix/appservice/r0\n` +
|
||||
`as_token: ${this.appservice.asToken}\n` +
|
||||
`hs_token: ${this.appservice.hsToken}\n` +
|
||||
`sender_localpart: ${this.appservice.userPrefix}\n` +
|
||||
`namespaces:\n` +
|
||||
` users:\n` +
|
||||
` - exclusive: true\n` +
|
||||
` regex: '@${this.appservice.userPrefix}.*'\n` +
|
||||
` aliases: []\n` +
|
||||
` rooms: []`;
|
||||
}
|
||||
|
||||
public test() {
|
||||
this.adminAppserviceApi.test(this.neb.appserviceId).then(() => {
|
||||
this.toaster.pop("success", "The appservice appears to be correctly set up");
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
this.toaster.pop("error", "The appservice is not correctly set up");
|
||||
});
|
||||
}
|
||||
}
|
@ -5,6 +5,11 @@ import { AdminUpstreamApiService } from "../../shared/services/admin/admin-upstr
|
||||
import { AdminAppserviceApiService } from "../../shared/services/admin/admin-appservice-api.service";
|
||||
import { FE_Appservice, FE_NebConfiguration, FE_Upstream } from "../../shared/models/admin_responses";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import {
|
||||
AdminNebAppserviceConfigComponent,
|
||||
AppserviceConfigDialogContext
|
||||
} from "./appservice-config/appservice-config.component";
|
||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./neb.component.html",
|
||||
@ -24,7 +29,8 @@ export class AdminNebComponent {
|
||||
private appserviceApi: AdminAppserviceApiService,
|
||||
private toaster: ToasterService,
|
||||
private router: Router,
|
||||
private activatedRoute: ActivatedRoute) {
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private modal: Modal) {
|
||||
|
||||
this.reload().then(() => this.isLoading = false).catch(error => {
|
||||
console.error(error);
|
||||
@ -68,7 +74,12 @@ export class AdminNebComponent {
|
||||
}
|
||||
|
||||
public showAppserviceConfig(neb: FE_NebConfiguration) {
|
||||
console.log(neb);
|
||||
this.modal.open(AdminNebAppserviceConfigComponent, overlayConfigFactory({
|
||||
neb: neb,
|
||||
|
||||
isBlocking: true,
|
||||
size: 'lg',
|
||||
}, AppserviceConfigDialogContext));
|
||||
}
|
||||
|
||||
public getEnabledBotsString(neb: FE_NebConfiguration): string {
|
||||
|
@ -53,6 +53,7 @@ import { AdminUpstreamApiService } from "./shared/services/admin/admin-upstream-
|
||||
import { AdminNebComponent } from "./admin/neb/neb.component";
|
||||
import { AdminEditNebComponent } from "./admin/neb/edit/edit.component";
|
||||
import { AdminAddSelfhostedNebComponent } from "./admin/neb/add_selfhosted/add_selfhosted.component";
|
||||
import { AdminNebAppserviceConfigComponent } from "./admin/neb/appservice-config/appservice-config.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -100,6 +101,7 @@ import { AdminAddSelfhostedNebComponent } from "./admin/neb/add_selfhosted/add_s
|
||||
AdminNebComponent,
|
||||
AdminEditNebComponent,
|
||||
AdminAddSelfhostedNebComponent,
|
||||
AdminNebAppserviceConfigComponent,
|
||||
|
||||
// Vendor
|
||||
],
|
||||
@ -122,6 +124,7 @@ import { AdminAddSelfhostedNebComponent } from "./admin/neb/add_selfhosted/add_s
|
||||
entryComponents: [
|
||||
AdminWidgetEtherpadConfigComponent,
|
||||
AdminWidgetJitsiConfigComponent,
|
||||
AdminNebAppserviceConfigComponent,
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
|
@ -13,7 +13,15 @@ export class AdminAppserviceApiService extends AuthedApi {
|
||||
return this.authedGet("/api/v1/dimension/admin/appservices/all").map(r => r.json()).toPromise();
|
||||
}
|
||||
|
||||
public getAppservice(appserviceId: string): Promise<FE_Appservice> {
|
||||
return this.authedGet("/api/v1/dimension/admin/appservices/" + appserviceId).map(r => r.json()).toPromise();
|
||||
}
|
||||
|
||||
public createAppservice(userPrefix: string): Promise<FE_Appservice> {
|
||||
return this.authedPost("/api/v1/dimension/admin/appservices/new", {userPrefix: userPrefix}).map(r => r.json()).toPromise();
|
||||
}
|
||||
|
||||
public test(appserviceId: string): Promise<any> {
|
||||
return this.authedPost("/api/v1/dimension/admin/appservices/" + appserviceId + "/test").map(r => r.json()).toPromise();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user