From cee9face7f01af130bcba2e8d7fa4d36ea1ec8e4 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Fri, 3 Nov 2017 20:53:35 +0100 Subject: [PATCH] [TypeScript] Popup app services (#353) * Convert services to typescript. * Change to for of. --- src/popup/app/app.js | 7 +- src/popup/app/services/auth.service.ts | 79 +++++++++++++++++ src/popup/app/services/authService.js | 90 -------------------- src/popup/app/services/background.service.ts | 24 ++++++ src/popup/app/services/backgroundService.js | 71 --------------- src/popup/app/services/services.module.js | 5 -- src/popup/app/services/services.module.ts | 31 +++++++ src/popup/app/services/validation.service.ts | 33 +++++++ src/popup/app/services/validationService.js | 42 --------- 9 files changed, 169 insertions(+), 213 deletions(-) create mode 100644 src/popup/app/services/auth.service.ts delete mode 100644 src/popup/app/services/authService.js create mode 100644 src/popup/app/services/background.service.ts delete mode 100644 src/popup/app/services/backgroundService.js delete mode 100644 src/popup/app/services/services.module.js create mode 100644 src/popup/app/services/services.module.ts create mode 100644 src/popup/app/services/validation.service.ts delete mode 100644 src/popup/app/services/validationService.js diff --git a/src/popup/app/app.js b/src/popup/app/app.js index c33cf3eb735..adc69617bf6 100644 --- a/src/popup/app/app.js +++ b/src/popup/app/app.js @@ -28,6 +28,7 @@ require('../less/popup.less'); import ComponentsModule from './components/components.module'; import ToolsModule from './tools/tools.module'; +import ServicesModule from './services/services.module'; // Model imports import { AttachmentData } from '../../models/data/attachmentData'; @@ -74,7 +75,7 @@ angular 'bit.directives', ComponentsModule, - 'bit.services', + ServicesModule, 'bit.global', 'bit.accounts', @@ -85,16 +86,12 @@ angular 'bit.lock' ]); -require('./services/services.module'); require('./config'); require('./directives/directivesModule.js'); require('./directives/formDirective.js'); require('./directives/stopClickDirective.js'); require('./directives/stopPropDirective.js'); require('./directives/fallbackSrcDirective.js'); -require('./services/backgroundService.js'); -require('./services/authService.js'); -require('./services/validationService.js'); require('./global/globalModule.js'); require('./global/mainController.js'); require('./global/tabsController.js'); diff --git a/src/popup/app/services/auth.service.ts b/src/popup/app/services/auth.service.ts new file mode 100644 index 00000000000..2cc44867cd2 --- /dev/null +++ b/src/popup/app/services/auth.service.ts @@ -0,0 +1,79 @@ +import { DeviceRequest } from '../../../models/request/deviceRequest'; +import { TokenRequest } from '../../../models/request/tokenRequest'; + +class AuthService { + + constructor(public cryptoService: any, public apiService: any, public userService: any, public tokenService: any, + public $rootScope: any, public appIdService: any, public utilsService: any, + public constantsService: any) { + + } + + async logIn(email: string, masterPassword: string, twoFactorProvider?: number, + twoFactorToken?: string, remember?: boolean) { + email = email.toLowerCase(); + + const key = this.cryptoService.makeKey(masterPassword, email); + const appId = await this.appIdService.getAppId(); + const storedTwoFactorToken = await this.tokenService.getTwoFactorToken(email); + const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key); + + const deviceRequest = new DeviceRequest(appId, this.utilsService); + + let request: TokenRequest; + + if (twoFactorToken != null && twoFactorProvider != null) { + request = new TokenRequest(email, hashedPassword, twoFactorProvider, twoFactorToken, remember, + deviceRequest); + } else if (storedTwoFactorToken) { + request = new TokenRequest(email, hashedPassword, this.constantsService.twoFactorProvider.remember, + storedTwoFactorToken, false, deviceRequest); + } else { + request = new TokenRequest(email, hashedPassword, null, null, false, deviceRequest); + } + + const response = await this.apiService.postIdentityToken(request); + if (!response) { + return; + } + + if (!response.accessToken) { + // two factor required + return { + twoFactor: true, + twoFactorProviders: response, + }; + } + + if (response.twoFactorToken) { + this.tokenService.setTwoFactorToken(response.twoFactorToken, email); + } + + await this.tokenService.setTokens(response.accessToken, response.refreshToken); + await this.cryptoService.setKey(key); + await this.cryptoService.setKeyHash(hashedPassword); + await this.setUserIdAndEmail(this.tokenService.getUserId(), this.tokenService.getEmail()); + await this.cryptoService.setEncKey(response.key); + await this.cryptoService.setEncPrivateKey(response.privateKey); + + chrome.runtime.sendMessage({ command: 'loggedIn' }); + return { + twoFactor: false, + twoFactorProviders: null, + }; + } + + setUserIdAndEmail(userId: any, email: any) { + return new Promise((resolve) => { + return this.userService.setUserIdAndEmail(userId, email, resolve); + }); + } + + logOut(callback: Function) { + this.$rootScope.vaultCiphers = null; + this.$rootScope.vaultFolders = null; + callback(); + } +} + +export default AuthService; diff --git a/src/popup/app/services/authService.js b/src/popup/app/services/authService.js deleted file mode 100644 index 1164961c941..00000000000 --- a/src/popup/app/services/authService.js +++ /dev/null @@ -1,90 +0,0 @@ -angular - .module('bit.services') - - .factory('authService', function (cryptoService, apiService, userService, tokenService, $q, $rootScope, - folderService, settingsService, syncService, appIdService, utilsService, constantsService) { - var _service = {}; - - _service.logIn = function (email, masterPassword, twoFactorProvider, twoFactorToken, remember) { - email = email.toLowerCase(); - var key = cryptoService.makeKey(masterPassword, email), - deferred = $q.defer(), - deviceRequest = null, - twoFactorRememberedToken, - hashedPassword; - - appIdService.getAppId().then(function (appId) { - deviceRequest = new DeviceRequest(appId, utilsService); - return tokenService.getTwoFactorToken(email); - }).then(function (theTwoFactorRememberedToken) { - twoFactorRememberedToken = theTwoFactorRememberedToken; - return cryptoService.hashPassword(masterPassword, key); - }).then(function (theHashedPassword) { - hashedPassword = theHashedPassword; - var request; - - if (twoFactorToken && typeof (twoFactorProvider) !== 'undefined' && twoFactorProvider !== null) { - request = new TokenRequest(email, hashedPassword, twoFactorProvider, twoFactorToken, remember, - deviceRequest); - } - else if (twoFactorRememberedToken) { - request = new TokenRequest(email, hashedPassword, constantsService.twoFactorProvider.remember, - twoFactorRememberedToken, false, deviceRequest); - } - else { - request = new TokenRequest(email, hashedPassword, null, null, false, deviceRequest); - } - - return apiService.postIdentityToken(request); - }).then(function (response) { - if (!response) { - return; - } - - if (!response.accessToken) { - // two factor required - deferred.resolve({ - twoFactor: true, - twoFactorProviders: response - }); - return; - } - - if (response.twoFactorToken) { - tokenService.setTwoFactorToken(response.twoFactorToken, email); - } - - return tokenService.setTokens(response.accessToken, response.refreshToken).then(function () { - return cryptoService.setKey(key); - }).then(function () { - return cryptoService.setKeyHash(hashedPassword); - }).then(function () { - userService.setUserIdAndEmail(tokenService.getUserId(), tokenService.getEmail(), - function () { - cryptoService.setEncKey(response.key).then(function () { - return cryptoService.setEncPrivateKey(response.privateKey); - }).then(function () { - chrome.runtime.sendMessage({ command: 'loggedIn' }); - deferred.resolve({ - twoFactor: false, - twoFactorProviders: null - }); - }); - }); - }); - }, function (error) { - // error - deferred.reject(error); - }); - - return deferred.promise; - }; - - _service.logOut = function (callback) { - $rootScope.vaultCiphers = null; - $rootScope.vaultFolders = null; - callback(); - }; - - return _service; - }); diff --git a/src/popup/app/services/background.service.ts b/src/popup/app/services/background.service.ts new file mode 100644 index 00000000000..517c5109e36 --- /dev/null +++ b/src/popup/app/services/background.service.ts @@ -0,0 +1,24 @@ +function getBackgroundService(service: string) { + return () => { + const page = chrome.extension.getBackgroundPage(); + return page ? page['bg_' + service] : null; + }; +} + +export const tokenService = getBackgroundService('tokenService'); +export const cryptoService = getBackgroundService('cryptoService'); +export const userService = getBackgroundService('userService'); +export const apiService = getBackgroundService('apiService'); +export const folderService = getBackgroundService('folderService'); +export const cipherService = getBackgroundService('cipherService'); +export const syncService = getBackgroundService('syncService'); +export const autofillService = getBackgroundService('autofillService'); +export const passwordGenerationService = getBackgroundService('passwordGenerationService'); +export const utilsService = getBackgroundService('utilsService'); +export const appIdService = getBackgroundService('appIdService'); +export const i18nService = getBackgroundService('i18nService'); +export const constantsService = getBackgroundService('constantsService'); +export const settingsService = getBackgroundService('settingsService'); +export const lockService = getBackgroundService('lockService'); +export const totpService = getBackgroundService('totpService'); +export const environmentService = getBackgroundService('environmentService'); diff --git a/src/popup/app/services/backgroundService.js b/src/popup/app/services/backgroundService.js deleted file mode 100644 index 009ef61d475..00000000000 --- a/src/popup/app/services/backgroundService.js +++ /dev/null @@ -1,71 +0,0 @@ -angular - .module('bit.services') - - .factory('tokenService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_tokenService : null; - }) - .factory('cryptoService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_cryptoService : null; - }) - .factory('userService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_userService : null; - }) - .factory('apiService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_apiService : null; - }) - .factory('folderService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_folderService : null; - }) - .factory('cipherService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_cipherService : null; - }) - .factory('syncService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_syncService : null; - }) - .factory('autofillService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_autofillService : null; - }) - .factory('passwordGenerationService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_passwordGenerationService : null; - }) - .factory('utilsService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_utilsService : null; - }) - .factory('appIdService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_appIdService : null; - }) - .factory('i18nService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_i18nService : null; - }) - .factory('constantsService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_constantsService : null; - }) - .factory('settingsService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_settingsService : null; - }) - .factory('lockService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_lockService : null; - }) - .factory('totpService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_totpService : null; - }) - .factory('environmentService', function () { - var page = chrome.extension.getBackgroundPage(); - return page ? page.bg_environmentService : null; - }); diff --git a/src/popup/app/services/services.module.js b/src/popup/app/services/services.module.js deleted file mode 100644 index 6b4b061f94c..00000000000 --- a/src/popup/app/services/services.module.js +++ /dev/null @@ -1,5 +0,0 @@ -import StateService from './state.service'; - -angular - .module('bit.services', ['toastr']) - .service('stateService', StateService); diff --git a/src/popup/app/services/services.module.ts b/src/popup/app/services/services.module.ts new file mode 100644 index 00000000000..051d4d60042 --- /dev/null +++ b/src/popup/app/services/services.module.ts @@ -0,0 +1,31 @@ +import * as angular from 'angular'; +import AuthService from './auth.service'; +import * as backgroundServices from './background.service'; +import StateService from './state.service'; +import ValidationService from './validation.service'; + +export default angular + .module('bit.services', ['toastr']) + .service('stateService', StateService) + .service('validationService', ValidationService) + .service('authService', AuthService) + + .factory('tokenService', backgroundServices.tokenService) + .factory('cryptoService', backgroundServices.cryptoService) + .factory('userService', backgroundServices.userService) + .factory('apiService', backgroundServices.apiService) + .factory('folderService', backgroundServices.folderService) + .factory('cipherService', backgroundServices.cipherService) + .factory('syncService', backgroundServices.syncService) + .factory('autofillService', backgroundServices.autofillService) + .factory('passwordGenerationService', backgroundServices.passwordGenerationService) + .factory('utilsService', backgroundServices.utilsService) + .factory('appIdService', backgroundServices.appIdService) + .factory('i18nService', backgroundServices.i18nService) + .factory('constantsService', backgroundServices.constantsService) + .factory('settingsService', backgroundServices.settingsService) + .factory('lockService', backgroundServices.lockService) + .factory('totpService', backgroundServices.totpService) + .factory('environmentService', backgroundServices.environmentService) + + .name; diff --git a/src/popup/app/services/validation.service.ts b/src/popup/app/services/validation.service.ts new file mode 100644 index 00000000000..4f82767102d --- /dev/null +++ b/src/popup/app/services/validation.service.ts @@ -0,0 +1,33 @@ +import * as angular from 'angular'; + +class ValidationService { + + constructor(private toastr: any, private i18nService: any) { + } + + showError(data: any) { + const defaultErrorMessage = this.i18nService.unexpectedError; + const errors: string[] = []; + + if (!data || !angular.isObject(data)) { + errors.push(defaultErrorMessage); + } else if (!data.validationErrors) { + errors.push(data.message ? data.message : defaultErrorMessage); + } else { + for (const error of data.validationErrors) { + error.forEach((item: string) => { + errors.push(item); + }); + } + } + + if (errors.length) { + this.toastr.error(errors[0], this.i18nService.errorsOccurred); + } + + return errors; + } + +} + +export default ValidationService; diff --git a/src/popup/app/services/validationService.js b/src/popup/app/services/validationService.js deleted file mode 100644 index 0d6ce03c4b7..00000000000 --- a/src/popup/app/services/validationService.js +++ /dev/null @@ -1,42 +0,0 @@ -angular - .module('bit.services') - - .factory('validationService', function (toastr, i18nService) { - var _service = {}; - - _service.showError = function (data) { - var defaultErrorMessage = i18nService.unexpectedError; - var errors = []; - - if (!data || !angular.isObject(data)) { - errors.push(defaultErrorMessage); - } - else if (!data.validationErrors) { - if (data.message) { - errors.push(data.message); - } - else { - errors.push(defaultErrorMessage); - } - } - else { - for (var key in data.validationErrors) { - if (!data.validationErrors.hasOwnProperty(key)) { - continue; - } - - for (var i = 0; i < data.validationErrors[key].length; i++) { - errors.push(data.validationErrors[key][i]); - } - } - } - - if (errors.length) { - toastr.error(errors[0], i18nService.errorsOccurred); - } - - return errors; - }; - - return _service; - });