Skip to content

Instantly share code, notes, and snippets.

@seanmonstar
Last active December 17, 2015 05:49
Show Gist options
  • Save seanmonstar/5561248 to your computer and use it in GitHub Desktop.
Save seanmonstar/5561248 to your computer and use it in GitHub Desktop.
navigator.id.experimental.login()
/*global setTimeout:true, navigator:true*/
/*
* navigator.id.experimental.login(options)
* - takes same options as navigator.id.request()
* - returns a Promise
* : navigator.id.experimental.login({ siteName: 'Foo"})
* .then(verifyAssertion, onCancel);
*
* navigator.id.experimental.automatic([function])
* - takes an optional callback function
* - only triggers if the user is returning from verifying their email
* - should be always called at page load
* : navigator.id.experimental.automatic(verifyAssertion)
*
*/
(function() {
if (!navigator.id || !navigator.id.watch) throw new Error('navigator.id.watch is missing!');
if (!navigator.id.experimental) navigator.id.experimental = {};
function isFunction(val) {
return typeof val === 'function';
}
function Deferred() {
this.promise = new Promise();
}
Deferred.prototype = {
resolve: function resolve(value) {
this.promise._resolve(value);
},
reject: function reject(reason) {
this.promise._reject(reason);
}
};
function Promise(resolver) {
this._resolveListeners = [];
this._rejectListeners = [];
this._fulfilled = false;
}
Promise.prototype = {
then: function then(onResolve, onReject) {
var deferred = new Deferred();
if (isFunction(onResolve)) {
this._resolveListeners.push(function deferred_onResolve(value) {
promisize(deferred, onResolve, value);
});
}
if (isFunction(onReject)) {
this._rejectListeners.push(function deferred_onReject(reason) {
promisize(deferred, onReject, reason);
});
}
if (this._fulfilled) {
this._schedule();
}
return deferred.promise;
},
_resolve: function _resolve(value) {
var promise = this;
if (this._fulfilled) return;
this._value = value;
this._schedule();
},
_reject: function _reject(reason) {
var promise = this;
if (this._fulfilled) return;
this._reason = reason;
this._schedule();
},
_schedule: function _schedule() {
if (this._scheduled) return;
this._scheduled = true;
var promise = this;
setTimeout(function() {
promise._scheduled = undefined;
promise._fulfill();
}, 0);
},
_fulfill: function _fulfill() {
this._fulfilled = true;
var listeners = this._reason ? this._rejectListeners : this._resolveListeners;
var listener;
while (listener = listeners.shift()) {
listener(this._reason || this._value);
}
}
};
function promisize(deferred, func, value) {
var retVal;
try {
retVal = func(value);
} catch (ex) {
deferred.reject(ex);
}
if (retVal && (isFunction(retVal.then))) {
retVal.then(function deferred_promise_resolve(val) {
deferred.resolve(val);
}, function deferred_promise_reject(reason) {
deferred.reject(reason);
});
} else {
deferred.resolve(retVal);
}
}
function noop() {}
var onRedirect, isAutomatic = false;
function watch() {
navigator.id.watch({
onlogin: function promised_watch(assertion) {
if (isAutomatic && isFunction(onRedirect)) {
onRedirect(assertion);
onRedirect = undefined;
}
},
onlogout: noop
});
}
navigator.id.experimental.login = function login(options) {
if (!options) options = {};
var deferred = new Deferred();
var onLogin = function(assertion) {
deferred.resolve(assertion);
};
options.oncancel = function() {
deferred.reject(new Error('Cancelled'));
};
navigator.id.get(onLogin, options);
return deferred.promise;
};
navigator.id.experimental.automatic = function automatic(func) {
isAutomatic = true;
onRedirect = func
watch();
};
})();
@mattbasta
Copy link

Is navigator.id.get a thing? Can that be used safely? :O

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment