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