Skip to content

Instantly share code, notes, and snippets.

@hillar
Created June 1, 2020 07:25
Show Gist options
  • Save hillar/601f527bb9c92205735fbb6f46cbd8ed to your computer and use it in GitHub Desktop.
Save hillar/601f527bb9c92205735fbb6f46cbd8ed to your computer and use it in GitHub Desktop.
var webeid = function(e) {
"use strict";
var t, s = Object.freeze({
VERSION: "0.0.1",
MSG_DEFAULT_TIMEOUT: 12e4
});
!function(e) {
e.ERR_WEBEID_AUTH_FAIL = "ERR_WEBEID_AUTH_FAIL",
e.ERR_WEBEID_STATUS_FAIL = "ERR_WEBEID_STATUS_FAIL",
e.ERR_WEBEID_MSG_PENDING = "ERR_WEBEID_MSG_PENDING",
e.ERR_WEBEID_MSG_TIMEOUT = "ERR_WEBEID_MSG_TIMEOUT",
e.ERR_WEBEID_VERSION_MISMATCH = "ERR_WEBEID_VERSION_MISMATCH"
}(t || (t = {}));
var n, r = t;
class i extends Error {
constructor(e="authentication failed", t) {
super(e),
this.name = "AuthenticationFailureError",
this.code = r.ERR_WEBEID_AUTH_FAIL,
this.response = t
}
}
class a extends Error {
constructor(e="same message to Web-eID browser extension is already pending") {
super(e),
this.name = "MessagePendingError",
this.code = r.ERR_WEBEID_MSG_PENDING
}
}
class o extends Error {
constructor(e="extension message timeout") {
super(e),
this.name = "MessageTimeoutError",
this.code = r.ERR_WEBEID_MSG_TIMEOUT
}
}
class c extends Error {
constructor(e="status failed", t) {
super(e),
this.name = "StatusFailureError",
this.code = r.ERR_WEBEID_STATUS_FAIL;
const {library: s, extension: n, nativeApp: i} = t;
Object.assign(this, {
library: s,
extension: n,
nativeApp: i
})
}
}
!function(e) {
e.AUTHENTICATE = "web-eid:authenticate",
e.AUTHENTICATE_SUCCESS = "web-eid:authenticate-success",
e.AUTHENTICATE_FAILURE = "web-eid:authenticate-failure",
e.STATUS = "web-eid:status",
e.STATUS_SUCCESS = "web-eid:status-success",
e.STATUS_FAILURE = "web-eid:status-failure"
}(n || (n = {}));
var E = n;
class u extends Error {
constructor(e) {
super(e),
this.name = "SemverParseError"
}
}
const _ = new RegExp("^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$");
var I;
function d(e="") {
const t = e.match(_)
, [,s,n,r,i,a] = t || []
, o = parseInt(s, 10)
, c = parseInt(n, 10)
, E = parseInt(r, 10);
for (const t of [o, c, E])
if (Number.isNaN(t))
throw new u(`Invalid SemVer string '${e}'`);
return {
major: o,
minor: c,
patch: E,
rc: i,
build: a,
string: e
}
}
function h(e, t) {
return {
major: Math.sign(e.major - t.major),
minor: Math.sign(e.minor - t.minor),
patch: Math.sign(e.patch - t.patch)
}
}
function A(e) {
if ("object" == typeof e)
for (const t of ["library", "extension", "nativeApp"])
if (Object.hasOwnProperty.call(e, t))
return !0;
return !1
}
function l(e, t) {
return `Update required for Web-eID ${t}`
}
!function(e) {
e[e.NEWER = 1] = "NEWER",
e[e.SAME = 0] = "SAME",
e[e.OLDER = -1] = "OLDER"
}(I || (I = {}));
class R extends c {
constructor(e, t, s) {
e || (s.extension && s.nativeApp ? e = l`${"extension and native app"}` : s.extension ? e = l`${"extension"}` : s.nativeApp && (e = l`${"native app"}`)),
super(e, t),
this.name = "VersionMismatchError",
this.code = r.ERR_WEBEID_VERSION_MISMATCH,
this.requiresUpdate = s
}
}
const T = new class {
constructor() {
this.queue = [],
window.addEventListener("message", e=>this.receive(e))
}
receive(e) {
var t, s, n, r, i;
const a = e.data
, o = null === (t = a.action) || void 0 === t ? void 0 : t.split("-").pop()
, c = this.getInitialAction(a.action)
, E = this.getPendingMessage(c);
E && (clearTimeout(E.timer),
"success" === o ? null === (n = (s = E).resolve) || void 0 === n || n.call(s, a) : "failure" === o && (null === (i = (r = E).reject) || void 0 === i || i.call(r, a)),
this.removeFromQueue(c))
}
send(e) {
if (this.getPendingMessage(e.action))
return Promise.reject({
action: this.getFailureAction(e.action),
code: r.ERR_WEBEID_MSG_PENDING
});
{
const t = {
message: e
};
return this.queue.push(t),
t.promise = new Promise((e,s)=>{
t.resolve = e,
t.reject = s
}
),
t.timer = setTimeout(()=>this.onTimeout(t), e.timeout ? e.timeout + 1e3 : s.MSG_DEFAULT_TIMEOUT),
t.promise
}
}
onTimeout(e) {
var t, s;
null === (s = (t = e).reject) || void 0 === s || s.call(t, {
action: this.getFailureAction(e.message.action),
code: r.ERR_WEBEID_MSG_TIMEOUT
}),
this.removeFromQueue(e.message.action)
}
getPendingMessage(e) {
return this.queue.find(t=>t.message.action === e)
}
getSuccessAction(e) {
return `${e}-success`
}
getFailureAction(e) {
return `${e}-failure`
}
getInitialAction(e) {
return e.replace(/-success$|-failure$/, "")
}
removeFromQueue(e) {
this.queue = this.queue.filter(t=>t.message.action !== e)
}
}
;
return e.Action = E,
e.ErrorCode = r,
e.authenticate = async function(e) {
const t = Object.assign(Object.assign({}, e), {
action: E.AUTHENTICATE
});
try {
return await T.send(t)
} catch (e) {
const {code: t, message: s, response: n} = e;
switch (t) {
case r.ERR_WEBEID_MSG_TIMEOUT:
throw new o;
case r.ERR_WEBEID_MSG_PENDING:
throw new a;
default:
throw new i(s,n)
}
}
}
,
e.hasVersionProperties = A,
e.status = async function(e={
timeout: 2e3
}) {
let t;
const n = s.VERSION
, i = Object.assign(Object.assign({}, e), {
action: E.STATUS
});
try {
t = await T.send(i)
} catch (e) {
const {message: t, code: s} = e;
if (A(e)) {
const {extension: t, nativeApp: s, message: r} = e;
throw new c(r,{
extension: t,
library: n,
nativeApp: s
})
}
switch (s) {
case r.ERR_WEBEID_MSG_TIMEOUT:
throw new o;
case r.ERR_WEBEID_MSG_PENDING:
throw new a;
default:
throw new c(t,{
library: n
})
}
}
const u = Object.assign({
library: n
}, t)
, _ = function(e) {
const t = d(e.library)
, s = d(e.extension)
, n = d(e.nativeApp)
, r = h(s, t)
, i = h(n, t);
return {
extension: r.major === I.OLDER,
nativeApp: i.major === I.OLDER
}
}(u);
if (_.extension || _.nativeApp)
throw new R(void 0,u,_);
return u
}
,
e
}({});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment