2019-07-23 19:52:00 +03:00
|
|
|
/*
|
|
|
|
Copyright 2017 Vector Creations Ltd
|
|
|
|
Copyright 2018, 2019 New Vector Ltd
|
2020-07-10 21:07:11 +03:00
|
|
|
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
2019-07-23 19:52:00 +03:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2017-07-26 13:28:43 +03:00
|
|
|
import React from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
2017-07-26 18:47:58 +03:00
|
|
|
import url from 'url';
|
2019-12-20 04:19:56 +03:00
|
|
|
import * as sdk from '../../../index';
|
2017-07-28 18:39:18 +03:00
|
|
|
import { _t } from '../../../languageHandler';
|
2020-07-10 21:07:11 +03:00
|
|
|
import SdkConfig from '../../../SdkConfig';
|
2018-06-26 13:59:16 +03:00
|
|
|
import WidgetUtils from "../../../utils/WidgetUtils";
|
2021-06-29 15:11:58 +03:00
|
|
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
|
|
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
2017-07-26 13:28:43 +03:00
|
|
|
|
2021-03-09 05:59:41 +03:00
|
|
|
@replaceableComponent("views.elements.AppPermission")
|
2017-07-26 13:28:43 +03:00
|
|
|
export default class AppPermission extends React.Component {
|
2019-11-16 00:25:53 +03:00
|
|
|
static propTypes = {
|
|
|
|
url: PropTypes.string.isRequired,
|
|
|
|
creatorUserId: PropTypes.string.isRequired,
|
|
|
|
roomId: PropTypes.string.isRequired,
|
|
|
|
onPermissionGranted: PropTypes.func.isRequired,
|
2019-11-21 02:26:06 +03:00
|
|
|
isRoomEncrypted: PropTypes.bool,
|
2019-11-16 00:25:53 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
static defaultProps = {
|
|
|
|
onPermissionGranted: () => {},
|
|
|
|
};
|
|
|
|
|
2017-07-26 13:28:43 +03:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
2019-11-16 00:25:53 +03:00
|
|
|
// The first step is to pick apart the widget so we can render information about it
|
|
|
|
const urlInfo = this.parseWidgetUrl();
|
2017-07-26 13:28:43 +03:00
|
|
|
|
2019-11-16 00:25:53 +03:00
|
|
|
// The second step is to find the user's profile so we can show it on the prompt
|
|
|
|
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
|
|
|
let roomMember;
|
|
|
|
if (room) roomMember = room.getMember(this.props.creatorUserId);
|
2017-07-26 18:47:58 +03:00
|
|
|
|
2019-11-16 00:25:53 +03:00
|
|
|
// Set all this into the initial state
|
|
|
|
this.state = {
|
|
|
|
...urlInfo,
|
|
|
|
roomMember,
|
|
|
|
};
|
|
|
|
}
|
2017-07-28 12:01:58 +03:00
|
|
|
|
2019-11-16 00:25:53 +03:00
|
|
|
parseWidgetUrl() {
|
|
|
|
const widgetUrl = url.parse(this.props.url);
|
|
|
|
const params = new URLSearchParams(widgetUrl.search);
|
|
|
|
|
|
|
|
// HACK: We're relying on the query params when we should be relying on the widget's `data`.
|
|
|
|
// This is a workaround for Scalar.
|
|
|
|
if (WidgetUtils.isScalarUrl(widgetUrl) && params && params.get('url')) {
|
|
|
|
const unwrappedUrl = url.parse(params.get('url'));
|
|
|
|
return {
|
|
|
|
widgetDomain: unwrappedUrl.host || unwrappedUrl.hostname,
|
|
|
|
isWrapped: true,
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
return {
|
|
|
|
widgetDomain: widgetUrl.host || widgetUrl.hostname,
|
|
|
|
isWrapped: false,
|
|
|
|
};
|
2017-07-27 18:42:29 +03:00
|
|
|
}
|
2017-07-26 13:28:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2020-07-10 21:07:11 +03:00
|
|
|
const brand = SdkConfig.get().brand;
|
2019-11-16 00:25:53 +03:00
|
|
|
const AccessibleButton = sdk.getComponent("views.elements.AccessibleButton");
|
|
|
|
const MemberAvatar = sdk.getComponent("views.avatars.MemberAvatar");
|
|
|
|
const BaseAvatar = sdk.getComponent("views.avatars.BaseAvatar");
|
|
|
|
const TextWithTooltip = sdk.getComponent("views.elements.TextWithTooltip");
|
|
|
|
|
|
|
|
const displayName = this.state.roomMember ? this.state.roomMember.name : this.props.creatorUserId;
|
|
|
|
const userId = displayName === this.props.creatorUserId ? null : this.props.creatorUserId;
|
|
|
|
|
|
|
|
const avatar = this.state.roomMember
|
|
|
|
? <MemberAvatar member={this.state.roomMember} width={38} height={38} />
|
|
|
|
: <BaseAvatar name={this.props.creatorUserId} width={38} height={38} />;
|
|
|
|
|
|
|
|
const warningTooltipText = (
|
|
|
|
<div>
|
2021-07-20 00:43:11 +03:00
|
|
|
{ _t("Any of the following data may be shared:") }
|
2019-11-16 00:25:53 +03:00
|
|
|
<ul>
|
2021-07-20 00:43:11 +03:00
|
|
|
<li>{ _t("Your display name") }</li>
|
|
|
|
<li>{ _t("Your avatar URL") }</li>
|
|
|
|
<li>{ _t("Your user ID") }</li>
|
|
|
|
<li>{ _t("Your theme") }</li>
|
|
|
|
<li>{ _t("%(brand)s URL", { brand }) }</li>
|
|
|
|
<li>{ _t("Room ID") }</li>
|
|
|
|
<li>{ _t("Widget ID") }</li>
|
2019-11-16 00:25:53 +03:00
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
const warningTooltip = (
|
|
|
|
<TextWithTooltip tooltip={warningTooltipText} tooltipClass='mx_AppPermissionWarning_tooltip mx_Tooltip_dark'>
|
|
|
|
<span className='mx_AppPermissionWarning_helpIcon' />
|
|
|
|
</TextWithTooltip>
|
|
|
|
);
|
|
|
|
|
|
|
|
// Due to i18n limitations, we can't dedupe the code for variables in these two messages.
|
|
|
|
const warning = this.state.isWrapped
|
2021-07-13 18:04:50 +03:00
|
|
|
? _t("Using this widget may share data <helpIcon /> with %(widgetDomain)s & your integration manager.",
|
2021-06-29 15:11:58 +03:00
|
|
|
{ widgetDomain: this.state.widgetDomain }, { helpIcon: () => warningTooltip })
|
2019-11-16 00:25:53 +03:00
|
|
|
: _t("Using this widget may share data <helpIcon /> with %(widgetDomain)s.",
|
2021-06-29 15:11:58 +03:00
|
|
|
{ widgetDomain: this.state.widgetDomain }, { helpIcon: () => warningTooltip });
|
2019-11-16 00:25:53 +03:00
|
|
|
|
2019-11-21 19:12:07 +03:00
|
|
|
const encryptionWarning = this.props.isRoomEncrypted ? _t("Widgets do not use message encryption.") : null;
|
2019-11-21 02:26:06 +03:00
|
|
|
|
2017-07-26 13:28:43 +03:00
|
|
|
return (
|
2017-07-26 18:47:58 +03:00
|
|
|
<div className='mx_AppPermissionWarning'>
|
2019-11-16 00:25:53 +03:00
|
|
|
<div className='mx_AppPermissionWarning_row mx_AppPermissionWarning_bolder mx_AppPermissionWarning_smallText'>
|
2021-07-20 00:43:11 +03:00
|
|
|
{ _t("Widget added by") }
|
2017-07-26 18:47:58 +03:00
|
|
|
</div>
|
2019-11-16 00:25:53 +03:00
|
|
|
<div className='mx_AppPermissionWarning_row'>
|
2021-07-20 00:43:11 +03:00
|
|
|
{ avatar }
|
|
|
|
<h4 className='mx_AppPermissionWarning_bolder'>{ displayName }</h4>
|
|
|
|
<div className='mx_AppPermissionWarning_smallText'>{ userId }</div>
|
2019-11-16 00:25:53 +03:00
|
|
|
</div>
|
|
|
|
<div className='mx_AppPermissionWarning_row mx_AppPermissionWarning_smallText'>
|
2021-07-20 00:43:11 +03:00
|
|
|
{ warning }
|
2019-11-16 00:25:53 +03:00
|
|
|
</div>
|
|
|
|
<div className='mx_AppPermissionWarning_row mx_AppPermissionWarning_smallText'>
|
2021-07-20 00:43:11 +03:00
|
|
|
{ _t("This widget may use cookies.") } { encryptionWarning }
|
2019-11-16 00:25:53 +03:00
|
|
|
</div>
|
|
|
|
<div className='mx_AppPermissionWarning_row'>
|
|
|
|
<AccessibleButton kind='primary_sm' onClick={this.props.onPermissionGranted}>
|
2021-07-20 00:43:11 +03:00
|
|
|
{ _t("Continue") }
|
2019-11-16 00:25:53 +03:00
|
|
|
</AccessibleButton>
|
2017-07-26 18:47:58 +03:00
|
|
|
</div>
|
2017-07-26 13:28:43 +03:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|