(()=>{var e,r,n,i={80172(e,r,n){"use strict";var i=n(21777),a=n(81222),o=n(85471),s=n(47176);function c(t){const e=new Uint8Array(t);let r="";for(const t of e)r+=String.fromCharCode(t);return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function u(t){const e=t.replace(/-/g,"+").replace(/_/g,"/"),r=(4-e.length%4)%4,n=e.padEnd(e.length+r,"="),i=atob(n),a=new ArrayBuffer(i.length),o=new Uint8Array(a);for(let t=0;tt};function d(t){const{id:e}=t;return{...t,id:u(e),transports:t.transports}}class f extends Error{constructor({message:t,code:e,cause:r,name:n}){super(t,{cause:r}),Object.defineProperty(this,"code",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.name=n??r.name,this.code=e}}const h=new class{constructor(){Object.defineProperty(this,"controller",{enumerable:!0,configurable:!0,writable:!0,value:void 0})}createNewAbortSignal(){if(this.controller){const t=new Error("Cancelling existing WebAuthn API call for new one");t.name="AbortError",this.controller.abort(t)}const t=new AbortController;return this.controller=t,t.signal}cancelCeremony(){if(this.controller){const t=new Error("Manually cancelling existing WebAuthn API call");t.name="AbortError",this.controller.abort(t),this.controller=void 0}}},v=["cross-platform","platform"];function g(t){if(t&&!(v.indexOf(t)<0))return t}function y(t,e){console.warn(`The browser extension that intercepted this WebAuthn API call incorrectly implemented ${t}. You should report this error to them.\n`,e)}var A=n(10854),m=n.n(A),b=n(371),x=n(85168),w=n(74095),_=n(82182);const R=(0,n(35947).YK)().setApp("settings").detectUser().build();var E=n(19051),I=n(53334),C=n(63814);function W(t){return e=>(R.debug(t),e)}const O=Object.freeze({READY:1,REGISTRATION:2,NAMING:3,PERSIST:4}),S={name:"WebAuthnAddDevice",components:{NcButton:w.A,NcTextField:_.A},props:{httpWarning:Boolean,isHttps:{type:Boolean,default:!1},isLocalhost:{type:Boolean,default:!1}},setup:()=>({RegistrationSteps:O}),data:()=>({name:"",credential:{},step:O.READY}),watch:{step(){this.step===O.NAMING&&this.$nextTick(()=>this.$refs.nameInput?.focus())}},methods:{async start(){this.step=O.REGISTRATION,R.debug("Starting WebAuthn registration");try{await(0,s.C5)(),this.credential=await async function(){const t=(0,C.Jv)("/settings/api/personal/webauthn/registration");try{R.debug("Fetching webauthn registration data");const{data:e}=await E.Ay.get(t);return R.debug("Start webauthn registration"),await async function(t){!t.optionsJSON&&t.challenge&&(console.warn("startRegistration() was not called correctly. It will try to continue with the provided options, but this call should be refactored to use the expected call structure instead. See https://simplewebauthn.dev/docs/packages/browser#typeerror-cannot-read-properties-of-undefined-reading-challenge for more information."),t={optionsJSON:t});const{optionsJSON:e,useAutoRegister:r=!1}=t;if(!l())throw new Error("WebAuthn is not supported in this browser");const n={...e,challenge:u(e.challenge),user:{...e.user,id:u(e.user.id)},excludeCredentials:e.excludeCredentials?.map(d)},i={};let a;r&&(i.mediation="conditional"),i.publicKey=n,i.signal=h.createNewAbortSignal();try{a=await navigator.credentials.create(i)}catch(t){throw function({error:t,options:e}){const{publicKey:r}=e;if(!r)throw Error("options was missing required publicKey property");if("AbortError"===t.name){if(e.signal instanceof AbortSignal)return new f({message:"Registration ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:t})}else if("ConstraintError"===t.name){if(!0===r.authenticatorSelection?.requireResidentKey)return new f({message:"Discoverable credentials were required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",cause:t});if("conditional"===e.mediation&&"required"===r.authenticatorSelection?.userVerification)return new f({message:"User verification was required during automatic registration but it could not be performed",code:"ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE",cause:t});if("required"===r.authenticatorSelection?.userVerification)return new f({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 f({message:"The authenticator was previously registered",code:"ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",cause:t});if("NotAllowedError"===t.name)return new f({message:t.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:t});if("NotSupportedError"===t.name)return 0===r.pubKeyCredParams.filter(t=>"public-key"===t.type).length?new f({message:'No entry in pubKeyCredParams was of type "public-key"',code:"ERROR_MALFORMED_PUBKEYCREDPARAMS",cause:t}):new f({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=globalThis.location.hostname;if("localhost"!==(n=e)&&!/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(n))return new f({message:`${globalThis.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:t});if(r.rp.id!==e)return new f({message:`The RP ID "${r.rp.id}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:t})}else if("TypeError"===t.name){if(r.user.id.byteLength<1||r.user.id.byteLength>64)return new f({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 f({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 n;return t}({error:t,options:i})}if(!a)throw new Error("Registration was not completed");const{id:o,rawId:s,response:p,type:v}=a;let A,m,b,x;if("function"==typeof p.getTransports&&(A=p.getTransports()),"function"==typeof p.getPublicKeyAlgorithm)try{m=p.getPublicKeyAlgorithm()}catch(t){y("getPublicKeyAlgorithm()",t)}if("function"==typeof p.getPublicKey)try{const t=p.getPublicKey();null!==t&&(b=c(t))}catch(t){y("getPublicKey()",t)}if("function"==typeof p.getAuthenticatorData)try{x=c(p.getAuthenticatorData())}catch(t){y("getAuthenticatorData()",t)}return{id:o,rawId:c(s),response:{attestationObject:c(p.attestationObject),clientDataJSON:c(p.clientDataJSON),transports:A,publicKeyAlgorithm:m,publicKey:b,authenticatorData:x},type:v,clientExtensionResults:a.getClientExtensionResults(),authenticatorAttachment:g(a.authenticatorAttachment)}}({optionsJSON:e})}catch(t){if(R.error(t),(0,E.F0)(t))throw new Error((0,I.Tl)("settings","Could not register device: Network error"));if("InvalidStateError"===t.name)throw new Error((0,I.Tl)("settings","Could not register device: Probably already registered"));throw new Error((0,I.Tl)("settings","Could not register device"))}}(),this.step=O.NAMING}catch(t){(0,x.Qg)(t),this.step=O.READY}},submit(){return this.step=O.PERSIST,(0,s.C5)().then(W("confirmed password")).then(this.saveRegistrationData).then(W("registration data saved")).then(()=>this.reset()).then(W("app reset")).catch(R.error)},async saveRegistrationData(){try{const t=await async function(t,e){const r=(0,C.Jv)("/settings/api/personal/webauthn/registration");return(await E.Ay.post(r,{name:t,data:JSON.stringify(e)})).data}(this.name,this.credential);R.info("new device added",{device:t}),this.$emit("added",t)}catch(e){throw R.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=O.READY}}};var N=n(85072),j=n.n(N),D=n(97825),T=n.n(D),k=n(77659),P=n.n(k),B=n(55056),M=n.n(B),L=n(10540),F=n.n(L),U=n(41113),q=n.n(U),K=n(84192),$={};$.styleTagTransform=q(),$.setAttributes=M(),$.insert=P().bind(null,"head"),$.domAPI=T(),$.insertStyleElement=F(),j()(K.A,$),K.A&&K.A.locals&&K.A.locals;var z=n(14486),G=(0,z.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:{variant:"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"),"show-trailing-button":"","trailing-button-label":t.t("settings","Add"),"trailing-button-icon":"arrowEnd"},on:{"trailing-button-click":t.submit},model:{value:t.name,callback:function(e){t.name=e},expression:"name"}})],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,"7be1a5bb",null);const H=G.exports;var Y=n(57505),V=n(24764);const J={name:"WebAuthnDevice",components:{NcActionButton:Y.A,NcActions:V.A},props:{name:{type:String,required:!0}}};var X=n(77474),Q={};Q.styleTagTransform=q(),Q.setAttributes=M(),Q.insert=P().bind(null,"head"),Q.domAPI=T(),Q.insertStyleElement=F(),j()(X.A,Q),X.A&&X.A.locals&&X.A.locals;const Z=(0,z.A)(J,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,"25420b68",null).exports,tt=m()("name"),et={name:"WebAuthnSection",components:{WebAuthnAddDevice:H,WebAuthnDevice:Z,NcNoteCard:b.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 tt(this.devices)}},methods:{deviceAdded(t){R.debug(`adding new device to the list ${t.id}`),this.devices.push(t)},async deleteDevice(t){R.info(`deleting webauthn device ${t}`),await(0,s.C5)(),await async function(t){const e=(0,C.Jv)(`/settings/api/personal/webauthn/registration/${t}`);await E.Ay.delete(e)}(t),this.devices=this.devices.filter(e=>e.id!==t),R.info(`webauthn device ${t} removed successfully`)}}};var rt=n(38791),nt={};nt.styleTagTransform=q(),nt.setAttributes=M(),nt.insert=P().bind(null,"head"),nt.domAPI=T(),nt.insertStyleElement=F(),j()(rt.A,nt),rt.A&&rt.A.locals&&rt.A.locals;const it=(0,z.A)(et,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(r){return e("WebAuthnDevice",{key:r.id,attrs:{name:r.name},on:{delete:function(e){return t.deleteDevice(r.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("WebAuthnAddDevice",{attrs:{"is-https":t.isHttps,"is-localhost":t.isLocalhost},on:{added:t.deviceAdded}}):t._e()],1)},[],!1,null,"20183f56",null).exports;n.nc=(0,i.aV)(),o.Ay.prototype.t=t,new(o.Ay.extend(it))({propsData:{initialDevices:(0,a.C)("settings","webauthn-devices"),isHttps:"https:"===window.location.protocol,isLocalhost:"localhost"===window.location.hostname}}).$mount("#security-webauthn")},84192(t,e,r){"use strict";r.d(e,{A:()=>s});var n=r(71354),i=r.n(n),a=r(76314),o=r.n(a)()(i());o.push([t.id,".webauthn-loading[data-v-7be1a5bb]{display:inline-block;vertical-align:sub;margin-inline:2px}.new-webauthn-device[data-v-7be1a5bb]{display:flex;gap:22px;align-items:center}.new-webauthn-device__name[data-v-7be1a5bb]{max-width:min(100vw,400px)}","",{version:3,sources:["webpack://./apps/settings/src/components/WebAuthn/WebAuthnAddDevice.vue"],names:[],mappings:"AACA,mCACC,oBAAA,CACA,kBAAA,CACA,iBAAA,CAGD,sCACC,YAAA,CACA,QAAA,CACA,kBAAA,CAEA,4CACC,0BAAA",sourcesContent:["\n.webauthn-loading {\n\tdisplay: inline-block;\n\tvertical-align: sub;\n\tmargin-inline: 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},77474(t,e,r){"use strict";r.d(e,{A:()=>s});var n=r(71354),i=r.n(n),a=r(76314),o=r.n(a)()(i());o.push([t.id,"\n.webauthn-device[data-v-25420b68] {\n\tline-height: 300%;\n\tdisplay: flex;\n}\n.icon-webauthn-device[data-v-25420b68] {\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/WebAuthnDevice.vue"],names:[],mappings:";AAoDA;CACA,iBAAA;CACA,aAAA;AACA;AAEA;CACA,qBAAA;CACA,qBAAA;CACA,YAAA;CACA,WAAA;AACA",sourcesContent:["\x3c!--\n - SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n--\x3e\n\n\n\n