Skip to content

Commit 5960e4d

Browse files
committed
Login - closes #64
1 parent 87e9973 commit 5960e4d

28 files changed

+959
-149
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules/
2+
db/
23
*.snap
34
krellian-kiosk_*.txt

chrome/js/kiosk.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const ipcRenderer = electron.ipcRenderer;
33
const parseArgs = require('minimist');
44
const DEFAULT_HOST = 'http://localhost';
55
const DEFAULT_PORT = '8080';
6-
const DEFAULT_PAGE = '/placeholder.html';
6+
const DEFAULT_PAGE = '/display';
77

88
/**
99
* System chrome loaded inside the top level window.

package-lock.json

Lines changed: 92 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"dbus": "^1.0.7",
2323
"dompurify": "^2.0.12",
2424
"express": "^4.17.1",
25+
"jsonwebtoken": "^8.5.1",
2526
"level": "^6.0.1",
2627
"minimist": "^1.2.5"
2728
}

services.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
const express = require('express');
22
const router = require('./services/router');
33
const database = require('./services/database');
4-
const networkManager = require('./services/models/network-manager');
4+
const credentials = require('./services/models/credentials');
5+
const network = require('./services/models/network');
56

67
/**
78
* Services expose kiosk features over HTTP, both locally and via the
@@ -15,11 +16,13 @@ var Services = {
1516
* @param {integer} port HTTP port.
1617
*/
1718
start: function(port) {
18-
// Start database;
19-
database.start();
19+
// Start database and credential manager
20+
database.start()
21+
.then(() => credentials.start())
22+
.catch((error) => {console.log(error)});
2023

2124
// Start network manager
22-
networkManager.start();
25+
network.start();
2326

2427
// Start HTTP server
2528
this.server = express();

services/authentication.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Authenticate user.
3+
*/
4+
5+
'use strict';
6+
7+
const jwt = require('jsonwebtoken');
8+
const credentials = require('./models/credentials');
9+
const DEFAULT_USER = 'admin';
10+
11+
const Authentication = {
12+
/**
13+
* Authenticate user based on username and password.
14+
*
15+
* @param {String} username Username provided by user.
16+
* @param {String} password Password provided by user.
17+
* @return {Promise<Object>} false if invalid, if valid object of the form:
18+
* {
19+
* user: { username: 'admin' },
20+
* jwt: 'fmkdalfmkadl.hfidoafhiado.hifoadhfidao'
21+
* }
22+
*
23+
*/
24+
authenticate: async function(username, password) {
25+
// Check username (currently hard coded)
26+
if (username != DEFAULT_USER) {
27+
return false;
28+
}
29+
30+
// Check Password
31+
return credentials.checkPassword(password).then((match) => {
32+
if (!match) {
33+
return false;
34+
}
35+
const user = { 'username': DEFAULT_USER };
36+
// Get private keys
37+
let privateKey = credentials.getPrivateKey();
38+
// Generate a JWT (JSON Web Token)
39+
// TODO: Send public key with response
40+
const token = jwt.sign(user, privateKey, { algorithm: 'RS256' });
41+
return { user: user, jwt: token };
42+
}).catch((error) => {
43+
console.error('Error checking password: ' + error);
44+
return false;
45+
});
46+
}
47+
};
48+
49+
module.exports = Authentication;

services/authorization.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use strict';
2+
3+
const jwt = require('jsonwebtoken');
4+
const credentials = require('./models/credentials');
5+
6+
/**
7+
* Authorisation middleware.
8+
*
9+
* Checks incoming requests for a valid JSON Web Token.
10+
*
11+
* Note: So far just JWT-based authentication with blanket authorization for
12+
* all requests with a verified JWT which go through this middleware.
13+
*
14+
* @param {Object} request HTTP request object.
15+
* @param {Object} response HTTP response object.
16+
* @param {Object} next Callback.
17+
*/
18+
function middleware(request, response, next) {
19+
let authorized = authorize(request);
20+
if (authorized) {
21+
next();
22+
} else {
23+
response.status(401).send('No valid JWT provided.');
24+
}
25+
}
26+
27+
/**
28+
* Authorisation middleware.
29+
*
30+
* Authorizes a request based on its JWT (JSON Web Token).
31+
*
32+
* @param {Object} request HTTP request object.
33+
*/
34+
function authorize(request) {
35+
const authorization = request.headers.authorization;
36+
// Check for authorization header
37+
if (!authorization) {
38+
return false;
39+
}
40+
const [type, token] = authorization.split(' ');
41+
if (type !== 'Bearer') {
42+
return false;
43+
}
44+
45+
// Get public key to verify JWT
46+
let publicKey = credentials.getPublicKey();
47+
48+
// Try to verify JWT
49+
try {
50+
var decoded = jwt.verify(token, publicKey);
51+
return true;
52+
} catch {
53+
return false;
54+
}
55+
}
56+
57+
58+
module.exports = {
59+
middleware,
60+
authorize
61+
};

services/controllers/actions-controller.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ router.post('/load_url', function(request, response) {
1717
if (request.body) {
1818
var url = request.body;
1919
userAgent.loadURL(url);
20-
response.status(201).send(url);
20+
response.status(201).json(url);
2121
} else {
2222
response.status(400).send();
2323
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Login Controller
3+
*
4+
* Serves requests to /login
5+
*/
6+
7+
'use strict';
8+
9+
const express = require('express');
10+
const router = express.Router();
11+
const authentication = require('../authentication');
12+
13+
router.post('/', (request, response) => {
14+
const username = request.body.username;
15+
const password = request.body.password;
16+
if (!username || !password) {
17+
response.status(400).send('Username or password not provided.');
18+
}
19+
authentication.authenticate(username, password).then((result) => {
20+
if (result == false) {
21+
response.status(401).send('Invalid username or password.');
22+
} else {
23+
response.status(200).json(result);
24+
}
25+
});
26+
});
27+
28+
module.exports = router;

0 commit comments

Comments
 (0)