11// Desktop auth extraction approach inspired by:
22// - slacktokens: https://github.com/hraftery/slacktokens
33import { cp , mkdir , rm , unlink } from "node:fs/promises" ;
4- import { existsSync , readFileSync , readdirSync , copyFileSync , writeFileSync , unlinkSync } from "node:fs" ;
4+ import {
5+ existsSync ,
6+ readFileSync ,
7+ readdirSync ,
8+ copyFileSync ,
9+ writeFileSync ,
10+ unlinkSync ,
11+ } from "node:fs" ;
512import { execFileSync } from "node:child_process" ;
613import { pbkdf2Sync , createDecipheriv } from "node:crypto" ;
714import { homedir , platform , tmpdir } from "node:os" ;
@@ -109,10 +116,7 @@ const SLACK_SUPPORT_DIR_WIN_APPDATA = join(
109116 * so we search for the matching prefix.
110117 */
111118function getWindowsStoreSlackPath ( ) : string | null {
112- const pkgBase = join (
113- process . env . LOCALAPPDATA || join ( homedir ( ) , "AppData" , "Local" ) ,
114- "Packages" ,
115- ) ;
119+ const pkgBase = join ( process . env . LOCALAPPDATA || join ( homedir ( ) , "AppData" , "Local" ) , "Packages" ) ;
116120 try {
117121 const entries = readdirSync ( pkgBase ) ;
118122 const slackPkg = entries . find ( ( e ) => e . startsWith ( "com.tinyspeck.slackdesktop_" ) ) ;
@@ -431,7 +435,9 @@ function decryptCookieWindows(encrypted: Buffer, slackDataDir: string): string {
431435 "$d=[System.Security.Cryptography.ProtectedData]::Unprotect($e,$null,[System.Security.Cryptography.DataProtectionScope]::CurrentUser)" ,
432436 `[System.IO.File]::WriteAllBytes('${ psDecKeyFile } ',$d)` ,
433437 ] . join ( "; " ) ;
434- execFileSync ( "powershell" , [ "-ExecutionPolicy" , "Bypass" , "-Command" , psCmd ] , { stdio : "pipe" } ) ;
438+ execFileSync ( "powershell" , [ "-ExecutionPolicy" , "Bypass" , "-Command" , psCmd ] , {
439+ stdio : "pipe" ,
440+ } ) ;
435441 if ( ! existsSync ( decKeyFile ) ) {
436442 throw new Error ( "DPAPI decryption failed: PowerShell did not produce the decrypted key file" ) ;
437443 }
@@ -440,8 +446,8 @@ function decryptCookieWindows(encrypted: Buffer, slackDataDir: string): string {
440446 // AES-256-GCM: v10(3) + nonce(12) + ciphertext(N-16) + tag(16)
441447 const nonce = encrypted . subarray ( 3 , 15 ) ;
442448 const ciphertextWithTag = encrypted . subarray ( 15 ) ;
443- const tag = ciphertextWithTag . subarray ( ciphertextWithTag . length - 16 ) ;
444- const ciphertext = ciphertextWithTag . subarray ( 0 , ciphertextWithTag . length - 16 ) ;
449+ const tag = ciphertextWithTag . subarray ( - 16 ) ;
450+ const ciphertext = ciphertextWithTag . subarray ( 0 , - 16 ) ;
445451
446452 const decipher = createDecipheriv ( "aes-256-gcm" , aesKey , nonce ) ;
447453 decipher . setAuthTag ( tag ) ;
@@ -450,8 +456,16 @@ function decryptCookieWindows(encrypted: Buffer, slackDataDir: string): string {
450456
451457 return decrypted ;
452458 } finally {
453- try { unlinkSync ( encKeyFile ) ; } catch { /* ignore */ }
454- try { unlinkSync ( decKeyFile ) ; } catch { /* ignore */ }
459+ try {
460+ unlinkSync ( encKeyFile ) ;
461+ } catch {
462+ /* ignore */
463+ }
464+ try {
465+ unlinkSync ( decKeyFile ) ;
466+ } catch {
467+ /* ignore */
468+ }
455469 }
456470}
457471
@@ -485,7 +499,11 @@ async function extractCookieDFromSlackCookiesDb(
485499 ) ) as typeof rows ;
486500 } finally {
487501 if ( IS_WIN32 && dbPathToQuery !== cookiesPath ) {
488- try { unlinkSync ( dbPathToQuery ) ; } catch { /* ignore */ }
502+ try {
503+ unlinkSync ( dbPathToQuery ) ;
504+ } catch {
505+ /* ignore */
506+ }
489507 }
490508 }
491509
0 commit comments