/* Copyright 2024 New Vector Ltd. Copyright 2019 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ import React from "react"; import { SERVICE_TYPES } from "matrix-js-sdk/src/matrix"; import { _t, pickBestLanguage } from "../../../languageHandler"; import DialogButtons from "../elements/DialogButtons"; import BaseDialog from "./BaseDialog"; import { ServicePolicyPair } from "../../../Terms"; import ExternalLink from "../elements/ExternalLink"; import { parseUrl } from "../../../utils/UrlUtils"; interface ITermsCheckboxProps { onChange: (url: string, checked: boolean) => void; url: string; checked: boolean; } class TermsCheckbox extends React.PureComponent { private onChange = (ev: React.FormEvent): void => { this.props.onChange(this.props.url, ev.currentTarget.checked); }; public render(): React.ReactNode { return ; } } interface ITermsDialogProps { /** * Array of [Service, policies] pairs, where policies is the response from the * /terms endpoint for that service */ policiesAndServicePairs: ServicePolicyPair[]; /** * urls that the user has already agreed to */ agreedUrls: string[]; /** * Called with: * * success {bool} True if the user accepted any douments, false if cancelled * * agreedUrls {string[]} List of agreed URLs */ onFinished: (success: boolean, agreedUrls?: string[]) => void; } interface IState { agreedUrls: any; } export default class TermsDialog extends React.PureComponent { public constructor(props: ITermsDialogProps) { super(props); this.state = { // url -> boolean agreedUrls: {}, }; for (const url of props.agreedUrls) { this.state.agreedUrls[url] = true; } } private onCancelClick = (): void => { this.props.onFinished(false); }; private onNextClick = (): void => { this.props.onFinished( true, Object.keys(this.state.agreedUrls).filter((url) => this.state.agreedUrls[url]), ); }; private nameForServiceType(serviceType: SERVICE_TYPES, host: string): JSX.Element { switch (serviceType) { case SERVICE_TYPES.IS: return (
{_t("common|identity_server")}
({host})
); case SERVICE_TYPES.IM: return (
{_t("common|integration_manager")}
({host})
); } } private summaryForServiceType(serviceType: SERVICE_TYPES): JSX.Element { switch (serviceType) { case SERVICE_TYPES.IS: return (
{_t("terms|summary_identity_server_1")}
{_t("terms|summary_identity_server_2")}
); case SERVICE_TYPES.IM: return
{_t("terms|integration_manager")}
; } } private onTermsCheckboxChange = (url: string, checked: boolean): void => { this.setState({ agreedUrls: Object.assign({}, this.state.agreedUrls, { [url]: checked }), }); }; public render(): React.ReactNode { const rows: JSX.Element[] = []; for (const policiesAndService of this.props.policiesAndServicePairs) { const parsedBaseUrl = parseUrl(policiesAndService.service.baseUrl); const policyValues = Object.values(policiesAndService.policies); for (let i = 0; i < policyValues.length; ++i) { const termDoc = policyValues[i]; const termsLang = pickBestLanguage(Object.keys(termDoc).filter((k) => k !== "version")); let serviceName: JSX.Element | undefined; let summary: JSX.Element | undefined; if (i === 0) { serviceName = this.nameForServiceType(policiesAndService.service.serviceType, parsedBaseUrl.host); summary = this.summaryForServiceType(policiesAndService.service.serviceType); } rows.push( {serviceName} {summary} {termDoc[termsLang].name} , ); } } // if all the documents for at least one service have been checked, we can enable // the submit button let enableSubmit = false; for (const policiesAndService of this.props.policiesAndServicePairs) { let docsAgreedForService = 0; for (const terms of Object.values(policiesAndService.policies)) { let docAgreed = false; for (const lang of Object.keys(terms)) { if (lang === "version") continue; if (this.state.agreedUrls[terms[lang].url]) { docAgreed = true; break; } } if (docAgreed) { ++docsAgreedForService; } } if (docsAgreedForService === Object.keys(policiesAndService.policies).length) { enableSubmit = true; break; } } return (

{_t("terms|intro")}

{rows}
{_t("terms|column_service")} {_t("terms|column_summary")} {_t("terms|column_document")} {_t("action|accept")}
); } }