bitwarden-estensione-browser/src/services/tokenService.js

248 lines
6.7 KiB
JavaScript

function TokenService(utilsService) {
this.utilsService = utilsService;
initTokenService();
}
function initTokenService() {
var _token,
_decodedToken,
_refreshToken;
TokenService.prototype.setTokens = function (accessToken, refreshToken, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
var self = this;
self.setToken(accessToken, function () {
self.setRefreshToken(refreshToken, function () {
callback();
});
});
};
TokenService.prototype.setToken = function (token, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
_token = token;
_decodedToken = null;
chrome.storage.local.set({
'accessToken': token
}, function () {
callback();
});
};
TokenService.prototype.getToken = function (callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
if (_token) {
return callback(_token);
}
chrome.storage.local.get('accessToken', function (obj) {
if (obj && obj.accessToken) {
_token = obj.accessToken;
}
return callback(_token);
});
};
TokenService.prototype.setRefreshToken = function (refreshToken, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
_refreshToken = refreshToken;
chrome.storage.local.set({
'refreshToken': refreshToken
}, function () {
callback();
});
};
TokenService.prototype.getRefreshToken = function (callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
if (_refreshToken) {
return callback(_refreshToken);
}
chrome.storage.local.get('refreshToken', function (obj) {
if (obj && obj.refreshToken) {
_refreshToken = obj.refreshToken;
}
return callback(_refreshToken);
});
};
TokenService.prototype.setTwoFactorToken = function (token, email, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
var obj = {};
obj['twoFactorToken_' + email] = token;
chrome.storage.local.set(obj, function () {
callback();
});
};
TokenService.prototype.getTwoFactorToken = function (email) {
return this.utilsService.getObjFromStorage('twoFactorToken_' + email).then(function (token) {
return token;
});
};
TokenService.prototype.clearTwoFactorToken = function (email, callback) {
if (!callback || typeof callback !== 'function') {
throw 'callback function required';
}
chrome.storage.local.remove('twoFactorToken_' + email, function () {
callback();
});
};
TokenService.prototype.clearToken = function () {
var self = this;
return Q.all([
self.utilsService.removeFromStorage('accessToken'),
self.utilsService.removeFromStorage('refreshToken')
]).then(function () {
_token = _decodedToken = _refreshToken = null;
});
};
// jwthelper methods
// ref https://github.com/auth0/angular-jwt/blob/master/src/angularJwt/services/jwt.js
TokenService.prototype.decodeToken = function () {
if (_decodedToken) {
return _decodedToken;
}
if (!_token) {
throw 'Token not found.';
}
var parts = _token.split('.');
if (parts.length !== 3) {
throw 'JWT must have 3 parts';
}
var decoded = urlBase64Decode(parts[1]);
if (!decoded) {
throw 'Cannot decode the token';
}
_decodedToken = JSON.parse(decoded);
return _decodedToken;
};
TokenService.prototype.getTokenExpirationDate = function () {
var decoded = this.decodeToken();
if (typeof decoded.exp === 'undefined') {
return null;
}
var d = new Date(0); // The 0 here is the key, which sets the date to the epoch
d.setUTCSeconds(decoded.exp);
return d;
};
TokenService.prototype.tokenSecondsRemaining = function (offsetSeconds) {
var d = this.getTokenExpirationDate();
offsetSeconds = offsetSeconds || 0;
if (d === null) {
return 0;
}
var msRemaining = d.valueOf() - (new Date().valueOf() + (offsetSeconds * 1000));
return Math.round(msRemaining / 1000);
};
TokenService.prototype.tokenNeedsRefresh = function (minutes) {
minutes = minutes || 5; // default 5 minutes
var sRemaining = this.tokenSecondsRemaining();
return sRemaining < (60 * minutes);
};
TokenService.prototype.getUserId = function () {
var decoded = this.decodeToken();
if (typeof decoded.sub === 'undefined') {
throw 'No user id found';
}
return decoded.sub;
};
TokenService.prototype.getEmail = function () {
var decoded = this.decodeToken();
if (typeof decoded.email === 'undefined') {
throw 'No email found';
}
return decoded.email;
};
TokenService.prototype.getName = function () {
var decoded = this.decodeToken();
if (typeof decoded.name === 'undefined') {
throw 'No name found';
}
return decoded.name;
};
TokenService.prototype.getPremium = function () {
var decoded = this.decodeToken();
if (typeof decoded.premium === 'undefined') {
return false;
}
return !!decoded.premium;
};
TokenService.prototype.getIssuer = function () {
var decoded = this.decodeToken();
if (typeof decoded.iss === 'undefined') {
throw 'No issuer found';
}
return decoded.iss;
};
function urlBase64Decode(str) {
var output = str.replace(/-/g, '+').replace(/_/g, '/');
switch (output.length % 4) {
case 0: { break; }
case 2: { output += '=='; break; }
case 3: { output += '='; break; }
default: {
throw 'Illegal base64url string!';
}
}
//polyfill https://github.com/davidchambers/Base64.js
return window.decodeURIComponent(escape(window.atob(output)));
}
}