Skip to content

Commit 3e28ae2

Browse files
committed
feat: asar integrity (macos only for now)
1 parent 2fab4bf commit 3e28ae2

File tree

11 files changed

+96
-34
lines changed

11 files changed

+96
-34
lines changed

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"private": true,
33
"license": "MIT",
44
"scripts": {
5-
"compile": "ts-babel packages/electron-builder-http packages/electron-builder-core packages/electron-builder-util packages/electron-publish packages/electron-builder packages/electron-builder-squirrel-windows packages/electron-updater packages/electron-publisher-s3 test && node ./test/vendor/yarn.js schema",
5+
"compile": "ts-babel packages/asar-integrity packages/electron-builder-http packages/electron-builder-core packages/electron-builder-util packages/electron-publish packages/electron-builder packages/electron-builder-squirrel-windows packages/electron-updater packages/electron-publisher-s3 test && node ./test/vendor/yarn.js schema",
66
"lint": "node test/out/helpers/lint.js",
77
"pretest": "node ./test/vendor/yarn.js compile && node ./test/vendor/yarn.js lint && node ./test/vendor/yarn.js lint-deps",
88
"lint-deps": "node ./test/out/helpers/checkDeps.js",
@@ -15,7 +15,7 @@
1515
"whitespace": "whitespace 'src/**/*.ts'",
1616
"docker-images": "docker/build.sh",
1717
"test-deps-mac": "brew install rpm dpkg mono lzip gnu-tar graphicsmagick xz && brew install wine --without-x11",
18-
"update-deps": "lerna exec -- npm-check-updates --reject 'electron-builder-http,electron-builder-util,electron-builder-core,electron-publish,electron-forge-maker-appimage,electron-forge-maker-nsis,electron-forge-maker-snap' -a",
18+
"update-deps": "node ./packages/update-deps.js",
1919
"set-versions": "node test/out/helpers/setVersions.js",
2020
"npm-publish": "yarn set-versions && yarn compile && ./packages/npm-publish.sh && conventional-changelog -p angular -i CHANGELOG.md -s",
2121
"schema": "typescript-json-schema packages/electron-builder/tsconfig.json Config --out packages/electron-builder/scheme.json --noExtraProps --useTypeOfKeyword --strictNullChecks --titles",
@@ -31,15 +31,15 @@
3131
"ajv": "^5.1.5",
3232
"ajv-keywords": "^2.1.0",
3333
"archiver": "^1.3.0",
34-
"aws-sdk": "^2.59.0",
34+
"aws-sdk": "^2.61.0",
3535
"bluebird-lst": "^1.0.2",
3636
"chalk": "^1.1.3",
3737
"chromium-pickle-js": "^0.2.0",
3838
"cuint": "^0.2.2",
3939
"debug": "^2.6.8",
4040
"electron-download-tf": "4.3.1",
4141
"electron-is-dev": "^0.1.2",
42-
"electron-osx-sign": "0.4.5",
42+
"electron-osx-sign": "0.4.6",
4343
"fs-extra-p": "^4.3.0",
4444
"hosted-git-info": "^2.4.2",
4545
"ini": "^1.3.4",
@@ -66,10 +66,10 @@
6666
},
6767
"devDependencies": {
6868
"@types/ini": "^1.3.29",
69-
"@types/jest": "^19.2.3",
69+
"@types/jest": "^19.2.4",
7070
"@types/js-yaml": "^3.5.30",
7171
"@types/node-forge": "^0.6.9",
72-
"@types/source-map-support": "^0.2.28",
72+
"@types/source-map-support": "^0.4.0",
7373
"@types/xml2js": "^0.0.33",
7474
"babel-plugin-array-includes": "^2.0.3",
7575
"babel-plugin-transform-async-to-module-method": "^6.24.1",
@@ -90,7 +90,7 @@
9090
"path-sort": "^0.1.0",
9191
"source-map-support": "^0.4.15",
9292
"ts-babel": "^3.0.1",
93-
"tslint": "^5.3.2",
93+
"tslint": "^5.4.2",
9494
"typescript": "^2.3.4",
9595
"whitespace": "^2.1.0",
9696
"xml2js": "^0.4.17"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "asar-integrity",
3+
"version": "0.0.0-semantic-release",
4+
"main": "out/asarIntegrity.js",
5+
"author": "Vladimir Krivosheev",
6+
"license": "MIT",
7+
"repository": "electron-userland/electron-builder",
8+
"bugs": "https://github.com/electron-userland/electron-builder/issues",
9+
"homepage": "https://github.com/electron-userland/electron-builder",
10+
"files": [
11+
"out"
12+
],
13+
"dependencies": {
14+
"bluebird-lst": "^1.0.2",
15+
"fs-extra-p": "^4.3.0"
16+
},
17+
"typings": "./out/asar-integrity.d.ts"
18+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import BluebirdPromise from "bluebird-lst"
2+
import { createHash } from "crypto"
3+
import { createReadStream } from "fs"
4+
import { readdir } from "fs-extra-p"
5+
import * as path from "path"
6+
7+
export async function computeData(resourcesPath: string): Promise<{ [key: string]: string; }> {
8+
// sort to produce constant result
9+
const names = (await readdir(resourcesPath)).filter(it => it.endsWith(".asar")).sort()
10+
const checksums = await BluebirdPromise.map(names, it => hashFile(path.join(resourcesPath, it), "sha512"))
11+
12+
const result: { [key: string]: string; } = {}
13+
for (let i = 0; i < names.length; i++) {
14+
result[names[i]] = checksums[i]
15+
}
16+
return result
17+
}
18+
19+
export function hashFile(file: string, algorithm: string) {
20+
return new BluebirdPromise<string>((resolve, reject) => {
21+
const hash = createHash(algorithm)
22+
hash
23+
.on("error", reject)
24+
.setEncoding("hex")
25+
26+
createReadStream(file)
27+
.on("error", reject)
28+
.on("end", () => {
29+
hash.end()
30+
resolve(<string>hash.read())
31+
})
32+
.pipe(hash, {end: false})
33+
})
34+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "../tsconfig-base.json",
3+
"compilerOptions": {
4+
"outDir": "out"
5+
},
6+
"declaration": true,
7+
"include": [
8+
"src/**/*.ts"
9+
]
10+
}

packages/electron-builder/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
"electron-builder-http": "0.0.0-semantic-release",
5757
"electron-builder-util": "0.0.0-semantic-release",
5858
"electron-download-tf": "4.3.1",
59-
"electron-osx-sign": "0.4.5",
59+
"electron-osx-sign": "0.4.6",
6060
"electron-publish": "0.0.0-semantic-release",
6161
"fs-extra-p": "^4.3.0",
6262
"hosted-git-info": "^2.4.2",
@@ -74,7 +74,8 @@
7474
"update-notifier": "^2.1.0",
7575
"uuid-1345": "^0.99.6",
7676
"yargs": "^8.0.1",
77-
"debug": "2.6.8"
77+
"debug": "2.6.8",
78+
"asar-integrity": "0.0.0-semantic-release"
7879
},
7980
"typings": "./out/electron-builder.d.ts",
8081
"publishConfig": {

packages/electron-builder/src/packager/mac.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export function filterCFBundleIdentifier(identifier: string) {
2525
return identifier.replace(/ /g, "-").replace(/[^a-zA-Z0-9.-]/g, "")
2626
}
2727

28-
export async function createApp(packager: PlatformPackager<any>, appOutDir: string) {
28+
export async function createApp(packager: PlatformPackager<any>, appOutDir: string, checksums: { [key: string]: string; }) {
2929
const appInfo = packager.appInfo
3030
const appFilename = appInfo.productFilename
3131

@@ -135,6 +135,10 @@ export async function createApp(packager: PlatformPackager<any>, appOutDir: stri
135135
use(packager.platformSpecificBuildOptions.category || (<any>buildMetadata).category, it => appPlist.LSApplicationCategoryType = it)
136136
appPlist.NSHumanReadableCopyright = appInfo.copyright
137137

138+
if (checksums != null) {
139+
appPlist.AsarChecksums = JSON.stringify(checksums)
140+
}
141+
138142
const promises: Array<Promise<any | n>> = [
139143
writeFile(appPlistFilename, buildPlist(appPlist)),
140144
writeFile(helperPlistFilename, buildPlist(helperPlist)),

packages/electron-builder/src/platformPackager.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Config } from "./metadata"
1515
import { unpackElectron, unpackMuon } from "./packager/dirPackager"
1616
import { BuildInfo, PackagerOptions } from "./packagerApi"
1717
import { readInstalled } from "./readInstalled"
18+
import { computeData } from "asar-integrity"
1819

1920
export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions> {
2021
readonly packagerOptions: PackagerOptions
@@ -208,7 +209,7 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
208209
await BluebirdPromise.all(promises)
209210

210211
if (platformName === "darwin" || platformName === "mas") {
211-
await (<any>require("./packager/mac")).createApp(this, appOutDir)
212+
await (<any>require("./packager/mac")).createApp(this, appOutDir, asarOptions == null ? null : await computeData(resourcesPath))
212213
}
213214

214215
await copyFiles(extraResourceMatchers)
@@ -363,7 +364,7 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
363364
}
364365

365366
const appInfo = this.appInfo
366-
return pattern.replace(/\$\{([_a-zA-Z./*]+)\}/g, (match, p1): string => {
367+
return pattern.replace(/\${([_a-zA-Z./*]+)}/g, (match, p1): string => {
367368
switch (p1) {
368369
case "productName":
369370
return appInfo.productFilename

packages/electron-builder/src/publish/PublishManager.ts

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import BluebirdPromise from "bluebird-lst"
2-
import { createHash } from "crypto"
32
import { Arch, Platform, PlatformSpecificBuildOptions, Target } from "electron-builder-core"
43
import { CancellationToken } from "electron-builder-http/out/CancellationToken"
54
import { BintrayOptions, GenericServerOptions, GithubOptions, githubUrl, PublishConfiguration, PublishProvider, S3Options, s3Url, UpdateInfo, VersionInfo } from "electron-builder-http/out/publishOptions"
@@ -10,7 +9,7 @@ import { HttpPublisher, PublishContext, Publisher, PublishOptions } from "electr
109
import { BintrayPublisher } from "electron-publish/out/BintrayPublisher"
1110
import { GitHubPublisher } from "electron-publish/out/gitHubPublisher"
1211
import { MultiProgress } from "electron-publish/out/multiProgress"
13-
import { createReadStream, ensureDir, outputJson, writeFile } from "fs-extra-p"
12+
import { ensureDir, outputJson, writeFile } from "fs-extra-p"
1413
import isCi from "is-ci"
1514
import { safeDump } from "js-yaml"
1615
import * as path from "path"
@@ -21,6 +20,7 @@ import { Packager } from "../packager"
2120
import { ArtifactCreated, BuildInfo } from "../packagerApi"
2221
import { PlatformPackager } from "../platformPackager"
2322
import { WinPackager } from "../winPackager"
23+
import { hashFile } from "asar-integrity"
2424

2525
const publishForPrWarning = "There are serious security concerns with PUBLISH_FOR_PULL_REQUEST=true (see the CircleCI documentation (https://circleci.com/docs/1.0/fork-pr-builds/) for details)" +
2626
"\nIf you have SSH keys, sensitive env vars or AWS credentials stored in your project settings and untrusted forks can make pull requests against your repo, then this option isn't for you."
@@ -247,8 +247,8 @@ async function writeUpdateInfo(event: ArtifactCreated, _publishConfigs: Array<Pu
247247
}
248248

249249
const version = packager.appInfo.version
250-
let sha2 = new Lazy(() => hash(event.file!, "sha256"))
251-
let sha512 = new Lazy(() => hash(event.file!, "sha512"))
250+
let sha2 = new Lazy(() => hashFile(event.file!, "sha256"))
251+
let sha512 = new Lazy(() => hashFile(event.file!, "sha512"))
252252
const isMac = packager.platform === Platform.MAC
253253

254254
for (const publishConfig of publishConfigs) {
@@ -421,23 +421,6 @@ export async function getPublishConfigs(packager: PlatformPackager<any>, targetS
421421
return await (<Promise<Array<PublishConfiguration>>>BluebirdPromise.map(asArray(publishers), it => getResolvedPublishConfig(packager, typeof it === "string" ? {provider: it} : it, arch)))
422422
}
423423

424-
function hash(file: string, algorithm: string) {
425-
return new BluebirdPromise<string>((resolve, reject) => {
426-
const hash = createHash(algorithm)
427-
hash
428-
.on("error", reject)
429-
.setEncoding("hex")
430-
431-
createReadStream(file)
432-
.on("error", reject)
433-
.on("end", () => {
434-
hash.end()
435-
resolve(<string>hash.read())
436-
})
437-
.pipe(hash, {end: false})
438-
})
439-
}
440-
441424
function isSuitableWindowsTarget(target: Target) {
442425
return target.name === "nsis" || target.name.startsWith("nsis-")
443426
}

packages/electron-publisher-s3/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
],
1313
"dependencies": {
1414
"fs-extra-p": "^4.3.0",
15-
"aws-sdk": "^2.60.0",
15+
"aws-sdk": "^2.61.0",
1616
"mime": "^1.3.6",
1717
"electron-publish": "~0.0.0-semantic-release",
1818
"electron-builder-util": "~0.0.0-semantic-release"

test/out/mac/__snapshots__/macPackagerTest.js.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Object {
2929
3030
exports[`one-package 2`] = `
3131
Object {
32+
"AsarChecksums": "{\\"app.asar\\":\\"hash\\",\\"electron.asar\\":\\"hash\\"}",
3233
"BuildMachineOSBuild": "16E195",
3334
"CFBundleDisplayName": "Test App ßW",
3435
"CFBundleDocumentTypes": Array [

0 commit comments

Comments
 (0)