/*! For license information please see settings-vue-settings-personal-webauthn.js.license?v=35db88cea98cb4e17a59 */ (()=>{var e,n,r,i={28944:(e,n,r)=>{"use strict";var i=r(85471),a=r(38613),o=r(96763);function s(t){const e=new Uint8Array(t);let n="";for(const t of e)n+=String.fromCharCode(t);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function c(t){const e=t.replace(/-/g,"+").replace(/_/g,"/"),n=(4-e.length%4)%4,r=e.padEnd(e.length+n,"="),i=atob(r),a=new ArrayBuffer(i.length),o=new Uint8Array(a);for(let t=0;te=>(x.debug(t),e),N=Object.freeze({READY:1,REGISTRATION:2,NAMING:3,PERSIST:4}),S={name:"AddDevice",components:{NcButton:w.A,NcTextField:_.A},props:{httpWarning:Boolean,isHttps:{type:Boolean,default:!1},isLocalhost:{type:Boolean,default:!1}},setup:()=>({RegistrationSteps:N}),data:()=>({name:"",credential:{},step:N.READY}),watch:{step(){this.step===N.NAMING&&this.$nextTick((()=>{var t;return null===(t=this.$refs.nameInput)||void 0===t?void 0:t.focus()}))}},methods:{async start(){this.step=N.REGISTRATION,W.debug("Starting WebAuthn registration");try{await(0,g.C)(),this.credential=await async function(){const t=(0,E.Jv)("/settings/api/personal/webauthn/registration");try{x.debug("Fetching webauthn registration data");const{data:e}=await I.A.get(t);return x.debug("Start webauthn registration"),await async function(t){if(!l())throw new Error("WebAuthn is not supported in this browser");const e={publicKey:{...t,challenge:c(t.challenge),user:{...t.user,id:c(t.user.id)},excludeCredentials:t.excludeCredentials?.map(u)}};let n;e.signal=p.createNewAbortSignal();try{n=await navigator.credentials.create(e)}catch(t){throw function({error:t,options:e}){const{publicKey:n}=e;if(!n)throw Error("options was missing required publicKey property");if("AbortError"===t.name){if(e.signal instanceof AbortSignal)return new d({message:"Registration ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:t})}else if("ConstraintError"===t.name){if(!0===n.authenticatorSelection?.requireResidentKey)return new d({message:"Discoverable credentials were required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",cause:t});if("required"===n.authenticatorSelection?.userVerification)return new d({message:"User verification was required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",cause:t})}else{if("InvalidStateError"===t.name)return new d({message:"The authenticator was previously registered",code:"ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",cause:t});if("NotAllowedError"===t.name)return new d({message:t.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:t});if("NotSupportedError"===t.name)return 0===n.pubKeyCredParams.filter((t=>"public-key"===t.type)).length?new d({message:'No entry in pubKeyCredParams was of type "public-key"',code:"ERROR_MALFORMED_PUBKEYCREDPARAMS",cause:t}):new d({message:"No available authenticator supported any of the specified pubKeyCredParams algorithms",code:"ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",cause:t});if("SecurityError"===t.name){const e=window.location.hostname;if("localhost"!==(r=e)&&!/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(r))return new d({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:t});if(n.rp.id!==e)return new d({message:`The RP ID "${n.rp.id}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:t})}else if("TypeError"===t.name){if(n.user.id.byteLength<1||n.user.id.byteLength>64)return new d({message:"User ID was not between 1 and 64 characters",code:"ERROR_INVALID_USER_ID_LENGTH",cause:t})}else if("UnknownError"===t.name)return new d({message:"The authenticator was unable to process the specified options, or could not create a new credential",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:t})}var r;return t}({error:t,options:e})}if(!n)throw new Error("Registration was not completed");const{id:r,rawId:i,response:a,type:o}=n;let h,g,m,A;if("function"==typeof a.getTransports&&(h=a.getTransports()),"function"==typeof a.getPublicKeyAlgorithm)try{g=a.getPublicKeyAlgorithm()}catch(t){v("getPublicKeyAlgorithm()",t)}if("function"==typeof a.getPublicKey)try{const t=a.getPublicKey();null!==t&&(m=s(t))}catch(t){v("getPublicKey()",t)}if("function"==typeof a.getAuthenticatorData)try{A=s(a.getAuthenticatorData())}catch(t){v("getAuthenticatorData()",t)}return{id:r,rawId:s(i),response:{attestationObject:s(a.attestationObject),clientDataJSON:s(a.clientDataJSON),transports:h,publicKeyAlgorithm:g,publicKey:m,authenticatorData:A},type:o,clientExtensionResults:n.getClientExtensionResults(),authenticatorAttachment:f(n.authenticatorAttachment)}}(e)}catch(t){if(x.error(t),C.A.isAxiosError(t))throw new Error((0,R.Tl)("settings","Could not register device: Network error"));if("InvalidStateError"===t.name)throw new Error((0,R.Tl)("settings","Could not register device: Probably already registered"));throw new Error((0,R.Tl)("settings","Could not register device"))}}(),this.step=N.NAMING}catch(t){(0,b.Qg)(t),this.step=N.READY}},submit(){return this.step=N.PERSIST,(0,g.C)().then(O("confirmed password")).then(this.saveRegistrationData).then(O("registration data saved")).then((()=>this.reset())).then(O("app reset")).catch(W.error)},async saveRegistrationData(){try{const t=await async function(t,e){const n=(0,E.Jv)("/settings/api/personal/webauthn/registration");return(await I.A.post(n,{name:t,data:JSON.stringify(e)})).data}(this.name,this.credential);x.info("new device added",{device:t}),this.$emit("added",t)}catch(e){throw x.error("Error persisting webauthn registration",{error:e}),new Error(t("settings","Server error while trying to complete WebAuthn device registration"))}},reset(){this.name="",this.registrationData={},this.step=N.READY}}};var T=r(85072),D=r.n(T),P=r(97825),k=r.n(P),B=r(77659),L=r.n(B),M=r(55056),j=r.n(M),F=r(10540),U=r.n(F),G=r(41113),q=r.n(G),K=r(65774),z={};z.styleTagTransform=q(),z.setAttributes=j(),z.insert=L().bind(null,"head"),z.domAPI=k(),z.insertStyleElement=U(),D()(K.A,z),K.A&&K.A.locals&&K.A.locals;var Y=r(14486);const H=(0,Y.A)(S,(function(){var t=this,e=t._self._c;return t.isHttps||t.isLocalhost?e("div",[t.step===t.RegistrationSteps.READY?e("NcButton",{attrs:{type:"primary"},on:{click:t.start}},[t._v("\n\t\t"+t._s(t.t("settings","Add WebAuthn device"))+"\n\t")]):t.step===t.RegistrationSteps.REGISTRATION?e("div",{staticClass:"new-webauthn-device"},[e("span",{staticClass:"icon-loading-small webauthn-loading"}),t._v("\n\t\t"+t._s(t.t("settings","Please authorize your WebAuthn device."))+"\n\t")]):t.step===t.RegistrationSteps.NAMING?e("div",{staticClass:"new-webauthn-device"},[e("span",{staticClass:"icon-loading-small webauthn-loading"}),t._v(" "),e("form",{on:{submit:function(e){return e.preventDefault(),t.submit.apply(null,arguments)}}},[e("NcTextField",{ref:"nameInput",staticClass:"new-webauthn-device__name",attrs:{label:t.t("settings","Device name"),value:t.name,"show-trailing-button":"","trailing-button-label":t.t("settings","Add"),"trailing-button-icon":"arrowRight"},on:{"update:value":function(e){t.name=e},"trailing-button-click":t.submit}})],1)]):t.step===t.RegistrationSteps.PERSIST?e("div",{staticClass:"new-webauthn-device"},[e("span",{staticClass:"icon-loading-small webauthn-loading"}),t._v("\n\t\t"+t._s(t.t("settings","Adding your device …"))+"\n\t")]):e("div",[t._v("\n\t\tInvalid registration step. This should not have happened.\n\t")])],1):e("div",[t._v("\n\t"+t._s(t.t("settings","Passwordless authentication requires a secure connection."))+"\n")])}),[],!1,null,"f616ec86",null).exports;var $=r(24764);const V={name:"Device",components:{NcActionButton:r(63420).A,NcActions:$.A},props:{name:{type:String,required:!0}}};var J=r(14220),Q={};Q.styleTagTransform=q(),Q.setAttributes=j(),Q.insert=L().bind(null,"head"),Q.domAPI=k(),Q.insertStyleElement=U(),D()(J.A,Q),J.A&&J.A.locals&&J.A.locals;const X=(0,Y.A)(V,(function(){var t=this,e=t._self._c;return e("li",{staticClass:"webauthn-device"},[e("span",{staticClass:"icon-webauthn-device"}),t._v("\n\t"+t._s(t.name||t.t("settings","Unnamed device"))+"\n\t"),e("NcActions",{attrs:{"force-menu":!0}},[e("NcActionButton",{attrs:{icon:"icon-delete"},on:{click:function(e){return t.$emit("delete")}}},[t._v("\n\t\t\t"+t._s(t.t("settings","Delete"))+"\n\t\t")])],1)],1)}),[],!1,null,"be10994c",null).exports,Z=y()("name"),tt={components:{AddDevice:H,Device:X,NcNoteCard:m.A},props:{initialDevices:{type:Array,required:!0},isHttps:{type:Boolean,default:!1},isLocalhost:{type:Boolean,default:!1}},setup:()=>({supportsWebauthn:l()}),data(){return{devices:this.initialDevices}},computed:{sortedDevices(){return Z(this.devices)}},methods:{deviceAdded(t){x.debug("adding new device to the list ".concat(t.id)),this.devices.push(t)},async deleteDevice(t){x.info("deleting webauthn device ".concat(t)),await(0,g.C)(),await async function(t){const e=(0,E.Jv)("/settings/api/personal/webauthn/registration/".concat(t));await I.A.delete(e)}(t),this.devices=this.devices.filter((e=>e.id!==t)),x.info("webauthn device ".concat(t," removed successfully"))}}};var et=r(28337),nt={};nt.styleTagTransform=q(),nt.setAttributes=j(),nt.insert=L().bind(null,"head"),nt.domAPI=k(),nt.insertStyleElement=U(),D()(et.A,nt),et.A&&et.A.locals&&et.A.locals;const rt=(0,Y.A)(tt,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"section",attrs:{id:"security-webauthn"}},[e("h2",[t._v(t._s(t.t("settings","Passwordless Authentication")))]),t._v(" "),e("p",{staticClass:"settings-hint hidden-when-empty"},[t._v("\n\t\t"+t._s(t.t("settings","Set up your account for passwordless authentication following the FIDO2 standard."))+"\n\t")]),t._v(" "),0===t.devices.length?e("NcNoteCard",{attrs:{type:"info"}},[t._v("\n\t\t"+t._s(t.t("settings","No devices configured."))+"\n\t")]):e("h3",{attrs:{id:"security-webauthn__active-devices"}},[t._v("\n\t\t"+t._s(t.t("settings","The following devices are configured for your account:"))+"\n\t")]),t._v(" "),e("ul",{staticClass:"security-webauthn__device-list",attrs:{"aria-labelledby":"security-webauthn__active-devices"}},t._l(t.sortedDevices,(function(n){return e("Device",{key:n.id,attrs:{name:n.name},on:{delete:function(e){return t.deleteDevice(n.id)}}})})),1),t._v(" "),t.supportsWebauthn?t._e():e("NcNoteCard",{attrs:{type:"warning"}},[t._v("\n\t\t"+t._s(t.t("settings","Your browser does not support WebAuthn."))+"\n\t")]),t._v(" "),t.supportsWebauthn?e("AddDevice",{attrs:{"is-https":t.isHttps,"is-localhost":t.isLocalhost},on:{added:t.deviceAdded}}):t._e()],1)}),[],!1,null,"6f64ab3e",null).exports;r.nc=btoa(OC.requestToken),i.Ay.prototype.t=t,new(i.Ay.extend(rt))({propsData:{initialDevices:(0,a.C)("settings","webauthn-devices"),isHttps:"https:"===window.location.protocol,isLocalhost:"localhost"===window.location.hostname}}).$mount("#security-webauthn")},65774:(t,e,n)=>{"use strict";n.d(e,{A:()=>s});var r=n(71354),i=n.n(r),a=n(76314),o=n.n(a)()(i());o.push([t.id,".webauthn-loading[data-v-f616ec86]{display:inline-block;vertical-align:sub;margin-left:2px;margin-right:2px}.new-webauthn-device[data-v-f616ec86]{display:flex;gap:22px;align-items:center}.new-webauthn-device__name[data-v-f616ec86]{max-width:min(100vw,400px)}","",{version:3,sources:["webpack://./apps/settings/src/components/WebAuthn/AddDevice.vue"],names:[],mappings:"AACA,mCACC,oBAAA,CACA,kBAAA,CACA,eAAA,CACA,gBAAA,CAGD,sCACC,YAAA,CACA,QAAA,CACA,kBAAA,CAEA,4CACC,0BAAA",sourcesContent:["\n.webauthn-loading {\n\tdisplay: inline-block;\n\tvertical-align: sub;\n\tmargin-left: 2px;\n\tmargin-right: 2px;\n}\n\n.new-webauthn-device {\n\tdisplay: flex;\n\tgap: 22px;\n\talign-items: center;\n\n\t&__name {\n\t\tmax-width: min(100vw, 400px);\n\t}\n}\n"],sourceRoot:""}]);const s=o},14220:(t,e,n)=>{"use strict";n.d(e,{A:()=>s});var r=n(71354),i=n.n(r),a=n(76314),o=n.n(a)()(i());o.push([t.id,"\n.webauthn-device[data-v-be10994c] {\n\tline-height: 300%;\n\tdisplay: flex;\n}\n.icon-webauthn-device[data-v-be10994c] {\n\tdisplay: inline-block;\n\tbackground-size: 100%;\n\tpadding: 3px;\n\tmargin: 3px;\n}\n","",{version:3,sources:["webpack://./apps/settings/src/components/WebAuthn/Device.vue"],names:[],mappings:";AAkEA;CACA,iBAAA;CACA,aAAA;AACA;AAEA;CACA,qBAAA;CACA,qBAAA;CACA,YAAA;CACA,WAAA;AACA",sourcesContent:["\x3c!--\n - @copyright 2020 Christoph Wurst \n -\n - @author 2020 Christoph Wurst \n -\n - @license GNU AGPL version 3 or any later version\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see .\n --\x3e\n\n\n\n