diff --git a/package.json b/package.json
index 3ddba55..66755c3 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/src/main/api.js b/src/main/api.js
index 78bbd7c..7100e19 100644
--- a/src/main/api.js
+++ b/src/main/api.js
@@ -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())
@@ -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
}
}
diff --git a/src/main/certificate.js b/src/main/certificate.js
new file mode 100644
index 0000000..192a15c
--- /dev/null
+++ b/src/main/certificate.js
@@ -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
+}
diff --git a/src/main/configuration.js b/src/main/configuration.js
new file mode 100644
index 0000000..23f8de4
--- /dev/null
+++ b/src/main/configuration.js
@@ -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
+}
diff --git a/src/main/index.js b/src/main/index.js
index 561cded..0987598 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -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
@@ -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)
}
/**
diff --git a/src/renderer/components/Home.vue b/src/renderer/components/Home.vue
index 79762f6..9bd45c1 100644
--- a/src/renderer/components/Home.vue
+++ b/src/renderer/components/Home.vue
@@ -53,9 +53,7 @@
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/src/renderer/main.js b/src/renderer/main.js
index 0c4fc5f..0246164 100644
--- a/src/renderer/main.js
+++ b/src/renderer/main.js
@@ -1,12 +1,19 @@
+import { remote } from 'electron'
import Vue from 'vue'
-import axios from 'axios'
import App from './App'
import router from './router'
+import http from './plugins/http'
+
+const api = remote.getGlobal('printrz').api
if (!process.env.IS_WEB) Vue.use(require('vue-electron'))
-Vue.http = Vue.prototype.$http = axios
Vue.config.productionTip = false
+Vue.use(http, {
+ protocol: api.isHttps ? 'https' : 'http',
+ host: 'localhost',
+ port: api.port
+})
/* eslint-disable no-new */
new Vue({
diff --git a/src/renderer/plugins/http.js b/src/renderer/plugins/http.js
new file mode 100644
index 0000000..facb71d
--- /dev/null
+++ b/src/renderer/plugins/http.js
@@ -0,0 +1,9 @@
+import axios from 'axios'
+
+export default {
+ install: function (Vue, { protocol, host, port }) {
+ Vue.http = Vue.prototype.$http = axios.create({
+ baseURL: `${protocol}://${host}:${port}`
+ })
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index 3f4de68..67ef7c7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7311,6 +7311,11 @@ node-forge@0.7.5:
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"
integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==
+node-forge@^0.8.2:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.8.2.tgz#b4bcc59fb12ce77a8825fc6a783dfe3182499c5a"
+ integrity sha512-mXQ9GBq1N3uDCyV1pdSzgIguwgtVpM7f5/5J4ipz12PKWElmPpVWLDuWl8iXmhysr21+WmX/OJ5UKx82wjomgg==
+
node-gyp@^3.8.0:
version "3.8.0"
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c"