Skip to content

Commit

Permalink
Added code comments/log messages. Fixed issue in server.js still look…
Browse files Browse the repository at this point in the history
…ing at NODE_ENV. (#104)
  • Loading branch information
rmcvey authored Feb 19, 2019
1 parent f58ba2c commit 38ecdf9
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 20 deletions.
38 changes: 25 additions & 13 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const Resolvers = require('./resolvers/')
const Schema = fs.readFileSync(path.join(__dirname, './schema.graphql'), 'utf8')
const spacesToCamelCase = require('./src/lib/spacesToCamelCase')
const defaultPolicyServer = HOST
const IS_DEV = process.env.NODE_ENV === 'development'
const IS_DEV = process.env.STETHOSCOPE_ENV === 'development'

const app = express()
const http = require('http').Server(app)
Expand All @@ -33,23 +33,23 @@ setKmdEnv({
})

function precompile () {
return glob(path.resolve(__dirname, `./sources/${process.platform}/*.sh`)).then(files => {
return files.map(file => {
const content = readFileSync(file, 'utf8')
const code = compile(content)
return code
})
})
const searchPath = path.resolve(__dirname, `./sources/${process.platform}/*.sh`)
return glob(searchPath)
.then(files =>
files.map(file =>
compile(readFileSync(file, 'utf8'))
)
)
}

// used to ensure that user is not shown multiple notifications for a login scan
// sessionId is used as a key
const alertCache = new Map()

module.exports = async function startServer (env, log, language, appActions) {
module.exports = async function startServer (env, log, language = 'en-US', appActions) {
log.info('starting express server')
const checks = await precompile()
const find = filePath => env === 'development' ? filePath : path.join(__dirname, filePath)
const find = filePath => IS_DEV ? filePath : path.join(__dirname, filePath)

const settingsHandle = fs.readFileSync(find('./practices/config.yaml'), 'utf8')
const defaultConfig = yaml.safeLoad(settingsHandle)
Expand All @@ -69,9 +69,10 @@ module.exports = async function startServer (env, log, language, appActions) {
policyServer = defaultPolicyServer
} = defaultConfig

// wide open in dev, limited to hosts specified in './practices/config.yaml' in production
const corsOptions = {
origin (origin, callback) {
if (env === 'development') return callback(null, true)
if (IS_DEV) return callback(null, true)
if (allowHosts.includes(origin)) return callback(null, true)
if (hostLabels.length) {
const isAllowed = hostLabels
Expand All @@ -97,7 +98,7 @@ module.exports = async function startServer (env, log, language, appActions) {
}
}

if (env === 'development') {
if (IS_DEV) {
const { graphiqlExpress } = require('graphql-server-express')
app.use('/graphiql', cors(corsOptions), graphiqlExpress({ endpointURL: '/scan' }))
}
Expand All @@ -115,6 +116,7 @@ module.exports = async function startServer (env, log, language, appActions) {
const remote = origin !== 'stethoscope://main'
let remoteLabel

// Try to find the host label to display in app ("Last scanned by X")
if (remote) {
try {
const matchHost = ({ pattern }) => (new RegExp(pattern)).test(origin)
Expand All @@ -127,8 +129,13 @@ module.exports = async function startServer (env, log, language, appActions) {
}

let { query, variables: policy, sessionId = false } = req[key]
// native notifications are only shown for external requests and
// are throttled by the users's session id
let showNotification = sessionId && !alertCache.has(sessionId)
const start = performance.now()
// TODO each of these checks should probably be individually executed
// by relecvant resolvers. Since it is currently super fast, there is no
// real performance penalty for running all checks on each request
const checkData = await Promise.all(checks.map(async script => {
const response = await run(script)
return response
Expand All @@ -137,6 +144,8 @@ module.exports = async function startServer (env, log, language, appActions) {

context.kmdResponse = extend(true, {}, ...checkData)

policy = policy || {}

if (sessionId && !alertCache.has(sessionId)) {
alertCache.set(sessionId, true)
}
Expand All @@ -145,6 +154,7 @@ module.exports = async function startServer (env, log, language, appActions) {
policy = JSON.parse(policy)
}

// tell the app if a policy was passed to display scanning status
if (Object.keys(policy).length) {
// show the scan is happening in the UI
io.sockets.emit('scan:init', { remote, remoteLabel })
Expand All @@ -154,6 +164,7 @@ module.exports = async function startServer (env, log, language, appActions) {
const { data = {} } = result
let scanResult = { noResults: true }

// update the tray icon if a policy result is in the response
if (data.policy && data.policy.validate) {
appActions.setScanStatus(data.policy.validate.status)
scanResult = { result, remote, remoteLabel, policy, showNotification }
Expand Down Expand Up @@ -227,7 +238,8 @@ module.exports = async function startServer (env, log, language, appActions) {
})

const serverInstance = http.listen(PORT, '127.0.0.1', () => {
console.log(`local server listening on ${PORT}`)
console.log(`GraphQL server listening on ${PORT}`)
IS_DEV && console.log(`Explore the schema: http://127.0.0.1:${PORT}/graphiql`)
serverInstance.emit('server:ready')
})

Expand Down
7 changes: 6 additions & 1 deletion src/start-react.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* Used in dev - polls for create-react-app HMR server readyness,
* triggers `npm run electron` once react is ready
*/
const net = require('net')
const { spawn } = require('child_process')
const os = require('os')
Expand All @@ -13,7 +17,8 @@ const tryConnection = () => {
client.connect({ port }, () => {
client.end()
if (!startedElectron) {
console.log('starting electron')
console.log(`npm start react:start - react ready on http://127.0.0.1:${port}`)
console.log('npm start electron:start')
startedElectron = true
const cmd = os.platform() === 'win32' ? 'npm.cmd' : 'npm'
const appServer = spawn(cmd, ['run', 'electron'], {
Expand Down
27 changes: 21 additions & 6 deletions src/start.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/**
* main entry point for the electron app. This file configures and initializes
* the entire application which includes:
* - Handle launch/deeplink events
* - Initialize custom protocols used within the app (e.g. app://foo, ps://bar)
* - Initialize auto launch behavior
* - Create the BrowserWindow (stored as global.app for use throughout the app)
* - initialize app menus and dock/tray behavior
* - Start the GraphQL (express) server
* - handle server triggered events (e.g. changing app icon based on policy result)
* - Handle uncaught exceptions in any part of the app
* - Handle IPC calls from other parts of the application
* - 'scan:init' - Automatic update triggered (resizes app, displays progress)
* - 'app:loaded' - Notify when client side app is loaded
* - 'download:completed' - update has finished downloading
*/
const { app, ipcMain, dialog, BrowserWindow, session, Tray, nativeImage } = require('electron')
const path = require('path')
const url = require('url')
Expand Down Expand Up @@ -48,6 +64,7 @@ const windowPrefs = {
}
}

// use build/ assets in production, webpack HMR server in dev
const BASE_URL = process.env.ELECTRON_START_URL || url.format({
pathname: path.join(__dirname, '/../build/index.html'),
protocol: 'file:',
Expand All @@ -69,13 +86,10 @@ const focusOrCreateWindow = () => {
initMenu(mainWindow, app, focusOrCreateWindow, updater, log)
mainWindow.loadURL(BASE_URL)
}

if (IS_DEV) {
loadReactDevTools(mainWindow)
}
}

async function createWindow () {
// used to show initial launch messages to user
if (!settings.has('userHasLaunchedApp')) {
isFirstLaunch = true
settings.set('userHasLaunchedApp', true)
Expand Down Expand Up @@ -105,7 +119,7 @@ async function createWindow () {

// wait for process to load before hiding in dock, prevents the app
// from flashing into view and then hiding
if (!IS_DEV && IS_MAC) setTimeout(() => app.dock.hide(), 0)
if (!IS_DEV && IS_MAC) setImmediate(() => app.dock.hide())
// windows detection of deep link path
if (IS_WIN) deeplinkingUrl = process.argv.slice(1)
// only allow resize if debugging production build
Expand All @@ -114,12 +128,12 @@ async function createWindow () {
mainWindow = new BrowserWindow(windowPrefs)

if (IS_DEV) loadReactDevTools(BrowserWindow)

// open developer console if env vars or args request
if (enableDebugger || DEBUG_MODE) {
mainWindow.webContents.openDevTools()
}

// required at run time so dependencies can be injected
updater = require('./updater')(env, mainWindow, log, server)

if (isLaunching) {
Expand Down Expand Up @@ -268,6 +282,7 @@ app.on('ready', () => setTimeout(() => {
})

if (launchIntoUpdater) {
// triggered via stethoscope://update app link
log.info(`Launching into updater: ${launchIntoUpdater}`)
updater.checkForUpdates(env, mainWindow).catch(err =>
log.error(`start:launch:check for updates exception${err}`)
Expand Down

0 comments on commit 38ecdf9

Please sign in to comment.