|
|
(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{1441:function(e,t,a){"use strict";a.r(t),a.d(t,"default",(function(){return v}));var s=a(3),n=a.n(s),r=a(33),o=a.n(r),i=a(35),c=a.n(i),l=a(36),u=a(37),h=a(712),p=a(178),d=a.n(p),m=a(34),y=a(41),g=a(84);const b=3;class v extends o.a.PureComponent{constructor(e){super(e),n()(this,"_onKeyBackupStatusChange",()=>{2===this.state.phase&&this._fetchBackupInfo()}),n()(this,"_collectRecoveryKeyNode",e=>{this._recoveryKeyNode=e}),n()(this,"_onUseKeyBackupChange",e=>{this.setState({useKeyBackup:e})}),n()(this,"_onMigrateFormSubmit",e=>{e.preventDefault(),this.state.backupSigStatus.usable?this._bootstrapSecretStorage():this._restoreBackup()}),n()(this,"_onCopyClick",()=>{!function(e){const t=document.createRange();t.selectNodeContents(e);const a=window.getSelection();a.removeAllRanges(),a.addRange(t)}(this._recoveryKeyNode),document.execCommand("copy")&&this.setState({copied:!0,phase:6})}),n()(this,"_onDownloadClick",()=>{const e=new Blob([this._recoveryKey.encodedPrivateKey],{type:"text/plain;charset=us-ascii"});d.a.saveAs(e,"recovery-key.txt"),this.setState({downloaded:!0,phase:6})}),n()(this,"_doBootstrapUIAuth",async e=>{if(this.state.canUploadKeysWithPasswordOnly&&this.state.accountPassword)await e({type:"m.login.password",identifier:{type:"m.id.user",user:u.a.get().getUserId()},user:u.a.get().getUserId(),password:this.state.accountPassword});else{const t=l.getComponent("dialogs.InteractiveAuthDialog"),{finished:a}=y.a.createTrackedDialog("Cross-signing keys dialog","",t,{title:Object(m.a)("Setting up keys"),matrixClient:u.a.get(),makeRequest:e}),[s]=await a;if(!s)throw new Error("Cross-signing key upload auth canceled")}}),n()(this,"_bootstrapSecretStorage",async()=>{this.setState({phase:7,error:null});const e=u.a.get(),{force:t}=this.props;try{t?await e.bootstrapSecretStorage({authUploadDeviceSigningKeys:this._doBootstrapUIAuth,createSecretStorageKey:async()=>this._recoveryKey,setupNewKeyBackup:!0,setupNewSecretStorage:!0}):await e.bootstrapSecretStorage({authUploadDeviceSigningKeys:this._doBootstrapUIAuth,createSecretStorageKey:async()=>this._recoveryKey,keyBackupInfo:this.state.backupInfo,setupNewKeyBackup:!this.state.backupInfo&&this.state.useKeyBackup,getKeyBackupPassphrase:()=>this._backupKey?this._backupKey:Object(g.d)()}),this.setState({phase:8})}catch(e){this.state.canUploadKeysWithPasswordOnly&&401===e.httpStatus&&e.data.flows?this.setState({accountPassword:"",accountPasswordCorrect:!1,phase:2}):this.setState({error:e}),console.error("Error bootstrapping secret storage",e)}}),n()(this,"_onCancel",()=>{this.props.onFinished(!1)}),n()(this,"_onDone",()=>{this.props.onFinished(!0)}),n()(this,"_restoreBackup",async()=>{const e=l.getComponent("dialogs.keybackup.RestoreKeyBackupDialog"),{finished:t}=y.a.createTrackedDialog("Restore Backup","",e,{showSummary:!1,keyCallback:e=>this._backupKey=e},null,!1,!1);await t;const{backupSigStatus:a}=await this._fetchBackupInfo();a.usable&&this.state.canUploadKeysWithPasswordOnly&&this.state.accountPassword&&this._bootstrapSecretStorage()}),n()(this,"_onLoadRetryClick",()=>{this.setState({phase:0}),this._fetchBackupInfo()}),n()(this,"_onSkipSetupClick",()=>{this.setState({phase:9})}),n()(this,"_onSetUpClick",()=>{this.setState({phase:b})}),n()(this,"_onSkipPassPhraseClick",async()=>{this._recoveryKey=await u.a.get().createRecoveryKeyFromPassphrase(),this.setState({copied:!1,downloaded:!1,phase:5})}),n()(this,"_onPassPhraseNextClick",async e=>{e.preventDefault(),null!==this._setZxcvbnResultTimeout&&(clearTimeout(this._setZxcvbnResultTimeout),this._setZxcvbnResultTimeout=null,await new Promise(e=>{this.setState({zxcvbnResult:Object(h.scorePassword)(this.state.passPhrase)},e)})),this._passPhraseIsValid()&&this.setState({phase:4})}),n()(this,"_onPassPhraseConfirmNextClick",async e=>{e.preventDefault(),this.state.passPhrase===this.state.passPhraseConfirm&&(this._recoveryKey=await u.a.get().createRecoveryKeyFromPassphrase(this.state.passPhrase),this.setState({copied:!1,downloaded:!1,phase:5}))}),n()(this,"_onSetAgainClick",()=>{this.setState({passPhrase:"",passPhraseConfirm:"",phase:b,zxcvbnResult:null})}),n()(this,"_onKeepItSafeBackClick",()=>{this.setState({phase:5})}),n()(this,"_onPassPhraseChange",e=>{this.setState({passPhrase:e.target.value}),null!==this._setZxcvbnResultTimeout&&clearTimeout(this._setZxcvbnResultTimeout),this._setZxcvbnResultTimeout=setTimeout(()=>{this._setZxcvbnResultTimeout=null,this.setState({zxcvbnResult:Object(h.scorePassword)(this.state.passPhrase)})},500)}),n()(this,"_onPassPhraseConfirmChange",e=>{this.setState({passPhraseConfirm:e.target.value})}),n()(this,"_onAccountPasswordChange",e=>{this.setState({accountPassword:e.target.value})}),this._recoveryKey=null,this._recoveryKeyNode=null,this._setZxcvbnResultTimeout=null,this._backupKey=null,this.state={phase:0,passPhrase:"",passPhraseConfirm:"",copied:!1,downloaded:!1,zxcvbnResult:null,backupInfo:null,backupSigStatus:null,canUploadKeysWithPasswordOnly:null,accountPassword:e.accountPassword||"",accountPasswordCorrect:null,useKeyBackup:!0},this._fetchBackupInfo(),this.state.accountPassword?this.state.canUploadKeysWithPasswordOnly=!0:this._queryKeyUploadAuth(),u.a.get().on("crypto.keyBackupStatus",this._onKeyBackupStatusChange)}componentWillUnmount(){u.a.get().removeListener("crypto.keyBackupStatus",this._onKeyBackupStatusChange),null!==this._setZxcvbnResultTimeout&&clearTimeout(this._setZxcvbnResultTimeout)}async _fetchBackupInfo(){try{const e=await u.a.get().getKeyBackupVersion(),t=u.a.get().isCryptoEnabled()&&await u.a.get().isKeyBackupTrusted(e),{force:a}=this.props,s=e&&!a?2:b;return this.setState({phase:s,backupInfo:e,backupSigStatus:t}),{backupInfo:e,backupSigStatus:t}}catch(e){this.setState({phase:1})}}async _queryKeyUploadAuth(){try{await u.a.get().uploadDeviceSigningKeys(null,{}),console.log("uploadDeviceSigningKeys unexpectedly succeeded without UI auth!")}catch(e){if(!e.data||!e.data.flows)return void console.log("uploadDeviceSigningKeys advertised no flows!");const t=e.data.flows.some(e=>1===e.stages.length&&"m.login.password"===e.stages[0]);this.setState({canUploadKeysWithPasswordOnly:t})}}_passPhraseIsValid(){return this.state.zxcvbnResult&&this.state.zxcvbnResult.score>=4}_renderPhaseMigrate(){const e=l.getComponent("views.elements.DialogButtons"),t=l.getComponent("views.elements.Field");let a,s=Object(m.a)("Next");return this.state.canUploadKeysWithPasswordOnly?a=o.a.createElement("div",null,o.a.createElement("div",null,Object(m.a)("Enter your account password to confirm the upgrade:")),o.a.createElement("div",null,o.a.createElement(t,{type:"password",label:Object(m.a)("Password"),value:this.state.accountPassword,onChange:this._onAccountPasswordChange,flagInvalid:!1===this.state.accountPasswordCorrect,autoFocus:!0}))):this.state.backupSigStatus.usable?a=o.a.createElement("p",null,Object(m.a)("You'll need to authenticate with the server to confirm the upgrade.")):(a=o.a.createElement("div",null,o.a.createElement("div",null,Object(m.a)("Restore your key backup to upgrade your encryption"))),s=Object(m.a)("Restore")),o.a.createElement("form",{onSubmit:this._onMigrateFormSubmit},o.a.createElement("p",null,Object(m.a)("Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.")),o.a.createElement("div",null,a),o.a.createElement(e,{primaryButton:s,onPrimaryButtonClick:this._onMigrateFormSubmit,hasCancel:!1,primaryDisabled:this.state.canUploadKeysWithPasswordOnly&&!this.state.accountPassword},o.a.createElement("button",{type:"button",className:"danger",onClick:this._onSkipSetupClick},Object(m.a)("Skip"))))}_renderPhasePassPhrase(){const e=l.getComponent("views.elements.DialogButtons"),t=l.getComponent("views.elements.Field"),a=l.getComponent("elements.AccessibleButton"),s=l.getComponent("views.elements.LabelledToggleSwitch");let n,r;if(this.state.zxcvbnResult){if(this.state.zxcvbnResult.score>=4)r=Object(m.a)("Great! This recovery passphrase looks strong enough.");else{const e=this.state.zxcvbnResult.feedback.warning||this.state.zxcvbnResult.feedback.suggestions[0],t=o.a.createElement("div",null,e||Object(m.a)("Keep going..."));r=o.a.createElement("div",null,t)}n=o.a.createElement("div",null,o.a.createElement("progress",{max:4,value:this.state.zxcvbnResult.score}))}return o.a.createElement("form",{onSubmit:this._onPassPhraseNextClick},o.a.createElement("p",null,Object(m.a)("Set a recovery passphrase to secure encrypted information and recover it if you log out. This should be different to your account password:")),o.a.createElement("div",{className:"mx_CreateSecretStorageDialog_passPhraseContainer"},o.a.createElement(t,{type:"password",className:"mx_CreateSecretStorageDialog_passPhraseField",onChange:this._onPassPhraseChange,value:this.state.passPhrase,label:Object(m.a)("Enter a recovery passphrase"),autoFocus:!0,autoComplete:"new-password"}),o.a.createElement("div",{className:"mx_CreateSecretStorageDialog_passPhraseHelp"},n,r)),o.a.createElement(s,{label:Object(m.a)("Back up encrypted message keys"),onChange:this._onUseKeyBackupChange,value:this.state.useKeyBackup}),o.a.createElement(e,{primaryButton:Object(m.a)("Continue"),onPrimaryButtonClick:this._onPassPhraseNextClick,hasCancel:!1,disabled:!this._passPhraseIsValid()},o.a.createElement("button",{type:"button",onClick:this._onSkipSetupClick,className:"danger"},Object(m.a)("Skip"))),o.a.createElement("details",null,o.a.createElement("summary",null,Object(m.a)("Advanced")),o.a.createElement(a,{kind:"primary",onClick:this._onSkipPassPhraseClick},Object(m.a)("Set up with a recovery key"))))}_renderPhasePassPhraseConfirm(){const e=l.getComponent("elements.AccessibleButton"),t=l.getComponent("views.elements.Field");let a;this.state.passPhraseConfirm===this.state.passPhrase?a=Object(m.a)("That matches!"):this.state.passPhrase.startsWith(this.state.passPhraseConfirm)||(a=Object(m.a)("That doesn't match."));let s=null;a&&(s=o.a.createElement("div",null,o.a.createElement("div",null,a),o.a.createElement("div",null,o.a.createElement(e,{element:"span",className:"mx_linkButton",onClick:this._onSetAgainClick},Object(m.a)("Go back to set it again.")))));const n=l.getComponent("views.elements.DialogButtons");return o.a.createElement("form",{onSubmit:this._onPassPhraseConfirmNextClick},o.a.createElement("p",null,Object(m.a)("Enter your recovery passphrase a second time to confirm it.")),o.a.createElement("div",{className:"mx_CreateSecretStorageDialog_passPhraseContainer"},o.a.createElement(t,{type:"password",onChange:this._onPassPhraseConfirmChange,value:this.state.passPhraseConfirm,className:"mx_CreateSecretStorageDialog_passPhraseField",label:Object(m.a)("Confirm your recovery passphrase"),autoFocus:!0,autoComplete:"new-password"}),o.a.createElement("div",{className:"mx_CreateSecretStorageDialog_passPhraseMatch"},s)),o.a.createElement(n,{primaryButton:Object(m.a)("Continue"),onPrimaryButtonClick:this._onPassPhraseConfirmNextClick,hasCancel:!1,disabled:this.state.passPhrase!==this.state.passPhraseConfirm},o.a.createElement("button",{type:"button",onClick:this._onSkipSetupClick,className:"danger"},Object(m.a)("Skip"))))}_renderPhaseShowKey(){const e=l.getComponent("elements.AccessibleButton");return o.a.createElement("div",null,o.a.createElement("p",null,Object(m.a)("Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.")),o.a.createElement("p",null,Object(m.a)("Keep a copy of it somewhere secure, like a password manager or even a safe.")),o.a.createElement("div",{className:"mx_CreateSecretStorageDialog_primaryContainer"},o.a.createElement("div",{className:"mx_CreateSecretStorageDialog_recoveryKeyHeader"},Object(m.a)("Your recovery key")),o.a.createElement("div",{className:"mx_CreateSecretStorageDialog_recoveryKeyContainer"},o.a.createElement("div",{className:"mx_CreateSecretStorageDialog_recoveryKey"},o.a.createElement("code",{ref:this._collectRecoveryKeyNode},this._recoveryKey.encodedPrivateKey)),o.a.createElement("div",{className:"mx_CreateSecretStorageDialog_recoveryKeyButtons"},o.a.createElement(e,{kind:"primary",className:"mx_Dialog_primary mx_CreateSecretStorageDialog_recoveryKeyButtons_copyBtn",onClick:this._onCopyClick},Object(m.a)("Copy")),o.a.createElement(e,{kind:"primary",className:"mx_Dialog_primary",onClick:this._onDownloadClick},Object(m.a)("Download"))))))}_renderPhaseKeepItSafe(){let e;this.state.copied?e=Object(m.a)("Your recovery key has been <b>copied to your clipboard</b>, paste it to:",{},{b:e=>o.a.createElement("b",null,e)}):this.state.downloaded&&(e=Object(m.a)("Your recovery key is in your <b>Downloads</b> folder.",{},{b:e=>o.a.createElement("b",null,e)}));const t=l.getComponent("views.elements.DialogButtons");return o.a.createElement("div",null,e,o.a.createElement("ul",null,o.a.createElement("li",null,Object(m.a)("<b>Print it</b> and store it somewhere safe",{},{b:e=>o.a.createElement("b",null,e)})),o.a.createElement("li",null,Object(m.a)("<b>Save it</b> on a USB key or backup drive",{},{b:e=>o.a.createElement("b",null,e)})),o.a.createElement("li",null,Object(m.a)("<b>Copy it</b> to your personal cloud storage",{},{b:e=>o.a.createElement("b",null,e)}))),o.a.createElement(t,{primaryButton:Object(m.a)("Continue"),onPrimaryButtonClick:this._bootstrapSecretStorage,hasCancel:!1},o.a.createElement("button",{onClick:this._onKeepItSafeBackClick},Object(m.a)("Back"))))}_renderBusyPhase(){const e=l.getComponent("views.elements.Spinner");return o.a.createElement("div",null,o.a.createElement(e,null))}_renderPhaseLoadError(){const e=l.getComponent("views.elements.DialogButtons");return o.a.createElement("div",null,o.a.createElement("p",null,Object(m.a)("Unable to query secret storage status")),o.a.createElement("div",{className:"mx_Dialog_buttons"},o.a.createElement(e,{primaryButton:Object(m.a)("Retry"),onPrimaryButtonClick:this._onLoadRetryClick,hasCancel:!0,onCancel:this._onCancel})))}_renderPhaseDone(){const e=l.getComponent("views.elements.DialogButtons");return o.a.createElement("div",null,o.a.createElement("p",null,Object(m.a)("You can now verify your other devices, and other users to keep your chats safe.")),o.a.createElement(e,{primaryButton:Object(m.a)("OK"),onPrimaryButtonClick:this._onDone,hasCancel:!1}))}_renderPhaseSkipConfirm(){const e=l.getComponent("views.elements.DialogButtons");return o.a.createElement("div",null,Object(m.a)("Without completing security on this session, it won’t have access to encrypted messages."),o.a.createElement(e,{primaryButton:Object(m.a)("Go back"),onPrimaryButtonClick:this._onSetUpClick,hasCancel:!1},o.a.createElement("button",{type:"button",className:"danger",onClick:this._onCancel},Object(m.a)("Skip"))))}_titleForPhase(e){switch(e){case 2:return Object(m.a)("Upgrade your encryption");case b:return Object(m.a)("Set up encryption");case 4:return Object(m.a)("Confirm recovery passphrase");case 9:return Object(m.a)("Are you sure?");case 5:case 6:return Object(m.a)("Make a copy of your recovery key");case 7:return Object(m.a)("Setting up keys");case 8:return Object(m.a)("You're done!");default:return""}}render(){const e=l.getComponent("views.dialogs.BaseDialog");let t,s;if(this.state.error){const e=l.getComponent("views.elements.DialogButtons");t=o.a.createElement("div",null,o.a.createElement("p",null,Object(m.a)("Unable to set up secret storage")),o.a.createElement("div",{className:"mx_Dialog_buttons"},o.a.createElement(e,{primaryButton:Object(m.a)("Retry"),onPrimaryButtonClick:this._bootstrapSecretStorage,hasCancel:!0,onCancel:this._onCancel})))}else switch(this.state.phase){case 0:t=this._renderBusyPhase();break;case 1:t=this._renderPhaseLoadError();break;case 2:t=this._renderPhaseMigrate();break;case b:t=this._renderPhasePassPhrase();break;case 4:t=this._renderPhasePassPhraseConfirm();break;case 5:t=this._renderPhaseShowKey();break;case 6:t=this._renderPhaseKeepItSafe();break;case 7:t=this._renderBusyPhase();break;case 8:t=this._renderPhaseDone();break;case 9:t=this._renderPhaseSkipConfirm()}return this._titleForPhase(this.state.phase)&&(s=a(1447)),o.a.createElement(e,{className:"mx_CreateSecretStorageDialog",onFinished:this.props.onFinished,title:this._titleForPhase(this.state.phase),headerImage:s,hasCancel:this.props.hasCancel&&[b].includes(this.state.phase),fixedWidth:!1},o.a.createElement("div",null,t))}}n()(v,"propTypes",{hasCancel:c.a.bool,accountPassword:c.a.string,force:c.a.bool}),n()(v,"defaultProps",{hasCancel:!0,force:!1})},1447:function(e,t){e.exports="img/e2e/normal.38c8458.svg"},178:function(e,t,a){var s,n=n||function(e){"use strict";if(!(void 0===e||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent))){var t=e.document,a=function(){return e.URL||e.webkitURL||e},s=t.createElementNS("http://www.w3.org/1999/xhtml","a"),n="download"in s,r=/constructor/i.test(e.HTMLElement)||e.safari,o=/CriOS\/[\d]+/.test(navigator.userAgent),i=function(t){(e.setImmediate||e.setTimeout)((function(){throw t}),0)},c=function(e){setTimeout((function(){"string"==typeof e?a().revokeObjectURL(e):e.remove()}),4e4)},l=function(e){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)?new Blob([String.fromCharCode(65279),e],{type:e.type}):e},u=function(t,u,h){h||(t=l(t));var p,d=this,m="application/octet-stream"===t.type,y=function(){!function(e,t,a){for(var s=(t=[].concat(t)).length;s--;){var n=e["on"+t[s]];if("function"==typeof n)try{n.call(e,a||e)}catch(e){i(e)}}}(d,"writestart progress write writeend".split(" "))};if(d.readyState=d.INIT,n)return p=a().createObjectURL(t),void setTimeout((function(){var e,t;s.href=p,s.download=u,e=s,t=new MouseEvent("click"),e.dispatchEvent(t),y(),c(p),d.readyState=d.DONE}));!function(){if((o||m&&r)&&e.FileReader){var s=new FileReader;return s.onloadend=function(){var t=o?s.result:s.result.replace(/^data:[^;]*;/,"data:attachment/file;");e.open(t,"_blank")||(e.location.href=t),t=void 0,d.readyState=d.DONE,y()},s.readAsDataURL(t),void(d.readyState=d.INIT)}(p||(p=a().createObjectURL(t)),m)?e.location.href=p:e.open(p,"_blank")||(e.location.href=p);d.readyState=d.DONE,y(),c(p)}()},h=u.prototype;return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(e,t,a){return t=t||e.name||"download",a||(e=l(e)),navigator.msSaveOrOpenBlob(e,t)}:(h.abort=function(){},h.readyState=h.INIT=0,h.WRITING=1,h.DONE=2,h.error=h.onwritestart=h.onprogress=h.onwrite=h.onabort=h.onerror=h.onwriteend=null,function(e,t,a){return new u(e,t||e.name||"download",a)})}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);e.exports?e.exports.saveAs=n:null!==a(179)&&null!==a(180)&&(void 0===(s=function(){return n}.call(t,a,t,e))||(e.exports=s))},179:function(e,t){e.exports=function(){throw new Error("define cannot be used indirect")}},180:function(e,t){(function(t){e.exports=t}).call(this,{})}}]); |