const gulp = require('gulp'); const googleWebFonts = require('gulp-google-webfonts'); const del = require('del'); const fs = require('fs'); const child = require('child_process'); const paths = { cssDir: './src/css/', node_modules: './node_modules/', dist: './dist/', resources: './resources/', }; function clean() { return del([paths.cssDir]); } function webfonts() { return gulp.src('./webfonts.list') .pipe(googleWebFonts({ fontsDir: 'webfonts', cssFilename: 'webfonts.css', format: 'woff', })) .pipe(gulp.dest(paths.cssDir)); } // ref: https://github.com/angular/angular/issues/22524 function cleanupAotIssue() { return del(['./node_modules/@types/uglify-js/node_modules/source-map/source-map.d.ts']); } // ref: https://github.com/t4t5/sweetalert/issues/890 function fixSweetAlert(cb) { fs.writeFileSync(paths.node_modules + 'sweetalert/typings/sweetalert.d.ts', 'import swal, { SweetAlert } from "./core";export default swal;export as namespace swal;'); cb(); } function pkgMas(cb) { const appPath = paths.dist + 'mas/Bitwarden.app'; const pkgPath = paths.dist + 'mas/Bitwarden-mas.pkg'; const pkgSignedPath = paths.dist + 'mas/Bitwarden-mas-signed.pkg'; return del([paths.dist + 'mas/Bitwarden*.pkg']) .then(() => { return signMas(cb); }).then(() => { const proc = child.spawn('productbuild', [ '--component', appPath, '/Applications', pkgPath]); stdOutProc(proc); return new Promise((resolve) => proc.on('close', resolve)); }).then(() => { const proc = child.spawn('productsign', [ '--sign', '3rd Party Mac Developer Installer: 8bit Solutions LLC', pkgPath, pkgSignedPath]); stdOutProc(proc); return new Promise((resolve) => proc.on('close', resolve)); }).then(() => { return cb; }, () => { return cb; }); } function signMas(cb) { return signApp(cb, 'mas'); } function signMac(cb) { return signApp(cb, 'mac'); } function signApp(cb, dir) { const appPath = paths.dist + dir + '/Bitwarden.app'; const safariAppexPath = appPath + '/Contents/PlugIns/safari.appex'; const safariAppexFrameworkPath = safariAppexPath + '/Contents/Frameworks/'; const safariEntitlementsPath = paths.resources + 'safari.entitlements'; const appEntitlementsPath = paths.resources + 'entitlements.' + dir + '.plist'; const libs = fs.readdirSync(safariAppexFrameworkPath).filter((p) => p.endsWith('.dylib')) .map((p) => safariAppexFrameworkPath + p); const libPromises = []; var args = dir === 'mas' ? [ '--verbose', '--force', '--sign', '3rd Party Mac Developer Application: 8bit Solutions LLC', '--entitlements' ] : [ '--verbose', '--force', '-o', 'runtime', '--sign', 'Developer ID Application: 8bit Solutions LLC', '--entitlements' ]; libs.forEach((i) => { const proc = child.spawn('codesign', args.concat([safariEntitlementsPath, i])); stdOutProc(proc); libPromises.push(new Promise((resolve) => proc.on('close', resolve))); libPromises.push(new Promise((resolve) => setTimeout(() => resolve(), 10000))); }); return Promise.all(libPromises).then(() => { const proc = child.spawn('codesign', args.concat([safariEntitlementsPath, safariAppexPath])); stdOutProc(proc); return new Promise((resolve) => proc.on('close', resolve)); }).then(() => { const proc = child.spawn('codesign', args.concat([appEntitlementsPath, appPath])); stdOutProc(proc); return new Promise((resolve) => proc.on('close', resolve)); }).then(() => { return cb; }, () => { return cb; }); } function stdOutProc(proc) { proc.stdout.on('data', (data) => console.log(data.toString())); proc.stderr.on('data', (data) => console.error(data.toString())); } exports.clean = clean; exports.cleanupAotIssue = cleanupAotIssue; exports.webfonts = gulp.series(clean, webfonts); exports['prebuild:renderer'] = gulp.parallel(webfonts, cleanupAotIssue); exports.fixSweetAlert = fixSweetAlert; exports.pkgMas = pkgMas; exports.signMas = signMas; exports.signMac = signMac; exports.postinstall = fixSweetAlert;