element-web-synapse01pim.gr.jp

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

7692.js.map (29978B)


      1 {"version":3,"file":"bundles/9cacd6575f4c8ee1aedb/7692.js","mappings":"8pBAsBKA,EAAK,SAALA,GAAK,OAALA,EAAK,YAALA,EAAK,sBAALA,CAAK,EAALA,GAAK,IAmBK,MAAMC,UAA4BC,EAAAA,UAMtCC,WAAAA,CAAYC,GACfC,MAAMD,IAAOE,EAAAA,EAAAA,GAAA,qBANqB,OAAIA,EAAAA,EAAAA,GAAA,4BACG,OAAIA,EAAAA,EAAAA,GAAA,kBAE7B,IAAKA,EAAAA,EAAAA,GAAA,8BA+CQC,UAG7B,GAFAC,EAAGC,wBAESC,KAAKC,2BAA6B,OAC9C,GAAID,KAAKE,UAAW,OAEpB,MAAMC,EAAaH,KAAKI,MAAMC,YAC9BL,KAAKM,YAAYH,MACpBP,EAAAA,EAAAA,GAAA,qBAqCwBE,IACrBA,EAAGC,iBACHC,KAAKN,MAAMa,YAAW,IACf,KACVX,EAAAA,EAAAA,GAAA,0BAE4B,CAACE,EAAyCU,KACnER,KAAKS,SAAS,CACV,CAACD,GAASV,EAAGY,OAAOC,UA/FxBX,KAAKI,MAAQ,CACTQ,MAAOtB,EAAMuB,KACbC,OAAQ,KACRT,YAAa,GACbU,YAAa,GAErB,CAEOC,iBAAAA,GACHhB,KAAKE,WAAY,CACrB,CAEOe,oBAAAA,GACHjB,KAAKE,WAAY,CACrB,CAEA,8BAAcD,GACV,MAAMiB,EAAuB,CAAClB,KAAKmB,cAAenB,KAAKoB,sBAEjDC,EAAyB,GAE/B,IAAK,MAAMC,KAASJ,EAAsB,CACtC,IAAKI,EAAO,eAEQA,EAAMC,SAAS,CAAEC,YAAY,KAE7CH,EAAcI,KAAKH,EAE3B,CAEA,OAA6B,IAAzBD,EAAcK,SAMlBL,EAAc,GAAGM,QACjBN,EAAc,GAAGE,SAAS,CAAEC,YAAY,EAAOI,SAAS,KAEjD,EACX,CAYQtB,WAAAA,CAAYH,GAGhB0B,QAAQC,UACHC,KAAK,IACK/B,KAAKN,MAAMsC,aAAaC,YAAaC,wBAE/CH,KAAMI,GACIC,EAAAA,EAA4CD,EAAGhC,IAEzD4B,KAAMM,IACH,MAAMC,EAAO,IAAIC,KAAK,CAACF,GAAI,CACvBG,KAAM,gCAEVC,IAAAA,OAAiBH,EAAM,oBACvBtC,KAAKN,MAAMa,YAAW,KAEzBmC,MAAOC,IAEJ,GADAC,EAAAA,GAAOC,MAAM,4BAA6BF,GACtC3C,KAAKE,UACL,OAEJ,MAAM4C,EAAMH,EAAEI,eAAgBC,EAAAA,EAAAA,IAAG,iBACjChD,KAAKS,SAAS,CACVK,OAAQgC,EACRlC,MAAOtB,EAAMuB,SAIzBb,KAAKS,SAAS,CACVK,OAAQ,KACRF,MAAOtB,EAAM2D,WAErB,CAcOC,MAAAA,GACH,MAAMC,EAAcnD,KAAKI,MAAMQ,QAAUtB,EAAM2D,UAE/C,OACIzD,EAAAA,cAAC4D,EAAAA,EAAU,CACPC,UAAU,yBACV9C,WAAYP,KAAKN,MAAMa,WACvB+C,OAAON,EAAAA,EAAAA,IAAG,4CAEVxD,EAAAA,cAAA,QAAM+D,SAAUvD,KAAKwD,wBACjBhE,EAAAA,cAAA,OAAK6D,UAAU,qBACX7D,EAAAA,cAAA,UAAIwD,EAAAA,EAAAA,IAAG,oDACPxD,EAAAA,cAAA,UAAIwD,EAAAA,EAAAA,IAAG,oDACPxD,EAAAA,cAAA,OAAK6D,UAAU,SAASrD,KAAKI,MAAMU,QACnCtB,EAAAA,cAAA,OAAK6D,UAAU,+BACX7D,EAAAA,cAAA,OAAK6D,UAAU,6BACX7D,EAAAA,cAACiE,EAAAA,EAAe,CACZC,SAAU,EACVC,OAAOC,EAAAA,EAAAA,IAAI,+CACXC,oBAAoBD,EAAAA,EAAAA,IAAI,+CACxBE,qBAAqBF,EAAAA,EAAAA,IAAI,mDACzBG,uBAAuBH,EAAAA,EAAAA,IAAI,mDAC3BjD,MAAOX,KAAKI,MAAMC,YAClB2D,SAAWrB,GACP3C,KAAKiE,mBAAmBtB,EAAG,eAE/BuB,WAAW,EACXC,KAAM,GACN3B,KAAK,WACL4B,SAAUjB,EACVkB,aAAa,eACbC,SAAWhD,IACPtB,KAAKmB,cAAgBG,MAIjC9B,EAAAA,cAAA,OAAK6D,UAAU,6BACX7D,EAAAA,cAAC+E,EAAAA,EAAsB,CACnBC,SAAUxE,KAAKI,MAAMC,YACrBsD,OAAOC,EAAAA,EAAAA,IAAI,iDACXa,eAAeb,EAAAA,EAAAA,IAAI,qDACnBc,cAAcd,EAAAA,EAAAA,IAAI,gDAClBjD,MAAOX,KAAKI,MAAMW,YAClBiD,SAAWrB,GACP3C,KAAKiE,mBAAmBtB,EAAG,eAE/BwB,KAAM,GACN3B,KAAK,WACL4B,SAAUjB,EACVkB,aAAa,eACbC,SAAWhD,IACPtB,KAAKoB,qBAAuBE,QAMhD9B,EAAAA,cAAA,OAAK6D,UAAU,qBACX7D,EAAAA,cAAA,SACI6D,UAAU,oBACVb,KAAK,SACL7B,OAAOqC,EAAAA,EAAAA,IAAG,iBACVoB,SAAUjB,IAEd3D,EAAAA,cAAA,UAAQmF,QAAS3E,KAAK4E,cAAeR,SAAUjB,IAC1CH,EAAAA,EAAAA,IAAG,oBAM5B,E,2LC9MJ,MAAM6B,EAAeC,OAAOC,OAAOC,OAUnC,SAASC,EAAcC,EAAiBnC,GACpC,MAAO,CAAEmC,UAASnC,eACtB,CAEA,SAASoC,IACL,OAAOnC,EAAAA,EAAAA,IAAG,gCACd,CAWOnD,eAAeuF,EAAqBC,EAAmBb,GAC1D,MAAMc,EAqNV,SAA6BD,GAIzB,MAAME,GAAU,IAAIC,aAAcC,OAAO,IAAIC,WAAWL,IAGxD,IAAIM,EAAY,EAEhB,OAAU,CACN,MAAMC,EAAUL,EAAQM,QAAQ,KAAMF,GACtC,GAAIC,EAAU,EACV,MAAM,IAAIE,MAAM,yBAEpB,MAAMC,EAAOR,EAAQS,MAAML,EAAWC,GAASK,OAK/C,GAFAN,EAAYC,EAAU,EAElBG,IAASG,EACT,KAER,CAEA,MAAMC,EAAYR,EAIlB,OAAU,CACN,MAAMC,EAAUL,EAAQM,QAAQ,KAAMF,GAEtC,GADaJ,EAAQS,MAAML,EAAWC,EAAU,OAAIQ,EAAYR,GAASK,SAC5DI,EACT,MAGJ,GAAIT,EAAU,EACV,MAAM,IAAIE,MAAM,0BAIpBH,EAAYC,EAAU,CAC1B,CAEA,MAAMU,EAAUX,EAChB,OA+CJ,SAAsBY,GAElB,MAAMC,EAAe1B,OAAO2B,KAAKF,GAE3BG,EAAa,IAAIhB,WAAWc,EAAa9E,QAC/C,IAAK,IAAIiF,EAAI,EAAGA,EAAIH,EAAa9E,OAAQiF,IACrCD,EAAWC,GAAKH,EAAaI,WAAWD,GAE5C,OAAOD,CACX,CAxDWG,CAAatB,EAAQS,MAAMG,EAAWG,GACjD,CAlQiBQ,CAAoBzB,GAC3B0B,EAAQC,EAAAA,GAAUC,MAAMF,MAG9B,GAAIzB,EAAK5D,OAAS,EACd,MAAMuD,EAAc,2BAA2BjC,EAAAA,EAAAA,IAAG,oCAAqC,CAAE+D,WAI7F,GAAgB,IADAzB,EAAK,GAEjB,MAAML,EAAc,uBAAuBjC,EAAAA,EAAAA,IAAG,oCAAqC,CAAE+D,WAGzF,MAAMG,EAAmB5B,EAAK5D,OAAS,GACvC,GAAIwF,EAAmB,EACnB,MAAMjC,EAAc,2BAA2BjC,EAAAA,EAAAA,IAAG,oCAAqC,CAAE+D,WAG7F,MAAMI,EAAO7B,EAAK8B,SAAS,EAAG,IACxBC,EAAK/B,EAAK8B,SAAS,GAAI,IACvBE,EAAchC,EAAK,KAAO,GAAOA,EAAK,KAAO,GAAOA,EAAK,KAAO,EAAKA,EAAK,IAC1EiC,EAAajC,EAAK8B,SAAS,GAAI,GAAKF,GACpCM,EAAOlC,EAAK8B,UAAU,KAErBK,EAAQC,SAAiBC,EAAWR,EAAMG,EAAY9C,GACvDoD,EAAWtC,EAAK8B,SAAS,GAAI,IAEnC,IAAIS,EAUAC,EATJ,IACID,QAAgBhD,EAAakD,OAAO,CAAEC,KAAM,QAAUN,EAASF,EAAMI,EACzE,CAAE,MAAOjF,GACL,MAAMsC,EAAc,+BAAiCtC,EAAGwC,IAC5D,CACA,IAAK0C,EACD,MAAM5C,EAAc,iBAAiBjC,EAAAA,EAAAA,IAAG,yCAI5C,IACI8E,QAAkBjD,EAAaoD,QAC3B,CACID,KAAM,UACNE,QAASb,EACT3F,OAAQ,IAEZ+F,EACAF,EAER,CAAE,MAAO5E,GACL,MAAMsC,EAAc,gCAAkCtC,EAAGwC,IAC7D,CAEA,OAAO,IAAIK,aAAcC,OAAO,IAAIC,WAAWoC,GACnD,CAYOjI,eAAesI,EAClB9C,EACAb,EACA4D,GAGA,MAAMC,GADND,EAAUA,GAAW,CAAC,GACIE,YAAc,IAElCnB,EAAO,IAAIzB,WAAW,IAC5BZ,OAAOC,OAAOwD,gBAAgBpB,GAE9B,MAAME,EAAK,IAAI3B,WAAW,IAC1BZ,OAAOC,OAAOwD,gBAAgBlB,GAK9BA,EAAG,IAAM,IAET,MAAOI,EAAQC,SAAiBC,EAAWR,EAAMkB,EAAW7D,GACtDgE,GAAc,IAAIC,aAAcC,OAAOrD,GAE7C,IAAIkC,EACJ,IACIA,QAAmB1C,EAAa8D,QAC5B,CACIX,KAAM,UACNE,QAASb,EACT3F,OAAQ,IAEZ+F,EACAe,EAER,CAAE,MAAO7F,GACL,MAAMsC,EAAc,gCAAkCtC,EAAGwC,IAC7D,CAEA,MAAMyD,EAAc,IAAIlD,WAAW6B,GAC7BsB,EAAa,EAAI1B,EAAKzF,OAAS2F,EAAG3F,OAAS,EAAIkH,EAAYlH,OAAS,GACpEoH,EAAe,IAAIpD,WAAWmD,GACpC,IAAIE,EAAM,EACVD,EAAaC,KAAS,EACtBD,EAAaE,IAAI7B,EAAM4B,GACvBA,GAAO5B,EAAKzF,OACZoH,EAAaE,IAAI3B,EAAI0B,GACrBA,GAAO1B,EAAG3F,OACVoH,EAAaC,KAASV,GAAa,GACnCS,EAAaC,KAAUV,GAAa,GAAM,IAC1CS,EAAaC,KAAUV,GAAa,EAAK,IACzCS,EAAaC,KAAqB,IAAZV,EACtBS,EAAaE,IAAIJ,EAAaG,GAC9BA,GAAOH,EAAYlH,OAEnB,MAAMuH,EAASH,EAAa1B,SAAS,EAAG2B,GAExC,IAAIvB,EACJ,IACIA,QAAa3C,EAAaqE,KAAK,CAAElB,KAAM,QAAUN,EAASuB,EAC9D,CAAE,MAAOtG,GACL,MAAMsC,EAAc,6BAA+BtC,EAAGwC,IAC1D,CAEA,MAAMgE,EAAY,IAAIzD,WAAW8B,GAEjC,OADAsB,EAAaE,IAAIG,EAAWJ,GA4IhC,SAA2B1D,GAGvB,MAAM+D,EAAe,GACfC,EAASC,KAAKC,KAAKlE,EAAK3D,OAAS0H,GACjCI,EAAQ,IAAIC,MAAMJ,EAAS,GACjCG,EAAM,GAAKtD,EACX,IACIS,EADA+C,EAAI,EAER,IAAK/C,EAAI,EAAGA,GAAK0C,EAAQ1C,IACrB6C,EAAM7C,GAAKgD,EAAatE,EAAK+B,SAASsC,EAAGA,EAAIN,IAC7CM,GAAKN,EAIT,OAFAI,EAAM7C,KAAON,EACbmD,EAAM7C,GAAK,IACJ,IAAI8B,aAAcC,OAAOc,EAAMI,KAAK,OAAOC,MACtD,CA3JWC,CAAkBhB,EAC7B,CAUAjJ,eAAe8H,EACXR,EACAG,EACA9C,GAEA,MAAMuF,EAAQ,IAAIC,KAElB,IAAIC,EASAC,EARJ,IACID,QAAYpF,EAAasF,UAAU,OAAO,IAAI1B,aAAcC,OAAOlE,GAAW,CAAEwD,KAAM,WAAY,EAAO,CACrG,cAER,CAAE,MAAOrF,GACL,MAAMsC,EAAc,kCAAoCtC,EAAGwC,IAC/D,CAGA,IACI+E,QAAgBrF,EAAauF,WACzB,CACIpC,KAAM,SACNb,KAAMA,EACNG,WAAYA,EACZ+C,KAAM,WAEVJ,EACA,IAER,CAAE,MAAOtH,GACL,MAAMsC,EAAc,mCAAqCtC,EAAGwC,IAChE,CAEA,MAAMmF,EAAM,IAAIN,KAChBpH,EAAAA,GAAO2H,IAAI,uCAAyCD,EAAIE,UAAYT,EAAMS,WAAa,MAEvF,MAAM/C,EAASyC,EAAQlE,MAAM,EAAG,IAC1B0B,EAAUwC,EAAQlE,MAAM,IAExByE,EAAU5F,EACXsF,UAAU,MAAO1C,EAAQ,CAAEO,KAAM,YAAa,EAAO,CAAC,UAAW,YACjEtF,MAAOC,IACJ,MAAMsC,EAAc,8CAAgDtC,EAAGwC,OAGzEuF,EAAW7F,EACZsF,UACG,MACAzC,EACA,CACIM,KAAM,OACNqC,KAAM,CAAErC,KAAM,aAElB,EACA,CAAC,OAAQ,WAEZtF,MAAOC,IACJ,MAAMsC,EAAc,+CAAiDtC,EAAGwC,OAGhF,OAAOtD,QAAQ8I,IAAI,CAACF,EAASC,GACjC,CAEA,MAAMxE,EAAc,sCACdG,EAAe,oCAwFrB,SAASsD,EAAajD,GAGlB,MAAMF,EAAeoE,OAAOC,aAAaC,MAAM,KAAMrB,MAAMsB,KAAKrE,IAEhE,OAAO5B,OAAOkG,KAAKxE,EACvB,C","sources":["webpack://element-web/./src/async-components/views/dialogs/security/ExportE2eKeysDialog.tsx","webpack://element-web/./src/utils/MegolmExportEncryption.ts"],"sourcesContent":["/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\nCopyright 2017 Vector Creations Ltd\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport FileSaver from \"file-saver\";\nimport React, { type ChangeEvent } from \"react\";\nimport { type MatrixClient } from \"matrix-js-sdk/src/matrix\";\nimport { logger } from \"matrix-js-sdk/src/logger\";\n\nimport { _t, _td } from \"../../../../languageHandler\";\nimport * as MegolmExportEncryption from \"../../../../utils/MegolmExportEncryption\";\nimport BaseDialog from \"../../../../components/views/dialogs/BaseDialog\";\nimport { type KeysStartingWith } from \"../../../../@types/common\";\nimport PassphraseField from \"../../../../components/views/auth/PassphraseField\";\nimport PassphraseConfirmField from \"../../../../components/views/auth/PassphraseConfirmField\";\nimport type Field from \"../../../../components/views/elements/Field\";\n\nenum Phase {\n    Edit = \"edit\",\n    Exporting = \"exporting\",\n}\n\ninterface IProps {\n    matrixClient: MatrixClient;\n    onFinished(doExport?: boolean): void;\n}\n\ninterface IState {\n    phase: Phase;\n    errStr: string | null;\n    passphrase1: string;\n    passphrase2: string;\n}\n\ntype AnyPassphrase = KeysStartingWith<IState, \"passphrase\">;\n\nexport default class ExportE2eKeysDialog extends React.Component<IProps, IState> {\n    private fieldPassword: Field | null = null;\n    private fieldPasswordConfirm: Field | null = null;\n\n    private unmounted = false;\n\n    public constructor(props: IProps) {\n        super(props);\n\n        this.state = {\n            phase: Phase.Edit,\n            errStr: null,\n            passphrase1: \"\",\n            passphrase2: \"\",\n        };\n    }\n\n    public componentDidMount(): void {\n        this.unmounted = false;\n    }\n\n    public componentWillUnmount(): void {\n        this.unmounted = true;\n    }\n\n    private async verifyFieldsBeforeSubmit(): Promise<boolean> {\n        const fieldsInDisplayOrder = [this.fieldPassword, this.fieldPasswordConfirm];\n\n        const invalidFields: Field[] = [];\n\n        for (const field of fieldsInDisplayOrder) {\n            if (!field) continue;\n\n            const valid = await field.validate({ allowEmpty: false });\n            if (!valid) {\n                invalidFields.push(field);\n            }\n        }\n\n        if (invalidFields.length === 0) {\n            return true;\n        }\n\n        // Focus on the first invalid field, then re-validate,\n        // which will result in the error tooltip being displayed for that field.\n        invalidFields[0].focus();\n        invalidFields[0].validate({ allowEmpty: false, focused: true });\n\n        return false;\n    }\n\n    private onPassphraseFormSubmit = async (ev: React.FormEvent): Promise<void> => {\n        ev.preventDefault();\n\n        if (!(await this.verifyFieldsBeforeSubmit())) return;\n        if (this.unmounted) return;\n\n        const passphrase = this.state.passphrase1;\n        this.startExport(passphrase);\n    };\n\n    private startExport(passphrase: string): void {\n        // extra Promise.resolve() to turn synchronous exceptions into\n        // asynchronous ones.\n        Promise.resolve()\n            .then(() => {\n                return this.props.matrixClient.getCrypto()!.exportRoomKeysAsJson();\n            })\n            .then((k) => {\n                return MegolmExportEncryption.encryptMegolmKeyFile(k, passphrase);\n            })\n            .then((f) => {\n                const blob = new Blob([f], {\n                    type: \"text/plain;charset=us-ascii\",\n                });\n                FileSaver.saveAs(blob, \"element-keys.txt\");\n                this.props.onFinished(true);\n            })\n            .catch((e) => {\n                logger.error(\"Error exporting e2e keys:\", e);\n                if (this.unmounted) {\n                    return;\n                }\n                const msg = e.friendlyText || _t(\"error|unknown\");\n                this.setState({\n                    errStr: msg,\n                    phase: Phase.Edit,\n                });\n            });\n\n        this.setState({\n            errStr: null,\n            phase: Phase.Exporting,\n        });\n    }\n\n    private onCancelClick = (ev: React.MouseEvent): boolean => {\n        ev.preventDefault();\n        this.props.onFinished(false);\n        return false;\n    };\n\n    private onPassphraseChange = (ev: React.ChangeEvent<HTMLInputElement>, phrase: AnyPassphrase): void => {\n        this.setState({\n            [phrase]: ev.target.value,\n        } as Pick<IState, AnyPassphrase>);\n    };\n\n    public render(): React.ReactNode {\n        const disableForm = this.state.phase === Phase.Exporting;\n\n        return (\n            <BaseDialog\n                className=\"mx_exportE2eKeysDialog\"\n                onFinished={this.props.onFinished}\n                title={_t(\"settings|key_export_import|export_title\")}\n            >\n                <form onSubmit={this.onPassphraseFormSubmit}>\n                    <div className=\"mx_Dialog_content\">\n                        <p>{_t(\"settings|key_export_import|export_description_1\")}</p>\n                        <p>{_t(\"settings|key_export_import|export_description_2\")}</p>\n                        <div className=\"error\">{this.state.errStr}</div>\n                        <div className=\"mx_E2eKeysDialog_inputTable\">\n                            <div className=\"mx_E2eKeysDialog_inputRow\">\n                                <PassphraseField\n                                    minScore={3}\n                                    label={_td(\"settings|key_export_import|enter_passphrase\")}\n                                    labelEnterPassword={_td(\"settings|key_export_import|enter_passphrase\")}\n                                    labelStrongPassword={_td(\"settings|key_export_import|phrase_strong_enough\")}\n                                    labelAllowedButUnsafe={_td(\"settings|key_export_import|phrase_strong_enough\")}\n                                    value={this.state.passphrase1}\n                                    onChange={(e: ChangeEvent<HTMLInputElement>) =>\n                                        this.onPassphraseChange(e, \"passphrase1\")\n                                    }\n                                    autoFocus={true}\n                                    size={64}\n                                    type=\"password\"\n                                    disabled={disableForm}\n                                    autoComplete=\"new-password\"\n                                    fieldRef={(field) => {\n                                        this.fieldPassword = field;\n                                    }}\n                                />\n                            </div>\n                            <div className=\"mx_E2eKeysDialog_inputRow\">\n                                <PassphraseConfirmField\n                                    password={this.state.passphrase1}\n                                    label={_td(\"settings|key_export_import|confirm_passphrase\")}\n                                    labelRequired={_td(\"settings|key_export_import|phrase_cannot_be_empty\")}\n                                    labelInvalid={_td(\"settings|key_export_import|phrase_must_match\")}\n                                    value={this.state.passphrase2}\n                                    onChange={(e: ChangeEvent<HTMLInputElement>) =>\n                                        this.onPassphraseChange(e, \"passphrase2\")\n                                    }\n                                    size={64}\n                                    type=\"password\"\n                                    disabled={disableForm}\n                                    autoComplete=\"new-password\"\n                                    fieldRef={(field) => {\n                                        this.fieldPasswordConfirm = field;\n                                    }}\n                                />\n                            </div>\n                        </div>\n                    </div>\n                    <div className=\"mx_Dialog_buttons\">\n                        <input\n                            className=\"mx_Dialog_primary\"\n                            type=\"submit\"\n                            value={_t(\"action|export\")}\n                            disabled={disableForm}\n                        />\n                        <button onClick={this.onCancelClick} disabled={disableForm}>\n                            {_t(\"action|cancel\")}\n                        </button>\n                    </div>\n                </form>\n            </BaseDialog>\n        );\n    }\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2020 The Matrix.org Foundation C.I.C.\nCopyright 2017 Vector Creations Ltd\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { logger } from \"matrix-js-sdk/src/logger\";\n\nimport { _t } from \"../languageHandler\";\nimport SdkConfig from \"../SdkConfig\";\n\nconst subtleCrypto = window.crypto.subtle;\n\n/**\n * Make an Error object which has a friendlyText property which is already\n * translated and suitable for showing to the user.\n *\n * @param {string} message message for the exception\n * @param {string} friendlyText\n * @returns {{message: string, friendlyText: string}}\n */\nfunction friendlyError(message: string, friendlyText: string): { message: string; friendlyText: string } {\n    return { message, friendlyText };\n}\n\nfunction cryptoFailMsg(): string {\n    return _t(\"encryption|export_unsupported\");\n}\n\n/**\n * Decrypt a megolm key file\n *\n * @param {ArrayBuffer} data file to decrypt\n * @param {String} password\n * @return {Promise<String>} promise for decrypted output\n *\n *\n */\nexport async function decryptMegolmKeyFile(data: ArrayBuffer, password: string): Promise<string> {\n    const body = unpackMegolmKeyFile(data);\n    const brand = SdkConfig.get().brand;\n\n    // check we have a version byte\n    if (body.length < 1) {\n        throw friendlyError(\"Invalid file: too short\", _t(\"encryption|import_invalid_keyfile\", { brand }));\n    }\n\n    const version = body[0];\n    if (version !== 1) {\n        throw friendlyError(\"Unsupported version\", _t(\"encryption|import_invalid_keyfile\", { brand }));\n    }\n\n    const ciphertextLength = body.length - (1 + 16 + 16 + 4 + 32);\n    if (ciphertextLength < 0) {\n        throw friendlyError(\"Invalid file: too short\", _t(\"encryption|import_invalid_keyfile\", { brand }));\n    }\n\n    const salt = body.subarray(1, 1 + 16);\n    const iv = body.subarray(17, 17 + 16);\n    const iterations = (body[33] << 24) | (body[34] << 16) | (body[35] << 8) | body[36];\n    const ciphertext = body.subarray(37, 37 + ciphertextLength);\n    const hmac = body.subarray(-32);\n\n    const [aesKey, hmacKey] = await deriveKeys(salt, iterations, password);\n    const toVerify = body.subarray(0, -32);\n\n    let isValid;\n    try {\n        isValid = await subtleCrypto.verify({ name: \"HMAC\" }, hmacKey, hmac, toVerify);\n    } catch (e) {\n        throw friendlyError(\"subtleCrypto.verify failed: \" + e, cryptoFailMsg());\n    }\n    if (!isValid) {\n        throw friendlyError(\"hmac mismatch\", _t(\"encryption|import_invalid_passphrase\"));\n    }\n\n    let plaintext;\n    try {\n        plaintext = await subtleCrypto.decrypt(\n            {\n                name: \"AES-CTR\",\n                counter: iv,\n                length: 64,\n            },\n            aesKey,\n            ciphertext,\n        );\n    } catch (e) {\n        throw friendlyError(\"subtleCrypto.decrypt failed: \" + e, cryptoFailMsg());\n    }\n\n    return new TextDecoder().decode(new Uint8Array(plaintext));\n}\n\n/**\n * Encrypt a megolm key file\n *\n * @param {String} data\n * @param {String} password\n * @param {Object=} options\n * @param {Number=} options.kdf_rounds Number of iterations to perform of the\n *    key-derivation function.\n * @return {Promise<ArrayBuffer>} promise for encrypted output\n */\nexport async function encryptMegolmKeyFile(\n    data: string,\n    password: string,\n    options?: { kdf_rounds?: number }, // eslint-disable-line camelcase\n): Promise<ArrayBuffer> {\n    options = options || {};\n    const kdfRounds = options.kdf_rounds || 500000;\n\n    const salt = new Uint8Array(16);\n    window.crypto.getRandomValues(salt);\n\n    const iv = new Uint8Array(16);\n    window.crypto.getRandomValues(iv);\n\n    // clear bit 63 of the IV to stop us hitting the 64-bit counter boundary\n    // (which would mean we wouldn't be able to decrypt on Android). The loss\n    // of a single bit of iv is a price we have to pay.\n    iv[8] &= 0x7f;\n\n    const [aesKey, hmacKey] = await deriveKeys(salt, kdfRounds, password);\n    const encodedData = new TextEncoder().encode(data);\n\n    let ciphertext;\n    try {\n        ciphertext = await subtleCrypto.encrypt(\n            {\n                name: \"AES-CTR\",\n                counter: iv,\n                length: 64,\n            },\n            aesKey,\n            encodedData,\n        );\n    } catch (e) {\n        throw friendlyError(\"subtleCrypto.encrypt failed: \" + e, cryptoFailMsg());\n    }\n\n    const cipherArray = new Uint8Array(ciphertext);\n    const bodyLength = 1 + salt.length + iv.length + 4 + cipherArray.length + 32;\n    const resultBuffer = new Uint8Array(bodyLength);\n    let idx = 0;\n    resultBuffer[idx++] = 1; // version\n    resultBuffer.set(salt, idx);\n    idx += salt.length;\n    resultBuffer.set(iv, idx);\n    idx += iv.length;\n    resultBuffer[idx++] = kdfRounds >> 24;\n    resultBuffer[idx++] = (kdfRounds >> 16) & 0xff;\n    resultBuffer[idx++] = (kdfRounds >> 8) & 0xff;\n    resultBuffer[idx++] = kdfRounds & 0xff;\n    resultBuffer.set(cipherArray, idx);\n    idx += cipherArray.length;\n\n    const toSign = resultBuffer.subarray(0, idx);\n\n    let hmac;\n    try {\n        hmac = await subtleCrypto.sign({ name: \"HMAC\" }, hmacKey, toSign);\n    } catch (e) {\n        throw friendlyError(\"subtleCrypto.sign failed: \" + e, cryptoFailMsg());\n    }\n\n    const hmacArray = new Uint8Array(hmac);\n    resultBuffer.set(hmacArray, idx);\n    return packMegolmKeyFile(resultBuffer);\n}\n\n/**\n * Derive the AES and HMAC-SHA-256 keys for the file\n *\n * @param {Unit8Array} salt  salt for pbkdf\n * @param {Number} iterations number of pbkdf iterations\n * @param {String} password  password\n * @return {Promise<[CryptoKey, CryptoKey]>} promise for [aes key, hmac key]\n */\nasync function deriveKeys(\n    salt: Uint8Array<ArrayBuffer>,\n    iterations: number,\n    password: string,\n): Promise<[CryptoKey, CryptoKey]> {\n    const start = new Date();\n\n    let key;\n    try {\n        key = await subtleCrypto.importKey(\"raw\", new TextEncoder().encode(password), { name: \"PBKDF2\" }, false, [\n            \"deriveBits\",\n        ]);\n    } catch (e) {\n        throw friendlyError(\"subtleCrypto.importKey failed: \" + e, cryptoFailMsg());\n    }\n\n    let keybits;\n    try {\n        keybits = await subtleCrypto.deriveBits(\n            {\n                name: \"PBKDF2\",\n                salt: salt,\n                iterations: iterations,\n                hash: \"SHA-512\",\n            },\n            key,\n            512,\n        );\n    } catch (e) {\n        throw friendlyError(\"subtleCrypto.deriveBits failed: \" + e, cryptoFailMsg());\n    }\n\n    const now = new Date();\n    logger.log(\"E2e import/export: deriveKeys took \" + (now.getTime() - start.getTime()) + \"ms\");\n\n    const aesKey = keybits.slice(0, 32);\n    const hmacKey = keybits.slice(32);\n\n    const aesProm = subtleCrypto\n        .importKey(\"raw\", aesKey, { name: \"AES-CTR\" }, false, [\"encrypt\", \"decrypt\"])\n        .catch((e) => {\n            throw friendlyError(\"subtleCrypto.importKey failed for AES key: \" + e, cryptoFailMsg());\n        });\n\n    const hmacProm = subtleCrypto\n        .importKey(\n            \"raw\",\n            hmacKey,\n            {\n                name: \"HMAC\",\n                hash: { name: \"SHA-256\" },\n            },\n            false,\n            [\"sign\", \"verify\"],\n        )\n        .catch((e) => {\n            throw friendlyError(\"subtleCrypto.importKey failed for HMAC key: \" + e, cryptoFailMsg());\n        });\n\n    return Promise.all([aesProm, hmacProm]);\n}\n\nconst HEADER_LINE = \"-----BEGIN MEGOLM SESSION DATA-----\";\nconst TRAILER_LINE = \"-----END MEGOLM SESSION DATA-----\";\n\n/**\n * Unbase64 an ascii-armoured megolm key file\n *\n * Strips the header and trailer lines, and unbase64s the content\n *\n * @param {ArrayBuffer} data  input file\n * @return {Uint8Array} unbase64ed content\n */\nfunction unpackMegolmKeyFile(data: ArrayBuffer): Uint8Array<ArrayBuffer> {\n    // parse the file as a great big String. This should be safe, because there\n    // should be no non-ASCII characters, and it means that we can do string\n    // comparisons to find the header and footer, and feed it into window.atob.\n    const fileStr = new TextDecoder().decode(new Uint8Array(data));\n\n    // look for the start line\n    let lineStart = 0;\n    // eslint-disable-next-line no-constant-condition\n    while (1) {\n        const lineEnd = fileStr.indexOf(\"\\n\", lineStart);\n        if (lineEnd < 0) {\n            throw new Error(\"Header line not found\");\n        }\n        const line = fileStr.slice(lineStart, lineEnd).trim();\n\n        // start the next line after the newline\n        lineStart = lineEnd + 1;\n\n        if (line === HEADER_LINE) {\n            break;\n        }\n    }\n\n    const dataStart = lineStart;\n\n    // look for the end line\n    // eslint-disable-next-line no-constant-condition\n    while (1) {\n        const lineEnd = fileStr.indexOf(\"\\n\", lineStart);\n        const line = fileStr.slice(lineStart, lineEnd < 0 ? undefined : lineEnd).trim();\n        if (line === TRAILER_LINE) {\n            break;\n        }\n\n        if (lineEnd < 0) {\n            throw new Error(\"Trailer line not found\");\n        }\n\n        // start the next line after the newline\n        lineStart = lineEnd + 1;\n    }\n\n    const dataEnd = lineStart;\n    return decodeBase64(fileStr.slice(dataStart, dataEnd));\n}\n\n/**\n * ascii-armour a  megolm key file\n *\n * base64s the content, and adds header and trailer lines\n *\n * @param {Uint8Array} data  raw data\n * @return {ArrayBuffer} formatted file\n */\nfunction packMegolmKeyFile(data: Uint8Array): ArrayBuffer {\n    // we split into lines before base64ing, because encodeBase64 doesn't deal\n    // terribly well with large arrays.\n    const LINE_LENGTH = (72 * 4) / 3;\n    const nLines = Math.ceil(data.length / LINE_LENGTH);\n    const lines = new Array(nLines + 3);\n    lines[0] = HEADER_LINE;\n    let o = 0;\n    let i;\n    for (i = 1; i <= nLines; i++) {\n        lines[i] = encodeBase64(data.subarray(o, o + LINE_LENGTH));\n        o += LINE_LENGTH;\n    }\n    lines[i++] = TRAILER_LINE;\n    lines[i] = \"\";\n    return new TextEncoder().encode(lines.join(\"\\n\")).buffer;\n}\n\n/**\n * Encode a typed array of uint8 as base64.\n * @param {Uint8Array} uint8Array The data to encode.\n * @return {string} The base64.\n */\nfunction encodeBase64(uint8Array: Uint8Array): string {\n    // Misinterpt the Uint8Array as Latin-1.\n    // window.btoa expects a unicode string with codepoints in the range 0-255.\n    const latin1String = String.fromCharCode.apply(null, Array.from(uint8Array));\n    // Use the builtin base64 encoder.\n    return window.btoa(latin1String);\n}\n\n/**\n * Decode a base64 string to a typed array of uint8.\n * @param {string} base64 The base64 to decode.\n * @return {Uint8Array} The decoded data.\n */\nfunction decodeBase64(base64: string): Uint8Array<ArrayBuffer> {\n    // window.atob returns a unicode string with codepoints in the range 0-255.\n    const latin1String = window.atob(base64);\n    // Encode the string as a Uint8Array\n    const uint8Array = new Uint8Array(latin1String.length);\n    for (let i = 0; i < latin1String.length; i++) {\n        uint8Array[i] = latin1String.charCodeAt(i);\n    }\n    return uint8Array;\n}\n"],"names":["Phase","ExportE2eKeysDialog","React","constructor","props","super","_defineProperty","async","ev","preventDefault","this","verifyFieldsBeforeSubmit","unmounted","passphrase","state","passphrase1","startExport","onFinished","phrase","setState","target","value","phase","Edit","errStr","passphrase2","componentDidMount","componentWillUnmount","fieldsInDisplayOrder","fieldPassword","fieldPasswordConfirm","invalidFields","field","validate","allowEmpty","push","length","focus","focused","Promise","resolve","then","matrixClient","getCrypto","exportRoomKeysAsJson","k","MegolmExportEncryption","f","blob","Blob","type","FileSaver","catch","e","logger","error","msg","friendlyText","_t","Exporting","render","disableForm","BaseDialog","className","title","onSubmit","onPassphraseFormSubmit","PassphraseField","minScore","label","_td","labelEnterPassword","labelStrongPassword","labelAllowedButUnsafe","onChange","onPassphraseChange","autoFocus","size","disabled","autoComplete","fieldRef","PassphraseConfirmField","password","labelRequired","labelInvalid","onClick","onCancelClick","subtleCrypto","window","crypto","subtle","friendlyError","message","cryptoFailMsg","decryptMegolmKeyFile","data","body","fileStr","TextDecoder","decode","Uint8Array","lineStart","lineEnd","indexOf","Error","line","slice","trim","HEADER_LINE","dataStart","undefined","TRAILER_LINE","dataEnd","base64","latin1String","atob","uint8Array","i","charCodeAt","decodeBase64","unpackMegolmKeyFile","brand","SdkConfig","get","ciphertextLength","salt","subarray","iv","iterations","ciphertext","hmac","aesKey","hmacKey","deriveKeys","toVerify","isValid","plaintext","verify","name","decrypt","counter","encryptMegolmKeyFile","options","kdfRounds","kdf_rounds","getRandomValues","encodedData","TextEncoder","encode","encrypt","cipherArray","bodyLength","resultBuffer","idx","set","toSign","sign","hmacArray","LINE_LENGTH","nLines","Math","ceil","lines","Array","o","encodeBase64","join","buffer","packMegolmKeyFile","start","Date","key","keybits","importKey","deriveBits","hash","now","log","getTime","aesProm","hmacProm","all","String","fromCharCode","apply","from","btoa"],"sourceRoot":""}