1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-04 13:44:00 +01:00
bitwarden-browser/src/app/services/authService.js
2017-10-12 23:35:58 -04:00

252 lines
9.2 KiB
JavaScript

angular
.module('bit.services')
.factory('authService', function (cryptoService, apiService, tokenService, $q, jwtHelper, $rootScope, constants) {
var _service = {},
_userProfile = null;
_service.logIn = function (email, masterPassword, token, provider, remember) {
email = email.toLowerCase();
var deferred = $q.defer();
var makeResult;
cryptoService.makeKeyAndHash(email, masterPassword).then(function (result) {
makeResult = result;
var request = {
username: email,
password: result.hash,
grant_type: 'password',
scope: 'api offline_access',
client_id: 'web'
};
// TODO: device information one day?
if (token && typeof (provider) !== 'undefined' && provider !== null) {
remember = remember || remember !== false;
request.twoFactorToken = token;
request.twoFactorProvider = provider;
request.twoFactorRemember = remember ? '1' : '0';
}
else if (tokenService.getTwoFactorToken(email)) {
request.twoFactorToken = tokenService.getTwoFactorToken(email);
request.twoFactorProvider = constants.twoFactorProvider.remember;
request.twoFactorRemember = '0';
}
return apiService.identity.token(request).$promise;
}).then(function (response) {
if (!response || !response.access_token) {
return;
}
tokenService.setToken(response.access_token);
tokenService.setRefreshToken(response.refresh_token);
cryptoService.setKey(makeResult.key);
if (response.TwoFactorToken) {
tokenService.setTwoFactorToken(response.TwoFactorToken, email);
}
if (response.Key) {
cryptoService.setEncKey(response.Key, makeResult.key);
}
if (response.PrivateKey) {
cryptoService.setPrivateKey(response.PrivateKey);
return true;
}
else {
return cryptoService.makeKeyPair();
}
}).then(function (keyResults) {
if (keyResults === true) {
return;
}
cryptoService.setPrivateKey(keyResults.privateKeyEnc);
return apiService.accounts.putKeys({
publicKey: keyResults.publicKey,
encryptedPrivateKey: keyResults.privateKeyEnc
}).$promise;
}).then(function () {
return _service.setUserProfile();
}).then(function () {
deferred.resolve();
}, function (error) {
_service.logOut();
if (error.status === 400 && error.data.TwoFactorProviders2 &&
Object.keys(error.data.TwoFactorProviders2).length) {
tokenService.clearTwoFactorToken(email);
deferred.resolve(error.data.TwoFactorProviders2);
}
else {
deferred.reject(error);
}
});
return deferred.promise;
};
_service.logOut = function () {
tokenService.clearTokens();
cryptoService.clearKeys();
$rootScope.vaultFolders = $rootScope.vaultCiphers = null;
_userProfile = null;
};
_service.getUserProfile = function () {
if (!_userProfile) {
return _service.setUserProfile();
}
var deferred = $q.defer();
deferred.resolve(_userProfile);
return deferred.promise;
};
var _setDeferred = null;
_service.setUserProfile = function () {
if (_setDeferred && _setDeferred.promise.$$state.status === 0) {
return _setDeferred.promise;
}
_setDeferred = $q.defer();
var token = tokenService.getToken();
if (!token) {
_setDeferred.reject();
return _setDeferred.promise;
}
apiService.accounts.getProfile({}, function (profile) {
_userProfile = {
id: profile.Id,
email: profile.Email,
emailVerified: profile.EmailVerified,
premium: profile.Premium,
extended: {
name: profile.Name,
twoFactorEnabled: profile.TwoFactorEnabled,
culture: profile.Culture
}
};
if (profile.Organizations) {
var orgs = {};
for (var i = 0; i < profile.Organizations.length; i++) {
orgs[profile.Organizations[i].Id] = {
id: profile.Organizations[i].Id,
name: profile.Organizations[i].Name,
key: profile.Organizations[i].Key,
status: profile.Organizations[i].Status,
type: profile.Organizations[i].Type,
enabled: profile.Organizations[i].Enabled,
maxCollections: profile.Organizations[i].MaxCollections,
maxStorageGb: profile.Organizations[i].MaxStorageGb,
seats: profile.Organizations[i].Seats,
useGroups: profile.Organizations[i].UseGroups,
useTotp: profile.Organizations[i].UseTotp
};
}
_userProfile.organizations = orgs;
cryptoService.setOrgKeys(orgs);
_setDeferred.resolve(_userProfile);
}
}, function (error) {
_setDeferred.reject(error);
});
return _setDeferred.promise;
};
_service.addProfileOrganizationOwner = function (org, keyCt) {
return _service.getUserProfile().then(function (profile) {
if (profile) {
if (!profile.organizations) {
profile.organizations = {};
}
var o = {
id: org.Id,
name: org.Name,
key: keyCt,
status: 2, // 2 = Confirmed
type: 0, // 0 = Owner
enabled: true,
maxCollections: org.MaxCollections,
maxStorageGb: org.MaxStorageGb,
seats: org.Seats,
useGroups: org.UseGroups,
useTotp: org.UseTotp
};
profile.organizations[o.id] = o;
_userProfile = profile;
cryptoService.addOrgKey(o.id, o.key);
}
});
};
_service.removeProfileOrganization = function (orgId) {
return _service.getUserProfile().then(function (profile) {
if (profile) {
if (profile.organizations && profile.organizations.hasOwnProperty(orgId)) {
delete profile.organizations[orgId];
_userProfile = profile;
}
cryptoService.clearOrgKey(orgId);
}
});
};
_service.updateProfileOrganization = function (org) {
return _service.getUserProfile().then(function (profile) {
if (profile) {
if (profile.organizations && org.Id in profile.organizations) {
profile.organizations[org.Id].name = org.Name;
_userProfile = profile;
}
}
});
};
_service.updateProfilePremium = function (isPremium) {
return _service.getUserProfile().then(function (profile) {
if (profile) {
profile.premium = isPremium;
_userProfile = profile;
}
});
};
_service.isAuthenticated = function () {
return tokenService.getToken() !== null;
};
_service.refreshAccessToken = function () {
var refreshToken = tokenService.getRefreshToken();
if (!refreshToken) {
return null;
}
return apiService.identity.token({
grant_type: 'refresh_token',
client_id: 'web',
refresh_token: refreshToken
}).$promise.then(function (response) {
tokenService.setToken(response.access_token);
tokenService.setRefreshToken(response.refresh_token);
return response.access_token;
}, function (response) { });
};
return _service;
});