1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-19 07:35:48 +02:00
bitwarden-browser/src/services/apiService.js

491 lines
18 KiB
JavaScript
Raw Normal View History

function ApiService(tokenService, appIdService, utilsService, logoutCallback) {
// Desktop
//this.baseUrl = 'http://localhost:4000';
2017-06-26 15:38:17 +02:00
//this.identityBaseUrl = 'http://localhost:33656';
// Desktop HTTPS
//this.baseUrl = 'https://localhost:44377';
//this.identityBaseUrl = 'https://localhost:44392';
// Desktop external
2017-06-06 03:15:27 +02:00
//this.baseUrl = 'http://192.168.1.6:4000';
//this.identityBaseUrl = 'http://192.168.1.6:33656';
// Preview
//this.baseUrl = 'https://preview-api.bitwarden.com';
//this.identityBaseUrl = 'https://preview-identity.bitwarden.com';
// Production
2017-06-06 03:15:27 +02:00
this.baseUrl = 'https://api.bitwarden.com';
this.identityBaseUrl = 'https://identity.bitwarden.com';
2016-09-03 06:38:27 +02:00
this.tokenService = tokenService;
this.logoutCallback = logoutCallback;
this.appIdService = appIdService;
this.utilsService = utilsService;
initApiService();
2016-09-03 06:38:27 +02:00
};
function initApiService() {
// Auth APIs
ApiService.prototype.postIdentityToken = function (tokenRequest, success, successWithTwoFactor, error) {
2017-01-18 05:07:46 +01:00
var self = this;
$.ajax({
type: 'POST',
url: self.identityBaseUrl + '/connect/token',
2017-01-18 05:07:46 +01:00
data: tokenRequest.toIdentityToken(),
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
dataType: 'json',
success: function (response) {
success(new IdentityTokenResponse(response));
},
error: function (jqXHR, textStatus, errorThrown) {
2017-01-25 06:34:57 +01:00
if (jqXHR.responseJSON && jqXHR.responseJSON.TwoFactorProviders &&
jqXHR.responseJSON.TwoFactorProviders.length) {
successWithTwoFactor();
}
else {
error(new ErrorResponse(jqXHR, true));
}
2017-01-18 05:07:46 +01:00
}
});
};
2016-09-03 07:13:09 +02:00
// Account APIs
2016-09-03 18:07:30 +02:00
ApiService.prototype.getAccountRevisionDate = function (success, error) {
var self = this;
handleTokenState(self).then(function (token) {
$.ajax({
type: 'GET',
url: self.baseUrl + '/accounts/revision-date?' + token,
dataType: 'json',
success: function (response) {
success(response);
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
});
};
2016-09-03 06:38:27 +02:00
ApiService.prototype.getProfile = function (success, error) {
var self = this;
handleTokenState(self).then(function (token) {
2016-09-03 06:38:27 +02:00
$.ajax({
type: 'GET',
url: self.baseUrl + '/accounts/profile?' + token,
2016-09-03 06:38:27 +02:00
dataType: 'json',
2016-09-03 07:13:09 +02:00
success: function (response) {
2016-09-22 20:16:24 +02:00
success(new ProfileResponse(response));
2016-09-03 07:13:09 +02:00
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-03 07:13:09 +02:00
}
2016-09-03 06:38:27 +02:00
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
2016-09-03 06:38:27 +02:00
});
};
2016-09-03 07:13:09 +02:00
ApiService.prototype.getKeys = function (success, error) {
var self = this;
handleTokenState(self).then(function (token) {
$.ajax({
type: 'GET',
url: self.baseUrl + '/accounts/keys?' + token,
dataType: 'json',
success: function (response) {
success(new KeysResponse(response));
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
});
};
2016-09-20 23:47:21 +02:00
ApiService.prototype.postPasswordHint = function (request, success, error) {
var self = this;
$.ajax({
type: 'POST',
url: self.baseUrl + '/accounts/password-hint',
2016-12-29 22:09:28 +01:00
dataType: 'text',
2016-09-20 23:47:21 +02:00
data: JSON.stringify(request),
2016-09-21 01:57:24 +02:00
contentType: 'application/json; charset=utf-8',
2016-09-20 23:47:21 +02:00
success: function (response) {
success();
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-20 23:47:21 +02:00
}
});
};
2016-09-21 01:57:24 +02:00
ApiService.prototype.postRegister = function (request, success, error) {
2016-09-20 23:47:21 +02:00
var self = this;
$.ajax({
type: 'POST',
url: self.baseUrl + '/accounts/register',
data: JSON.stringify(request),
2016-12-29 22:09:28 +01:00
dataType: 'text',
2016-09-21 01:57:24 +02:00
contentType: 'application/json; charset=utf-8',
2016-09-20 23:47:21 +02:00
success: function (response) {
success();
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-20 23:47:21 +02:00
}
});
};
2017-01-14 17:20:44 +01:00
// Settings APIs
ApiService.prototype.getIncludedDomains = function (success, error) {
var self = this;
handleTokenState(self).then(function (token) {
2017-01-14 17:20:44 +01:00
$.ajax({
type: 'GET',
url: self.baseUrl + '/settings/domains?excluded=false&' + token,
2017-01-14 17:20:44 +01:00
dataType: 'json',
success: function (response) {
success(new DomainsResponse(response));
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2017-01-14 17:20:44 +01:00
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
2017-01-14 17:20:44 +01:00
});
};
2017-01-04 00:40:07 +01:00
// Login APIs
2016-09-03 07:13:09 +02:00
2017-01-04 00:40:07 +01:00
ApiService.prototype.getLogin = function (id, success, error) {
2016-09-03 18:07:30 +02:00
var self = this;
handleTokenState(self).then(function (token) {
2016-09-03 18:07:30 +02:00
$.ajax({
type: 'GET',
2017-06-16 18:35:46 +02:00
url: self.baseUrl + '/logins/' + id + '?' + token,
2016-09-03 18:07:30 +02:00
dataType: 'json',
success: function (response) {
2017-01-04 00:40:07 +01:00
success(new LoginResponse(response));
2016-09-03 18:07:30 +02:00
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-03 18:07:30 +02:00
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
2016-09-03 18:07:30 +02:00
});
};
2017-01-04 00:40:07 +01:00
ApiService.prototype.postLogin = function (loginRequest, success, error) {
2016-09-03 18:07:30 +02:00
var self = this;
handleTokenState(self).then(function (token) {
2016-09-03 18:07:30 +02:00
$.ajax({
type: 'POST',
2017-06-16 18:35:46 +02:00
url: self.baseUrl + '/logins?' + token,
2017-01-04 00:40:07 +01:00
data: JSON.stringify(loginRequest),
2016-09-21 01:57:24 +02:00
contentType: 'application/json; charset=utf-8',
2016-09-03 18:07:30 +02:00
dataType: 'json',
success: function (response) {
2017-01-04 00:40:07 +01:00
success(new LoginResponse(response));
2016-09-03 18:07:30 +02:00
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-03 18:07:30 +02:00
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
2016-09-03 18:07:30 +02:00
});
};
2017-01-04 00:40:07 +01:00
ApiService.prototype.putLogin = function (id, loginRequest, success, error) {
2016-09-03 18:07:30 +02:00
var self = this;
handleTokenState(self).then(function (token) {
2016-09-03 18:07:30 +02:00
$.ajax({
type: 'POST',
2017-06-16 18:35:46 +02:00
url: self.baseUrl + '/logins/' + id + '?' + token,
2017-01-04 00:40:07 +01:00
data: JSON.stringify(loginRequest),
2016-09-21 01:57:24 +02:00
contentType: 'application/json; charset=utf-8',
2016-09-03 18:07:30 +02:00
dataType: 'json',
success: function (response) {
2017-01-04 00:40:07 +01:00
success(new LoginResponse(response));
2016-09-03 18:07:30 +02:00
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-03 18:07:30 +02:00
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
2016-09-03 18:07:30 +02:00
});
};
2016-09-03 07:13:09 +02:00
// Folder APIs
2016-09-03 18:07:30 +02:00
ApiService.prototype.getFolder = function (id, success, error) {
var self = this;
handleTokenState(self).then(function (token) {
2016-09-03 18:07:30 +02:00
$.ajax({
type: 'GET',
url: self.baseUrl + '/folders/' + id + '?' + token,
2016-09-03 18:07:30 +02:00
dataType: 'json',
success: function (response) {
2016-09-22 20:16:24 +02:00
success(new FolderResponse(response));
2016-09-03 18:07:30 +02:00
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-03 18:07:30 +02:00
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
});
2016-09-03 18:07:30 +02:00
};
2017-04-24 17:08:32 +02:00
ApiService.prototype.getFolders = function (success, error) {
var self = this;
handleTokenState(self).then(function (token) {
$.ajax({
type: 'GET',
url: self.baseUrl + '/folders?' + token,
2017-04-24 17:08:32 +02:00
dataType: 'json',
success: function (response) {
var data = [];
for (var i = 0; i < response.Data.length; i++) {
data.push(new FolderResponse(response.Data[i]));
}
success(new ListResponse(data));
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
});
};
2016-09-03 18:07:30 +02:00
ApiService.prototype.postFolder = function (folderRequest, success, error) {
var self = this;
handleTokenState(self).then(function (token) {
2016-09-03 18:07:30 +02:00
$.ajax({
type: 'POST',
url: self.baseUrl + '/folders?' + token,
data: JSON.stringify(folderRequest),
2016-09-21 01:57:24 +02:00
contentType: 'application/json; charset=utf-8',
2016-09-03 18:07:30 +02:00
dataType: 'json',
success: function (response) {
2016-09-22 20:16:24 +02:00
success(new FolderResponse(response));
2016-09-03 18:07:30 +02:00
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-03 18:07:30 +02:00
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
2016-09-03 18:07:30 +02:00
});
};
ApiService.prototype.putFolder = function (id, folderRequest, success, error) {
var self = this;
handleTokenState(self).then(function (token) {
2016-09-03 18:07:30 +02:00
$.ajax({
type: 'POST',
url: self.baseUrl + '/folders/' + id + '?' + token,
data: JSON.stringify(folderRequest),
2016-09-21 01:57:24 +02:00
contentType: 'application/json; charset=utf-8',
2016-09-03 18:07:30 +02:00
dataType: 'json',
success: function (response) {
2016-09-22 20:16:24 +02:00
success(new FolderResponse(response));
2016-09-03 18:07:30 +02:00
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-03 18:07:30 +02:00
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
2016-09-03 18:07:30 +02:00
});
};
2016-09-03 07:13:09 +02:00
// Cipher APIs
2016-09-03 18:07:30 +02:00
2016-09-03 07:13:09 +02:00
ApiService.prototype.getCipher = function (id, success, error) {
var self = this;
handleTokenState(self).then(function (token) {
2016-09-03 07:13:09 +02:00
$.ajax({
type: 'GET',
url: self.baseUrl + '/ciphers/' + id + '?' + token,
2016-09-03 07:13:09 +02:00
dataType: 'json',
success: function (response) {
2016-09-22 20:16:24 +02:00
success(new CipherResponse(response));
2016-09-03 07:13:09 +02:00
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-03 07:13:09 +02:00
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
2016-09-03 07:13:09 +02:00
});
};
ApiService.prototype.getCiphers = function (success, error) {
var self = this;
handleTokenState(self).then(function (token) {
2016-09-03 07:13:09 +02:00
$.ajax({
type: 'GET',
url: self.baseUrl + '/ciphers?includeFolders=false&includeShared=true&' + token,
2016-09-03 07:13:09 +02:00
dataType: 'json',
success: function (response) {
var data = [];
2016-09-07 05:30:49 +02:00
for (var i = 0; i < response.Data.length; i++) {
data.push(new CipherResponse(response.Data[i]));
2016-09-03 07:13:09 +02:00
}
2016-09-22 20:16:24 +02:00
success(new ListResponse(data));
2016-09-03 07:13:09 +02:00
},
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-03 07:13:09 +02:00
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
2016-09-03 07:13:09 +02:00
});
};
2016-09-03 18:07:30 +02:00
ApiService.prototype.deleteCipher = function (id, success, error) {
var self = this;
handleTokenState(self).then(function (token) {
2016-09-03 18:07:30 +02:00
$.ajax({
type: 'POST',
url: self.baseUrl + '/ciphers/' + id + '/delete?' + token,
2016-12-29 22:09:28 +01:00
dataType: 'text',
2016-09-22 20:16:24 +02:00
success: function (response) {
success();
},
2016-09-03 18:07:30 +02:00
error: function (jqXHR, textStatus, errorThrown) {
handleError(error, jqXHR, false, self);
2016-09-03 18:07:30 +02:00
}
});
}, function (jqXHR) {
handleError(error, jqXHR, true, self);
2016-09-03 18:07:30 +02:00
});
};
// Helpers
function handleError(errorCallback, jqXHR, tokenError, self) {
2017-03-16 00:26:16 +01:00
if (jqXHR && (tokenError && jqXHR.status === 400) || jqXHR.status === 401 || jqXHR.status === 403) {
console.log('Logging out from apiService at ' + new Date() + '. Reason: Status ' + jqXHR.status + '.');
console.log(jqXHR);
if (self && self.logoutCallback) {
self.logoutCallback(true, function () { })
}
else {
chrome.runtime.sendMessage({ command: 'logout', expired: true });
}
2016-09-21 21:21:50 +02:00
return;
}
2016-09-03 07:13:09 +02:00
errorCallback(new ErrorResponse(jqXHR));
}
function handleTokenState(self) {
var deferred = Q.defer();
2017-01-22 04:00:02 +01:00
self.tokenService.getAuthBearer(function (authBearer) {
self.tokenService.getToken(function (accessToken) {
// handle transferring from old auth bearer
if (authBearer && !accessToken) {
self.appIdService.getAppId(function (appId) {
postConnectToken(self, {
grant_type: 'password',
oldAuthBearer: authBearer,
username: 'abcdefgh', // has to be something
password: 'abcdefgh', // has to be something
scope: 'api offline_access',
client_id: 'browser',
deviceIdentifier: appId,
deviceType: self.utilsService.getDeviceType(),
deviceName: self.utilsService.getBrowser()
}, function (token) {
self.tokenService.clearAuthBearer(function () {
tokenService.setTokens(token.accessToken, token.refreshToken, function () {
resolveTokenQs(token.accessToken, self, deferred);
});
2017-01-22 04:00:02 +01:00
});
}, function (jqXHR) {
deferred.reject(jqXHR);
2017-01-22 04:00:02 +01:00
});
});
} // handle token refresh
else if (self.tokenService.tokenNeedsRefresh()) {
self.tokenService.getRefreshToken(function (refreshToken) {
if (!refreshToken || refreshToken === '') {
deferred.reject();
return;
}
2017-01-22 04:07:08 +01:00
postConnectToken(self, {
grant_type: 'refresh_token',
client_id: 'browser',
refresh_token: refreshToken
2017-01-22 04:00:02 +01:00
}, function (token) {
tokenService.setTokens(token.accessToken, token.refreshToken, function () {
resolveTokenQs(token.accessToken, self, deferred);
});
2017-01-22 04:00:02 +01:00
}, function (jqXHR) {
deferred.reject(jqXHR);
2017-01-22 04:00:02 +01:00
});
});
2017-01-22 04:00:02 +01:00
}
else {
if (authBearer) {
self.tokenService.clearAuthBearer(function () { });
}
resolveTokenQs(accessToken, self, deferred);
2017-01-22 04:00:02 +01:00
}
});
});
return deferred.promise
}
2017-01-22 04:00:02 +01:00
function resolveTokenQs(token, self, deferred) {
var issuer = self.tokenService.getIssuer();
if (issuer === self.baseUrl) {
deferred.resolve('access_token2=' + token);
}
else {
deferred.resolve('access_token3=' + token);
}
}
2017-01-22 04:07:08 +01:00
function postConnectToken(self, data, success, error) {
2017-01-22 04:00:02 +01:00
$.ajax({
type: 'POST',
url: self.identityBaseUrl + '/connect/token',
2017-01-22 04:00:02 +01:00
data: data,
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
dataType: 'json',
success: function (response) {
success(new IdentityTokenResponse(response));
},
error: function (jqXHR, textStatus, errorThrown) {
error(jqXHR);
}
});
}
};