Merge branch 'v1.2'
This commit is contained in:
		
						commit
						e6fa1d5314
					
				| @ -706,7 +706,7 @@ | ||||
|       */ | ||||
|       return OAUTH3._browser.request(preq, opts); | ||||
|     } | ||||
|   , implicitGrant: function(directives, opts) { | ||||
|   , implicitGrant: function (directives, opts) { | ||||
|       var promise; | ||||
|       var providerUri = directives.azp || directives.issuer || directives; | ||||
| 
 | ||||
|  | ||||
| @ -8,6 +8,9 @@ | ||||
|     OAUTH3.crypto.core = require('./oauth3.node.crypto'); | ||||
|   } catch (error) { | ||||
|     OAUTH3.crypto.core = {}; | ||||
|     OAUTH3.crypto.core.ready = false; | ||||
|     var finishBeforeReady = []; | ||||
|     var deferedCalls = []; | ||||
| 
 | ||||
|     // We don't currently have a fallback method for this function, so we assign
 | ||||
|     // it directly to the core object instead of the webCrypto object.
 | ||||
| @ -17,10 +20,31 @@ | ||||
|     }; | ||||
| 
 | ||||
|     var webCrypto = {}; | ||||
| 
 | ||||
|     var deferCryptoCall = function(name) { | ||||
|       return function() { | ||||
|         var args = arguments; | ||||
|         return new OAUTH3.PromiseA(function(resolve, reject) { | ||||
|           deferedCalls.push(function(){ | ||||
|             try { | ||||
|               webCrypto[name].apply(webCrypto, args) | ||||
|                 .then(function(result){ | ||||
|                   resolve(result); | ||||
|                 }); | ||||
|             } catch(e) { | ||||
|               reject(e); | ||||
|             } | ||||
|           }); | ||||
|         }); | ||||
|       }; | ||||
|     }; | ||||
| 
 | ||||
|     OAUTH3.crypto.core.sha256 = deferCryptoCall("sha256"); | ||||
|     webCrypto.sha256 = function (buf) { | ||||
|       return OAUTH3._browser.window.crypto.subtle.digest({name: 'SHA-256'}, buf); | ||||
|     }; | ||||
| 
 | ||||
|     OAUTH3.crypto.core.pbkdf2 = deferCryptoCall("pbkdf2"); | ||||
|     webCrypto.pbkdf2 = function (password, salt) { | ||||
|       return OAUTH3._browser.window.crypto.subtle.importKey('raw', OAUTH3._binStr.binStrToBuffer(password), {name: 'PBKDF2'}, false, ['deriveKey']) | ||||
|         .then(function (key) { | ||||
| @ -32,12 +56,15 @@ | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     OAUTH3.crypto.core.encrypt = deferCryptoCall("encrypt"); | ||||
|     webCrypto.encrypt = function (rawKey, iv, data) { | ||||
|       return OAUTH3._browser.window.crypto.subtle.importKey('raw', rawKey, {name: 'AES-GCM'}, false, ['encrypt']) | ||||
|         .then(function (key) { | ||||
|           return OAUTH3._browser.window.crypto.subtle.encrypt({name: 'AES-GCM', iv: iv}, key, data); | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     OAUTH3.crypto.core.decrypt = deferCryptoCall("decrypt"); | ||||
|     webCrypto.decrypt = function (rawKey, iv, data) { | ||||
|       return OAUTH3._browser.window.crypto.subtle.importKey('raw', rawKey, {name: 'AES-GCM'}, false, ['decrypt']) | ||||
|         .then(function (key) { | ||||
| @ -45,6 +72,7 @@ | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     OAUTH3.crypto.core.genEcdsaKeyPair = deferCryptoCall("genEcdsaKeyPair"); | ||||
|     webCrypto.genEcdsaKeyPair = function () { | ||||
|       return OAUTH3._browser.window.crypto.subtle.generateKey({name: 'ECDSA', namedCurve: 'P-256'}, true, ['sign', 'verify']) | ||||
|         .then(function (keyPair) { | ||||
| @ -57,6 +85,7 @@ | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     OAUTH3.crypto.core.sign = deferCryptoCall("sign"); | ||||
|     webCrypto.sign = function (jwk, msg) { | ||||
|       return OAUTH3._browser.window.crypto.subtle.importKey('jwk', jwk, {name: 'ECDSA', namedCurve: jwk.crv}, false, ['sign']) | ||||
|         .then(function (key) { | ||||
| @ -66,6 +95,8 @@ | ||||
|           return new Uint8Array(sig); | ||||
|         }); | ||||
|     }; | ||||
|      | ||||
|     OAUTH3.crypto.core.verify = deferCryptoCall("verify"); | ||||
|     webCrypto.verify = function (jwk, msg, signature) { | ||||
|       // If the JWK has properties that should only exist on the private key or is missing
 | ||||
|       // "verify" in the key_ops, importing in as a public key won't work.
 | ||||
| @ -103,18 +134,19 @@ | ||||
|         return prom; | ||||
|       }; | ||||
|       function checkException(name, func) { | ||||
|         OAUTH3.PromiseA.resolve().then(func) | ||||
|         return OAUTH3.PromiseA.resolve().then(func) | ||||
|           .then(function () { | ||||
|             OAUTH3.crypto.core[name] = webCrypto[name]; | ||||
|           }, function (err) { | ||||
|             console.warn('error with WebCrypto', name, '- using fallback', err); | ||||
|             loadFallback().then(function () { | ||||
|             return loadFallback().then(function () { | ||||
|               OAUTH3.crypto.core[name] = OAUTH3_crypto_fallback[name]; | ||||
|             }); | ||||
|           }); | ||||
|       } | ||||
|       function checkResult(name, expected, func) { | ||||
|         checkException(name, function () { | ||||
|          | ||||
|         finishBeforeReady.push(checkException(name, function () { | ||||
|           return func() | ||||
|             .then(function (result) { | ||||
|               if (typeof expected === typeof result) { | ||||
| @ -127,7 +159,7 @@ | ||||
|                 throw new Error("result ("+result+") doesn't match expectation ("+expected+")"); | ||||
|               } | ||||
|             }); | ||||
|         }); | ||||
|         })); | ||||
|       } | ||||
| 
 | ||||
|       var zeroBuf = new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]); | ||||
| @ -159,12 +191,20 @@ | ||||
|         return webCrypto.verify(jwk, dataBuf, sig); | ||||
|       }); | ||||
|       // The results of these functions are less predictable, so we can't check their return value.
 | ||||
|       checkException('genEcdsaKeyPair', function () { | ||||
|       finishBeforeReady.push(checkException('genEcdsaKeyPair', function () { | ||||
|         return webCrypto.genEcdsaKeyPair(); | ||||
|       }); | ||||
|       checkException('sign', function () { | ||||
|       })); | ||||
|       finishBeforeReady.push(checkException('sign', function () { | ||||
|         return webCrypto.sign(jwk, dataBuf); | ||||
|       }); | ||||
|       })); | ||||
|        | ||||
|       OAUTH3.PromiseA.all(finishBeforeReady) | ||||
|         .then(function(results) { | ||||
|           OAUTH3.crypto.core.ready = true; | ||||
|           deferedCalls.forEach(function(request) { | ||||
|             request(); | ||||
|           }); | ||||
|         }); | ||||
|     } | ||||
|     checkWebCrypto(); | ||||
|   } | ||||
|  | ||||
| @ -192,8 +192,9 @@ OAUTH3.urls.grants = function (directive, opts) { | ||||
|   } | ||||
| 
 | ||||
|   var url = OAUTH3.url.resolve(directive.api, grantsDir.url) | ||||
|     .replace(/(:azp|:client_id)/g, OAUTH3.uri.normalize(opts.client_id || opts.client_uri)) | ||||
|     .replace(/(:sub|:account_id)/g, opts.session.token.sub || 'ISSUER:GRANT:TOKEN_SUB:UNDEFINED') | ||||
|     .replace(/(:azp|:client_id)/g, !opts.all && OAUTH3.uri.normalize(opts.client_id || opts.client_uri) || '') | ||||
|     .replace(/\/\/$/, '/') // if there's a double slash due to the sub not existing
 | ||||
|     ; | ||||
|   var data = { | ||||
|     client_id: opts.client_id | ||||
| @ -287,21 +288,25 @@ OAUTH3.urls.publishKey = function (directive, opts) { | ||||
|   , session: opts.session | ||||
|   }; | ||||
| }; | ||||
| OAUTH3.urls.credentialMeta = function (directive, opts) { | ||||
|   return OAUTH3.url.resolve(directive.api, directive.credential_meta.url) | ||||
|       .replace(':type', 'email') | ||||
|       .replace(':id', opts.email) | ||||
| }; | ||||
| 
 | ||||
| OAUTH3.authn = {}; | ||||
| OAUTH3.authn.loginMeta = function (directive, opts) { | ||||
|   var url = OAUTH3.urls.credentialMeta(directive, opts); | ||||
|   return OAUTH3.request({ | ||||
|     method: directive.credential_meta.method || 'GET' | ||||
|     // TODO lint urls
 | ||||
|     // TODO client_uri
 | ||||
|   , url: OAUTH3.url.resolve(directive.api, directive.credential_meta.url) | ||||
|       .replace(':type', 'email') | ||||
|       .replace(':id', opts.email) | ||||
|   , url: url | ||||
|   }); | ||||
| }; | ||||
| OAUTH3.authn.otp = function (directive, opts) { | ||||
| OAUTH3.urls.otp = function (directive, opts) { | ||||
|   // TODO client_uri
 | ||||
|   var preq = { | ||||
|   return { | ||||
|     method: directive.credential_otp.method || 'POST' | ||||
|   , url: OAUTH3.url.resolve(directive.api, directive.credential_otp.url) | ||||
|   , data: { | ||||
| @ -314,6 +319,9 @@ OAUTH3.authn.otp = function (directive, opts) { | ||||
|     , username: opts.email | ||||
|     } | ||||
|   }; | ||||
| }; | ||||
| OAUTH3.authn.otp = function (directive, opts) { | ||||
|   var preq = OAUTH3.urls.otp(directive, opts); | ||||
| 
 | ||||
|   return OAUTH3.request(preq); | ||||
| }; | ||||
| @ -425,7 +433,7 @@ OAUTH3.authz.grants = function (providerUri, opts) { | ||||
|     } | ||||
|     // the responses for GET and POST requests are now the same, so we should alway be able to
 | ||||
|     // use the response and save it the same way.
 | ||||
|     if ('GET' !== opts.method && 'POST' !== opts.method) { | ||||
|     if (opts.all || ('GET' !== opts.method && 'POST' !== opts.method)) { | ||||
|       return grants; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user