Comparing version 0.0.4 to 0.0.5
@@ -168,3 +168,3 @@ // Copyright 2014 Google Inc. All rights reserved | ||
setTimeout(function() { | ||
callback(new u2f.WrappedChromeRuntimePort_(port)); | ||
callback(null, new u2f.WrappedChromeRuntimePort_(port)); | ||
}, 0); | ||
@@ -223,2 +223,4 @@ }; | ||
var hasCalledBack = false; | ||
var channel = new MessageChannel(); | ||
@@ -228,3 +230,7 @@ var ready = function(message) { | ||
channel.port1.removeEventListener('message', ready); | ||
callback(channel.port1); | ||
if (!hasCalledBack) | ||
{ | ||
hasCalledBack = true; | ||
callback(null, channel.port1); | ||
} | ||
} else { | ||
@@ -241,2 +247,11 @@ console.error('First event on iframe port was not "ready"'); | ||
}); | ||
// Give this 200ms to initialize, after that, we treat this method as failed | ||
setTimeout(function() { | ||
if (!hasCalledBack) | ||
{ | ||
hasCalledBack = true; | ||
callback(new Error("IFrame extension not supported")); | ||
} | ||
}, 200); | ||
}; | ||
@@ -289,13 +304,15 @@ | ||
if (u2f.port_) { | ||
callback(u2f.port_); | ||
callback(null, u2f.port_); | ||
} else { | ||
if (u2f.waitingForPort_.length == 0) { | ||
u2f.getMessagePort(function(port) { | ||
u2f.port_ = port; | ||
u2f.port_.addEventListener('message', | ||
/** @type {function(Event)} */ (u2f.responseHandler_)); | ||
u2f.getMessagePort(function(err, port) { | ||
if (!err) { | ||
u2f.port_ = port; | ||
u2f.port_.addEventListener('message', | ||
/** @type {function(Event)} */ (u2f.responseHandler_)); | ||
} | ||
// Careful, here be async callbacks. Maybe. | ||
while (u2f.waitingForPort_.length) | ||
u2f.waitingForPort_.shift()(u2f.port_); | ||
u2f.waitingForPort_.shift()(err, port); | ||
}); | ||
@@ -321,6 +338,16 @@ } | ||
delete u2f.callbackMap_[reqId]; | ||
cb(response['responseData']); | ||
cb(null, response['responseData']); | ||
}; | ||
/** | ||
* Calls the callback with true or false as first and only argument | ||
* @param {Function} callback | ||
*/ | ||
u2f.isSupported = function(callback) { | ||
u2f.getPortSingleton_(function(err, port) { | ||
callback(!err); | ||
}); | ||
} | ||
/** | ||
* Dispatches an array of sign requests to available U2F tokens. | ||
@@ -332,3 +359,6 @@ * @param {Array.<u2f.SignRequest>} signRequests | ||
u2f.sign = function(signRequests, callback, opt_timeoutSeconds) { | ||
u2f.getPortSingleton_(function(port) { | ||
u2f.getPortSingleton_(function(err, port) { | ||
if (err) | ||
return callback(err); | ||
var reqId = ++u2f.reqCounter_; | ||
@@ -357,3 +387,6 @@ u2f.callbackMap_[reqId] = callback; | ||
callback, opt_timeoutSeconds) { | ||
u2f.getPortSingleton_(function(port) { | ||
u2f.getPortSingleton_(function(err, port) { | ||
if (err) | ||
return callback(err); | ||
var reqId = ++u2f.reqCounter_; | ||
@@ -360,0 +393,0 @@ u2f.callbackMap_[reqId] = callback; |
@@ -10,5 +10,7 @@ 'use strict'; | ||
return { | ||
register : register.bind( Promise ), | ||
sign : sign.bind( Promise ), | ||
ErrorCodes : API.ErrorCodes | ||
isSupported : isSupported.bind( Promise ), | ||
ensureSupport : ensureSupport.bind( Promise ), | ||
register : register.bind( Promise ), | ||
sign : sign.bind( Promise ), | ||
ErrorCodes : API.ErrorCodes | ||
}; | ||
@@ -47,3 +49,10 @@ } | ||
ret.reject = reject; | ||
fun && fun( resolve, reject ); | ||
try | ||
{ | ||
fun && fun( resolve, reject ); | ||
} | ||
catch ( err ) | ||
{ | ||
reject( err ); | ||
} | ||
} ); | ||
@@ -57,2 +66,20 @@ ret.promise.cancel = function( msg ) | ||
function isSupported( ) | ||
{ | ||
var Promise = this; | ||
return defer( Promise, coreApi.isSupported ).promise; | ||
} | ||
function ensureSupport( ) | ||
{ | ||
var Promise = this; | ||
return defer( Promise, coreApi.isSupported ).promise | ||
.then( function( value ) { | ||
if ( !value ) | ||
throw new Error( "U2F not supported" ); | ||
} ); | ||
} | ||
function register( registerRequests, signRequests /* = null */, timeout ) | ||
@@ -75,4 +102,6 @@ { | ||
return defer( Promise, function( resolve, reject ) { | ||
function cb( response ) { | ||
if ( response.errorCode ) | ||
function cb( err, response ) { | ||
if ( err ) | ||
reject( err ); | ||
else if ( response.errorCode ) | ||
reject( makeError( "Registration failed", response ) ); | ||
@@ -94,4 +123,6 @@ else | ||
return defer( Promise, function( resolve, reject ) { | ||
function cb( response ) { | ||
if ( response.errorCode ) | ||
function cb( err, response ) { | ||
if ( err ) | ||
reject( err ); | ||
else if ( response.errorCode ) | ||
reject( makeError( "Sign failed", response ) ); | ||
@@ -120,3 +151,5 @@ else | ||
// Provide default functions using the built-in Promise if available. | ||
makeDefault( 'isSupported' ); | ||
makeDefault( 'ensureSupport' ); | ||
makeDefault( 'register' ); | ||
makeDefault( 'sign' ); |
@@ -5,3 +5,3 @@ { | ||
"license": "MIT", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"author": "Gustaf Räntilä <g.rantila@gmail.com>", | ||
@@ -8,0 +8,0 @@ "repository": { |
@@ -7,8 +7,22 @@ # u2f-api | ||
### Support | ||
U2F is tested to work with newer versions of Chrome for Mac. It doesn't work very well with | ||
### Basics | ||
u2f-api exports two functions and an error "enum". The functions are `register()` and `sign()`. | ||
u2f-api exports two main functions and an error "enum". The main functions are `register()` and `sign()`, although since U2F isn't widely supported, the functions `isSupported()` as well as `ensureSupport()` helps you build applications which can use U2F only when the client supports it. | ||
The `register()` and `sign()` functions return *cancellable promises*, i.e. promises you can cancel manually. This helps you to ensure your code doesn't continue in success flow and by mistake accept a registration or authentification request. The returned promise has a function `cancel()` which will immediately reject the promise. | ||
#### Check or ensure support | ||
```js | ||
Promise{ Boolean } isSupported() // Doesn't throw/reject | ||
``` | ||
```js | ||
Promise{ undefined } ensureSupport() // Throws/rejects if not supported | ||
``` | ||
#### Register | ||
@@ -42,3 +56,3 @@ | ||
``` | ||
OK = 0 | ||
OK = 0 // u2f-api will never throw errors with this code | ||
OTHER_ERROR = 1 | ||
@@ -86,2 +100,20 @@ BAD_REQUEST = 2 | ||
### Example with checks for client support | ||
```js | ||
u2fApi.isSupported( ) | ||
.then( function( supported ) { | ||
if ( supported ) | ||
{ | ||
return u2fApi.sign( signRequestsFromServer ) | ||
.then( sendSignResponseToServer ) | ||
} | ||
else | ||
{ | ||
... // Other authentication method | ||
} | ||
} ) | ||
.catch( ... ); | ||
``` | ||
### Canceling | ||
@@ -88,0 +120,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19068
483
131