diff --git a/caplib.js b/caplib.js index f5cab22..5af6264 100644 --- a/caplib.js +++ b/caplib.js @@ -17,9 +17,6 @@ information regarding how to obtain the source code for this library. /*global console, require, module */ module.exports = function() { "use strict"; -var fs = require("fs"); -var path = require("path"); -var crypto = require("crypto"); /** * Function typeCheck allows a quick, concise limited form of duck typing of the * arguments to a function. The function using typeCheck should pass in its @@ -77,6 +74,8 @@ function tvalid(args, types, additionalTest, errMsg) { return valid(typeCheck(args, types) && additionalTest, errMsg); } +function makeUnique(crypto) { + function unique() { var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; var ans = ""; @@ -91,6 +90,12 @@ function unique() { //} return ans; } + + return { + unique: unique + }; +} + function makeSealerPair() { var holder = null; function seal(x) { @@ -174,6 +179,9 @@ function argMap(argv, webkeyStringToLive) { return args; } + +function makeFileUtils(fs, path) { + function copyFile(src, dest) { var data = fs.readFileSync(src); fs.writeFileSync(dest); @@ -205,17 +213,22 @@ function makeNewServer() { copyIfAbsent("ssl"); } + return { + makeNewServer: makeNewServer, + copyRecurse: copyRecurse + }; +} + var self = { typeCheck: typeCheck, - unique: unique, + makeUnique: makeUnique, valid: valid, tvalid: tvalid, makeSealerPair: makeSealerPair, cloneMap: cloneMap, argMap:argMap, deepObjToJSON: deepObjToJSON, - makeNewServer: makeNewServer, - copyRecurse: copyRecurse + makeFileUtils: makeFileUtils }; return self; diff --git a/saver.js b/saver.js index 04d97db..4ce8f0b 100644 --- a/saver.js +++ b/saver.js @@ -15,12 +15,14 @@ information regarding how to obtain the source code for this library. */ /*global require, Map, console, Proxy, setImmediate */ -var fs = require("fs"); var Q = require("q"); var caplib = require("./caplib"); module.exports = function(){ "use strict"; + + function makeSaver(unique, fs, fss, require) { + var dbfile = "capper.db"; function log(text) {console.log(text);} @@ -79,8 +81,8 @@ module.exports = function(){ **/ var sysState = {}; function loadSysState(){ - if (!fs.existsSync(dbfile)) {fs.writeFileSync(dbfile, "{}");} - var jsonState = fs.readFileSync(dbfile, 'utf8'); + if (!fss.existsSync(dbfile)) {fss.writeFileSync(dbfile, "{}");} + var jsonState = fss.readFileSync(dbfile, 'utf8'); if (jsonState.length === 0) {jsonState = "{}";} sysState = JSON.parse(jsonState); } @@ -250,7 +252,7 @@ module.exports = function(){ } make = function(makerLocation, optInitArgs) { setupCheckpoint(); - var cred = caplib.unique(); + var cred = unique(); var newId = credToId(cred); sysState[cred] = {data: {}, reviver: makerLocation}; var newContext = makeContext(newId); @@ -326,4 +328,7 @@ module.exports = function(){ drop: drop }; return Object.freeze(self); -}(); \ No newline at end of file +} + + return makeSaver; +}(); diff --git a/server.js b/server.js index 582d9a5..abc2626 100644 --- a/server.js +++ b/server.js @@ -16,14 +16,13 @@ information regarding how to obtain the source code for this library. /*global require, console, process */ "use strict"; -var https = require("https"); -var fs = require("fs"); -var express = require("express"); var Q = require("q"); var caplib = require("./caplib"); -var saver = require("./saver"); +var makeSaver = require("./saver"); var log = function(text) {console.log(text);}; +function makeConfig(fs) { + var domain; var port; var deferStart = Q.defer(); @@ -33,8 +32,13 @@ fs.readFile("capper.config", "utf8", function(err, data) { port = config.port; domain = config.protocol + "://" + config.domain + ":" + config.port + "/"; log("config domain " + domain); - deferStart.resolve(true); + deferStart.resolve({domain: domain, port: port}); }); + + return deferStart.promise; +} + +function sslOptions(fs) { var sslOptions = { key: fs.readFileSync('./ssl/server.key'), cert: fs.readFileSync('./ssl/server.crt'), @@ -42,7 +46,10 @@ var sslOptions = { requestCert: true, rejectUnauthorized: false }; -var app = express(); + return sslOptions; +} + + function parseBody(req, res, next) { req.rawBody = ''; req.setEncoding('utf8'); @@ -65,18 +72,20 @@ function reviverToUIPath(reviver) { revstring += filename + ".html"; return revstring; } -function getObj(req) { - var cred = req.query.s; - var id = saver.credToId(cred); - var reviver = saver.reviver(id); - var live = saver.live(id); - return { - cred: cred, - reviver: reviver, - live: live, - id: id, - method: req.query.q - }; + +function makeSturdy(saver, domain) { + +function vowAnsToVowJSONString(vowAns) { + return vowAns.then(function(ans) { + var result = caplib.deepObjToJSON(ans, idToWebkey, saver); + log(JSON.stringify(result)); + if (result !== null && typeof result === "object" && ("@" in result)) { + return JSON.stringify(result); + } else {return JSON.stringify({"=": result});} + }, function(err){ + log("vowAnsToVowJSONString err " + err); + return JSON.stringify({"!": err}); + }); } /** * webkeyToLive(wkeyObj) looks to see if the arg is a webkeyObject, if so, @@ -94,6 +103,26 @@ function webkeyToLive(wkeyObj) { function idToWebkey(id) { return domain + "ocaps/#s=" + saver.idToCred(id); } + +function wkeyStringToLive(keyString) { + return webkeyToLive({"@": keyString}); +} + + return { + idToWebkey: idToWebkey, + vowAnsToVowJSONString: vowAnsToVowJSONString, + webkeyToLive: webkeyToLive, + wkeyStringToLive + }; +} + +// express is *nearly* powerless, but it seems to appeal +// to at least path.resolve() +function makeApp(express, saver, sturdy) { + var webkeyToLive = sturdy.webkeyToLive; + var vowAnsToVowJSONString = sturdy.vowAnsToVowJSONString; + +var app = express(); app.get("/views/:filename", function(req, res) { res.sendfile("./views/" + req.params.filename); }); @@ -106,6 +135,21 @@ app.get("/apps/:theapp/ui/:filename", function(req, res) { app.get('/', function(req, res) { res.sendfile('./views/index.html'); }); + +function getObj(req) { + var cred = req.query.s; + var id = saver.credToId(cred); + var reviver = saver.reviver(id); + var live = saver.live(id); + return { + cred: cred, + reviver: reviver, + live: live, + id: id, + method: req.query.q + }; +} + function showActor(req, res) { if (!req.query.s ) { res.sendfile("./bootstrap.html"); @@ -125,19 +169,6 @@ function showActor(req, res) { } app.get("/ocaps/", showActor); -function vowAnsToVowJSONString(vowAns) { - return vowAns.then(function(ans) { - var result = caplib.deepObjToJSON(ans, idToWebkey, saver); - log(JSON.stringify(result)) - if (result !== null && typeof result === "object" && ("@" in result)) { - return JSON.stringify(result); - } else {return JSON.stringify({"=": result});} - }, function(err){ - log("vowAnsToVowJSONString err " + err); - return JSON.stringify({"!": err}); - }); -} - function invokeActor(req, res){ log("post query " + JSON.stringify(req.query)); log("post body: " + JSON.stringify(req.body)); @@ -158,11 +189,21 @@ function invokeActor(req, res){ } app.post("/ocaps/", parseBody, invokeActor); -function wkeyStringToLive(keyString) { - return webkeyToLive({"@": keyString}); + return app; } -deferStart.promise.then(function(){ - var argMap = caplib.argMap(process.argv, wkeyStringToLive); + + +function main(argv, require, crypto, fs, fsSync, https, express) { + const unique = caplib.makeUnique(crypto); + const saver = makeSaver(unique.unique, fs, fsSync, require); + + makeConfig(fs).then(config => { + const sturdy = makeSturdy(saver, config.domain); + const wkeyStringToLive = sturdy.wkeyStringToLive; + const idToWebkey = sturdy.idToWebkey; + const vowAnsToVowJSONString = sturdy.vowAnsToVowJSONString; + + var argMap = caplib.argMap(argv, wkeyStringToLive); if ("-drop" in argMap) { saver.drop(saver.credToId(argMap["-drop"][0])); saver.checkpoint().then(function() {console.log("drop done");}); @@ -186,7 +227,25 @@ deferStart.promise.then(function(){ }); } } else { - var s = https.createServer(sslOptions, app); + const app = makeApp(express, saver, config.domain); + const sslOpts = sslOptions(fsSync); + const port = config.port; + + var s = https.createServer(sslOpts, app); s.listen(port); } -}); + }); +} + + +if (require.main == module) { + main(process.argv, + require, // to load app modules + require("crypto"), + { readFile: require("fs").readFile, + writeFile: require("fs").writeFile }, + require("fs"), + { createServer: require("https").createServer }, + require("express") + ); +}