Created
March 15, 2013 22:05
-
-
Save lloyd/5173429 to your computer and use it in GitHub Desktop.
line4.js
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
(a[d])); | |
b && b.length && (c = b.join("&")); | |
return c | |
} | |
function d(a, b) { | |
try { | |
a.readyState == 4 && (a.onreadystatechange = c, b && b(a.responseText, a.status)) | |
} catch (d) {} | |
} | |
function c() {} | |
function b() { | |
var a; | |
window.XMLHttpRequest ? a = new XMLHttpRequest : window.ActiveXObject && (a = new ActiveXObject("Microsoft.XM/LHTTP")); | |
return a | |
} | |
function a(a) { | |
var b = [].slice.call(arguments, 1), | |
c = function () { | |
return a.apply(null, b.concat([].slice.call(arguments))) | |
}; | |
return c | |
} | |
"use strict"; | |
var j = { | |
ajax: function (a) { | |
var b = a.error, | |
c = a.success, | |
d = { | |
readyState: 0 | |
}; | |
i(a, function (a, e) { | |
d.status = e, d.responseText = a, d.readyState = 4; | |
if (e >= 200 && e < 300 || e === 304) { | |
var f = a; | |
try { | |
var f = JSON.parse(a) | |
} catch (g) {} | |
c && c(f, a, d) | |
} else b && b(d, e, a) | |
}); | |
return d | |
} | |
}; | |
return j | |
}(), | |
function () { | |
"use strict", Function.prototype.bind || (Function.prototype.bind = function (a) { | |
if (typeof this != "function") throw new TypeError("Function.prototype.bind - what is trying to be fBound is not callable"); | |
var b = Array.prototype.slice.call(arguments, 1), | |
c = this, | |
d = function () {}, e = function () { | |
return c.apply(this instanceof d ? this : a || window, b.concat(Array.prototype.slice.call(arguments))) | |
}; | |
d.prototype = this.prototype, e.prototype = new d; | |
return e | |
}), Function.prototype.curry || (Function.prototype.curry = function () { | |
var a = this, | |
b = Array.prototype.slice.call(arguments); | |
return function () { | |
return a.apply(this, b.concat(Array.prototype.slice.call(arguments))) | |
} | |
}), window.console || (window.console = {}), window.console.log || (window.console.log = function () {}), String.prototype.trim || (String.prototype.trim = function () { | |
return this.replace(/^\s+|\s+$/g, "") | |
}) | |
}(), BrowserID.Mediator = function () { | |
var a = Hub; | |
return { | |
subscribeAll: a.all.bind(a), | |
subscribe: a.on.bind(a), | |
unsubscribe: a.off.bind(a), | |
publish: a.fire.bind(a), | |
reset: a.reset.bind(a) | |
} | |
}(), | |
function () { | |
function m(a) { | |
return String(a).replace(l, "") | |
} | |
function k(a) { | |
try { | |
window.console.log(a) | |
} catch (b) {} | |
} | |
function j(a) { | |
if (a) { | |
var b = [].slice.call(arguments, 1); | |
a.apply(null, b) | |
} | |
} | |
function i(a) { | |
return function (b) { | |
b && b.preventDefault(), a.call(this) | |
} | |
} | |
function h(a, b) { | |
var c = {}; | |
_.each(_.keys(a), function (d) { | |
_.indexOf(b, d) !== -1 && (c[d] = a[d]) | |
}); | |
return c | |
} | |
function g(a, b) { | |
var c = a, | |
d = []; | |
for (var e in b) d.push(e + "=" + encodeURIComponent(b[e])); | |
d.length && (c += "?" + d.join("&")); | |
return c | |
} | |
function f(a) { | |
var d = b.getInner(a) || ""; | |
return c.password(d) ? d : null | |
} | |
function e(a) { | |
var d = (b.getInner(a) || "").trim(); | |
return c.email(d) ? d : null | |
} | |
"use strict"; | |
var a = BrowserID, | |
b = a.DOM, | |
c = a.Validation, | |
d = a.Helpers = a.Helpers || {}, l = /.*@/; | |
_.extend(d, { | |
getAndValidateEmail: e, | |
getAndValidatePassword: f, | |
toURL: g, | |
whitelistFilter: h, | |
cancelEvent: i, | |
complete: j, | |
log: k, | |
getDomainFromEmail: m | |
}) | |
}(), BrowserID.getStorage = function () { | |
var a; | |
try { | |
a = localStorage | |
} catch (b) { | |
a = { | |
removeItem: function (a) { | |
this[a] = null, delete this[a] | |
} | |
} | |
} | |
return a | |
}, BrowserID.Storage = function () { | |
function K(a, b) { | |
var d; | |
try { | |
d = JSON.parse(c.emailToUserID); | |
if (typeof d != "object" || d === null) throw new Error("bogus") | |
} catch (e) { | |
d = {} | |
} | |
_.each(b, function (b) { | |
d[b] = a | |
}), c.emailToUserID = JSON.stringify(d) | |
} | |
function J(a) { | |
try { | |
var b = JSON.parse(c.usersComputer); | |
if (typeof b != "object") throw new Error("bogus"); | |
var d = b[a]; | |
d && (b[a] = null, delete b[a], c.usersComputer = JSON.stringify(b)) | |
} catch (e) {} | |
} | |
function I(a) { | |
try { | |
a = A(a); | |
var b = JSON.parse(c.usersComputer); | |
if (typeof b != "object") throw new Error("bogus"); | |
var d = b[a] || {}; | |
d.state = "ask", c.usersComputer = JSON.stringify(b) | |
} catch (e) {} | |
} | |
function H(a) { | |
C(a, "denied") | |
} | |
function G(a) { | |
C(a, "confirmed") | |
} | |
function F(a) { | |
C(a, "seen") | |
} | |
function E(a) { | |
if (typeof a != "number") return !1; | |
try { | |
a = A(a); | |
var d = JSON.parse(c.usersComputer), | |
e = d[a]; | |
if (e) { | |
var f = e.state, | |
g = new Date - Date.parse(e.updated); | |
if (f === "ask") return !0; | |
if (f === "confirmed") return !1; | |
if (f === "denied" && g > b) return !0; | |
if (f === "seen" && g > 6e4) return !0 | |
} | |
} catch (h) { | |
return !0 | |
} | |
return !1 | |
} | |
function D(a) { | |
try { | |
a = A(a); | |
var b = JSON.parse(c.usersComputer || "{}"); | |
return b[a].state === "confirmed" | |
} catch (d) { | |
return !1 | |
} | |
} | |
function C(a, d) { | |
a = A(a); | |
if (typeof a != "number") throw new Error("bad userid " + a); | |
if (!B(d)) throw new Error("invalid state"); | |
var e, f, g = 0; | |
try { | |
e = JSON.parse(c.usersComputer); | |
if (typeof e != "object") throw new Error("bogus"); | |
var h = e[a]; | |
if (h) { | |
f = h.state, g = Date.parse(h.updated); | |
if (!B(f)) throw new Error("corrupt/outdated"); | |
if (isNaN(g)) throw new Error("corrupt/outdated") | |
} | |
} catch (i) { | |
f = undefined, g = 0, e = {} | |
} | |
f === "denied" && (new Date).getTime() - g > b && (f = undefined, g = 0); | |
if (d !== "seen" || !f) e[a] = { | |
state: d, | |
updated: (new Date).toString() | |
}, c.usersComputer = JSON.stringify(e) | |
} | |
function B(a) { | |
return a === "seen" || a === "confirmed" || a === "denied" | |
} | |
function A(a) { | |
if (typeof a == "number") return a; | |
var b = JSON.parse(c.emailToUserID || "{}"); | |
return b[a] | |
} | |
function z() { | |
c.loggedIn = "{}" | |
} | |
function y(a, b) { | |
function d() { | |
var d = w(a); | |
c !== d && (b(), c = d) | |
} | |
var c = w(a); | |
window.addEventListener ? window.addEventListener("storage", d, !1) : window.setInterval(d, 2e3) | |
} | |
function x() { | |
var a = JSON.parse(c.loggedIn || "{}"); | |
return _.size(a) | |
} | |
function w(a) { | |
var b = JSON.parse(c.loggedIn || "{}"); | |
return b[a] | |
} | |
function v(a, b) { | |
var d = JSON.parse(c.loggedIn || "{}"); | |
b ? d[a] = b : delete d[a], c.loggedIn = JSON.stringify(d) | |
} | |
function u(a, b) { | |
var d = JSON.parse(c[a] || "{}"); | |
delete d[b], c[a] = JSON.stringify(d) | |
} | |
function t(a, b) { | |
var d = JSON.parse(c[a] || "{}"); | |
return d[b] | |
} | |
function s(a, b, d) { | |
var e = JSON.parse(c[a] || "{}"); | |
e[b] = d, c[a] = JSON.stringify(e) | |
} | |
function r(a) { | |
var b = JSON.parse(c.siteInfo || "{}"); | |
return _.size(b) | |
} | |
function q(a, b) { | |
var d = JSON.parse(c.siteInfo || "{}"), | |
e = d[a]; | |
e && (delete e[b], _.size(e) || delete d[a], c.siteInfo = JSON.stringify(d)) | |
} | |
function p(a, b) { | |
var d = JSON.parse(c.siteInfo || "{}"), | |
e = d[a]; | |
return e && e[b] | |
} | |
function o(a, b, d) { | |
var e = JSON.parse(c.siteInfo || "{}"), | |
f = e[a] = e[a] || {}; | |
if (b === "email" && !i(d)) throw new Error("unknown email address"); | |
f[b] = d, c.siteInfo = JSON.stringify(e) | |
} | |
function n() { | |
var a; | |
try { | |
var b = JSON.parse(c.returnTo); | |
if (b) { | |
if (new Date - new Date(b.at) > 3e5) throw new Error("stale"); | |
if (typeof b.url != "string") throw new Error("malformed"); | |
a = b.url | |
} | |
} catch (d) { | |
c.removeItem("returnTo") | |
} | |
return a | |
} | |
function m(a) { | |
c.returnTo = JSON.stringify({ | |
at: (new Date).toString(), | |
url: a | |
}) | |
} | |
function l(a) { | |
var b = i(a); | |
if (b) delete b.priv, delete b.pub, delete b.cert, j(a, b); | |
else throw new Error("unknown email address") | |
} | |
function k(a) { | |
var b = g(); | |
if (!b[a]) throw new Error("unknown email address"); | |
delete b[a], d(b); | |
var e = JSON.parse(c.siteInfo || "{}"); | |
for (var f in e) e[f].email === a && delete e[f].email; | |
c.siteInfo = JSON.stringify(e); | |
var h = JSON.parse(c.loggedIn || "{}"); | |
for (var i in h) h[i] === a && delete h[i]; | |
c.loggedIn = JSON.stringify(h) | |
} | |
function j(a, b) { | |
var c = g(); | |
b = b || {}, c[a] = b, d(c) | |
} | |
function i(a) { | |
var b = g(); | |
return b && b[a] | |
} | |
function h() { | |
return _.size(g()) | |
} | |
function g() { | |
try { | |
var a = JSON.parse(c.emails || "{}"); | |
if (a !== null) return a | |
} catch (b) {} | |
e(); | |
return {} | |
} | |
function f() { | |
_.each({ | |
emailToUserID: {}, | |
emails: {}, | |
interaction_data: {}, | |
loggedIn: {}, | |
main_site: {}, | |
managePage: {}, | |
returnTo: null, | |
siteInfo: {}, | |
stagedOnBehalfOf: null, | |
usersComputer: {} | |
}, function (a, b) { | |
c[b] || (c[b] = JSON.stringify(a)) | |
}) | |
} | |
function e() { | |
c.removeItem("emails"), c.removeItem("siteInfo"), c.removeItem("managePage"), f() | |
} | |
function d(a) { | |
c.emails = JSON.stringify(a) | |
} | |
"use strict"; | |
var a, b = 864e5, | |
c = BrowserID.getStorage(); | |
f(); | |
return { | |
addEmail: j, | |
getEmails: g, | |
getEmailCount: h, | |
getEmail: i, | |
removeEmail: k, | |
invalidateEmail: l, | |
site: { | |
set: o, | |
get: p, | |
remove: q, | |
count: r | |
}, | |
manage_page: { | |
set: s.curry("managePage"), | |
get: t.curry("managePage"), | |
remove: u.curry("managePage") | |
}, | |
signInEmail: { | |
set: s.curry("main_site", "signInEmail"), | |
get: t.curry("main_site", "signInEmail"), | |
remove: u.curry("main_site", "signInEmail") | |
}, | |
usersComputer: { | |
confirmed: D, | |
setConfirmed: G, | |
setDenied: H, | |
shouldAsk: E, | |
setSeen: F, | |
clear: J, | |
forceAsk: I | |
}, | |
updateEmailToUserIDMapping: K, | |
setLoggedIn: v, | |
getLoggedIn: w, | |
loggedInCount: x, | |
watchLoggedIn: y, | |
logoutEverywhere: z, | |
clear: e, | |
setReturnTo: m, | |
getReturnTo: n, | |
setDefaultValues: f | |
} | |
}(), BrowserID.XHRTransport = window.Micrajax, BrowserID.XHR = function () { | |
function p(a) { | |
o(function () { | |
var b = a.data || {}; | |
b.csrf = b.csrf || f; | |
var c = _.extend(a, { | |
type: "POST", | |
data: JSON.stringify(b), | |
contentType: "application/json", | |
processData: !1, | |
defer_success: !0 | |
}); | |
m(c) | |
}, a.error) | |
} | |
function o(a, c) { | |
typeof e != "undefined" ? a(e) : m({ | |
type: "GET", | |
url: "/wsapi/session_context", | |
success: function (c) { | |
f = c.csrf_token, e = c, b.publish("context_info", c), a && a(c) | |
}, | |
error: c | |
}) | |
} | |
function n(a) { | |
var b = _.extend(a, { | |
type: "GET", | |
defer_success: !0 | |
}); | |
m(b) | |
} | |
function m(a) { | |
var e = a.success, | |
f = a.error, | |
h, i = { | |
network: { | |
type: a.type.toUpperCase(), | |
url: a.url | |
}, | |
eventTime: new Date | |
}, m = function (b, c, d) { | |
h && (clearTimeout(h), h = null), l(i), a.defer_success ? _.defer(e.curry(b, c, d)) : e(b, c, d) | |
}, n = function (a, b, c) { | |
h && (clearTimeout(h), h = null), l(i), _.defer(j.curry(f, i, a, b, c)) | |
}, o = _.extend({}, a, { | |
success: m, | |
error: n, | |
headers: { | |
"BrowserID-Version": d | |
} | |
}); | |
g && (h = setTimeout(k.curry(i), g)), b.publish("xhr_start", i), c.ajax(o) | |
} | |
function l(a) { | |
a.duration = new Date - a.eventTime, b.publish("xhr_complete", a) | |
} | |
function k(a) { | |
b.publish("xhr_delay", a) | |
} | |
function j(a, c, d, e, f) { | |
c = c || {}, c.network = _.extend(c.network || {}, { | |
status: d && d.status, | |
textStatus: e, | |
errorThrown: f, | |
responseText: d.responseText | |
}), b.publish("xhr_error", c), a && a(c) | |
} | |
function i(a) { | |
a.hasOwnProperty("transport") && (c = a.transport), a.hasOwnProperty("time_until_delay") && (g = a.time_until_delay), h() | |
} | |
function h() { | |
f = e = undefined | |
} | |
"use strict"; | |
var a = BrowserID, | |
b = a.Mediator, | |
c = a.XHRTransport, | |
d = BrowserID.CODE_VERSION, | |
e, f, g; | |
return { | |
init: i, | |
get: n, | |
post: p, | |
withContext: o, | |
clearContext: h | |
} | |
}(), BrowserID.Network = function () { | |
function w(a, b, d, e, f) { | |
var h = { | |
token: b | |
}; | |
d !== null && (h.pass = d), m({ | |
url: a, | |
data: h, | |
success: function (a, b, d) { | |
a.success && (g = "password"), c(e, a.success) | |
}, | |
error: f | |
}) | |
} | |
function v(a, b, d, e) { | |
b.status === "complete" && b.userid && p(b.userid), c(a, b.status) | |
} | |
function u(a, b, d, e) { | |
m({ | |
url: b, | |
data: a, | |
success: function (a) { | |
c(d, a.success) | |
}, | |
error: function (a) { | |
a.network.status === 429 ? c(d, !1) : c(e, a) | |
} | |
}) | |
} | |
function t(a, b, d, e) { | |
try { | |
var f = e.success; | |
if (typeof f != "boolean") throw e; | |
p(e.userid), g = f && a, c(b, f) | |
} catch (h) { | |
d("unexpected server response: " + h) | |
} | |
} | |
function s() { | |
l.clearContext(); | |
var a; | |
d = e = g = i = a | |
} | |
function r(a, b) { | |
typeof d != "undefined" ? a(d) : l.withContext(a, b) | |
} | |
function q(b, c) { | |
d = c, e = { | |
remote: c.server_time, | |
local: (new Date).getTime() | |
}, f = c.domain_key_creation_time, g = c.auth_level, h = c.code_version, p(c.userid), a.addEntropy(c.random_seed) | |
} | |
function p(a) { | |
i = a, i && o.usersComputer.setSeen(i) | |
} | |
"use strict"; | |
var a = require("./lib/jwcrypto"), | |
b = BrowserID, | |
c = b.Helpers.complete, | |
d, e, f, g, h, i, j, k = b.Mediator, | |
l = b.XHR, | |
m = l.post, | |
n = l.get, | |
o = b.Storage, | |
x = { | |
init: function (a) { | |
k.subscribe("context_info", q), this.cookiesEnabledOverride = a && a.cookiesEnabledOverride, s() | |
}, | |
authenticate: function (a, b, c, d) { | |
m({ | |
url: "/wsapi/authenticate_user", | |
data: { | |
email: a, | |
pass: b, | |
ephemeral: !o.usersComputer.confirmed(a) | |
}, | |
success: t.curry("password", c, d), | |
error: d | |
}) | |
}, | |
authenticateWithAssertion: function (a, b, c, d) { | |
m({ | |
url: "/wsapi/auth_with_assertion", | |
data: { | |
assertion: b, | |
ephemeral: !o.usersComputer.confirmed(a) | |
}, | |
success: t.curry("assertion", c, d), | |
error: d | |
}) | |
}, | |
checkAuth: function (a, b) { | |
r(function () { | |
try { | |
c(a, g) | |
} catch (d) { | |
c(b, d.toString()) | |
} | |
}, b) | |
}, | |
withContext: function (a, b) { | |
r(a, b) | |
}, | |
clearContext: s, | |
logout: function (a, b) { | |
m({ | |
url: "/wsapi/logout", | |
success: function () { | |
g = !1, p(undefined), c(a) | |
}, | |
error: function (d, e, f) { | |
d.network.status === 400 ? (g = !1, c(a)) : b && b(d) | |
} | |
}) | |
}, | |
createUser: function (a, b, c, d, e) { | |
var f = { | |
email: a, | |
pass: b, | |
site: c | |
}; | |
u(f, "/wsapi/stage_user", d, e) | |
}, | |
emailForVerificationToken: function (a, b, d) { | |
n({ | |
url: "/wsapi/email_for_token?token=" + encodeURIComponent(a), | |
success: function (a) { | |
var d = null; | |
a.success !== !1 && (d = _.extend({ | |
needs_password: !1 | |
}, a)), c(b, d) | |
}, | |
error: d | |
}) | |
}, | |
checkUserRegistration: function (a, b, c) { | |
n({ | |
url: "/wsapi/user_creation_status?email=" + encodeURIComponent(a), | |
success: v.curry(b), | |
error: c | |
}) | |
}, | |
completeUserRegistration: w.curry("/wsapi/complete_user_creation"), | |
completeEmailRegistration: w.curry("/wsapi/complete_email_confirmation"), | |
requestPasswordReset: function (a, b, c, d) { | |
var e = { | |
email: a, | |
site: b | |
}; | |
u(e, "/wsapi/stage_reset", c, d) | |
}, | |
completePasswordReset: w.curry("/wsapi/complete_reset"), | |
checkPasswordReset: function (a, b, c) { | |
n({ | |
url: "/wsapi/password_reset_status?email=" + encodeURIComponent(a), | |
success: v.curry(b), | |
error: c | |
}) | |
}, | |
requestEmailReverify: function (a, b, c, d) { | |
var e = { | |
email: a, | |
site: b | |
}; | |
u(e, "/wsapi/stage_reverify", c, d) | |
}, | |
checkEmailReverify: function (a, b, c) { | |
n({ | |
url: "/wsapi/email_reverify_status?email=" + encodeURIComponent(a), | |
success: v.curry(b), | |
error: c | |
}) | |
}, | |
sendInteractionData: function (a, b, d) { | |
m({ | |
url: "/wsapi/interaction_data", | |
data: { | |
data: a | |
}, | |
success: function (a) { | |
c(b, a.success) | |
}, | |
error: d | |
}) | |
}, | |
changePassword: function (a, b, d, e) { | |
m({ | |
url: "/wsapi/update_password", | |
data: { | |
oldpass: a, | |
newpass: b | |
}, | |
success: function (a) { | |
a && (g = "password"), c(d, a.success) | |
}, | |
error: e | |
}) | |
}, | |
cancelUser: function (a, b) { | |
m({ | |
url: "/wsapi/account_cancel", | |
success: a, | |
error: b | |
}) | |
}, | |
addEmailWithAssertion: function (a, b, d) { | |
m({ | |
url: "/wsapi/add_email_with_assertion", | |
data: { | |
assertion: a | |
}, | |
success: function (a) { | |
c(b, a.success) | |
}, | |
error: d | |
}) | |
}, | |
addSecondaryEmail: function (a, b, c, d, e) { | |
var f = { | |
email: a, | |
pass: b, | |
site: c | |
}; | |
u(f, "/wsapi/stage_email", d, e) | |
}, | |
checkEmailRegistration: function (a, b, c) { | |
n({ | |
url: "/wsapi/email_addition_status?email=" + encodeURIComponent(a), | |
success: v.curry(b), | |
error: c | |
}) | |
}, | |
emailRegistered: function (a, b, d) { | |
n({ | |
url: "/wsapi/have_email?email=" + encodeURIComponent(a), | |
success: function (a, d, e) { | |
c(b, a.email_known) | |
}, | |
error: d | |
}) | |
}, | |
addressInfo: function (a, b, d) { | |
n({ | |
url: "/wsapi/address_info?email=" + encodeURIComponent(a), | |
success: function (a, d, e) { | |
c(b, a) | |
}, | |
error: d | |
}) | |
}, | |
removeEmail: function (a, b, d) { | |
m({ | |
url: "/wsapi/remove_email", | |
data: { | |
email: a | |
}, | |
success: function (a, d, e) { | |
c(b, a.success) | |
}, | |
error: d | |
}) | |
}, | |
certKey: function (a, b, c, d) { | |
m({ | |
url: "/wsapi/cert_key", | |
data: { | |
email: a, | |
pubkey: b.serialize(), | |
ephemeral: !o.usersComputer.confirmed(a) | |
}, | |
success: c, | |
error: d | |
}) | |
}, | |
listEmails: function (a, b) { | |
n({ | |
url: "/wsapi/list_emails", | |
success: function (b) { | |
i && o.updateEmailToUserIDMapping(i, b.emails), a && a(b.emails) | |
}, | |
error: b | |
}) | |
}, | |
userid: function () { | |
return i | |
}, | |
serverTime: function (a, b) { | |
r(function () { | |
try { | |
if (!e) throw new Error("can't get server time!"); | |
var d = (new Date).getTime() - e.local; | |
c(a, new Date(d + e.remote)) | |
} catch (f) { | |
c(b, f.toString()) | |
} | |
}, b) | |
}, | |
domainKeyCreationTime: function (a, b) { | |
r(function () { | |
try { | |
if (!f) throw new Error("can't get domain key creation time!"); | |
c(a, new Date(f)) | |
} catch (d) { | |
c(b, d.toString()) | |
} | |
}, b) | |
}, | |
codeVersion: function (a, b) { | |
r(function () { | |
c(a, h) | |
}, b) | |
}, | |
cookiesEnabled: function (a, b) { | |
var d; | |
try { | |
document.cookie = "__cookiesEnabledCheck=1", d = document.cookie.indexOf("__cookiesEnabledCheck") > -1; | |
var e = new Date; | |
e.setDate(e.getDate() - 1), document.cookie = "__cookiesEnabledCheck=; expires=" + e.toGMTString() | |
} catch (f) { | |
d = !1 | |
} | |
typeof x.cookiesEnabledOverride == "boolean" && (d = x.cookiesEnabledOverride), c(a, d) | |
}, | |
prolongSession: function (a, b) { | |
x.checkAuth(function (d) { | |
d ? m({ | |
url: "/wsapi/prolong_session", | |
success: a, | |
error: b | |
}) : c(b, "user not authenticated") | |
}, b) | |
}, | |
usedAddressAsPrimary: function (a, b, d) { | |
x.checkAuth(function e(e) { | |
e ? m({ | |
url: "/wsapi/used_address_as_primary", | |
data: { | |
email: a | |
}, | |
success: b, | |
error: d | |
}) : c(d, "user not authenticated") | |
}, d) | |
}, | |
requestTransitionToSecondary: function (a, b, c, d, e) { | |
var f = { | |
email: a, | |
pass: b, | |
site: c | |
}; | |
u(f, "/wsapi/stage_transition", d, e) | |
}, | |
completeTransitionToSecondary: w.curry("/wsapi/complete_transition"), | |
checkTransitionToSecondary: function (a, b, c) { | |
n({ | |
url: "/wsapi/transition_status?email=" + encodeURIComponent(a), | |
success: v.curry(b), | |
error: c | |
}) | |
} | |
}; | |
return x | |
}(), BrowserID.User = function () { | |
function B(a) { | |
e.addEmail(a.email, { | |
created: new Date | |
}) | |
} | |
function A(a, b, c, e) { | |
d.certKey(a, b.publicKey, function (d) { | |
z(a, b, d, c, e) | |
}, e) | |
} | |
function z(a, b, c, d, f) { | |
var g = new Date, | |
h = e.getEmails()[a] || { | |
created: g | |
}; | |
_.extend(h, { | |
updated: g, | |
pub: b.publicKey.toSimpleObject(), | |
priv: b.secretKey.toSimpleObject(), | |
cert: c | |
}), e.addEmail(a, h), d && d(!0) | |
} | |
function y(a) { | |
return f.getDomainFromEmail(a.email) | |
} | |
function x() { | |
h && (clearTimeout(h), h = null) | |
} | |
function w(a, b, c, f) { | |
function k() { | |
a(b, function (a) { | |
a === "complete" || a === "mustAuth" ? i(a) : a === "pending" ? h = setTimeout(k, o) : l(f, a) | |
}, f) | |
} | |
function j(a) { | |
e.setReturnTo(""), m = !0, a === "complete" ? g.syncEmails(function () { | |
l(c, a) | |
}, f) : l(c, a) | |
} | |
function i(a) { | |
p && q ? (g.authenticate(p, q, function (b) { | |
a = b ? "complete" : "mustAuth", j(a) | |
}, f), p = q = null) : (d.clearContext(), d.checkAuth(function (b) { | |
a === "complete" && b !== "password" && (a = "mustAuth"), j(a) | |
}, f)) | |
} | |
k() | |
} | |
function v(a, b, c, d, f) { | |
g.tokenInfo(b, function (g) { | |
var h = { | |
valid: !1 | |
}; | |
g ? a(b, c, function (a) { | |
var b = h; | |
a && (b = _.extend({ | |
valid: a | |
}, g), e.setReturnTo("")), l(d, b) | |
}, f) : d && d(h) | |
}, f) | |
} | |
function u(a, b, c, d, f) { | |
p = a, q = b, c(function (a) { | |
var b = { | |
success: a | |
}; | |
a || (b.reason = "throttle"); | |
var c = g.getReturnTo(); | |
a && c && e.setReturnTo(c), l(d, b) | |
}, f) | |
} | |
function t(a) { | |
if (window.$) { | |
var b = a ? "addClass" : "removeClass"; | |
$("body")[b]("authenticated") | |
} | |
a || e.clear() | |
} | |
function s(b) { | |
d.serverTime(function (c) { | |
d.domainKeyCreationTime(function (d) { | |
function g(a) { | |
var b = a.payload.exp.valueOf() - c.valueOf(); | |
if (b < 12e4) return !0; | |
if (!a.payload.iat) { | |
f.log("Data Format ERROR: expected cert to have iat property, but found none, marking expired"); | |
return !0 | |
} | |
if (a.payload.iat < d) { | |
f.log("Certificate issued " + a.payload.iat + " is before creation time " + d + ", marking expired"); | |
return !0 | |
} | |
return !1 | |
} | |
var h = e.getEmails(), | |
i = {}; | |
r(), _(h).each(function (b, c) { | |
try { | |
b.pub = a.loadPublicKeyFromObject(b.pub) | |
} catch (d) { | |
e.invalidateEmail(c); | |
return | |
} | |
if (!b.cert) e.invalidateEmail(c); | |
else try { | |
var i = a.extractComponents(h[c].cert); | |
g(i) && e.invalidateEmail(c) | |
} catch (j) { | |
f.log("error parsing cert for" + c + ":" + j), e.invalidateEmail(c) | |
} | |
}), b() | |
}, function (a) { | |
b() | |
}) | |
}) | |
} | |
function r() { | |
a || (a = require("./lib/jwcrypto")) | |
} | |
"use strict"; | |
var a, b, c = BrowserID, | |
d = c.Network, | |
e = c.Storage, | |
f = c.Helpers, | |
g, h, i = c.Provisioning, | |
j = {}, k = {}, l = c.Helpers.complete, | |
m = !1, | |
n = 3e3, | |
o = n, | |
p, q; | |
g = { | |
init: function (a) { | |
a.provisioning && (i = a.provisioning), a.pollDuration && (o = a.pollDuration) | |
}, | |
reset: function () { | |
i = BrowserID.Provisioning, g.resetCaches(), m = !1, o = n, p = q = null | |
}, | |
resetCaches: function () { | |
j = {}, k = {} | |
}, | |
setNetwork: function (a) { | |
d = a | |
}, | |
setOrigin: function (a) { | |
b = a | |
}, | |
getOrigin: function () { | |
return b | |
}, | |
setOriginEmail: function (a) { | |
e.site.set(b, "email", a) | |
}, | |
getOriginEmail: function () { | |
return e.site.get(b, "email") | |
}, | |
getHostname: function () { | |
return b.replace(/^.*:\/\//, "").replace(/:\d*$/, "") | |
}, | |
setReturnTo: function (a) { | |
this.returnTo = a | |
}, | |
getReturnTo: function () { | |
return this.returnTo | |
}, | |
createSecondaryUser: function (a, c, e, f) { | |
u(a, c, d.createUser.bind(d, a, c, b), e, f) | |
}, | |
createPrimaryUser: function (a, b, c) { | |
var d = a.email; | |
g.provisionPrimaryUser(d, a, function (a, e) { | |
a === "primary.verified" ? g.authenticateWithAssertion(d, e.assertion, function (a) { | |
a ? b("primary.verified") : b("primary.could_not_add") | |
}, c) : b(a, e) | |
}, c) | |
}, | |
provisionPrimaryUser: function (a, b, c, d) { | |
g.primaryUserAuthenticationInfo(a, b, function (e) { | |
e.authenticated ? z(a, e.keypair, e.cert, function () { | |
g.getAssertion(a, "https://login.anosrep.org", function (a) { | |
a ? c("primary.verified", { | |
assertion: a | |
}) : c("primary.could_not_add") | |
}, d) | |
}) : c("primary.verify", b) | |
}, d) | |
}, | |
primaryUserAuthenticationInfo: function (a, b, c, d) { | |
function h(b) { | |
k[a] = b, c && _.defer(c.curry(b)) | |
} | |
var f = e.getEmail(a), | |
g = this; | |
k = k || {}; | |
if (k[a]) h(k[a]); | |
else { | |
if (f && f.cert) { | |
var j = _.extend({ | |
authenticated: !0 | |
}, f, b); | |
h(j); | |
return | |
} | |
i({ | |
email: a, | |
url: b.prov, | |
ephemeral: !e.usersComputer.confirmed(a) | |
}, function (a, c) { | |
var d = _.extend({ | |
keypair: a, | |
cert: c, | |
authenticated: !0 | |
}, b); | |
h(d) | |
}, function (a) { | |
if (a.code === "primaryError" && a.msg === "user is not authenticated as target user") { | |
var c = _.extend({ | |
authenticated: !1 | |
}, b); | |
h(c) | |
} else d(b) | |
}) | |
} | |
}, isUserAuthenticatedToPrimary: function (a, b, c, d) { | |
g.primaryUserAuthenticationInfo(a, b, function (a) { | |
c(a.authenticated) | |
}, d) | |
}, | |
waitForUserValidation: w.curry(d.checkUserRegistration), | |
cancelUserValidation: x, | |
tokenInfo: function (a, b, c) { | |
d.emailForVerificationToken(a, function (a) { | |
a && (a = _.extend(a, { | |
returnTo: e.getReturnTo() | |
})), l(b, a) | |
}, c) | |
}, | |
verifyUser: v.curry(d.completeUserRegistration), | |
canSetPassword: function (a, b) { | |
d.withContext(function (b) { | |
l(a, b.has_password) | |
}, b) | |
}, | |
changePassword: function (a, b, c, e) { | |
d.changePassword(a, b, c, e) | |
}, | |
requestPasswordReset: function (a, c, e) { | |
g.addressInfo(a, function (f) { | |
f.state === "unknown" ? l(c, { | |
success: !1, | |
reason: "invalid_email" | |
}) : f.type === "primary" ? l(c, { | |
success: !1, | |
reason: "primary_address" | |
}) : u(a, null, d.requestPasswordReset.bind(d, a, b), c, e) | |
}, e) | |
}, | |
completePasswordReset: v.curry(d.completePasswordReset), | |
waitForPasswordResetComplete: w.curry(d.checkPasswordReset), | |
cancelWaitForPasswordResetComplete: x, | |
requestEmailReverify: function (a, c, f) { | |
e.getEmail(a) ? u(a, null, d.requestEmailReverify.bind(d, a, b), c, f) : l(c, { | |
success: !1, | |
reason: "invalid_email" | |
}) | |
}, | |
waitForEmailReverifyComplete: w.curry(d.checkEmailReverify), | |
cancelWaitForEmailReverifyComplete: x, | |
requestTransitionToSecondary: function (a, c, e, f) { | |
g.addressInfo(a, function (g) { | |
g.state === "unknown" ? l(e, { | |
success: !1, | |
reason: "invalid_email" | |
}) : g.type === "primary" ? l(e, { | |
success: !1, | |
reason: "primary_address" | |
}) : u(a, c, d.requestTransitionToSecondary.bind(d, a, c, b), e, f) | |
}, f) | |
}, | |
completeTransitionToSecondary: v.curry(d.completeTransitionToSecondary), | |
waitForTransitionToSecondaryComplete: w.curry(d.checkTransitionToSecondary), | |
cancelWaitForTransitionToSecondaryComplete: x, | |
cancelUser: function (a, b) { | |
d.cancelUser(function () { | |
t(!1), a && a() | |
}, b) | |
}, | |
logoutUser: function (a, b) { | |
g.checkAuthentication(function (c) { | |
c ? (e.logoutEverywhere(), d.logout(function () { | |
t(!1), l(a, !! c) | |
}, b)) : l(a, c) | |
}, b) | |
}, | |
syncEmails: function (a, b) { | |
s(function () { | |
var c = g.getStoredEmailKeypairs(); | |
d.listEmails(function (b) { | |
var d = _.keys(c), | |
f = _.difference(b, d), | |
g = _.difference(d, b), | |
h = _.intersection(d, b); | |
_.each(g, function (a) { | |
e.removeEmail(a) | |
}), _.each(f, function (a) { | |
B({ | |
email: a | |
}) | |
}), l(a) | |
}, b) | |
}) | |
}, | |
checkAuthentication: function (a, b) { | |
d.cookiesEnabled(function (c) { | |
c ? d.checkAuth(function (b) { | |
t(b), b || (b = !1), l(a, b) | |
}, b) : l(a, c) | |
}, b) | |
}, | |
checkAuthenticationAndSync: function (a, b) { | |
g.checkAuthentication(function (c) { | |
c ? g.syncEmails(function () { | |
a && a(c) | |
}, b) : a && a(c) | |
}, b) | |
}, | |
authenticate: function (a, b, c, e) { | |
d.authenticate(a, b, function (a) { | |
t(a), a ? g.syncEmails(function () { | |
c && c(a) | |
}, e) : c && c(a) | |
}, e) | |
}, | |
authenticateWithAssertion: function (a, b, c, e) { | |
d.authenticateWithAssertion(a, b, function (a) { | |
t(a), a ? g.syncEmails(function () { | |
l(c, a) | |
}, e) : l(c, a) | |
}, e) | |
}, | |
isEmailRegistered: function (a, b, c) { | |
d.emailRegistered(a, b, c) | |
}, | |
addressInfo: function (a, b, c) { | |
function e(c) { | |
c.email = a, j[a] = c, b && b(c) | |
} | |
j[a] ? e(j[a]) : d.addressInfo(a, function (b) { | |
b.email = a, b = g.checkEmailIssuer(a, b), b.type === "primary" ? g.isUserAuthenticatedToPrimary(a, b, function (a) { | |
b.authed = a, b.idpName = y(b), e(b) | |
}, c) : e(b) | |
}, c) | |
}, | |
checkEmailIssuer: function (b, c) { | |
function d(a, b) { | |
delete b.cert, delete k[a], e.addEmail(a, b) | |
} | |
r(); | |
var h = g.getStoredEmailKeypair(b); | |
if (h && h.cert && c && c.issuer) if ("transition_to_primary" === c.state && h.cert) d(b, h); | |
else { | |
var i; | |
try { | |
i = a.extractComponents(h.cert).payload.iss | |
} catch (j) { | |
f.log("Looking for issuer, error parsing cert for" + b + ":" + j), d(b, h) | |
} | |
i && c.issuer !== i && d(b, h) | |
} | |
return c | |
}, | |
addEmail: function (a, c, e, f) { | |
u(a, c, d.addSecondaryEmail.bind(d, a, c, b), e, f) | |
}, | |
passwordNeededToAddSecondaryEmail: function (a, b) { | |
d.withContext(function (b) { | |
l(a, !b.has_password) | |
}, b) | |
}, | |
waitForEmailValidation: w.curry(d.checkEmailRegistration), | |
cancelEmailValidation: x, | |
verifyEmail: v.curry(d.completeEmailRegistration), | |
removeEmail: function (a, b, c) { | |
e.getEmail(a) ? d.removeEmail(a, function () { | |
e.removeEmail(a), b && b() | |
}, c) : b && b() | |
}, | |
syncEmailKeypair: function (b, e, f) { | |
r(), d.withContext(function () { | |
a.generateKeypair({ | |
algorithm: "DS", | |
keysize: c.KEY_LENGTH | |
}, function (a, c) { | |
A(b, c, e, f) | |
}) | |
}) | |
}, | |
getAssertion: function (b, c, f, h) { | |
function m(f) { | |
d.serverTime(function (d) { | |
var g = a.loadSecretKeyFromObject(f.priv), | |
h = d.getTime() + 12e4, | |
j = new Date(h); | |
setTimeout(function () { | |
a.assertion.sign({}, { | |
audience: c, | |
expiresAt: j | |
}, g, function (d, g) { | |
k = a.cert.bundle([f.cert], g), e.site.set(c, "email", b), i(k) | |
}) | |
}, 0) | |
}, h) | |
} | |
function i(a) { | |
f && f(a) | |
} | |
var j = e.getEmail(b), | |
k, l = this; | |
j ? (r(), j.priv ? setTimeout(function () { | |
m(j) | |
}, 0) : g.addressInfo(b, function (a) { | |
a.type === "primary" ? g.provisionPrimaryUser(b, a, function (a) { | |
a === "primary.verified" ? g.getAssertion(b, c, f, h) : i(null) | |
}, h) : g.syncEmailKeypair(b, function (a) { | |
g.getAssertion(b, c, f, h) | |
}, h) | |
}, h)) : i(null) | |
}, | |
getStoredEmailKeypairs: function () { | |
return e.getEmails() | |
}, | |
getSortedEmailKeypairs: function () { | |
var a = g.getStoredEmailKeypairs(), | |
b = []; | |
for (var c in a) a.hasOwnProperty(c) && b.push({ | |
address: c, | |
info: a[c] | |
}); | |
b.sort(function (a, b) { | |
var c = a.address > b.address ? 1 : a.address < b.address ? -1 : 0; | |
return c | |
}); | |
return b | |
}, | |
getStoredEmailKeypair: function (a) { | |
return e.getEmail(a) | |
}, | |
clearStoredEmailKeypairs: function () { | |
e.clear() | |
}, | |
getSilentAssertion: function (a, c, d) { | |
g.checkAuthenticationAndSync(function (f) { | |
if (f) { | |
var h = e.getLoggedIn(b); | |
h !== a ? h ? g.getAssertion(h, b, function (a) { | |
c(a ? h : null, a) | |
}, d) : c(null, null) : c(h, null) | |
} else c && c(null, null) | |
}, d) | |
}, logout: function (a, c) { | |
g.checkAuthentication(function (c) { | |
c && e.setLoggedIn(b, !1), a && a( !! c) | |
}, c) | |
}, | |
setComputerOwnershipStatus: function (a, b, c) { | |
var f = d.userid(); | |
typeof f != "undefined" ? a ? (e.usersComputer.setConfirmed(f), d.prolongSession(b, c)) : (e.usersComputer.setDenied(f), l(b)) : l(c, "user is not authenticated") | |
}, | |
isUsersComputer: function (a, b) { | |
var c = d.userid(); | |
typeof c != "undefined" ? l(a, e.usersComputer.confirmed(c)) : l(b, "user is not authenticated") | |
}, | |
shouldAskIfUsersComputer: function (a, b) { | |
var c = d.userid(); | |
if (typeof c != "undefined") { | |
var f = e.usersComputer.shouldAsk(c) && !m; | |
l(a, f) | |
} else l(b, "user is not authenticated") | |
}, usedAddressAsPrimary: function (a, b, c) { | |
d.usedAddressAsPrimary(a, b, c) | |
} | |
}; | |
var C = window.location.protocol + "//" + window.location.hostname; | |
window.location.port && (C += ":" + window.location.port), g.setOrigin(C); | |
return g | |
}(), | |
function () { | |
function k() { | |
d.watchLoggedIn(f, j) | |
} | |
function j(a) { | |
i || c.getSilentAssertion(h, function (b, c) { | |
h === b ? e.notify({ | |
method: "match" | |
}) : b ? (c && e.notify({ | |
method: "login", | |
params: c | |
}), h = b) : h !== null && (e.notify({ | |
method: "logout" | |
}), h = null), a && a() | |
}, function (b) { | |
e.notify({ | |
method: "logout" | |
}), h = null, a && a() | |
}) | |
} | |
function g(a) { | |
f || (f = a, c.setOrigin(f)) | |
} | |
var a = BrowserID, | |
b = a.Network, | |
c = a.User, | |
d = a.Storage; | |
d.setDefaultValues(), b.init(), b.cookiesEnabledOverride = !0; | |
var e = Channel.build({ | |
window: window.parent, | |
origin: "*", | |
scope: "mozid_ni" | |
}), | |
f, h, i = !1; | |
e.bind("loggedInUser", function (a, b) { | |
h = b | |
}), e.bind("loaded", function (a, b) { | |
a.delayReturn(!0), g(a.origin), j(function () { | |
k(), a.complete() | |
}) | |
}), e.bind("logout", function (a, b) { | |
g(a.origin), h !== null && (d.setLoggedIn(f, !1), h = null, e.notify({ | |
method: "logout" | |
})) | |
}), e.bind("dialog_running", function (a, b) { | |
i = !0 | |
}), e.bind("dialog_complete", function (a, c) { | |
i = !1, b.clearContext(), j() | |
}) | |
}() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment