|
1 |
| -import type { createSeaSignTool as createSeaSignToolType } from '@electron/windows-sign'; |
2 |
| -import path from 'path'; |
3 |
| -import semver from 'semver'; |
4 |
| -import fs from 'fs-extra'; |
5 |
| - |
6 |
| -import { SquirrelWindowsOptions } from './options'; |
7 |
| - |
8 |
| -const VENDOR_PATH = path.join(__dirname, '..', 'vendor'); |
9 |
| -const ORIGINAL_SIGN_TOOL_PATH = path.join(VENDOR_PATH, 'signtool.exe'); |
10 |
| -const BACKUP_SIGN_TOOL_PATH = path.join(VENDOR_PATH, 'signtool-original.exe'); |
11 |
| -const SIGN_LOG_PATH = path.join(VENDOR_PATH, 'electron-windows-sign.log'); |
12 |
| - |
13 |
| -/** |
14 |
| - * This method uses @electron/windows-sign to create a fake signtool.exe |
15 |
| - * that can be called by Squirrel - but then just calls @electron/windows-sign |
16 |
| - * to actually perform the signing. |
17 |
| - * |
18 |
| - * That's useful for users who need a high degree of customization of the signing |
19 |
| - * process but still want to use @electron/windows-installer. |
20 |
| - */ |
21 |
| -export async function createSignTool(options: SquirrelWindowsOptions): Promise<void> { |
22 |
| - if (!options.windowsSign) { |
23 |
| - throw new Error('Signtool should only be created if windowsSign options are set'); |
24 |
| - } |
25 |
| - |
26 |
| - const createSeaSignTool = await getCreateSeaSignTool(); |
27 |
| - |
28 |
| - await resetSignTool(); |
29 |
| - await fs.remove(SIGN_LOG_PATH); |
30 |
| - |
31 |
| - // Make a backup of signtool.exe |
32 |
| - await fs.copy(ORIGINAL_SIGN_TOOL_PATH, BACKUP_SIGN_TOOL_PATH, { overwrite: true }); |
33 |
| - |
34 |
| - // Create a new signtool.exe using @electron/windows-sign |
35 |
| - await createSeaSignTool({ |
36 |
| - path: ORIGINAL_SIGN_TOOL_PATH, |
37 |
| - windowsSign: options.windowsSign |
38 |
| - }); |
39 |
| -} |
40 |
| - |
41 |
| -/** |
42 |
| - * Ensure that signtool.exe is actually the "real" signtool.exe, not our |
43 |
| - * fake substitute. |
44 |
| - */ |
45 |
| -export async function resetSignTool() { |
46 |
| - if (fs.existsSync(BACKUP_SIGN_TOOL_PATH)) { |
47 |
| - // Reset the backup of signtool.exe |
48 |
| - await fs.copy(BACKUP_SIGN_TOOL_PATH, ORIGINAL_SIGN_TOOL_PATH, { overwrite: true }); |
49 |
| - await fs.remove(BACKUP_SIGN_TOOL_PATH); |
50 |
| - } |
51 |
| -} |
52 |
| - |
53 |
| -/** |
54 |
| - * @electron/windows-installer only requires Node.js >= 8.0.0. |
55 |
| - * @electron/windows-sign requires Node.js >= 16.0.0. |
56 |
| - * @electron/windows-sign's "fake signtool.exe" feature requires |
57 |
| - * Node.js >= 20.0.0, the first version to contain the "single |
58 |
| - * executable" feature with proper support. |
59 |
| - * |
60 |
| - * Since this is overall a very niche feature and only benefits |
61 |
| - * consumers with rather advanced codesigning needs, we did not |
62 |
| - * want to make Node.js v18 a hard requirement for @electron/windows-installer. |
63 |
| - * |
64 |
| - * Instead, @electron/windows-sign is an optional dependency - and |
65 |
| - * if it didn't install, we'll throw a useful error here. |
66 |
| - * |
67 |
| - * @returns |
68 |
| - */ |
69 |
| -async function getCreateSeaSignTool(): Promise<typeof createSeaSignToolType> { |
70 |
| - try { |
71 |
| - const { createSeaSignTool } = await import('@electron/windows-sign'); |
72 |
| - return createSeaSignTool; |
73 |
| - } catch(error) { |
74 |
| - let message = 'In order to use windowsSign options, @electron/windows-sign must be installed as a dependency.'; |
75 |
| - |
76 |
| - if (semver.lte(process.version, '20.0.0')) { |
77 |
| - message += ` You are currently using Node.js ${process.version}. Please upgrade to Node.js 19 or later and reinstall all dependencies to ensure that @electron/windows-sign is available.`; |
78 |
| - } else { |
79 |
| - message += ` ${error}`; |
80 |
| - } |
81 |
| - |
82 |
| - throw new Error(message); |
83 |
| - } |
84 |
| -} |
| 1 | +import type { createSeaSignTool as createSeaSignToolType } from '@electron/windows-sign'; |
| 2 | +import path from 'path'; |
| 3 | +import semver from 'semver'; |
| 4 | +import fs from 'fs-extra'; |
| 5 | + |
| 6 | +import { SquirrelWindowsOptions } from './options'; |
| 7 | + |
| 8 | +let VENDOR_PATH: string; |
| 9 | +let ORIGINAL_SIGN_TOOL_PATH: string; |
| 10 | +let BACKUP_SIGN_TOOL_PATH: string; |
| 11 | +let SIGN_LOG_PATH: string; |
| 12 | + |
| 13 | +/** |
| 14 | + * This method uses @electron/windows-sign to create a fake signtool.exe |
| 15 | + * that can be called by Squirrel - but then just calls @electron/windows-sign |
| 16 | + * to actually perform the signing. |
| 17 | + * |
| 18 | + * That's useful for users who need a high degree of customization of the signing |
| 19 | + * process but still want to use @electron/windows-installer. |
| 20 | + */ |
| 21 | +export async function createSignTool(options: SquirrelWindowsOptions): Promise<void> { |
| 22 | + if (!options.windowsSign) { |
| 23 | + throw new Error('Signtool should only be created if windowsSign options are set'); |
| 24 | + } |
| 25 | + |
| 26 | + VENDOR_PATH = options.vendorDirectory || path.join(__dirname, '..', 'vendor'); |
| 27 | + ORIGINAL_SIGN_TOOL_PATH = path.join(VENDOR_PATH, 'signtool.exe'); |
| 28 | + BACKUP_SIGN_TOOL_PATH = path.join(VENDOR_PATH, 'signtool-original.exe'); |
| 29 | + SIGN_LOG_PATH = path.join(VENDOR_PATH, 'electron-windows-sign.log'); |
| 30 | + |
| 31 | + const createSeaSignTool = await getCreateSeaSignTool(); |
| 32 | + |
| 33 | + await resetSignTool(); |
| 34 | + await fs.remove(SIGN_LOG_PATH); |
| 35 | + |
| 36 | + // Make a backup of signtool.exe |
| 37 | + await fs.copy(ORIGINAL_SIGN_TOOL_PATH, BACKUP_SIGN_TOOL_PATH, { overwrite: true }); |
| 38 | + |
| 39 | + // Create a new signtool.exe using @electron/windows-sign |
| 40 | + await createSeaSignTool({ |
| 41 | + path: ORIGINAL_SIGN_TOOL_PATH, |
| 42 | + windowsSign: options.windowsSign |
| 43 | + }); |
| 44 | +} |
| 45 | + |
| 46 | +/** |
| 47 | + * Ensure that signtool.exe is actually the "real" signtool.exe, not our |
| 48 | + * fake substitute. |
| 49 | + */ |
| 50 | +export async function resetSignTool() { |
| 51 | + if (fs.existsSync(BACKUP_SIGN_TOOL_PATH)) { |
| 52 | + // Reset the backup of signtool.exe |
| 53 | + await fs.copy(BACKUP_SIGN_TOOL_PATH, ORIGINAL_SIGN_TOOL_PATH, { overwrite: true }); |
| 54 | + await fs.remove(BACKUP_SIGN_TOOL_PATH); |
| 55 | + } |
| 56 | +} |
| 57 | + |
| 58 | +/** |
| 59 | + * @electron/windows-installer only requires Node.js >= 8.0.0. |
| 60 | + * @electron/windows-sign requires Node.js >= 16.0.0. |
| 61 | + * @electron/windows-sign's "fake signtool.exe" feature requires |
| 62 | + * Node.js >= 20.0.0, the first version to contain the "single |
| 63 | + * executable" feature with proper support. |
| 64 | + * |
| 65 | + * Since this is overall a very niche feature and only benefits |
| 66 | + * consumers with rather advanced codesigning needs, we did not |
| 67 | + * want to make Node.js v18 a hard requirement for @electron/windows-installer. |
| 68 | + * |
| 69 | + * Instead, @electron/windows-sign is an optional dependency - and |
| 70 | + * if it didn't install, we'll throw a useful error here. |
| 71 | + * |
| 72 | + * @returns |
| 73 | + */ |
| 74 | +async function getCreateSeaSignTool(): Promise<typeof createSeaSignToolType> { |
| 75 | + try { |
| 76 | + const { createSeaSignTool } = await import('@electron/windows-sign'); |
| 77 | + return createSeaSignTool; |
| 78 | + } catch(error) { |
| 79 | + let message = 'In order to use windowsSign options, @electron/windows-sign must be installed as a dependency.'; |
| 80 | + |
| 81 | + if (semver.lte(process.version, '20.0.0')) { |
| 82 | + message += ` You are currently using Node.js ${process.version}. Please upgrade to Node.js 19 or later and reinstall all dependencies to ensure that @electron/windows-sign is available.`; |
| 83 | + } else { |
| 84 | + message += ` ${error}`; |
| 85 | + } |
| 86 | + |
| 87 | + throw new Error(message); |
| 88 | + } |
| 89 | +} |
0 commit comments