diff --git a/README.md b/README.md index 05e632f..23ff3c0 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,8 @@ Supported services Ninja Blocks (by [thatguydan](https://github.com/thatguydan)) + Visual Studio Online (by [asureddi](https://github.com/asureddi)) + Installation and Setup ---------------------- diff --git a/lib/assets/vso.PNG b/lib/assets/vso.PNG new file mode 100644 index 0000000..1dd8e3d Binary files /dev/null and b/lib/assets/vso.PNG differ diff --git a/lib/services/oauth2.js b/lib/services/oauth2.js index b6210ee..45e23c6 100644 --- a/lib/services/oauth2.js +++ b/lib/services/oauth2.js @@ -88,7 +88,11 @@ OAuth2.prototype.onStart = function(req, res) { } OAuth2.prototype.onCode = function(req, res) { - this.token.query.code = req.url.query.code + if (this.token.host == "app.vssps.visualstudio.com"){ + this.token.query.assertion = req.url.query.code + }else { + this.token.query.code = req.url.query.code + } delete req.url.query delete req.url.search @@ -101,17 +105,24 @@ OAuth2.prototype.onCode = function(req, res) { var tokenKey = this.user.tokenKey || "access_token" this.user.query[tokenKey] = data.access_token - + if (this.user.host == "oauth.reddit.com") { this.user.headers = {"Authorization": "bearer " + data.access_token}; } - + if (this.user.host == "api.stripe.com") { delete this.user.query[tokenKey]; this.user.headers = {"Authorization": "bearer " + data.access_token}; var stripe_publishable_key = data.stripe_publishable_key; } + if (this.user.host == "app.vssps.visualstudio.com") { + delete this.user.query[tokenKey]; + this.user.headers = {"Authorization": "bearer " + data.access_token, + "accept": "application/json; api-version=1.0", + "content-type": "application/json-patch+json "}; + } + this.request(this.user, function(err, user) { if (err) return this.emit("error", req, res, err) diff --git a/lib/services/vso.js b/lib/services/vso.js new file mode 100644 index 0000000..bdff7ba --- /dev/null +++ b/lib/services/vso.js @@ -0,0 +1,44 @@ +var OAuth2 = require("./oauth2") + , util = require("util") + +function vso(options) { + this.code.query = { + client_id: options.id, + response_type: "Assertion", + scope: options.scope + } + + this.token.query = { + client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", + client_assertion: options.secret, + grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", + assertion: "" + } + + this.user.query = {} + + this.on("request", this.onRequest.bind(this)) + + OAuth2.call(this, options) +} + +util.inherits(vso, OAuth2) + +vso.prototype.code = { + protocol: "https", + host: "app.vssps.visualstudio.com", + pathname: "/oauth2/authorize" +} + +vso.prototype.token = { + method: "POST", + host: "app.vssps.visualstudio.com", + path: "/oauth2/token", + headers: { "Content-Type": "application/x-www-form-urlencoded" } +} + +vso.prototype.user = { + host: "app.vssps.visualstudio.com", + path: "/_apis/profile/profiles/me?api-version=1.0" +} +module.exports = vso