-
-
Save Carlgo11/1f1dca56947c0e701b3519d2ae6df3a0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
'use strict'; | |
const e = e => { | |
throw new Error('Unexpected value.'); | |
}, t = () => globalThis.crypto.getRandomValues( | |
new Uint32Array(1))[0].toString(36), n = () => { | |
let e; | |
return { | |
resolve: t => e(t), promise: new Promise((t => { | |
e = t; | |
})), | |
}; | |
}; | |
var i, o; | |
!function(e) { | |
e.UpdateSettings = 'update-settings'; | |
}(i || (i = {})), function(e) { | |
e.Create = 'create-credential', e.Get = 'get-credential', e.ShouldInterceptWebauthn = 'should-intercept-webauthn'; | |
}(o || (o = {})); | |
const r = e => { | |
if (!e) return d(); | |
if (e.aborted) return Promise.resolve({type: 'aborted'}); | |
const t = n(), i = () => { | |
t.resolve({type: 'aborted'}), e.removeEventListener('abort', i); | |
}; | |
return e.addEventListener('abort', i), t.promise; | |
}, s = e => 'string' == typeof e && 0 !== e.length, | |
a = e => e instanceof ArrayBuffer || e instanceof window.ArrayBuffer || | |
e instanceof Uint8Array || e instanceof window.Uint8Array || e instanceof | |
DataView || e instanceof window.DataView || e instanceof Array || | |
e instanceof window.Array ? | |
Array.from( | |
e instanceof ArrayBuffer || e instanceof window.ArrayBuffer ? | |
new Uint8Array(e): | |
e): | |
e, d = () => new Promise((() => { | |
})); | |
function c() { | |
return 'function' == typeof globalThis.cloneInto ? | |
globalThis.cloneInto: | |
void 0; | |
} | |
function l(e) { | |
const t = c(); | |
return t ? t(e, window, {cloneFunctions: !0, wrapReflectors: !0}):e; | |
} | |
function u(e) { | |
const t = c(); | |
return t ? new window.Promise(((n, i) => { | |
e.then((e => { | |
n(t(e, window, {cloneFunctions: !0, wrapReflectors: !0})); | |
})).catch((e => { | |
i(e); | |
})); | |
})):e; | |
} | |
class p { | |
constructor(e) { | |
this.send = async (e, {body: n, signal: i}) => { | |
const o = t(), r = await this.handleOutgoingSyn(o, e, i); | |
if ('ack' !== r.type) return r; | |
const s = r.data; | |
return (await this.handleOutgoingDirect(s.ackedById, o, e, n, i)).data; | |
}, this.getRoutes = () => Object.keys( | |
this.routes), this.handleOutgoingSyn = async (e, t, i) => { | |
const o = r(i), s = { | |
msgId: e, | |
source: this.source, | |
type: p.opSynType, | |
message: void 0, | |
name: t, | |
}; | |
this.log.debug('starting request sequence', t); | |
const a = n(); | |
this.synRequests[e] = a, window.postMessage(s), this.log.debug( | |
'starting ack race', t); | |
const d = await Promise.race([ | |
a.promise, (c = 1e3, new Promise((e => { | |
setTimeout((() => e({type: 'timeout'})), c); | |
}))), o]); | |
var c; | |
if ('timeout' === d.type) return this.log.debug( | |
'finished request sequence: ack timed out', | |
t), delete this.synRequests[e], {type: p.NoReceivingEnd}; | |
if ('aborted' === d.type || | |
(null == i ? void 0:i.aborted)) return this.log.debug( | |
'finished request sequence: aborted sync', | |
t), delete this.synRequests[e], this.throwAbort(i); | |
this.log.debug(`ack race won by: ${d.data.ackedById}`, t); | |
const l = n(); | |
return this.directRequests[e] = l, d; | |
}, this.handleIncomingSyn = async e => { | |
if (!this.routes[e.name]) return void this.log.debug( | |
'received a request with no handler to call', e.name); | |
const t = { | |
msgId: e.msgId, | |
source: this.source, | |
destination: e.source, | |
name: e.name, | |
type: p.opSynAckType, | |
message: void 0, | |
}; | |
window.postMessage(t); | |
}, this.handleIncomingSynAck = e => { | |
if (void 0 === this.synRequests[e.msgId]) return; | |
this.synRequests[e.msgId].resolve({ | |
type: 'ack', | |
data: {ackedById: e.source}, | |
}), delete this.synRequests[e.msgId]; | |
}, this.handleOutgoingDirect = async (e, t, i, o, s) => { | |
const a = r(s), d = n(); | |
this.directRequests[t] = d; | |
const c = { | |
msgId: t, | |
source: this.source, | |
destination: e, | |
type: p.opDirectRequestType, | |
message: o, | |
name: i, | |
}; | |
this.log.debug(`sending direct request to: ${e}`, | |
i), window.postMessage(c); | |
const l = await Promise.race([d.promise, a]); | |
if (delete this.directRequests[t], 'aborted' === l.type) { | |
const e = Object.assign(Object.assign({}, c), {type: p.opAbortType}); | |
return e.reason = null == s ? void 0:s.reason, this.log.debug( | |
'notifying receiver to abort', i), window.postMessage( | |
e), this.log.debug('finished request sequence: aborted', | |
i), this.throwAbort(s); | |
} | |
return this.log.debug('finished request sequence: success', i), l; | |
}, this.handleIncomingDirectRequest = async e => { | |
const t = this.routes[e.name]; | |
if (!t) return void this.log.error( | |
'received a request with no handler to call', e.name); | |
const n = new AbortController; | |
this.abortableRequests[e.msgId] = n; | |
const i = r(n.signal); | |
let o; | |
try { | |
o = await Promise.race([t({body: e.message, signal: n.signal}), i]); | |
} catch (e) { | |
const t = e instanceof Error ? e.message:'unknown'; | |
o = {type: p.HandlerError, data: {reason: t}}; | |
} | |
delete this.abortableRequests[e.msgId]; | |
const s = o; | |
if (s && 'aborted' === (null == s ? void 0:s.type)) return; | |
const a = { | |
msgId: e.msgId, | |
source: this.source, | |
destination: e.source, | |
name: e.name, | |
type: p.opDirectResponseType, | |
message: o, | |
}; | |
window.postMessage(a); | |
}, this.handleIncomingAbortRequest = e => { | |
if (void 0 === | |
this.abortableRequests[e.msgId]) return void this.log.debug( | |
`received abort ${e.msgId} for no active request - likely already completed`, | |
e.name); | |
this.abortableRequests[e.msgId].abort( | |
e.reason), delete this.abortableRequests[e.msgId]; | |
}, this.handleIncomingResponse = e => { | |
if (void 0 === this.directRequests[e.msgId]) return void this.log.debug( | |
`received response ${e.msgId} with no promise to resolve - likely already aborted`, | |
e.name); | |
this.directRequests[e.msgId].resolve({ | |
type: 'completed', | |
data: e.message, | |
}), delete this.directRequests[e.msgId]; | |
}, this.throwAbort = e => { | |
if (null == e ? void 0:e.reason) throw new DOMException( | |
null == e ? void 0:e.reason, 'AbortError'); | |
throw new DOMException('signal is aborted without reason', 'AbortError'); | |
}, this.validateMessage = e => { | |
const t = 'validate'; | |
if ('object' != typeof e || null === e) return this.log.debug( | |
'invalid message - not an object', t), !1; | |
const n = e; | |
return s(n.msgId) ? | |
s(n.source) ? | |
s(n.name) ? | |
n.type === p.opSynType || n.type === p.opSynAckType || | |
n.type === p.opAbortType || n.type === | |
p.opDirectRequestType || n.type === | |
p.opDirectResponseType || | |
(this.log.debug('invalid message: type unsupported', | |
t), !1): | |
(this.log.debug('invalid message - missing name', t), !1): | |
(this.log.debug('invalid message - missing source', t), !1): | |
(this.log.debug('invalid message - missing msgId', t), !1); | |
}, this.routes = e, this.synRequests = {}, this.abortableRequests = {}, this.directRequests = {}, this.source = t(), this.debug = !1, this.log = { | |
error: ( | |
e, t) => console.error(`PWM-${this.source}-${t}: ${e}`), | |
debug: (e, t) => { | |
this.debug && console.info(`PWM-${this.source}-${t}: ${e}`); | |
}, | |
}, window.addEventListener('message', (e => { | |
if (!this.validateMessage(e.data)) return; | |
const t = e.data; | |
if (t.source === this.source) return; | |
if (t.destination && t.destination !== this.source) return; | |
const {type: n} = t; | |
n === p.opSynType && this.handleIncomingSyn(t), n === p.opSynAckType && | |
this.handleIncomingSynAck(t), n === p.opAbortType && | |
this.handleIncomingAbortRequest(t), n === p.opDirectRequestType && | |
this.handleIncomingDirectRequest(t), n === p.opDirectResponseType && | |
this.handleIncomingResponse(t); | |
})); | |
} | |
} | |
var g, w, y, h, b, v, f, m; | |
p.opSynType = 'op-window-syn', p.opSynAckType = 'op-window-syn-ack', p.opAbortType = 'op-window-abort', p.opDirectRequestType = 'op-window-direct-request', p.opDirectResponseType = 'op-window-direct-response', p.NoReceivingEnd = 'no-receiving-end', p.HandlerError = 'uncaught-handler-error'; | |
const A = null === (w = null === (g = window.navigator) || void 0 === g ? | |
void 0: | |
g.credentials) || void 0 === w ? | |
void 0: | |
w.get.bind(window.navigator.credentials), R = null === | |
(h = null === (y = window.navigator) || void 0 === y ? | |
void 0: | |
y.credentials) || void 0 === h ? | |
void 0: | |
h.create.bind(window.navigator.credentials), q = null === | |
(v = null === (b = window.PublicKeyCredential) || void 0 === b ? | |
void 0: | |
b.isConditionalMediationAvailable) || void 0 === v ? | |
void 0: | |
v.bind(window.PublicKeyCredential), I = null === | |
(m = null === (f = window.PublicKeyCredential) || void 0 === f ? | |
void 0: | |
f.isUserVerifyingPlatformAuthenticatorAvailable) || void 0 === m ? | |
void 0: | |
m.bind(window.PublicKeyCredential); | |
let T; | |
const O = new Promise((e => { | |
const t = () => { | |
T = !0, e(void 0); | |
}; | |
window.document.prerendering ? | |
document.addEventListener('prerenderingchange', t): | |
t(); | |
})), E = ({data: e}) => { | |
var t; | |
const n = { | |
clientDataJSON: new Uint8Array(e.response.clientDataJSON).buffer, | |
authenticatorData: new Uint8Array(e.response.authenticatorData).buffer, | |
signature: new Uint8Array(e.response.signature).buffer, | |
userHandle: e.response.userHandle ? | |
new Uint8Array(e.response.userHandle).buffer: | |
null, | |
}; | |
Object.setPrototypeOf(n, AuthenticatorAssertionResponse.prototype); | |
const i = { | |
id: e.id, | |
rawId: new Uint8Array(e.rawId).buffer, | |
type: e.type, | |
authenticatorAttachment: null !== (t = e.authenticatorAttachment) && | |
void 0 !== t ? t:null, | |
response: n, | |
getClientExtensionResults: () => { | |
var t; | |
return l(null !== (t = e.clientExtentionResults) && void 0 !== t ? t:{}); | |
}, | |
}; | |
return Object.setPrototypeOf(i, PublicKeyCredential.prototype), i; | |
}, P = ({data: e}) => { | |
var t; | |
const n = { | |
attestationObject: new Uint8Array(e.response.attestationObject).buffer, | |
clientDataJSON: new Uint8Array(e.response.clientDataJSON).buffer, | |
getTransports: () => { | |
var t; | |
return null !== (t = e.response.transports) && void 0 !== t ? t:[]; | |
}, | |
getAuthenticatorData: () => { | |
var t; | |
return new Uint8Array( | |
null !== (t = e.response.authenticatorData) && void 0 !== t ? | |
t: | |
[]).buffer; | |
}, | |
getPublicKey: () => e.response.publicKey ? | |
new Uint8Array(e.response.publicKey).buffer: | |
null, | |
getPublicKeyAlgorithm: () => e.response.publicKeyAlgorithm, | |
}; | |
Object.setPrototypeOf(n, AuthenticatorAttestationResponse.prototype); | |
const i = { | |
id: e.id, | |
rawId: new Uint8Array(e.rawId).buffer, | |
type: e.type, | |
authenticatorAttachment: null !== (t = e.authenticatorAttachment) && | |
void 0 !== t ? t:null, | |
response: n, | |
getClientExtensionResults: () => { | |
var t; | |
return l(null !== (t = e.clientExtentionResults) && void 0 !== t ? t:{}); | |
}, | |
}; | |
return Object.setPrototypeOf(i, PublicKeyCredential.prototype), i; | |
}; | |
let S; | |
const D = new p({ | |
[i.UpdateSettings]: async e => { | |
void 0 !== e.body.authenticatePasskeys && | |
(S = e.body.authenticatePasskeys); | |
}, | |
}), k = async () => (void 0 === T && await O, void 0 === S && | |
(S = await (async () => { | |
const e = {type: 'should-intercept-webauthn-request', data: void 0}, | |
t = await D.send(o.ShouldInterceptWebauthn, {body: e}); | |
return t.type !== p.NoReceivingEnd && t.type !== p.HandlerError && | |
'should-intercept-webauthn-error' !== t.type && t.data; | |
})()), S); | |
async function U(t) { | |
if (!await k()) { | |
if (R) return R(t); | |
throw new DOMException( | |
'The operation either timed out or was not allowed. See https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.', | |
'NotAllowedError'); | |
} | |
return (async t => { | |
const n = Object.assign({}, t); | |
null == n || delete n.signal; | |
const i = { | |
type: 'create-credential-request', | |
data: JSON.stringify(n, ((e, t) => a(t))), | |
}, r = await D.send(o.Create, {body: i}); | |
if (r.type === p.NoReceivingEnd || r.type === p.HandlerError) return R(t); | |
if ('create-credential-error' === r.type) { | |
if ('timeout' === r.data.reason) throw new DOMException( | |
'The operation either timed out or was not allowed. See https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.', | |
'NotAllowedError'); | |
if ('duplicate' === r.data.reason) throw new DOMException( | |
'The user attempted to register an authenticator that contains one of the credentials already registered with the relying party.', | |
'InvalidStateError'); | |
return 'user-cancelled' === r.data.reason ? | |
null: | |
('fallback-requested' === r.data.reason || 'internal-error' === | |
r.data.reason || 'invalid-request' === r.data.reason || | |
e(r.data.reason), R(t)); | |
} | |
return P(r); | |
})(t); | |
} | |
async function M(t) { | |
if (!await k()) { | |
if (A) return A(t); | |
throw new DOMException( | |
'The operation either timed out or was not allowed. See https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.', | |
'NotAllowedError'); | |
} | |
return (async t => { | |
var n; | |
const i = Object.assign({}, t); | |
null == i || delete i.signal, 'conditional' === i.mediation && | |
(null === (n = i.publicKey) || void 0 === n ? void 0:n.timeout) && | |
(i.publicKey.timeout = void 0); | |
const r = { | |
type: 'get-credential-request', | |
data: JSON.stringify(i, ((e, t) => a(t))), | |
}, s = await D.send(o.Get, {body: r}); | |
if (s.type === p.NoReceivingEnd || s.type === p.HandlerError) return A(t); | |
if ('get-credential-error' === s.type) { | |
if ('timeout' === s.data.reason) throw new DOMException( | |
'The operation either timed out or was not allowed. See https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.', | |
'NotAllowedError'); | |
if ('conditional' === i.mediation && 'user-cancelled' === | |
s.data.reason) return d(); | |
if ('conditional' === i.mediation && 'fallback-requested' === | |
s.data.reason) { | |
const e = Object.assign({}, t); | |
return delete e.mediation, A(e); | |
} | |
return 'user-cancelled' === s.data.reason ? | |
null: | |
('fallback-requested' === s.data.reason || 'internal-error' === | |
s.data.reason || 'invalid-request' === s.data.reason || | |
e(s.data.reason), A(t)); | |
} | |
return E(s); | |
})(t); | |
} | |
async function C() { | |
return !!await k() || !!q && q(); | |
} | |
async function K() { | |
return !!await k() || !!I && I(); | |
} | |
const j = () => { | |
const e = 'function' == typeof globalThis.exportFunction ? | |
globalThis.exportFunction: | |
void 0; | |
e ? | |
(e((e => u(U(e))), window.navigator.credentials, | |
{defineAs: 'create'}), e((e => u(M(e))), | |
window.navigator.credentials, {defineAs: 'get'}), e((() => u(C())), | |
window.PublicKeyCredential, | |
{defineAs: 'isConditionalMediationAvailable'}), e((() => u(K())), | |
window.PublicKeyCredential, | |
{defineAs: 'isUserVerifyingPlatformAuthenticatorAvailable'})): | |
(window.navigator.credentials.create = U, window.navigator.credentials.get = M, window.PublicKeyCredential.isConditionalMediationAvailable = C, window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable = K); | |
}, N = () => { | |
if (window.navigator.credentials.create.length > 0 && | |
window.navigator.credentials.get.length > 0) return; | |
const e = window.wrappedJSObject ? window.wrappedJSObject:void 0; | |
e && e.navigator.credentials.create.length > 0 && | |
e.navigator.credentials.get.length > 0 || j(); | |
}; | |
window.navigator.credentials && (k(), j(), setInterval(N, 100)); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment