Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto updater, server port and SSL certificate #6

Merged
merged 3 commits into from
May 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"ip": "^1.1.5",
"material-icons": "^0.3.1",
"morgan": "^1.9.1",
"node-forge": "^0.8.2",
"printer": "^0.2.2",
"vue": "^2.5.16",
"vue-electron": "^1.0.6",
Expand Down
57 changes: 32 additions & 25 deletions src/main/api.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
const express = require('express')
const cors = require('cors')
const bodyParser = require('body-parser')
const logger = require('morgan')
const printer = require('printer')
const port = 5000
import { app } from 'electron'
import express from 'express'
import cors from 'cors'
import bodyParser from 'body-parser'
import logger from 'morgan'
import printer from 'printer'
import https from 'https'
import { getCertificateFiles } from './certificate'

export default function (callback) {
export default function ({ port }) {
const server = express()
server.use(cors())
server.use(bodyParser.json())
Expand Down Expand Up @@ -48,26 +50,31 @@ export default function (callback) {
}
})
})
/* const instance = */server.listen(port, () => {

let isHttps = false
let callback = () => {
console.log(`Print server listening on port ${port}!`)
if (callback) {
callback()
}
})
}
try {
console.log('Starting server on HTTPS...')
let certFiles = getCertificateFiles(app.getPath('userData'), true)
https
.createServer(
{
key: certFiles.privateKey,
cert: certFiles.certificate
},
server
)
.listen(port, callback)
isHttps = true
} catch (e) {
console.log('Cannot run with HTTPS, fallback on HTTP...')
server.listen(port, callback)
}

return {
// TODO: fix that stuff
/* stopServer () {
return new Promise((resolve, reject) => {
try {
instance.close(() => {
console.log(`Print server stopped!`)
resolve()
})
} catch (e) {
reject(e)
}
})
} */
isHttps,
port
}
}
87 changes: 87 additions & 0 deletions src/main/certificate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import fs from 'fs'
import path from 'path'
import forge from 'node-forge'
import { promisify } from 'util'
const readFileAsync = promisify(fs.readFile)
const writeFileAsync = promisify(fs.writeFile)
forge.options.usePureJavaScript = true

/**
* Get certificate files paths and names
* @param {String} certsPath The certificate's files main location
*/
let getPaths = function (certsPath) {
return {
key: path.join(certsPath, 'key.pem'),
cert: path.join(certsPath, 'cert.pem')
}
}

/**
* Get certificate files content
* @param {String} certsPath The certificate's files main location
* @param {*} sync If true, load the file synchronously (default false)
*/
let getCertificateFiles = function (certsPath, sync = false) {
let paths = getPaths(certsPath)

if (sync) {
return {
privateKey: fs.readFileSync(paths.key),
certificate: fs.readFileSync(paths.cert)
}
}

return Promise.all([
readFileAsync(paths.key),
readFileAsync(paths.cert)
]).then(results => ({
privateKey: results[0],
certificate: results[1]
}))
}

/**
* Generate new SSL certificate files
* @param {String} certsPath The certificate's files main location
* @param {Object} object The certificate attributes
*/
let generateCertificateFiles = function (certsPath, { organizationName, countryName, stateOrProvinceName, localityName }) {
let paths = getPaths(certsPath)
let pki = forge.pki
let keys = pki.rsa.generateKeyPair(2048)
let cert = pki.createCertificate()
let attributes = [
{name: 'commonName', value: organizationName},
{name: 'countryName', value: countryName},
{shortName: 'ST', value: stateOrProvinceName},
{name: 'localityName', value: localityName},
{name: 'organizationName', value: organizationName},
{shortName: 'OU', value: organizationName}
]

cert.publicKey = keys.publicKey
cert.serialNumber = '01'
cert.validity.notBefore = new Date()
cert.validity.notAfter = new Date()
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 10)
cert.setSubject(attributes)
cert.setIssuer(attributes)
cert.sign(keys.privateKey)
let privateKey = pki.privateKeyToPem(keys.privateKey)
let certificate = pki.certificateToPem(cert)

return Promise.all([
writeFileAsync(paths.key, privateKey),
writeFileAsync(paths.cert, certificate)
]).then(() => ({
privateKey,
certificate
}))
}

export {
getPaths,
getCertificateFiles,
generateCertificateFiles
}
62 changes: 62 additions & 0 deletions src/main/configuration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import fs from 'fs'
import path from 'path'
import { promisify } from 'util'
const readFileAsync = promisify(fs.readFile)
const writeFileAsync = promisify(fs.writeFile)
const DEFAULT_CONFIGURATION = {
port: 5000
}

/**
* Get the path to the configuration file
* @param {String} configPath The path to root directory of config.json
*/
let getFilePath = function (configPath) {
return path.join(configPath, 'config.json')
}

/**
* Get the configuration file content (parsed to object)
* @param {String} configPath The path to root directory of config.json
* @param {Boolean} sync If true, load the file synchronously (default false)
*/
let getConfiguration = function (configPath, sync = false) {
let filePath = getFilePath(configPath)

if (sync) {
try {
return JSON.parse(fs.readFileSync(filePath))
} catch (e) {
return DEFAULT_CONFIGURATION
}
}

return readFileAsync(filePath)
.then(content => JSON.parse(content))
.catch(() => DEFAULT_CONFIGURATION)
}

/**
* Update the configuration file with full/partial configuration
* @param {String} configPath The path to root directory of config.json
* @param {Object} configuration A partial object which will be stored in the config.json file
*/
let setConfiguration = function (configPath, configuration) {
let filePath = getFilePath(configPath)
return getConfiguration(configPath)
.then(content => {
return writeFileAsync(
filePath,
JSON.stringify(
Object.assign({}, content, configuration),
null, 4
)
)
})
}

export {
getFilePath,
getConfiguration,
setConfiguration
}
9 changes: 7 additions & 2 deletions src/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { app, BrowserWindow } from 'electron'
import { autoUpdater } from 'electron-updater'
import log from 'electron-log'
import Api from './api'
import { getConfiguration } from './configuration'

app.commandLine.appendSwitch('ignore-certificate-errors')

/**
* Auto Updater
Expand All @@ -30,10 +33,12 @@ const winURL = process.env.NODE_ENV === 'development'
: `file://${__dirname}/index.html`

function createWindow () {
if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdatesAndNotify()

let conf = getConfiguration(app.getPath('userData'), true)
global.printrz = {
api: new Api()
configuration: conf,
api: new Api(conf)
}

/**
Expand Down
6 changes: 2 additions & 4 deletions src/renderer/components/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@

<script>
import Vue from 'vue'
import axios from 'axios'
import { MdCard, MdButton, MdDialog, MdEmptyState, MdSubheader } from 'vue-material/dist/components'
// import Api from '&/api.js'

Vue.use(MdCard)
Vue.use(MdButton)
Expand All @@ -79,7 +77,7 @@

methods: {
fetchPrinters () {
axios.get('http://localhost:5000/printers').then(response => {
this.$http.get('/printers').then(response => {
this.printers = response.data
})
},
Expand Down Expand Up @@ -117,7 +115,7 @@
cmds += newLine + newLine
cmds += '11/03/13 19:53:17'
cmds += newLine + newLine + newLine + newLine
axios.post('http://localhost:5000/job', {
this.$http.post('/job', {
printer: printer.name,
type: 'RAW',
data: cmds
Expand Down
Loading