import * as fs from 'fs' ; import * as path from 'path' ; import { createHash , randomBytes } from 'crypto' ; import { ENCRYPTION_KEY_ENV_OVERWRITE , EXTENSIONS_SUBDIRECTORY , IUserSettings , USER_FOLDER_ENV_OVERWRITE , USER_SETTINGS_FILE_NAME , USER_SETTINGS_SUBFOLDER , } from '.' ; const { promisify } = require ( 'util' ) ; const fsAccess = promisify ( fs . access ) ; const fsReadFile = promisify ( fs . readFile ) ; const fsMkdir = promisify ( fs . mkdir ) ; const fsWriteFile = promisify ( fs . writeFile ) ; let settingsCache ; export export async function prepareUserSettings ( ) { const settingsPath = getUserSettingsPath ( ) ; let userSettings = await getUserSettings ( settingsPath ) ; if ( userSettings !== undefined ) { if ( userSettings . encryptionKey !== undefined ) { if ( userSettings . instanceId === undefined ) { userSettings . instanceId = await generateInstanceId ( userSettings . encryptionKey ) ; settingsCache = userSettings ; } return userSettings ; } } else { userSettings = { } ; } if ( process . env [ ENCRYPTION_KEY_ENV_OVERWRITE ] !== undefined ) { userSettings . encryptionKey = process . env [ ENCRYPTION_KEY_ENV_OVERWRITE ] ; } else { userSettings . encryptionKey = randomBytes ( 24 ) . toString ( 'base64' ) ; } userSettings . instanceId = await generateInstanceId ( userSettings . encryptionKey ) ; console . log ( `UserSettings were generated and saved to: ${ settingsPath }` ) ; return writeUserSettings ( userSettings , settingsPath ) ; } export returns export async function getEncryptionKey ( ) { if ( process . env [ ENCRYPTION_KEY_ENV_OVERWRITE ] !== undefined ) { return process . env [ ENCRYPTION_KEY_ENV_OVERWRITE ] ; } const userSettings = await getUserSettings ( ) ; if ( userSettings === undefined ) { return undefined ; } if ( userSettings . encryptionKey === undefined ) { return undefined ; } return userSettings . encryptionKey ; } export returns export async function getInstanceId ( ) { const userSettings = await getUserSettings ( ) ; if ( userSettings === undefined ) { return '' ; } if ( userSettings . instanceId === undefined ) { return '' ; } return userSettings . instanceId ; } async function generateInstanceId ( key ? ) { const hash = key ? createHash ( 'sha256' ) . update ( key . slice ( Math . round ( key . length / 2 ) ) ) . digest ( 'hex' ) : undefined ; return hash ; } export param { IUserSettings } addSettings param { string } settingsPath returns { Promise < IUserSettings > } export async function addToUserSettings ( addSettings , settingsPath ? ) { if ( settingsPath === undefined ) { settingsPath = getUserSettingsPath ( ) ; } let userSettings = await getUserSettings ( settingsPath ) ; if ( userSettings === undefined ) { userSettings = { } ; } Object . assign ( userSettings , addSettings ) ; return writeUserSettings ( userSettings , settingsPath ) ; } export param { IUserSettings } userSettings param { string } settingsPath returns { Promise < IUserSettings > } export async function writeUserSettings ( userSettings , settingsPath ? ) { if ( settingsPath === undefined ) { settingsPath = getUserSettingsPath ( ) ; } if ( userSettings === undefined ) { userSettings = { } ; } try { await fsAccess ( path . dirname ( settingsPath ) ) ; } catch ( error ) { await fsMkdir ( path . dirname ( settingsPath ) ) ; } const settingsToWrite = { ... userSettings } ; if ( settingsToWrite . instanceId !== undefined ) { delete settingsToWrite . instanceId ; } await fsWriteFile ( settingsPath , JSON . stringify ( settingsToWrite , null , '\t' ) ) ; settingsCache = JSON . parse ( JSON . stringify ( userSettings ) ) ; return userSettings ; } export returns { UserSettings } export async function getUserSettings ( settingsPath ? , ignoreCache ? ) { if ( settingsCache !== undefined && ignoreCache !== true ) { return settingsCache ; } if ( settingsPath === undefined ) { settingsPath = getUserSettingsPath ( ) ; } try { await fsAccess ( settingsPath ) ; } catch ( error ) { return undefined ; } const settingsFile = await fsReadFile ( settingsPath , 'utf8' ) ; try { settingsCache = JSON . parse ( settingsFile ) ; } catch ( error ) { throw new Error ( `Error parsing n8n-config file "${ settingsPath }". It does not seem to be valid JSON.` ) ; } return settingsCache as IUserSettings ; } export returns { string } export function getUserSettingsPath ( ) { const n8nFolder = getUserN8nFolderPath ( ) ; return path . join ( n8nFolder , USER_SETTINGS_FILE_NAME ) ; } export returns { string } export function getUserN8nFolderPath ( ) { let userFolder ; if ( process . env [ USER_FOLDER_ENV_OVERWRITE ] !== undefined ) { userFolder = process . env [ USER_FOLDER_ENV_OVERWRITE ] as string ; } else { userFolder = getUserHome ( ) ; } return path . join ( userFolder , USER_SETTINGS_SUBFOLDER ) ; } export returns { string } export function getUserN8nFolderCustomExtensionPath ( ) { return path . join ( getUserN8nFolderPath ( ) , EXTENSIONS_SUBDIRECTORY ) ; } export returns { string } export function getUserHome ( ) { let variableName = 'HOME' ; if ( process . platform === 'win32' ) { variableName = 'USERPROFILE' ; } if ( process . env [ variableName ] === undefined ) { return process . cwd ( ) ; } return process . env [ variableName ] as string ; }