Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: remove deprecated fields from winOptions and macOptions to clean up configuration (BREAKING CHANGE) #8582

Merged
merged 10 commits into from
Jan 13, 2025
Merged
8 changes: 8 additions & 0 deletions .changeset/purple-sheep-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"app-builder-lib": major
---

chore: remove deprecated fields from `winOptions` and `macOptions`

For `winOptions` signing configuration, it has been moved to `win.signtoolOptions` in order to support `azureOptions` as a separate field and avoid bloating `win` configuration object
For `macOptions`, notarize options has been deprecated in favor of env vars for quite some time. Env vars are much more secure
143 changes: 4 additions & 139 deletions packages/app-builder-lib/scheme.json
Original file line number Diff line number Diff line change
Expand Up @@ -2703,18 +2703,8 @@
]
},
"notarize": {
"anyOf": [
{
"$ref": "#/definitions/NotarizeNotaryOptions"
},
{
"type": [
"null",
"boolean"
]
}
],
"description": "Options to use for"
"description": "Whether to disable electron-builder's [@electron/notarize](https://github.com/electron/notarize) integration.\n\nNote: In order to activate the notarization step You MUST specify one of the following via environment variables:\n\n1. `APPLE_API_KEY`, `APPLE_API_KEY_ID` and `APPLE_API_ISSUER`.\n2. `APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, and `APPLE_TEAM_ID`\n3. `APPLE_KEYCHAIN` and `APPLE_KEYCHAIN_PROFILE`\n\nFor security reasons it is recommended to use the first option (see https://github.com/electron-userland/electron-builder/issues/7859)",
"type": "boolean"
},
"preAutoEntitlements": {
"default": true,
Expand Down Expand Up @@ -3345,18 +3335,8 @@
]
},
"notarize": {
"anyOf": [
{
"$ref": "#/definitions/NotarizeNotaryOptions"
},
{
"type": [
"null",
"boolean"
]
}
],
"description": "Options to use for"
"description": "Whether to disable electron-builder's [@electron/notarize](https://github.com/electron/notarize) integration.\n\nNote: In order to activate the notarization step You MUST specify one of the following via environment variables:\n\n1. `APPLE_API_KEY`, `APPLE_API_KEY_ID` and `APPLE_API_ISSUER`.\n2. `APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, and `APPLE_TEAM_ID`\n3. `APPLE_KEYCHAIN` and `APPLE_KEYCHAIN_PROFILE`\n\nFor security reasons it is recommended to use the first option (see https://github.com/electron-userland/electron-builder/issues/7859)",
"type": "boolean"
},
"preAutoEntitlements": {
"default": true,
Expand Down Expand Up @@ -3866,16 +3846,6 @@
},
"type": "object"
},
"NotarizeNotaryOptions": {
"additionalProperties": false,
"properties": {
"teamId": {
"description": "The team ID you want to notarize under for when using `notarytool`",
"type": "string"
}
},
"type": "object"
},
"NsisOptions": {
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -6179,13 +6149,6 @@
"WindowsConfiguration": {
"additionalProperties": false,
"properties": {
"additionalCertificateFile": {
"description": "The path to an additional certificate file you want to add to the signature block.",
"type": [
"null",
"string"
]
},
"appId": {
"default": "com.electron.${name}",
"description": "The application id. Used as [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for MacOS and as\n[Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows (NSIS target only, Squirrel.Windows not supported). It is strongly recommended that an explicit ID is set.",
Expand Down Expand Up @@ -6244,34 +6207,6 @@
],
"description": "Options for usage of Azure Trusted Signing (beta)"
},
"certificateFile": {
"description": "The path to the *.pfx certificate you want to sign with. Please use it only if you cannot use env variable `CSC_LINK` (`WIN_CSC_LINK`) for some reason.\nPlease see [Code Signing](./code-signing.md).",
"type": [
"null",
"string"
]
},
"certificatePassword": {
"description": "The password to the certificate provided in `certificateFile`. Please use it only if you cannot use env variable `CSC_KEY_PASSWORD` (`WIN_CSC_KEY_PASSWORD`) for some reason.\nPlease see [Code Signing](./code-signing.md).",
"type": [
"null",
"string"
]
},
"certificateSha1": {
"description": "The SHA1 hash of the signing certificate. The SHA1 hash is commonly specified when multiple certificates satisfy the criteria specified by the remaining switches. Works only on Windows (or on macOS if [Parallels Desktop](https://www.parallels.com/products/desktop/) Windows 10 virtual machines exits).",
"type": [
"null",
"string"
]
},
"certificateSubjectName": {
"description": "The name of the subject of the signing certificate, which is often labeled with the field name `issued to`. Required only for EV Code Signing and works only on Windows (or on macOS if [Parallels Desktop](https://www.parallels.com/products/desktop/) Windows 10 virtual machines exits).",
"type": [
"null",
"string"
]
},
"compression": {
"anyOf": [
{
Expand Down Expand Up @@ -6519,23 +6454,6 @@
],
"description": "Publisher configuration. See [Auto Update](./publish.md) for more information."
},
"publisherName": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": [
"null",
"string"
]
}
],
"description": "[The publisher name](https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073), exactly as in your code signed certificate. Several names can be provided.\nDefaults to common name from your code signing certificate."
},
"releaseInfo": {
"$ref": "#/definitions/ReleaseInfo",
"description": "The release info. Intended for command line usage:\n\n```\n-c.releaseInfo.releaseNotes=\"new features\"\n```"
Expand All @@ -6557,38 +6475,11 @@
"default": "asInvoker",
"description": "The [security level](https://msdn.microsoft.com/en-us/library/6ad1fshk.aspx#Anchor_9) at which the application requests to be executed.\nCannot be specified per target, allowed only in the `win`."
},
"rfc3161TimeStampServer": {
"default": "http://timestamp.digicert.com",
"description": "The URL of the RFC 3161 time stamp server.",
"type": [
"null",
"string"
]
},
"sign": {
"anyOf": [
{
"typeof": "function"
},
{
"type": [
"null",
"string"
]
}
],
"description": "The custom function (or path to file or module id) to sign Windows executables"
},
"signAndEditExecutable": {
"default": true,
"description": "Whether to sign and add metadata to executable. Advanced option.",
"type": "boolean"
},
"signDlls": {
"default": false,
"description": "Whether to sign DLL files. Advanced option.",
"type": "boolean"
},
"signExts": {
"anyOf": [
{
Expand All @@ -6604,24 +6495,6 @@
"default": null,
"description": "Explicit file extensions to also sign. Advanced option."
},
"signingHashAlgorithms": {
"anyOf": [
{
"items": {
"enum": [
"sha1",
"sha256"
],
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"description": "Array of signing algorithms used. For AppX `sha256` is always used."
},
"signtoolOptions": {
"anyOf": [
{
Expand Down Expand Up @@ -6661,14 +6534,6 @@
"default": "nsis",
"description": "The target package type: list of `nsis`, `nsis-web` (Web installer), `portable` ([portable]./nsis.md#portable) app without installation), `appx`, `msi`, `msi-wrapped`, `squirrel`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`.\nAppX package can be built only on Windows 10.\n\nTo use Squirrel.Windows please install `electron-builder-squirrel-windows` dependency."
},
"timeStampServer": {
"default": "http://timestamp.digicert.com",
"description": "The URL of the time stamp server.",
"type": [
"null",
"string"
]
},
"verifyUpdateCodeSignature": {
"default": true,
"description": "Whether to verify the signature of an available update before installation.\nThe [publisher name](#publisherName) will be used for the signature verification.",
Expand Down
19 changes: 0 additions & 19 deletions packages/app-builder-lib/src/codeSign/windowsCodeSign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,6 @@ export async function signWindows(options: WindowsSignOptions, packager: WinPack
log.info({ path: log.filePath(options.path) }, "signing with Azure Trusted Signing (beta)")
} else {
log.info({ path: log.filePath(options.path) }, "signing with signtool.exe")
const deprecatedFields = {
sign: options.options.sign,
signDlls: options.options.signDlls,
signingHashAlgorithms: options.options.signingHashAlgorithms,
certificateFile: options.options.certificateFile,
certificatePassword: options.options.certificatePassword,
certificateSha1: options.options.certificateSha1,
certificateSubjectName: options.options.certificateSubjectName,
additionalCertificateFile: options.options.additionalCertificateFile,
rfc3161TimeStampServer: options.options.rfc3161TimeStampServer,
timeStampServer: options.options.timeStampServer,
publisherName: options.options.publisherName,
}
const fields = Object.entries(deprecatedFields)
.filter(([, value]) => !!value)
.map(([field]) => field)
if (fields.length) {
log.warn({ fields, reason: "please move to win.signtoolOptions.<field_name>" }, `deprecated field`)
}
}

return signWithRetry(async () => packageManager.signFile(options))
Expand Down
27 changes: 12 additions & 15 deletions packages/app-builder-lib/src/codeSign/windowsSignToolManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { resolveFunction } from "../util/resolve"
import { isUseSystemSigncode } from "../util/flags"
import { VmManager } from "../vm/vm"
import { WinPackager } from "../winPackager"
import { chooseNotNull } from "../platformPackager"
import { WindowsSignOptions } from "./windowsCodeSign"
import { getPSCmd } from "./windowsCodeSign"
import { MemoLazy, parseDn } from "builder-util-runtime"
Expand Down Expand Up @@ -76,7 +75,7 @@ export class WindowsSignToolManager implements SignManager {
}

readonly computedPublisherName = new Lazy<Array<string> | null>(async () => {
const publisherName = chooseNotNull(this.platformSpecificBuildOptions.signtoolOptions?.publisherName, this.platformSpecificBuildOptions.publisherName)
const publisherName = this.platformSpecificBuildOptions.signtoolOptions?.publisherName
if (publisherName === null) {
return null
} else if (publisherName != null) {
Expand Down Expand Up @@ -114,14 +113,14 @@ export class WindowsSignToolManager implements SignManager {
readonly cscInfo = new MemoLazy<WindowsConfiguration, FileCodeSigningInfo | CertificateFromStoreInfo | null>(
() => this.platformSpecificBuildOptions,
platformSpecificBuildOptions => {
const subjectName = chooseNotNull(platformSpecificBuildOptions.signtoolOptions?.certificateSubjectName, platformSpecificBuildOptions.certificateSubjectName)
const shaType = chooseNotNull(platformSpecificBuildOptions.signtoolOptions?.certificateSha1, platformSpecificBuildOptions.certificateSha1)
const subjectName = platformSpecificBuildOptions.signtoolOptions?.certificateSubjectName
const shaType = platformSpecificBuildOptions.signtoolOptions?.certificateSha1
if (subjectName != null || shaType != null) {
return this.packager.vm.value
.then(vm => this.getCertificateFromStoreInfo(platformSpecificBuildOptions, vm))
.catch((e: any) => {
// https://github.com/electron-userland/electron-builder/pull/2397
if (chooseNotNull(platformSpecificBuildOptions.signtoolOptions?.sign, platformSpecificBuildOptions.sign) == null) {
if (platformSpecificBuildOptions.signtoolOptions?.sign == null) {
throw e
} else {
log.debug({ error: e }, "getCertificateFromStoreInfo error")
Expand All @@ -130,7 +129,7 @@ export class WindowsSignToolManager implements SignManager {
})
}

const certificateFile = chooseNotNull(platformSpecificBuildOptions.signtoolOptions?.certificateFile, platformSpecificBuildOptions.certificateFile)
const certificateFile = platformSpecificBuildOptions.signtoolOptions?.certificateFile
if (certificateFile != null) {
const certificatePassword = this.packager.getCscPassword()
return Promise.resolve({
Expand Down Expand Up @@ -184,7 +183,7 @@ export class WindowsSignToolManager implements SignManager {
}

async signFile(options: WindowsSignOptions): Promise<boolean> {
let hashes = chooseNotNull(options.options.signtoolOptions?.signingHashAlgorithms, options.options.signingHashAlgorithms)
let hashes = options.options.signtoolOptions?.signingHashAlgorithms
// msi does not support dual-signing
if (options.path.endsWith(".msi")) {
hashes = [hashes != null && !hashes.includes("sha1") ? "sha256" : "sha1"]
Expand All @@ -199,7 +198,7 @@ export class WindowsSignToolManager implements SignManager {
const name = this.packager.appInfo.productName
const site = await this.packager.appInfo.computePackageUrl()

const customSign = await resolveFunction(this.packager.appInfo.type, chooseNotNull(options.options.signtoolOptions?.sign, options.options.sign), "sign")
const customSign = await resolveFunction(this.packager.appInfo.type, options.options.signtoolOptions?.sign, "sign")

const cscInfo = await this.cscInfo.value
if (cscInfo) {
Expand Down Expand Up @@ -275,13 +274,11 @@ export class WindowsSignToolManager implements SignManager {
const args = isWin ? ["sign"] : ["-in", inputFile, "-out", outputPath]

if (process.env.ELECTRON_BUILDER_OFFLINE !== "true") {
const timestampingServiceUrl = chooseNotNull(options.options.signtoolOptions?.timeStampServer, options.options.timeStampServer) || "http://timestamp.digicert.com"
const timestampingServiceUrl = options.options.signtoolOptions?.timeStampServer || "http://timestamp.digicert.com"
if (isWin) {
args.push(
options.isNest || options.hash === "sha256" ? "/tr" : "/t",
options.isNest || options.hash === "sha256"
? chooseNotNull(options.options.signtoolOptions?.rfc3161TimeStampServer, options.options.rfc3161TimeStampServer) || "http://timestamp.digicert.com"
: timestampingServiceUrl
options.isNest || options.hash === "sha256" ? options.options.signtoolOptions?.rfc3161TimeStampServer || "http://timestamp.digicert.com" : timestampingServiceUrl
)
} else {
args.push("-t", timestampingServiceUrl)
Expand Down Expand Up @@ -335,7 +332,7 @@ export class WindowsSignToolManager implements SignManager {
args.push(isWin ? "/p" : "-pass", password)
}

const additionalCert = chooseNotNull(options.options.signtoolOptions?.additionalCertificateFile, options.options.additionalCertificateFile)
const additionalCert = options.options.signtoolOptions?.additionalCertificateFile
if (additionalCert) {
args.push(isWin ? "/ac" : "-ac", vm.toVmFile(additionalCert))
}
Expand Down Expand Up @@ -395,8 +392,8 @@ export class WindowsSignToolManager implements SignManager {
}

async getCertificateFromStoreInfo(options: WindowsConfiguration, vm: VmManager): Promise<CertificateFromStoreInfo> {
const certificateSubjectName = chooseNotNull(options.signtoolOptions?.certificateSubjectName, options.certificateSubjectName)
const certificateSha1 = chooseNotNull(options.signtoolOptions?.certificateSha1, options.certificateSha1)?.toUpperCase()
const certificateSubjectName = options.signtoolOptions?.certificateSubjectName
const certificateSha1 = options.signtoolOptions?.certificateSha1?.toUpperCase()

const ps = await getPSCmd(vm)
const rawResult = await vm.exec(ps, [
Expand Down
2 changes: 1 addition & 1 deletion packages/app-builder-lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export {
export { ElectronBrandingOptions, ElectronDownloadOptions, ElectronPlatformName } from "./electron/ElectronFramework"
export { PlatformSpecificBuildOptions, AsarOptions, FileSet, Protocol, ReleaseInfo, FilesBuildOptions } from "./options/PlatformSpecificBuildOptions"
export { FileAssociation } from "./options/FileAssociation"
export { MacConfiguration, DmgOptions, MasConfiguration, MacOsTargetName, DmgContent, DmgWindow, NotarizeNotaryOptions } from "./options/macOptions"
export { MacConfiguration, DmgOptions, MasConfiguration, MacOsTargetName, DmgContent, DmgWindow } from "./options/macOptions"
export { PkgOptions, PkgBackgroundOptions, BackgroundAlignment, BackgroundScaling } from "./options/pkgOptions"
export { WindowsConfiguration, WindowsAzureSigningConfiguration, WindowsSigntoolConfiguration } from "./options/winOptions"
export { AppXOptions } from "./options/AppXOptions"
Expand Down
11 changes: 2 additions & 9 deletions packages/app-builder-lib/src/macPackager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AppInfo } from "./appInfo"
import { CertType, CodeSigningInfo, createKeychain, CreateKeychainOptions, findIdentity, Identity, isSignAllowed, removeKeychain, reportError, sign } from "./codeSign/macCodeSign"
import { DIR_TARGET, Platform, Target } from "./core"
import { AfterPackContext, ElectronPlatformName } from "./index"
import { MacConfiguration, MasConfiguration, NotarizeNotaryOptions } from "./options/macOptions"
import { MacConfiguration, MasConfiguration } from "./options/macOptions"
import { Packager } from "./packager"
import { chooseNotNull, PlatformPackager } from "./platformPackager"
import { ArchiveTarget } from "./targets/ArchiveTarget"
Expand Down Expand Up @@ -531,18 +531,11 @@ export class MacPackager extends PlatformPackager<MacConfiguration> {
}

private getNotarizeOptions(appPath: string): NotarizeOptionsNotaryTool | undefined {
let teamId = process.env.APPLE_TEAM_ID
const teamId = process.env.APPLE_TEAM_ID
const appleId = process.env.APPLE_ID
const appleIdPassword = process.env.APPLE_APP_SPECIFIC_PASSWORD
const options = this.platformSpecificBuildOptions.notarize
const tool = "notarytool"

const optionsTeamId = (options as NotarizeNotaryOptions)?.teamId
if (optionsTeamId) {
log.warn(null, "Please specify notarization Team ID in the `APPLE_TEAM_ID` env var instead of `notarize.teamId`")
teamId = optionsTeamId
}

// option 1: app specific password
if (appleId || appleIdPassword) {
if (!appleId) {
Expand Down
Loading
Loading