...
 
Commits (3)
......@@ -39,6 +39,10 @@ class Keys {
this.privateKey = sodium.crypto_secretbox_open_easy(this.encryptedPrivateKey, this.nonce, this.password)
}
signMessage (nonce) {
return sodium.crypto_sign(nonce, this.privateKey)
}
stringify (value) {
return sodium.to_hex(value)
}
......
const indexedDB = require('./indexedDB')
const form = document.getElementById('logout')
form.addEventListener('submit', (e) => {
e.preventDefault()
indexedDB.callOnStore('Indienet', 'keyStore', (store) => {
store.clear()
window.location = '/sign-in.html'
})
})
......@@ -5,6 +5,7 @@ const indexedDB = require('./indexedDB')
const Keys = require('./keys')
const form = document.getElementById('register')
const privateForm = document.getElementById('private')
function loadedKeyPair () {
indexedDB.callOnStore('testkeystore', 'keyStore', (store) => {
......@@ -44,3 +45,25 @@ form.addEventListener('submit', (e) => {
console.log(err)
})
})
privateForm.addEventListener('submit', (e) => {
e.preventDefault()
indexedDB.callOnStore('Indienet', 'keyStore', (store) => {
const getData = store.get(2)
getData.onsuccess = (event) => {
const jwt = getData.result.jwt
axios({
url: 'private',
method: 'get',
headers: {'Authorization': `Bearer ${jwt}` },
}).then((data) => {
console.log(data)
}).catch((err) => {
console.log(err)
})
}
})
})
......@@ -22,7 +22,21 @@ form.addEventListener('submit', (e) => {
unencryptedPrivateKey: key.privateKey
})
})
console.log(key)
return axios.get('authorize/nonce')
}).then((nonce) => {
const signedMessage = key.signMessage(key.parse(nonce.data))
return axios.post('authorize', {
signedMessage: key.stringify(signedMessage)
})
}).then((jwt) => {
indexedDB.callOnStore('Indienet', 'keyStore', (store) => {
store.put({
id: 2,
jwt: jwt.data
})
})
window.location = "signed-in.html"
}).catch((err) => {
console.log(err)
})
......
This diff is collapsed.
......@@ -35,6 +35,8 @@
"mocha": "mocha test/ --recursive --exit"
},
"dependencies": {
"@feathersjs/authentication": "^2.1.1",
"@feathersjs/authentication-jwt": "^2.0.0",
"@feathersjs/configuration": "^1.0.2",
"@feathersjs/errors": "^3.2.2",
"@feathersjs/express": "^1.1.2",
......@@ -44,6 +46,7 @@
"compression": "^1.7.1",
"cors": "^2.8.4",
"helmet": "^3.9.0",
"jsonwebtoken": "^8.1.1",
"libsodium-wrappers": "^0.7.3",
"serve-favicon": "^2.4.5",
"winston": "^2.4.0"
......
......@@ -8,6 +8,11 @@
<input type="password" name="password" id="password">
<input type="submit" value="Create site">
</form>
<form action="private" id="private">
<input type="submit" value="Get private data">
</form>
<script src="js/script.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Succesfully signed in</title>
</head>
<body>
<h1>Welcome to my.gent</h1>
<p>This is my personal space</p>
<form action="logout" id="logout">
<input type="submit" value="Log out">
</form>
<script src="js/logout.js"></script>
</body>
</html>
\ No newline at end of file
......@@ -9,6 +9,8 @@ const feathers = require('@feathersjs/feathers')
const configuration = require('@feathersjs/configuration')
const express = require('@feathersjs/express')
const socketio = require('@feathersjs/socketio')
const authentication = require('@feathersjs/authentication');
const jwt = require('@feathersjs/authentication-jwt');
const middleware = require('./middleware')
const services = require('./services')
......@@ -32,6 +34,8 @@ app.use('/', express.static(app.get('public')))
// Set up Plugins and providers
app.configure(express.rest())
app.configure(socketio())
app.configure(authentication({secret: "dit is een secret", service: 'private'}));
app.configure(jwt());
// Configure other middleware (see `middleware/index.js`)
app.configure(middleware)
......
const errors = require('@feathersjs/errors')
const sodium = require('libsodium-wrappers')
const jwt = require('jsonwebtoken')
const fileUtils = require('../../utils/fileUtils')
class Service {
constructor (options) {
......@@ -7,7 +9,7 @@ class Service {
}
async find (params) {
return [];
return []
}
async get (id, params) {
......@@ -18,11 +20,18 @@ class Service {
}
async create (data, params) {
if (Array.isArray(data)) {
return await Promise.all(data.map(current => this.create(current)));
const signedMessage = sodium.from_hex(data.signedMessage)
const keys = await fileUtils.readFile('./server/files/keys.json')
const publicKey = JSON.parse(keys).publicKey
const nonce = sodium.crypto_sign_open(signedMessage, sodium.from_hex(publicKey))
if(nonce == -1) {
const error = new errors.NotAuthenticated('You\'re not authorized', err)
throw error
} else {
const salt = sodium.randombytes_buf(sodium.crypto_pwhash_SALTBYTES)
this.options.app.set('secret', salt)
return jwt.sign({ nonce }, sodium.to_hex(salt));
}
return data;
}
async update (id, data, params) {
......
......@@ -8,7 +8,8 @@ module.exports = function (app) {
const options = {
name: 'authorize',
paginate
paginate,
app
};
// Initialize our service with any options it requires
......
const keys = require('./keys/keys.service.js');
const authorize = require('./authorize/authorize.service.js');
const private = require('./private/private.service.js');
module.exports = function (app) {
app.configure(keys);
app.configure(authorize);
app.configure(private);
};
/* eslint-disable no-unused-vars */
class Service {
constructor (options) {
this.options = options || {};
}
async find (params) {
return ['dit is alle data'];
}
async get (id, params) {
return {
id, text: `A new message with ID: ${id}!`
};
}
async create (data, params) {
if (Array.isArray(data)) {
return await Promise.all(data.map(current => this.create(current)));
}
return data;
}
async update (id, data, params) {
return data;
}
async patch (id, data, params) {
return data;
}
async remove (id, params) {
return { id };
}
}
module.exports = function (options) {
return new Service(options);
};
module.exports.Service = Service;
const authentication = require('@feathersjs/authentication');
module.exports = {
before: {
all: [],
find: [
authentication.hooks.authenticate('jwt')
],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
after: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
error: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
}
};
// Initializes the `private` service on path `/private`
const createService = require('./private.class.js');
const hooks = require('./private.hooks');
module.exports = function (app) {
const paginate = app.get('paginate');
const options = {
name: 'private',
paginate
};
// Initialize our service with any options it requires
app.use('/private', createService(options));
// Get our initialized service so that we can register hooks and filters
const service = app.service('private');
service.hooks(hooks);
};
const assert = require('assert');
const app = require('../../server/app');
describe('\'private\' service', () => {
it('registered the service', () => {
const service = app.service('private');
assert.ok(service, 'Registered the service');
});
});