mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-10-01 05:05:53 +00:00
Add an integration manager test widget
Fixes https://github.com/turt2live/matrix-dimension/issues/244
This commit is contained in:
parent
83b2062d87
commit
bb874b1fa0
@ -100,4 +100,10 @@ export class ScalarService {
|
||||
return {user_id: userId};
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("ping")
|
||||
public async ping(): Promise<any> {
|
||||
return {}; // 200 OK
|
||||
}
|
||||
|
||||
}
|
@ -110,6 +110,7 @@ import { AdminSlackBridgeManageSelfhostedComponent } from "./admin/bridges/slack
|
||||
import { AdminSlackBridgeComponent } from "./admin/bridges/slack/slack.component";
|
||||
import { AdminSlackApiService } from "./shared/services/admin/admin-slack-api.service";
|
||||
import { ReauthExampleWidgetWrapperComponent } from "./widget-wrappers/reauth-example/reauth-example.component";
|
||||
import { ManagerTestWidgetWrapperComponent } from "./widget-wrappers/manager-test/manager-test.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -200,6 +201,7 @@ import { ReauthExampleWidgetWrapperComponent } from "./widget-wrappers/reauth-ex
|
||||
AdminSlackBridgeManageSelfhostedComponent,
|
||||
AdminSlackBridgeComponent,
|
||||
ReauthExampleWidgetWrapperComponent,
|
||||
ManagerTestWidgetWrapperComponent,
|
||||
|
||||
// Vendor
|
||||
],
|
||||
|
@ -43,6 +43,7 @@ import { AdminCustomBotsComponent } from "./admin/custom-bots/custom-bots.compon
|
||||
import { AdminSlackBridgeComponent } from "./admin/bridges/slack/slack.component";
|
||||
import { SlackBridgeConfigComponent } from "./configs/bridge/slack/slack.bridge.component";
|
||||
import { ReauthExampleWidgetWrapperComponent } from "./widget-wrappers/reauth-example/reauth-example.component";
|
||||
import { ManagerTestWidgetWrapperComponent } from "./widget-wrappers/manager-test/manager-test.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{path: "", component: HomeComponent},
|
||||
@ -266,6 +267,7 @@ const routes: Routes = [
|
||||
{path: "tradingview", component: TradingViewWidgetWrapperComponent},
|
||||
{path: "spotify", component: SpotifyWidgetWrapperComponent},
|
||||
{path: "reauth", component: ReauthExampleWidgetWrapperComponent},
|
||||
{path: "manager-test", component: ManagerTestWidgetWrapperComponent},
|
||||
]
|
||||
},
|
||||
];
|
||||
|
@ -13,6 +13,10 @@ export class ScalarServerApiService extends AuthedApi {
|
||||
super(http)
|
||||
}
|
||||
|
||||
public ping(): Promise<any> {
|
||||
return this.http.get("/api/v1/scalar/ping").map(res => res.json()).toPromise();
|
||||
}
|
||||
|
||||
public getAccount(): Promise<FE_ScalarAccountResponse> {
|
||||
return this.authedGet("/api/v1/scalar/account").map(res => res.json()).toPromise();
|
||||
}
|
||||
|
@ -2,16 +2,23 @@ import { OnDestroy, OnInit } from "@angular/core";
|
||||
import { Subscription } from "rxjs/Subscription";
|
||||
import { ScalarWidgetApi } from "../shared/services/scalar/scalar-widget.api";
|
||||
import * as semver from "semver";
|
||||
import { FE_ScalarOpenIdRequestBody } from "../shared/models/scalar-server-responses";
|
||||
|
||||
export const WIDGET_API_VERSION_BASIC = "0.0.1";
|
||||
export const WIDGET_API_VERSION_OPENID = "0.0.2";
|
||||
|
||||
export const WIDGET_API_DIMENSION_VERSIONS = [WIDGET_API_VERSION_BASIC, WIDGET_API_VERSION_OPENID];
|
||||
|
||||
export interface OpenIdResponse {
|
||||
openId: FE_ScalarOpenIdRequestBody;
|
||||
blocked: boolean;
|
||||
}
|
||||
|
||||
export abstract class CapableWidget implements OnInit, OnDestroy {
|
||||
|
||||
private requestSubscription: Subscription;
|
||||
private responseSubscription: Subscription;
|
||||
private openIdRequest: { resolve: (a: OpenIdResponse) => void, promise: Promise<OpenIdResponse> } = null;
|
||||
|
||||
// The capabilities we support
|
||||
protected supportsScreenshots = false;
|
||||
@ -34,12 +41,29 @@ export abstract class CapableWidget implements OnInit, OnDestroy {
|
||||
this.onCapabilitiesSent();
|
||||
} else if (request.action === "supported_api_versions") {
|
||||
ScalarWidgetApi.replySupportedVersions(request, WIDGET_API_DIMENSION_VERSIONS);
|
||||
} else if (request.action === "openid_credentials" && this.openIdRequest) {
|
||||
if (request.data.success) {
|
||||
this.openIdRequest.resolve({openId: request.data, blocked: false});
|
||||
} else {
|
||||
this.openIdRequest.resolve({openId: null, blocked: true});
|
||||
}
|
||||
this.openIdRequest = null;
|
||||
}
|
||||
});
|
||||
this.responseSubscription = ScalarWidgetApi.replyReceived.subscribe(request => {
|
||||
if (request.action === "supported_api_versions" && request.response) {
|
||||
if (!request.response) return;
|
||||
|
||||
if (request.action === "supported_api_versions") {
|
||||
this.clientWidgetApiVersions = request.response.supported_versions || [];
|
||||
this.onSupportedVersionsFound();
|
||||
} else if (request.action === "get_openid" && this.openIdRequest) {
|
||||
if (request.response.state === "allowed") {
|
||||
this.openIdRequest.resolve({openId: request.response, blocked: false});
|
||||
this.openIdRequest = null;
|
||||
} else if (request.response.state === "blocked") {
|
||||
this.openIdRequest.resolve({openId: null, blocked: true});
|
||||
this.openIdRequest = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -65,4 +89,13 @@ export abstract class CapableWidget implements OnInit, OnDestroy {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected getOpenIdInfo(): Promise<OpenIdResponse> {
|
||||
if (this.openIdRequest) return this.openIdRequest.promise;
|
||||
const promise = new Promise<OpenIdResponse>(((resolve, _reject) => {
|
||||
this.openIdRequest = {resolve: resolve, promise};
|
||||
ScalarWidgetApi.requestOpenID();
|
||||
}));
|
||||
return promise;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<div class="wrapper">
|
||||
<div class="boat">
|
||||
<div class="prompt">
|
||||
<div class="diagram">
|
||||
<div class="circle {{selfState}}">
|
||||
<i class="fa fa-user fa-2x"></i>
|
||||
<span class="title">You</span>
|
||||
</div>
|
||||
<div class="link {{managerState}}"></div>
|
||||
<div class="circle {{managerState}}">
|
||||
<i class="fa fa-cubes fa-2x"></i>
|
||||
<span class="title">Integrations</span>
|
||||
</div>
|
||||
<div class="link {{homeserverState}}"></div>
|
||||
<div class="circle {{homeserverState}}">
|
||||
<i class="fa fa-server fa-2x"></i>
|
||||
<span class="title">Homeserver</span>
|
||||
</div>
|
||||
</div>
|
||||
<p *ngIf="!isSupported">
|
||||
Your client is too old to use this widget. Try upgrading your client to the latest available version,
|
||||
or contact the author to try and diagnose the problem. Your client needs to support OpenID information
|
||||
exchange.
|
||||
</p>
|
||||
<div *ngIf="isSupported">
|
||||
<p>{{message}}</p>
|
||||
<button type="button" (click)="start()" class="btn btn-primary btn-large" [disabled]="isBusy">
|
||||
Check connection
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,66 @@
|
||||
// component styles are encapsulated and only applied to their components
|
||||
@import "../../../style/themes/themes";
|
||||
|
||||
@include themifyComponent() {
|
||||
.wrapper {
|
||||
display: table;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: themed(troubleshooterBgColor);
|
||||
}
|
||||
|
||||
.boat {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.prompt {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 90%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.diagram {
|
||||
margin: 20px;
|
||||
|
||||
div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border: 5px solid themed(troubleshooterNeutralColor);
|
||||
border-radius: 120px;
|
||||
vertical-align: middle;
|
||||
padding-top: 22px;
|
||||
transition: border-color 0.2s;
|
||||
|
||||
.title {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.link {
|
||||
width: 120px;
|
||||
height: 1px;
|
||||
border: 2px solid themed(troubleshooterNeutralColor);
|
||||
margin: 5px;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
.circle.error, .link.error {
|
||||
border-color: themed(troubleshooterErrorColor);
|
||||
}
|
||||
|
||||
.circle.ok, .link.ok {
|
||||
border-color: themed(troubleshooterOkColor);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { ScalarWidgetApi } from "../../shared/services/scalar/scalar-widget.api";
|
||||
import { CapableWidget, WIDGET_API_VERSION_OPENID } from "../capable-widget";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { ScalarServerApiService } from "../../shared/services/scalar/scalar-server-api.service";
|
||||
|
||||
@Component({
|
||||
selector: "my-reauth-example-widget-wrapper",
|
||||
templateUrl: "manager-test.component.html",
|
||||
styleUrls: ["manager-test.component.scss"],
|
||||
})
|
||||
export class ManagerTestWidgetWrapperComponent extends CapableWidget implements OnInit, OnDestroy {
|
||||
|
||||
public readonly STATE_NEUTRAL = 'neutral';
|
||||
public readonly STATE_OK = 'ok';
|
||||
public readonly STATE_ERROR = 'error';
|
||||
|
||||
public isBusy = true;
|
||||
public isSupported = true;
|
||||
public selfState = this.STATE_NEUTRAL;
|
||||
public managerState = this.STATE_NEUTRAL;
|
||||
public homeserverState = this.STATE_NEUTRAL;
|
||||
public message = "Click the button to test your connection. This may cause your client to ask if it " +
|
||||
"is okay to share your identity with the widget - this is required to test your connection to your " +
|
||||
"homeserver.";
|
||||
|
||||
constructor(activatedRoute: ActivatedRoute,
|
||||
private scalarApi: ScalarServerApiService,
|
||||
private changeDetector: ChangeDetectorRef) {
|
||||
super();
|
||||
|
||||
const params: any = activatedRoute.snapshot.queryParams;
|
||||
ScalarWidgetApi.widgetId = params.widgetId;
|
||||
}
|
||||
|
||||
protected onSupportedVersionsFound(): void {
|
||||
super.onSupportedVersionsFound();
|
||||
this.isSupported = this.doesSupportAtLeastVersion(WIDGET_API_VERSION_OPENID);
|
||||
this.isBusy = false;
|
||||
if (!this.isSupported) {
|
||||
this.selfState = this.STATE_ERROR;
|
||||
}
|
||||
this.changeDetector.detectChanges();
|
||||
}
|
||||
|
||||
public async start(): Promise<any> {
|
||||
this.selfState = this.STATE_NEUTRAL;
|
||||
this.managerState = this.STATE_NEUTRAL;
|
||||
this.homeserverState = this.STATE_NEUTRAL;
|
||||
|
||||
this.message = "Please accept the prompt to verify your identity.";
|
||||
this.isBusy = true;
|
||||
|
||||
const response = await this.getOpenIdInfo();
|
||||
if (response.blocked) {
|
||||
this.isBusy = false;
|
||||
this.selfState = this.STATE_ERROR;
|
||||
this.message = "You have blocked this widget from verifying your identity.";
|
||||
return;
|
||||
}
|
||||
|
||||
this.selfState = this.STATE_OK;
|
||||
this.message = "Checking connectivity to integration manager...";
|
||||
|
||||
try {
|
||||
await this.scalarApi.ping();
|
||||
this.managerState = this.STATE_OK;
|
||||
this.message = "Checking connectivity to homeserver...";
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
this.isBusy = false;
|
||||
this.managerState = this.STATE_ERROR;
|
||||
this.message = "Error checking if the integration manager is alive. This usually means that the manager " +
|
||||
"which served this widget has gone offline.";
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.scalarApi.register(response.openId);
|
||||
this.homeserverState = this.STATE_OK;
|
||||
this.message = "You're all set! Click the button below to re-run the test.";
|
||||
this.isBusy = false;
|
||||
} catch (e) {
|
||||
this.isBusy = false;
|
||||
this.homeserverState = this.STATE_ERROR;
|
||||
this.message = "Error contacting homeserver. This usually means your federation setup is incorrect, or " +
|
||||
"your homeserver is offline. Consult your homeserver's documentation for how to set up federation.";
|
||||
}
|
||||
}
|
||||
}
|
@ -50,6 +50,11 @@ $theme_dark: (
|
||||
|
||||
jitsiWelcomeBgColor: #fff,
|
||||
|
||||
troubleshooterBgColor: #2d2d2d,
|
||||
troubleshooterNeutralColor: rgb(205, 215, 222),
|
||||
troubleshooterOkColor: #59bb59,
|
||||
troubleshooterErrorColor: #e84f4f,
|
||||
|
||||
genericControlBgColor: #eee,
|
||||
genericControlFgColor: #222,
|
||||
widgetBannedSymbolColor: #bd362f,
|
||||
|
@ -50,6 +50,11 @@ $theme_light: (
|
||||
|
||||
jitsiWelcomeBgColor: #fff,
|
||||
|
||||
troubleshooterBgColor: #fff,
|
||||
troubleshooterNeutralColor: rgb(205, 215, 222),
|
||||
troubleshooterOkColor: #59bb59,
|
||||
troubleshooterErrorColor: #e84f4f,
|
||||
|
||||
genericControlBgColor: #eee,
|
||||
genericControlFgColor: #222,
|
||||
widgetBannedSymbolColor: #bd362f,
|
||||
|
Loading…
Reference in New Issue
Block a user