@@ -27,227 +27,50 @@ export class AutoUpdaterService {
27
27
* Configure auto-updater settings and event handlers
28
28
*/
29
29
private setupAutoUpdater ( ) : void {
30
- // Configure auto -updater
31
- autoUpdater . autoDownload = false ;
32
- autoUpdater . autoInstallOnAppQuit = true ;
30
+ // DISABLED: Auto -updater disabled due to lack of code signing
31
+ // Using manual notification system as primary update method
32
+ log . info ( 'Auto-updater disabled - using manual notification system' , 'AutoUpdater' ) ;
33
33
34
- // DEVELOPMENT FIX: Force development mode to bypass macOS code signature validation
35
- // This solves "code object is not signed at all" error during development
36
- autoUpdater . forceDevUpdateConfig = true ;
37
-
38
- // In development, only skip event handlers if forceDevUpdateConfig is not enabled
39
- if ( process . env . NODE_ENV === 'development' && ! autoUpdater . forceDevUpdateConfig ) {
40
- return ;
41
- }
42
-
43
- // Set up event handlers
44
- autoUpdater . on ( 'checking-for-update' , ( ) => {
45
- log . info ( 'Checking for updates' , 'AutoUpdater' ) ;
46
- this . updateCheckInProgress = true ;
47
- } ) ;
48
-
49
- autoUpdater . on ( 'update-available' , ( info ) => {
50
- log . info ( `Update available: ${ info . version } ` , 'AutoUpdater' ) ;
51
- this . updateCheckInProgress = false ;
52
- void this . handleUpdateAvailable ( info ) ;
53
- } ) ;
54
-
55
- autoUpdater . on ( 'update-not-available' , ( info ) => {
56
- log . info ( `No updates available. Current version: ${ info . version } ` , 'AutoUpdater' ) ;
57
- this . updateCheckInProgress = false ;
58
- } ) ;
59
-
60
- autoUpdater . on ( 'error' , ( error ) => {
61
- log . error ( 'Auto-updater error' , error , 'AutoUpdater' ) ;
62
- this . updateCheckInProgress = false ;
63
-
64
- // Check if this is a signature validation error
65
- if ( this . isSignatureError ( error ) ) {
66
- log . info ( 'Signature validation error detected, trying manual update check' , 'AutoUpdater' ) ;
67
- void this . fallbackToManualUpdateCheck ( ) ;
68
- } else {
69
- void this . handleUpdateError ( error ) ;
70
- }
71
- } ) ;
72
-
73
- autoUpdater . on ( 'download-progress' , ( progressObj ) => {
74
- const logMessage = `Download progress: ${ progressObj . percent . toFixed ( 2 ) } % (${ progressObj . transferred } /${ progressObj . total } bytes)` ;
75
- log . info ( logMessage , 'AutoUpdater' ) ;
76
-
77
- // Send progress to renderer process
78
- if ( this . mainWindow && ! this . mainWindow . isDestroyed ( ) ) {
79
- this . mainWindow . webContents . send ( 'update-download-progress' , progressObj ) ;
80
- }
81
- } ) ;
82
-
83
- autoUpdater . on ( 'update-downloaded' , ( info ) => {
84
- log . info ( `Update downloaded: ${ info . version } ` , 'AutoUpdater' ) ;
85
- this . updateDownloaded = true ;
86
- void this . handleUpdateDownloaded ( info ) ;
87
- } ) ;
34
+ // Note: Auto-updater completely disabled to prevent signature validation errors
35
+ // All update functionality uses manual GitHub API checks via checkForUpdatesManually()
88
36
}
89
37
90
38
/**
91
- * Check for updates manually
39
+ * Check for updates manually (redirects to manual system)
92
40
*/
93
41
async checkForUpdates ( ) : Promise < boolean > {
94
- // Allow update checks in development when forceDevUpdateConfig is enabled
95
- if ( process . env . NODE_ENV === 'development' && ! autoUpdater . forceDevUpdateConfig ) {
96
- log . info ( 'Auto-updater disabled in development mode' , 'AutoUpdater' ) ;
97
- return false ;
98
- }
99
-
100
- if ( this . updateCheckInProgress ) {
101
- log . info ( 'Update check already in progress' , 'AutoUpdater' ) ;
102
- return false ;
103
- }
104
-
105
- try {
106
- const result = await autoUpdater . checkForUpdates ( ) ;
107
- return result !== null ;
108
- } catch ( error ) {
109
- log . error ( 'Failed to check for updates' , error as Error , 'AutoUpdater' ) ;
110
- return false ;
111
- }
42
+ log . info ( 'Auto-updater disabled - redirecting to manual update check' , 'AutoUpdater' ) ;
43
+ return this . checkForUpdatesManually ( ) ;
112
44
}
113
45
114
46
/**
115
- * Download and install update
47
+ * Download and install update (disabled - manual only)
116
48
*/
117
49
async downloadAndInstallUpdate ( ) : Promise < void > {
118
- // Allow downloads in development when forceDevUpdateConfig is enabled
119
- if ( process . env . NODE_ENV === 'development' && ! autoUpdater . forceDevUpdateConfig ) {
120
- return ;
121
- }
122
-
123
- try {
124
- await autoUpdater . downloadUpdate ( ) ;
125
- } catch ( error ) {
126
- log . error ( 'Failed to download update' , error as Error , 'AutoUpdater' ) ;
127
- throw error ;
128
- }
50
+ log . info ( 'Auto-download disabled - please use manual update check' , 'AutoUpdater' ) ;
51
+ throw new Error ( 'Automatic downloads disabled. Please use manual update check.' ) ;
129
52
}
130
53
131
54
/**
132
- * Install update and restart app
55
+ * Install update and restart app (disabled - manual only)
133
56
*/
134
57
quitAndInstall ( ) : void {
135
- if ( ! this . updateDownloaded ) {
136
- log . error ( 'No update downloaded to install' , new Error ( 'No update available' ) , 'AutoUpdater' ) ;
137
- return ;
138
- }
139
-
140
- log . info ( 'Installing update and restarting app' , 'AutoUpdater' ) ;
141
- autoUpdater . quitAndInstall ( ) ;
142
- }
143
-
144
- /**
145
- * Handle update available event
146
- */
147
- private async handleUpdateAvailable ( info : { version : string } ) : Promise < void > {
148
- if ( ! this . mainWindow || this . mainWindow . isDestroyed ( ) ) {
149
- return ;
150
- }
151
-
152
- const response = await dialog . showMessageBox ( this . mainWindow , {
153
- type : 'info' ,
154
- title : 'Update Available' ,
155
- message : `A new version (${ info . version } ) is available. Would you like to download it now?` ,
156
- detail : 'The update will be downloaded in the background. You can continue using the app.' ,
157
- buttons : [ 'Download Update' , 'Later' ] ,
158
- defaultId : 0 ,
159
- cancelId : 1
160
- } ) ;
161
-
162
- if ( response . response === 0 ) {
163
- try {
164
- await this . downloadAndInstallUpdate ( ) ;
165
- } catch ( error ) {
166
- log . error ( 'Failed to start update download' , error as Error , 'AutoUpdater' ) ;
167
- }
168
- }
169
- }
170
-
171
- /**
172
- * Handle update downloaded event
173
- */
174
- private async handleUpdateDownloaded ( info : { version : string } ) : Promise < void > {
175
- if ( ! this . mainWindow || this . mainWindow . isDestroyed ( ) ) {
176
- return ;
177
- }
178
-
179
- const response = await dialog . showMessageBox ( this . mainWindow , {
180
- type : 'info' ,
181
- title : 'Update Ready' ,
182
- message : `Update (${ info . version } ) has been downloaded and is ready to install.` ,
183
- detail : 'The app will restart to complete the installation.' ,
184
- buttons : [ 'Restart Now' , 'Restart Later' ] ,
185
- defaultId : 0 ,
186
- cancelId : 1
187
- } ) ;
188
-
189
- if ( response . response === 0 ) {
190
- this . quitAndInstall ( ) ;
191
- }
58
+ log . info ( 'Auto-install disabled - please download manually from GitHub' , 'AutoUpdater' ) ;
59
+ throw new Error ( 'Automatic installation disabled. Please download manually from GitHub.' ) ;
192
60
}
193
61
194
- /**
195
- * Handle update error
196
- */
197
- private async handleUpdateError ( error : Error ) : Promise < void > {
198
- if ( ! this . mainWindow || this . mainWindow . isDestroyed ( ) ) {
199
- return ;
200
- }
201
-
202
- // Provide user-friendly error messages for common issues
203
- let userMessage = 'An error occurred while checking for updates.' ;
204
- let userDetail = error . message ;
205
-
206
- if ( error . message . includes ( '404' ) && error . message . includes ( 'latest-mac.yml' ) ) {
207
- userMessage = 'Update check temporarily unavailable.' ;
208
- userDetail = 'The update service is currently unavailable. Please try again later or check for updates manually.' ;
209
- } else if ( error . message . includes ( 'network' ) || error . message . includes ( 'ENOTFOUND' ) ) {
210
- userMessage = 'Network connection issue.' ;
211
- userDetail = 'Unable to connect to the update server. Please check your internet connection.' ;
212
- }
213
-
214
- await dialog . showMessageBox ( this . mainWindow , {
215
- type : 'error' ,
216
- title : 'Update Error' ,
217
- message : userMessage ,
218
- detail : userDetail ,
219
- buttons : [ 'OK' ]
220
- } ) ;
221
- }
62
+ // Note: Auto-updater event handlers removed since auto-updater is disabled
63
+ // All update functionality now uses manual GitHub API system
222
64
223
65
/**
224
- * Initialize auto-updater after app is ready
66
+ * Initialize update system (manual notification only)
225
67
*/
226
68
initialize ( ) : void {
227
- // Allow initialization in development when forceDevUpdateConfig is enabled
228
- if ( process . env . NODE_ENV === 'development' && ! autoUpdater . forceDevUpdateConfig ) {
229
- log . info ( 'Auto-updater skipped in development mode' , 'AutoUpdater' ) ;
230
- return ;
231
- }
232
-
233
- // Log development mode status
234
- if ( autoUpdater . forceDevUpdateConfig ) {
235
- log . info ( 'Auto-updater initialized in development mode with forceDevUpdateConfig' , 'AutoUpdater' ) ;
236
- }
237
-
238
- // Wait a bit after app startup before checking for updates
239
- setTimeout ( ( ) => {
240
- this . checkForUpdates ( ) . catch ( ( error ) => {
241
- log . error ( 'Initial update check failed' , error as Error , 'AutoUpdater' ) ;
242
- } ) ;
243
- } , 10000 ) ; // Wait 10 seconds after startup
244
-
245
- // Set up periodic checks (every 4 hours)
246
- setInterval ( ( ) => {
247
- this . checkForUpdates ( ) . catch ( ( error ) => {
248
- log . error ( 'Periodic update check failed' , error as Error , 'AutoUpdater' ) ;
249
- } ) ;
250
- } , 4 * 60 * 60 * 1000 ) ;
69
+ log . info ( 'Update system initialized - manual notification mode only' , 'AutoUpdater' ) ;
70
+
71
+ // No automatic background checks since we use manual system
72
+ // Users can check for updates via Settings > About > Check for Updates
73
+ // This prevents background signature validation errors
251
74
}
252
75
253
76
/**
@@ -305,48 +128,7 @@ export class AutoUpdaterService {
305
128
}
306
129
}
307
130
308
- /**
309
- * Check if error is related to code signature validation
310
- */
311
- private isSignatureError ( error : Error ) : boolean {
312
- const signatureErrors = [
313
- 'code object is not signed' ,
314
- 'signature validation' ,
315
- 'code signature' ,
316
- 'gatekeeper' ,
317
- 'developer cannot be verified'
318
- ] ;
319
-
320
- return signatureErrors . some ( errorType =>
321
- error . message . toLowerCase ( ) . includes ( errorType . toLowerCase ( ) )
322
- ) ;
323
- }
324
-
325
- /**
326
- * Fallback to manual update check when auto-updater fails with signature error
327
- */
328
- private async fallbackToManualUpdateCheck ( ) : Promise < void > {
329
- try {
330
- const latestRelease = await this . fetchLatestRelease ( ) ;
331
-
332
- if ( ! latestRelease ) {
333
- await this . showSignatureErrorWithoutUpdate ( ) ;
334
- return ;
335
- }
336
-
337
- const currentVersion = getVersion ( ) ;
338
- const latestVersion = latestRelease . tag_name . replace ( / ^ v / , '' ) ;
339
-
340
- if ( this . isNewerVersion ( latestVersion , currentVersion ) ) {
341
- await this . showSignatureErrorWithUpdate ( latestRelease ) ;
342
- } else {
343
- await this . showSignatureErrorWithoutUpdate ( ) ;
344
- }
345
- } catch ( error ) {
346
- log . error ( 'Fallback manual update check failed' , error as Error , 'AutoUpdater' ) ;
347
- await this . showSignatureErrorWithoutUpdate ( ) ;
348
- }
349
- }
131
+ // Note: Signature error detection removed since auto-updater is completely disabled
350
132
351
133
/**
352
134
* Fetch latest release from GitHub API
@@ -454,48 +236,7 @@ export class AutoUpdaterService {
454
236
} ) ;
455
237
}
456
238
457
- /**
458
- * Show signature error dialog when update is available
459
- */
460
- private async showSignatureErrorWithUpdate ( release : any ) : Promise < void > {
461
- if ( ! this . mainWindow || this . mainWindow . isDestroyed ( ) ) {
462
- return ;
463
- }
464
-
465
- const releaseUrl = release . html_url ;
466
- const version = release . tag_name ;
467
-
468
- const response = await dialog . showMessageBox ( this . mainWindow , {
469
- type : 'warning' ,
470
- title : 'Update Available - Manual Download Required' ,
471
- message : `CCTracker ${ version } is available!` ,
472
- detail : `Automatic updates are not available due to code signing requirements. Please download the latest version manually from GitHub releases.` ,
473
- buttons : [ 'Download Now' , 'Later' ] ,
474
- defaultId : 0 ,
475
- cancelId : 1
476
- } ) ;
477
-
478
- if ( response . response === 0 ) {
479
- await shell . openExternal ( releaseUrl ) ;
480
- }
481
- }
482
-
483
- /**
484
- * Show signature error dialog when no update is available
485
- */
486
- private async showSignatureErrorWithoutUpdate ( ) : Promise < void > {
487
- if ( ! this . mainWindow || this . mainWindow . isDestroyed ( ) ) {
488
- return ;
489
- }
490
-
491
- await dialog . showMessageBox ( this . mainWindow , {
492
- type : 'warning' ,
493
- title : 'Update Check Complete' ,
494
- message : 'Automatic updates unavailable' ,
495
- detail : 'Automatic updates are not available due to code signing requirements, but you already have the latest version.' ,
496
- buttons : [ 'OK' ]
497
- } ) ;
498
- }
239
+ // Note: Signature error dialogs removed since we use manual-only update system
499
240
}
500
241
501
242
export const autoUpdaterService = new AutoUpdaterService ( ) ;
0 commit comments