From 0a3c758ad7e167eba244b1002efcd3d435f1af23 Mon Sep 17 00:00:00 2001 From: Will Murphy Date: Sat, 14 Sep 2019 21:49:33 -0500 Subject: [PATCH] generate keys for local users --- config-template.json | 3 ++- db/setup.js | 21 +++++------------- routes/inbox.js | 2 +- routes/outbox.js | 2 +- routes/user.js | 12 ++++++---- utils/index.js | 52 +++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 66 insertions(+), 26 deletions(-) diff --git a/config-template.json b/config-template.json index a1c50a4..861affa 100644 --- a/config-template.json +++ b/config-template.json @@ -4,5 +4,6 @@ "DOMAIN": "", "PORT": "3000", "PRIVKEY_PATH": "", - "CERT_PATH": "" + "CERT_PATH": "", + "KEYPASS": "" } diff --git a/db/setup.js b/db/setup.js index 8651066..4ad9d81 100644 --- a/db/setup.js +++ b/db/setup.js @@ -1,3 +1,6 @@ +const utils = require('../utils') +const crypto = require('crypto') + module.exports = async function dbSetup (db, domain) { await db.collection('streams').createIndex({ _target: 1, @@ -7,24 +10,10 @@ module.exports = async function dbSetup (db, domain) { actor: 1, _id: -1, }) + const dummyUser = await utils.createLocalActor('dummy', 'Person') await db.collection('objects').findOneAndReplace( {preferredUsername: 'dummy'}, - { - id: `https://${domain}/u/dummy`, - "type": "Person", - "following": `https://${domain}/u/dummy/following`, - "followers": `https://${domain}/u/dummy/followers`, - "liked": `https://${domain}/u/dummy/liked`, - "inbox": `https://${domain}/u/dummy/inbox`, - "outbox": `https://${domain}/u/dummy/outbox`, - "preferredUsername": "dummy", - "name": "Dummy Person", - "summary": "Gotta have someone in the db", - "icon": `http://${domain}/f/dummy.png`, - attachment: [ - `http://${domain}/f/dummy.glb` - ] - }, + dummyUser, { upsert: true, returnOriginal: false, diff --git a/routes/inbox.js b/routes/inbox.js index e476306..9dc4984 100644 --- a/routes/inbox.js +++ b/routes/inbox.js @@ -20,7 +20,7 @@ router.get('/', function (req, res) { db.collection('streams') .find({_target: req.user}) .sort({_id: -1}) - .project({_id: 0, _target: 0, '@context': 0, 'object._id': 0, 'object.@context': 0}) + .project({_id: 0, _target: 0, _meta: 0, '@context': 0, 'object._id': 0, 'object.@context': 0, 'objecct._meta': 0}) .toArray() .then(stream => res.json(utils.arrayToCollection(stream, true))) .catch(err => { diff --git a/routes/outbox.js b/routes/outbox.js index 5f8658b..f7ceb6d 100644 --- a/routes/outbox.js +++ b/routes/outbox.js @@ -19,7 +19,7 @@ router.get('/', function (req, res) { db.collection('streams') .find({actor: utils.userNameToIRI(req.user)}) .sort({_id: -1}) - .project({_id: 0, _target: 0, 'object._id': 0, 'object.@context': 0}) + .project({_id: 0, _target: 0, _meta: 0, 'object._id': 0, 'object.@context': 0, 'object._meta': 0}) .toArray() .then(stream => res.json(utils.arrayToCollection(stream, true))) .catch(err => { diff --git a/routes/user.js b/routes/user.js index 0688f8a..6f6b9e8 100644 --- a/routes/user.js +++ b/routes/user.js @@ -1,7 +1,7 @@ 'use strict'; const express = require('express'), router = express.Router(); -// const inbox = require('./inbox'); +const utils = require('../utils') const {toJSONLD} = require('../utils/index.js'); router.get('/:name', async function (req, res) { @@ -11,10 +11,14 @@ router.get('/:name', async function (req, res) { } else { let objs = req.app.get('objs'); - const id = `https://${req.app.get('domain')}/u/${name}` + let db = req.app.get('db') + const id = utils.userNameToIRI(name) console.log(`looking up '${id}'`) - const user = await objs.findOne({type: 'Person', id: id}, {fields: {_id: 0}}) - // .project({_id: 0}) + const user = await db.collection('objects') + .find({type: 'Person', id: id}) + .limit(1) + .project({_id: 0, _meta: 0}) + .next() if (user) { return res.json(toJSONLD(user)) } diff --git a/utils/index.js b/utils/index.js index 29db058..9554752 100644 --- a/utils/index.js +++ b/utils/index.js @@ -1,4 +1,6 @@ -const { ASContext } = require('./consts') +const crypto = require('crypto') +const {promisify} = require('util') +const {ASContext} = require('./consts') module.exports.validators = require('./validators'); const config = require('../config.json') @@ -32,6 +34,50 @@ module.exports.arrayToCollection = function (arr, ordered) { } } -module.exports.userNameToIRI = function (user) { +function userNameToIRI (user) { return `https://${config.DOMAIN}/u/${user}` -} \ No newline at end of file +} +module.exports.userNameToIRI = userNameToIRI + +const generateKeyPairPromise = promisify(crypto.generateKeyPair) +module.exports.createLocalActor = function (name, type) { + return generateKeyPairPromise('rsa', { + modulusLength: 4096, + publicKeyEncoding: { + type: 'spki', + format: 'pem' + }, + privateKeyEncoding: { + type: 'pkcs8', + format: 'pem', + cipher: 'aes-256-cbc', + passphrase: config.KEYPASS + } + }).then(pair => { + const actorBase = userNameToIRI(name); + return { + _meta: { + privateKey: pair.privateKey, + }, + id: `${actorBase}`, + "type": type, + "following": `${actorBase}/following`, + "followers": `${actorBase}/followers`, + "liked": `${actorBase}/liked`, + "inbox": `${actorBase}/inbox`, + "outbox": `${actorBase}/outbox`, + "preferredUsername": name, + "name": "Dummy Person", + "summary": "Gotta have someone in the db", + "icon": `http://${config.DOMAIN}/f/${name}.png`, + attachment: [ + `http://${config.DOMAIN}/f/${name}.glb` + ], + publicKey: { + 'id': `${actorBase}#main-key`, + 'owner': `${actorBase}`, + 'publicKeyPem': pair.publicKey + }, + } + }) +}