diff --git a/gulpfile.js b/gulpfile.js index 2bef4fc4..730e7774 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,19 +1,14 @@ const gulp = require('gulp'), gulpif = require('gulp-if'), replace = require('gulp-replace'), - rimraf = require('rimraf'), - runSequence = require('run-sequence'), jshint = require('gulp-jshint'), - merge = require('merge-stream'), - browserify = require('browserify'), - source = require('vinyl-source-stream'), googleWebFonts = require('gulp-google-webfonts'), - webpack = require('webpack-stream'), jeditor = require("gulp-json-editor"), child = require('child_process'), zip = require('gulp-zip'), manifest = require('./src/manifest.json'), - xmlpoke = require('gulp-xmlpoke'); + xmlpoke = require('gulp-xmlpoke'), + del = require("del"); const paths = { releases: './releases/', @@ -34,10 +29,13 @@ function dist(browserName, manifest) { return gulp.src(paths.dist + '**/*') .pipe(gulpif('popup/index.html', replace('__BROWSER__', browserName))) .pipe(gulpif('manifest.json', jeditor(manifest))) + //.pipe(gulpif(browserName !== 'edge', del(['edge/**']))) .pipe(zip(`dist-${browserName}.zip`)) .pipe(gulp.dest(paths.releases)); } +gulp.task('dist', ['dist:firefox', 'dist:chrome', 'dist:opera', 'dist:edge']); + gulp.task('dist:firefox', function (cb) { return dist('firefox', function (manifest) { manifest.applications = { @@ -63,7 +61,7 @@ gulp.task('dist:chrome', function (cb) { return dist('chrome', function (manifest) { return manifest; }); -}) +}); // Since Edge extensions require makeappx to be run we temporarily store it in a folder. gulp.task('dist:edge', function (cb) { @@ -74,7 +72,7 @@ gulp.task('dist:edge', function (cb) { .then(copyAssetsEdge('./store/windows/**/*', edgePath)) .then(function () { // makeappx.exe must be in your system's path already - child.spawn('makeappx.exe', ['pack', '/h', 'SHA256', '/d', edgePath, '/p', paths.releases + 'bitwarden.appx']); + child.spawn('makeappx.exe', ['pack', '/h', 'SHA256', '/d', edgePath, '/p', paths.releases + 'dist-edge.appx']); cb(); }, function () { cb(); @@ -116,12 +114,7 @@ function copyAssetsEdge(source, dest) { }); } -gulp.task('build', function (cb) { - return runSequence( - 'clean', - ['browserify', 'webpack', 'lib', 'lint', 'webfonts'], - cb); -}); +gulp.task('build', ['lint', 'webfonts']); gulp.task('webfonts', function () { return gulp.src('./webfonts.list') @@ -133,8 +126,6 @@ gulp.task('webfonts', function () { }); // LEGACY CODE! -// -// Needed until background.js is converted into a proper webpack compatible file. gulp.task('lint', function () { return gulp.src([ @@ -151,60 +142,3 @@ gulp.task('lint', function () { })) .pipe(jshint.reporter('default')); }); - -gulp.task('clean:lib', function (cb) { - return rimraf(paths.libDir, cb); -}); - -gulp.task('clean', ['clean:lib']); - -gulp.task('lib', ['clean:lib'], function () { - var libs = [ - { - src: paths.npmDir + 'jquery/dist/jquery.js', - dest: paths.libDir + 'jquery' - } - ]; - - var tasks = libs.map(function (lib) { - return gulp.src(lib.src).pipe(gulp.dest(lib.dest)); - }); - - return merge(tasks); -}); - -gulp.task('browserify', ['browserify:tldjs']); - -gulp.task('browserify:tldjs', function () { - return browserify(paths.npmDir + 'tldjs/index.js', { standalone: 'tldjs' }) - .bundle() - .pipe(source('tld.js')) - .pipe(gulp.dest(paths.libDir + 'tldjs')); -}); - -gulp.task('webpack', ['webpack:forge']); - -gulp.task('webpack:forge', function () { - var forgeDir = paths.npmDir + '/node-forge/lib/'; - - return gulp.src([ - forgeDir + 'pbkdf2.js', - forgeDir + 'aes.js', - forgeDir + 'hmac.js', - forgeDir + 'sha256.js', - forgeDir + 'random.js', - forgeDir + 'forge.js' - ]).pipe(webpack({ - output: { - filename: 'forge.js', - library: 'forge', - libraryTarget: 'umd' - }, - node: { - Buffer: false, - process: false, - crypto: false, - setImmediate: false - } - })).pipe(gulp.dest(paths.libDir + 'forge')); -}); diff --git a/package.json b/package.json index bbe22a83..e1f14ee8 100644 --- a/package.json +++ b/package.json @@ -17,12 +17,12 @@ "angulartics": "1.4.0", "angulartics-google-analytics": "0.4.0", "bootstrap": "3.3.7", - "browserify": "14.4.0", "child_process": "1.0.2", "clean-webpack-plugin": "^0.1.17", "clipboard": "1.7.1", "copy-webpack-plugin": "^4.2.0", "css-loader": "^0.28.7", + "del": "3.0.0", "extract-text-webpack-plugin": "^3.0.1", "file-loader": "^1.1.5", "font-awesome": "4.7.0", @@ -31,7 +31,6 @@ "gulp-if": "^2.0.2", "gulp-jshint": "2.0.4", "gulp-json-editor": "2.2.1", - "gulp-less": "3.3.2", "gulp-replace": "^0.6.1", "gulp-xmlpoke": "0.2.1", "gulp-zip": "4.0.0", @@ -41,13 +40,10 @@ "jshint": "2.9.5", "less": "^3.0.0-alpha.3", "less-loader": "^4.0.5", - "merge-stream": "1.0.1", "ng-infinite-scroll": "1.3.0", "ngclipboard": "1.1.1", "node-forge": "0.7.1", "papaparse": "4.3.5", - "rimraf": "2.6.1", - "run-sequence": "^2.2.0", "style-loader": "^0.19.0", "sweetalert": "1.1.3", "tldjs": "2.0.0", @@ -55,16 +51,16 @@ "tslint": "^5.8.0", "tslint-loader": "^3.5.3", "typescript": "^2.5.3", - "vinyl-source-stream": "1.1.0", "web-ext": "2.0.0", "webpack": "^3.8.1", - "webpack-merge": "^4.1.0", - "webpack-stream": "4.0.0" + "webpack-merge": "^4.1.0" }, "dependencies": { "@types/angular": "^1.6.34", "@types/chrome": "0.0.51", "@types/jquery": "^3.2.16", + "@types/node-forge": "0.6.10", + "@types/tldjs": "1.7.1", "@types/webcrypto": "^0.0.28", "@uirouter/angularjs": "^1.0.10" } diff --git a/src/background.d.ts b/src/background.d.ts index 5e5e2f9e..a4b6712c 100644 --- a/src/background.d.ts +++ b/src/background.d.ts @@ -1,4 +1,5 @@ declare function escape(s: string): string; declare function unescape(s: string): string; -declare var forge: any; declare var opr: any; +declare var tldjs: any; +declare var forge: any; diff --git a/src/background.html b/src/background.html index c34b7e20..53a7f242 100644 --- a/src/background.html +++ b/src/background.html @@ -1,8 +1,5 @@ - - - diff --git a/src/background.js b/src/background.js index 9c904039..e46a0487 100644 --- a/src/background.js +++ b/src/background.js @@ -1,3 +1,7 @@ +require('jquery'); +require('node-forge'); +require('tldjs'); + // Service imports import ApiService from './services/api.service'; import AppIdService from './services/appId.service'; diff --git a/src/services/utils.service.ts b/src/services/utils.service.ts index 24517fd1..420680a8 100644 --- a/src/services/utils.service.ts +++ b/src/services/utils.service.ts @@ -120,6 +120,15 @@ export default class UtilsService { return bytes; } + static fromUtf8ToArray(str: string): Uint8Array { + const strUtf8 = unescape(encodeURIComponent(str)); + const arr = new Uint8Array(strUtf8.length); + for (let i = 0; i < strUtf8.length; i++) { + arr[i] = strUtf8.charCodeAt(i); + } + return arr; + } + static fromBufferToB64(buffer: ArrayBuffer): string { let binary = ''; const bytes = new Uint8Array(buffer); @@ -135,15 +144,6 @@ export default class UtilsService { return decodeURIComponent(escape(encodedString)); } - static fromUtf8ToArray(str: string): Uint8Array { - const strUtf8 = unescape(encodeURIComponent(str)); - const arr = new Uint8Array(strUtf8.length); - for (let i = 0; i < strUtf8.length; i++) { - arr[i] = strUtf8.charCodeAt(i); - } - return arr; - } - static saveObjToStorage(key: string, obj: any) { return new Promise((resolve) => { chrome.storage.local.set({ [key]: obj }, () => { @@ -185,7 +185,7 @@ export default class UtilsService { if (uriString.startsWith('http://') || uriString.startsWith('https://')) { try { const url = new URL(uriString); - if (!url || !url.hostname) { + if (!url.hostname) { return null; } @@ -193,17 +193,17 @@ export default class UtilsService { return url.hostname; } - if ((window as any).tldjs) { - const domain = (window as any).tldjs.getDomain(uriString); - if (domain) { + if (typeof tldjs !== 'undefined' && tldjs) { + const domain = tldjs.getDomain(url.hostname); + if (domain != null) { return domain; } } return url.hostname; } catch (e) { } - } else if ((window as any).tldjs) { - const domain: string = (window as any).tldjs.getDomain(uriString); + } else if (typeof tldjs !== 'undefined' && tldjs) { + const domain = tldjs.getDomain(uriString); if (domain != null) { return domain; } @@ -212,12 +212,6 @@ export default class UtilsService { return null; } - static validIpAddress(ipString: string): boolean { - // tslint:disable-next-line - const ipRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; - return ipRegex.test(ipString); - } - static getHostname(uriString: string): string { if (uriString == null) { return null; @@ -231,7 +225,7 @@ export default class UtilsService { if (uriString.startsWith('http://') || uriString.startsWith('https://')) { try { const url = new URL(uriString); - if (!url || !url.hostname) { + if (!url.hostname) { return null; } @@ -242,6 +236,12 @@ export default class UtilsService { return null; } + private static validIpAddress(ipString: string): boolean { + // tslint:disable-next-line + const ipRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; + return ipRegex.test(ipString); + } + private browserCache: BrowserType = null; private analyticsIdCache: string = null; diff --git a/webpack.common.js b/webpack.common.js index 72f35d3a..a066f9a7 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -4,6 +4,11 @@ const CleanWebpackPlugin = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); +const isVendorModule = (module) => { + // returns true for everything in node_modules + return module.context && module.context.indexOf('node_modules') !== -1; +}; + module.exports = { entry: { 'popup/app': './src/popup/app/app.js', @@ -64,10 +69,12 @@ module.exports = { new webpack.optimize.CommonsChunkPlugin({ name: 'popup/vendor', chunks: ['popup/app'], - minChunks: function (module) { - // this assumes your vendor imports exist in the node_modules directory - return module.context && module.context.indexOf('node_modules') !== -1; - } + minChunks: isVendorModule + }), + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + chunks: ['background'], + minChunks: isVendorModule }), new HtmlWebpackPlugin({ template: './src/popup/index.html', @@ -77,7 +84,7 @@ module.exports = { new HtmlWebpackPlugin({ template: './src/background.html', filename: 'background.html', - chunks: ['background'] + chunks: ['vendor', 'background'] }), new HtmlWebpackPlugin({ template: './src/notification/bar.html', @@ -86,15 +93,14 @@ module.exports = { }), new CopyWebpackPlugin([ './src/manifest.json', + './src/background.js', { from: './src/_locales', to: '_locales' }, { from: './src/edge', to: 'edge' }, { from: './src/images', to: 'images' }, { from: './src/lib', to: 'lib' }, { from: './src/models', to: 'models' }, - { from: './src/overlay', to: 'overlay' }, { from: './src/scripts', to: 'scripts' }, - { from: './src/content/autofill.css', to: 'content' }, - './src/background.js' + { from: './src/content/autofill.css', to: 'content' } ]) ], resolve: { diff --git a/webpack.prod.js b/webpack.prod.js index a3f4ccb7..9ee986bf 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -1,16 +1,8 @@ const merge = require('webpack-merge'); -//const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const common = require('./webpack.common.js'); -const extractLess = new ExtractTextPlugin({ - filename: 'popup/css/[name].css', - disable: false, - allChunks: true -}); - module.exports = merge(common, { - devtool: 'source-map', module: { rules: [ { @@ -29,7 +21,14 @@ module.exports = merge(common, { ] }, plugins: [ - extractLess - //new UglifyJSPlugin() + new webpack.SourceMapDevToolPlugin({ + filename: '[name].js.map', + exclude: ['vendor.js', 'popup/vendor.js'] + }), + new ExtractTextPlugin({ + filename: 'popup/css/[name].css', + disable: false, + allChunks: true + }) ] });