-
Notifications
You must be signed in to change notification settings - Fork 0
/
simplewebauthn.js
2 lines (2 loc) · 6.67 KB
/
simplewebauthn.js
1
2
/* [@simplewebauthn/[email protected]] */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SimpleWebAuthnBrowser={})}(this,(function(e){"use strict";function t(e){const t=new Uint8Array(e);let n="";for(const e of t)n+=String.fromCharCode(e);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function n(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),n=(4-t.length%4)%4,r=t.padEnd(t.length+n,"="),o=atob(r),a=new ArrayBuffer(o.length),i=new Uint8Array(a);for(let e=0;e<o.length;e++)i[e]=o.charCodeAt(e);return a}function r(){return void 0!==window?.PublicKeyCredential&&"function"==typeof window.PublicKeyCredential}function o(e){const{id:t}=e;return{...e,id:n(t),transports:e.transports}}function a(e){return"localhost"===e||/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(e)}class i extends Error{code;constructor({message:e,code:t,cause:n,name:r}){super(e,{cause:n}),this.name=r??n.name,this.code=t}}const s=new class{controller;createNewAbortSignal(){if(this.controller){const e=new Error("Cancelling existing WebAuthn API call for new one");e.name="AbortError",this.controller.abort(e)}const e=new AbortController;return this.controller=e,e.signal}},c=["cross-platform","platform"];function l(e){if(e&&!(c.indexOf(e)<0))return e}async function u(){const e=window.PublicKeyCredential;return void 0!==e.isConditionalMediationAvailable&&e.isConditionalMediationAvailable()}e.browserSupportsWebAuthn=r,e.browserSupportsWebAuthnAutofill=u,e.platformAuthenticatorIsAvailable=async function(){return!!r()&&PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()},e.startAuthentication=async function(e,c=!1){if(!r())throw new Error("WebAuthn is not supported in this browser");let d;0!==e.allowCredentials?.length&&(d=e.allowCredentials?.map(o));const R={...e,challenge:n(e.challenge),allowCredentials:d},w={};if(c){if(!await u())throw Error("Browser does not support WebAuthn autofill");if(document.querySelectorAll("input[autocomplete*='webauthn']").length<1)throw Error('No <input> with `"webauthn"` in its `autocomplete` attribute was detected');w.mediation="conditional",R.allowCredentials=[]}let p;w.publicKey=R,w.signal=s.createNewAbortSignal();try{p=await navigator.credentials.get(w)}catch(e){throw function({error:e,options:t}){const{publicKey:n}=t;if(!n)throw Error("options was missing required publicKey property");if("AbortError"===e.name){if(t.signal instanceof AbortSignal)return new i({message:"Authentication ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:e})}else{if("NotAllowedError"===e.name)return new i({message:e.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:e});if("SecurityError"===e.name){const t=window.location.hostname;if(!a(t))return new i({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:e});if(n.rpId!==t)return new i({message:`The RP ID "${n.rpId}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:e})}else if("UnknownError"===e.name)return new i({message:"The authenticator was unable to process the specified options, or could not create a new assertion signature",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:e})}return e}({error:e,options:w})}if(!p)throw new Error("Authentication was not completed");const{id:f,rawId:E,response:h,type:A}=p;let g;var m;return h.userHandle&&(m=h.userHandle,g=new TextDecoder("utf-8").decode(m)),{id:f,rawId:t(E),response:{authenticatorData:t(h.authenticatorData),clientDataJSON:t(h.clientDataJSON),signature:t(h.signature),userHandle:g},type:A,clientExtensionResults:p.getClientExtensionResults(),authenticatorAttachment:l(p.authenticatorAttachment)}},e.startRegistration=async function(e){if(!r())throw new Error("WebAuthn is not supported in this browser");var c;const u={publicKey:{...e,challenge:n(e.challenge),user:{...e.user,id:(c=e.user.id,(new TextEncoder).encode(c))},excludeCredentials:e.excludeCredentials?.map(o)}};let d;u.signal=s.createNewAbortSignal();try{d=await navigator.credentials.create(u)}catch(e){throw function({error:e,options:t}){const{publicKey:n}=t;if(!n)throw Error("options was missing required publicKey property");if("AbortError"===e.name){if(t.signal instanceof AbortSignal)return new i({message:"Registration ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:e})}else if("ConstraintError"===e.name){if(!0===n.authenticatorSelection?.requireResidentKey)return new i({message:"Discoverable credentials were required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",cause:e});if("required"===n.authenticatorSelection?.userVerification)return new i({message:"User verification was required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",cause:e})}else{if("InvalidStateError"===e.name)return new i({message:"The authenticator was previously registered",code:"ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",cause:e});if("NotAllowedError"===e.name)return new i({message:e.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:e});if("NotSupportedError"===e.name)return 0===n.pubKeyCredParams.filter((e=>"public-key"===e.type)).length?new i({message:'No entry in pubKeyCredParams was of type "public-key"',code:"ERROR_MALFORMED_PUBKEYCREDPARAMS",cause:e}):new i({message:"No available authenticator supported any of the specified pubKeyCredParams algorithms",code:"ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",cause:e});if("SecurityError"===e.name){const t=window.location.hostname;if(!a(t))return new i({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:e});if(n.rp.id!==t)return new i({message:`The RP ID "${n.rp.id}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:e})}else if("TypeError"===e.name){if(n.user.id.byteLength<1||n.user.id.byteLength>64)return new i({message:"User ID was not between 1 and 64 characters",code:"ERROR_INVALID_USER_ID_LENGTH",cause:e})}else if("UnknownError"===e.name)return new i({message:"The authenticator was unable to process the specified options, or could not create a new credential",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:e})}return e}({error:e,options:u})}if(!d)throw new Error("Registration was not completed");const{id:R,rawId:w,response:p,type:f}=d;let E;return"function"==typeof p.getTransports&&(E=p.getTransports()),{id:R,rawId:t(w),response:{attestationObject:t(p.attestationObject),clientDataJSON:t(p.clientDataJSON),transports:E},type:f,clientExtensionResults:d.getClientExtensionResults(),authenticatorAttachment:l(d.authenticatorAttachment)}},Object.defineProperty(e,"__esModule",{value:!0})}));