Completely remove saving ssb keys to the filesystem, now the key is used on every request from the cookies and stays just in memory
This commit is contained in:
parent
37ff8c895e
commit
4e430255b6
|
@ -5,13 +5,8 @@ const port = process.env.PORT || 7624;
|
||||||
const bodyParser = require("body-parser");
|
const bodyParser = require("body-parser");
|
||||||
const {
|
const {
|
||||||
asyncRouter,
|
asyncRouter,
|
||||||
writeKey,
|
|
||||||
nextIdentityFilename,
|
|
||||||
reconstructKeys,
|
reconstructKeys,
|
||||||
readKey,
|
|
||||||
uploadPicture,
|
uploadPicture,
|
||||||
identityFilename,
|
|
||||||
ssbFolder,
|
|
||||||
isPhone,
|
isPhone,
|
||||||
} = require("./utils");
|
} = require("./utils");
|
||||||
const queries = require("./queries");
|
const queries = require("./queries");
|
||||||
|
@ -77,18 +72,15 @@ app.use(async (req, res, next) => {
|
||||||
};
|
};
|
||||||
res.locals.context = req.context;
|
res.locals.context = req.context;
|
||||||
try {
|
try {
|
||||||
const identities = await ssb.client().identities.list();
|
|
||||||
const key = req.signedCookies["ssb_key"];
|
const key = req.signedCookies["ssb_key"];
|
||||||
if (!key) return next();
|
if (!key) return next();
|
||||||
|
|
||||||
const parsedKey = JSON.parse(key);
|
const parsedKey = JSON.parse(key);
|
||||||
if (!identities.includes(parsedKey.id)) {
|
if (!parsedKey.id) return next();
|
||||||
const filename = await nextIdentityFilename(ssb.client());
|
|
||||||
|
|
||||||
writeKey(key, `/identities/${filename}`);
|
ssb.client().identities.addUnboxer(parsedKey);
|
||||||
ssb.client().identities.refresh();
|
|
||||||
}
|
|
||||||
req.context.profile = await queries.getProfile(parsedKey.id);
|
req.context.profile = await queries.getProfile(parsedKey.id);
|
||||||
|
req.context.profile.key = parsedKey;
|
||||||
|
|
||||||
const isRootUser =
|
const isRootUser =
|
||||||
req.context.profile.id == ssb.client().id ||
|
req.context.profile.id == ssb.client().id ||
|
||||||
|
@ -199,11 +191,11 @@ const doLogin = async (submittedKey, res) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
router.get("/login", { public: true }, async (req, res) => {
|
router.get("/login", { public: true }, async (req, res) => {
|
||||||
const login_key =
|
const loginKey =
|
||||||
req.query.key && Buffer.from(req.query.key, "base64").toString("utf8");
|
req.query.key && Buffer.from(req.query.key, "base64").toString("utf8");
|
||||||
|
|
||||||
if (login_key) {
|
if (loginKey) {
|
||||||
await doLogin(JSON.parse(login_key), res);
|
await doLogin(loginKey, res);
|
||||||
} else {
|
} else {
|
||||||
res.render("shared/login", { mode });
|
res.render("shared/login", { mode });
|
||||||
}
|
}
|
||||||
|
@ -241,31 +233,26 @@ router.post("/signup", { public: true }, async (req, res) => {
|
||||||
|
|
||||||
const pictureLink = picture && (await uploadPicture(ssb.client(), picture));
|
const pictureLink = picture && (await uploadPicture(ssb.client(), picture));
|
||||||
|
|
||||||
const filename = await nextIdentityFilename(ssb.client());
|
const key = await ssb.client().identities.createNewKey();
|
||||||
const profileId = await ssb.client().identities.create();
|
|
||||||
const key = readKey(`/identities/${filename}`);
|
|
||||||
if (key.id != profileId)
|
|
||||||
throw "profileId and key.id don't match, probably race condition, bailing out for safety";
|
|
||||||
|
|
||||||
debug("Created new user with id", profileId);
|
|
||||||
|
|
||||||
res.cookie("ssb_key", JSON.stringify(key), cookieOptions);
|
res.cookie("ssb_key", JSON.stringify(key), cookieOptions);
|
||||||
key.private = "[removed]";
|
|
||||||
debug("Generated key", key);
|
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: profileId,
|
key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "about",
|
type: "about",
|
||||||
about: profileId,
|
about: key.id,
|
||||||
name: name,
|
name: name,
|
||||||
...(pictureLink ? { image: pictureLink } : {}),
|
...(pictureLink ? { image: pictureLink } : {}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
debug("Published about", { about: profileId, name, image: pictureLink });
|
|
||||||
|
|
||||||
await queries.autofollow(profileId);
|
const debugKey = { ...key, private: "[removed]" };
|
||||||
|
debug("Generated key", debugKey);
|
||||||
|
|
||||||
|
debug("Published about", { about: key.id, name, image: pictureLink });
|
||||||
|
|
||||||
|
await queries.autofollow(key.id);
|
||||||
|
|
||||||
res.redirect("/keys");
|
res.redirect("/keys");
|
||||||
});
|
});
|
||||||
|
@ -273,7 +260,7 @@ router.post("/signup", { public: true }, async (req, res) => {
|
||||||
router.get("/keys", (req, res) => {
|
router.get("/keys", (req, res) => {
|
||||||
res.render("shared/keys", {
|
res.render("shared/keys", {
|
||||||
useEmail: process.env.SENDGRID_API_KEY,
|
useEmail: process.env.SENDGRID_API_KEY,
|
||||||
key: req.signedCookies["ssb_key"],
|
key: req.context.profile.key,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -287,8 +274,8 @@ router.post("/keys/email", async (req, res) => {
|
||||||
*/
|
*/
|
||||||
const email = req.body.email;
|
const email = req.body.email;
|
||||||
const origin = req.body.origin;
|
const origin = req.body.origin;
|
||||||
const ssb_key = req.signedCookies["ssb_key"];
|
const ssb_key = JSON.stringify(req.context.profile.key);
|
||||||
const login_key = Buffer.from(JSON.stringify(ssb_key)).toString("base64");
|
const login_key = Buffer.from(ssb_key).toString("base64");
|
||||||
|
|
||||||
if (process.env.NODE_ENV == "production") {
|
if (process.env.NODE_ENV == "production") {
|
||||||
let html = await ejs.renderFile("views/shared/email_sign_in.ejs", {
|
let html = await ejs.renderFile("views/shared/email_sign_in.ejs", {
|
||||||
|
@ -313,17 +300,33 @@ router.post("/keys/email", async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/keys/copy", (req, res) => {
|
router.get("/keys/copy", (req, res) => {
|
||||||
res.render("shared/keys_copy", { key: req.signedCookies["ssb_key"] });
|
res.render("shared/keys_copy", {
|
||||||
|
key: JSON.stringify(req.context.profile.key),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/keys/download", async (req, res) => {
|
router.get("/keys/download", async (req, res) => {
|
||||||
const identities = await ssb.client().identities.list();
|
const secretFile = `
|
||||||
const index = identities.indexOf(req.context.profile.id) - 1;
|
# WARNING: Never show this to anyone.
|
||||||
const filename = identityFilename(index);
|
# WARNING: Never edit it or use it on multiple devices at once.
|
||||||
const secretPath = `${ssbFolder()}/identities/${filename}`;
|
#
|
||||||
|
# This is your SECRET, it gives you magical powers. With your secret you can
|
||||||
|
# sign your messages so that your friends can verify that the messages came
|
||||||
|
# from you. If anyone learns your secret, they can use it to impersonate you.
|
||||||
|
#
|
||||||
|
# If you use this secret on more than one device you will create a fork and
|
||||||
|
# your friends will stop replicating your content.
|
||||||
|
#
|
||||||
|
${JSON.stringify(req.context.profile.key)}
|
||||||
|
#
|
||||||
|
# The only part of this file that's safe to share is your public name:
|
||||||
|
#
|
||||||
|
# ${req.context.profile.id}
|
||||||
|
`;
|
||||||
|
|
||||||
res.attachment("secret");
|
res.contentType("text/plain");
|
||||||
res.sendFile(secretPath);
|
res.header("Content-Disposition", "attachment; filename=secret");
|
||||||
|
res.send(secretFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
|
@ -367,7 +370,7 @@ router.post("/profile/:id(*)/add_friend", async (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "contact",
|
type: "contact",
|
||||||
|
@ -386,7 +389,7 @@ router.post("/profile/:id(*)/reject_friend", async (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "contact",
|
type: "contact",
|
||||||
|
@ -400,7 +403,7 @@ router.post("/profile/:id(*)/reject_friend", async (req, res) => {
|
||||||
|
|
||||||
router.post("/publish", async (req, res) => {
|
router.post("/publish", async (req, res) => {
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "post",
|
type: "post",
|
||||||
|
@ -416,7 +419,7 @@ router.post("/publish_secret", async (req, res) => {
|
||||||
const recipients = req.body.recipients;
|
const recipients = req.body.recipients;
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: true,
|
private: true,
|
||||||
content: {
|
content: {
|
||||||
type: "post",
|
type: "post",
|
||||||
|
@ -434,7 +437,7 @@ router.post("/vanish", async (req, res) => {
|
||||||
|
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "delete",
|
type: "delete",
|
||||||
|
@ -450,7 +453,7 @@ router.post("/profile/:id(*)/publish", async (req, res) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id;
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "post",
|
type: "post",
|
||||||
|
@ -466,7 +469,7 @@ router.post("/profile/:id(*)/publish_secret", async (req, res) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id;
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: true,
|
private: true,
|
||||||
content: {
|
content: {
|
||||||
type: "post",
|
type: "post",
|
||||||
|
@ -519,7 +522,7 @@ router.post("/about", async (req, res) => {
|
||||||
|
|
||||||
if (update.name || update.image || update.description) {
|
if (update.name || update.image || update.description) {
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: update,
|
content: update,
|
||||||
});
|
});
|
||||||
|
@ -562,7 +565,7 @@ router.post("/communities/new", async (req, res) => {
|
||||||
const post = req.body.post;
|
const post = req.body.post;
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "post",
|
type: "post",
|
||||||
|
@ -573,7 +576,7 @@ router.post("/communities/new", async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "channel",
|
type: "channel",
|
||||||
|
@ -635,7 +638,7 @@ router.post("/communities/:name/new", async (req, res) => {
|
||||||
const post = req.body.post;
|
const post = req.body.post;
|
||||||
|
|
||||||
const topic = await ssb.client().identities.publishAs({
|
const topic = await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "post",
|
type: "post",
|
||||||
|
@ -652,7 +655,7 @@ router.post("/communities/:name/join", async (req, res) => {
|
||||||
const name = req.params.name;
|
const name = req.params.name;
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "channel",
|
type: "channel",
|
||||||
|
@ -668,7 +671,7 @@ router.post("/communities/:name/leave", async (req, res) => {
|
||||||
const name = req.params.name;
|
const name = req.params.name;
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "channel",
|
type: "channel",
|
||||||
|
@ -686,7 +689,7 @@ router.post("/communities/:name/:key(*)/publish", async (req, res) => {
|
||||||
const reply = req.body.reply;
|
const reply = req.body.reply;
|
||||||
|
|
||||||
await ssb.client().identities.publishAs({
|
await ssb.client().identities.publishAs({
|
||||||
id: req.context.profile.id,
|
key: req.context.profile.key,
|
||||||
private: false,
|
private: false,
|
||||||
content: {
|
content: {
|
||||||
type: "post",
|
type: "post",
|
||||||
|
|
|
@ -1,139 +0,0 @@
|
||||||
// 1) Monkeypatched to include the refresh function
|
|
||||||
// 2) Monkeypatched to allow secret messages without published in the recps
|
|
||||||
var leftpad = require("left-pad");
|
|
||||||
var path = require("path");
|
|
||||||
var mkdirp = require("mkdirp");
|
|
||||||
var fs = require("fs");
|
|
||||||
var ssbKeys = require("ssb-keys");
|
|
||||||
var create = require("ssb-validate").create;
|
|
||||||
|
|
||||||
function toTarget(t) {
|
|
||||||
return "object" === typeof t ? t && t.link : t;
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.name = "identities";
|
|
||||||
exports.version = "1.0.0";
|
|
||||||
exports.manifest = {
|
|
||||||
main: "sync",
|
|
||||||
list: "async",
|
|
||||||
create: "async",
|
|
||||||
publishAs: "async",
|
|
||||||
help: "sync",
|
|
||||||
refresh: "sync",
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.init = function (sbot, config) {
|
|
||||||
var dir = path.join(config.path, "identities");
|
|
||||||
console.log("identities directory", config.path);
|
|
||||||
mkdirp.sync(dir);
|
|
||||||
|
|
||||||
function readKeys() {
|
|
||||||
return fs
|
|
||||||
.readdirSync(dir)
|
|
||||||
.filter(function (name) {
|
|
||||||
return /^secret_\d+\.butt$/.test(name);
|
|
||||||
})
|
|
||||||
.map(function (file) {
|
|
||||||
return ssbKeys.loadSync(path.join(dir, file));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var keys = readKeys();
|
|
||||||
|
|
||||||
var locks = {};
|
|
||||||
|
|
||||||
sbot.addUnboxer({
|
|
||||||
key: function (content) {
|
|
||||||
for (var i = 0; i < keys.length; i++) {
|
|
||||||
var key = ssbKeys.unboxKey(content, keys[i]);
|
|
||||||
if (key) return key;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
value: function (content, key) {
|
|
||||||
return ssbKeys.unboxBody(content, key);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
main: function () {
|
|
||||||
return sbot.id;
|
|
||||||
},
|
|
||||||
refresh: function () {
|
|
||||||
keys = readKeys();
|
|
||||||
},
|
|
||||||
list: function (cb) {
|
|
||||||
cb(
|
|
||||||
null,
|
|
||||||
[sbot.id].concat(
|
|
||||||
keys.map(function (e) {
|
|
||||||
return e.id;
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
create: function (cb) {
|
|
||||||
var filename = "secret_" + leftpad(keys.length, 2, "0") + ".butt";
|
|
||||||
ssbKeys.create(path.join(dir, filename), function (err, newKeys) {
|
|
||||||
keys.push(newKeys);
|
|
||||||
cb(err, newKeys.id);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
publishAs: function (opts, cb) {
|
|
||||||
var id = opts.id;
|
|
||||||
if (locks[id]) return cb(new Error("already writing"));
|
|
||||||
var _keys =
|
|
||||||
sbot.id === id
|
|
||||||
? sbot.keys
|
|
||||||
: keys.find(function (e) {
|
|
||||||
return id === e.id;
|
|
||||||
});
|
|
||||||
if (!_keys) return cb(new Error("must provide id of listed identities"));
|
|
||||||
var content = opts.content;
|
|
||||||
|
|
||||||
var recps = [].concat(content.recps).map(toTarget);
|
|
||||||
|
|
||||||
if (content.recps && !opts.private)
|
|
||||||
return cb(new Error("recps set, but opts.private not set"));
|
|
||||||
else if (!content.recps && opts.private)
|
|
||||||
return cb(new Error("opts.private set, but content.recps not set"));
|
|
||||||
else if (!!content.recps && opts.private) {
|
|
||||||
if (!Array.isArray(content.recps) || !content.recps.length)
|
|
||||||
return cb(
|
|
||||||
new Error(
|
|
||||||
"content.recps must be an array containing at least one id, was:" +
|
|
||||||
JSON.stringify(recps)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
content = ssbKeys.box(content, recps);
|
|
||||||
}
|
|
||||||
|
|
||||||
locks[id] = true;
|
|
||||||
sbot.getLatest(id, function (err, data) {
|
|
||||||
var state = data
|
|
||||||
? {
|
|
||||||
id: data.key,
|
|
||||||
sequence: data.value.sequence,
|
|
||||||
timestamp: data.value.timestamp,
|
|
||||||
queue: [],
|
|
||||||
}
|
|
||||||
: { id: null, sequence: null, timestamp: null, queue: [] };
|
|
||||||
sbot.add(
|
|
||||||
create(
|
|
||||||
state,
|
|
||||||
_keys,
|
|
||||||
config.caps && config.caps.sign,
|
|
||||||
content,
|
|
||||||
Date.now()
|
|
||||||
),
|
|
||||||
function (err, a, b) {
|
|
||||||
delete locks[id];
|
|
||||||
cb(err, a, b);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
help: function () {
|
|
||||||
return require("./help");
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
// Differently from ssb-identities, this plugin only keeps keys in memory, as we don't want to save them on the server
|
||||||
|
|
||||||
|
const ssbKeys = require("ssb-keys");
|
||||||
|
const { create } = require("ssb-validate");
|
||||||
|
|
||||||
|
exports.name = "identities";
|
||||||
|
exports.version = "1.0.0";
|
||||||
|
exports.manifest = {
|
||||||
|
create: "sync",
|
||||||
|
addUnboxer: "sync",
|
||||||
|
publishAs: "async",
|
||||||
|
createNewKey: "sync",
|
||||||
|
};
|
||||||
|
|
||||||
|
let unboxersAdded = [];
|
||||||
|
let locks = {};
|
||||||
|
|
||||||
|
const toTarget = (t) => (typeof t == "object" ? t && t.link : t);
|
||||||
|
|
||||||
|
const addUnboxer = (ssb) => (key) => {
|
||||||
|
if (unboxersAdded.includes(key.id)) return;
|
||||||
|
|
||||||
|
ssb.addUnboxer({
|
||||||
|
key: (content) => {
|
||||||
|
const unboxKey = ssbKeys.unboxKey(content, key);
|
||||||
|
if (unboxKey) return unboxKey;
|
||||||
|
},
|
||||||
|
value: (content, key) => {
|
||||||
|
return ssbKeys.unboxBody(content, key);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
unboxersAdded.push(key.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const publishAs = (ssb, config) => ({ key, private, content }, cb) => {
|
||||||
|
const id = key.id;
|
||||||
|
if (locks[id]) throw new Error("already writing");
|
||||||
|
|
||||||
|
const recps = [].concat(content.recps).map(toTarget);
|
||||||
|
|
||||||
|
if (content.recps && !private) {
|
||||||
|
return new Error("recps set, but private not set");
|
||||||
|
} else if (!content.recps && private) {
|
||||||
|
return new Error("private set, but content.recps not set");
|
||||||
|
} else if (!!content.recps && private) {
|
||||||
|
if (!Array.isArray(content.recps) || !~recps.indexOf(id))
|
||||||
|
return new Error(
|
||||||
|
"content.recps must be an array containing publisher id:" +
|
||||||
|
id +
|
||||||
|
" was:" +
|
||||||
|
JSON.stringify(recps) +
|
||||||
|
" indexOf:" +
|
||||||
|
recps.indexOf(id)
|
||||||
|
);
|
||||||
|
content = ssbKeys.box(content, recps);
|
||||||
|
}
|
||||||
|
|
||||||
|
locks[id] = true;
|
||||||
|
ssb.getLatest(id, (_err, data) => {
|
||||||
|
const state = data
|
||||||
|
? {
|
||||||
|
id: data.key,
|
||||||
|
sequence: data.value.sequence,
|
||||||
|
timestamp: data.value.timestamp,
|
||||||
|
queue: [],
|
||||||
|
}
|
||||||
|
: { id: null, sequence: null, timestamp: null, queue: [] };
|
||||||
|
|
||||||
|
ssb.add(
|
||||||
|
create(state, key, config.caps && config.caps.sign, content, Date.now()),
|
||||||
|
(err, a, b) => {
|
||||||
|
delete locks[id];
|
||||||
|
cb(err, a, b);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.init = function (ssb, config) {
|
||||||
|
return {
|
||||||
|
addUnboxer: addUnboxer(ssb),
|
||||||
|
publishAs: publishAs(ssb, config),
|
||||||
|
createNewKey: ssbKeys.generate,
|
||||||
|
};
|
||||||
|
};
|
|
@ -29,7 +29,7 @@ Server.use(require("ssb-master"))
|
||||||
.use(require("./monkeypatch/ssb-friends"))
|
.use(require("./monkeypatch/ssb-friends"))
|
||||||
.use(require("ssb-query"))
|
.use(require("ssb-query"))
|
||||||
.use(require("ssb-device-address"))
|
.use(require("ssb-device-address"))
|
||||||
.use(require("./monkeypatch/ssb-identities"))
|
.use(require("./plugins/memory-identities"))
|
||||||
.use(require("ssb-peer-invites"))
|
.use(require("ssb-peer-invites"))
|
||||||
.use(require("ssb-blobs"))
|
.use(require("ssb-blobs"))
|
||||||
.use(require("ssb-private"));
|
.use(require("ssb-private"));
|
||||||
|
|
|
@ -69,15 +69,6 @@ module.exports.writeKey = (key, path) => {
|
||||||
fs.writeFileSync(secretPath, key, { mode: 0x100, flag: "wx" });
|
fs.writeFileSync(secretPath, key, { mode: 0x100, flag: "wx" });
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.identityFilename = (index) => {
|
|
||||||
return "secret_" + leftpad(index, 2, "0") + ".butt";
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.nextIdentityFilename = async (ssbClient) => {
|
|
||||||
const identities = await ssbClient.identities.list();
|
|
||||||
return module.exports.identityFilename(identities.length - 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
// From ssb-keys
|
// From ssb-keys
|
||||||
module.exports.reconstructKeys = (keyfile) => {
|
module.exports.reconstructKeys = (keyfile) => {
|
||||||
var privateKey = keyfile
|
var privateKey = keyfile
|
||||||
|
@ -93,13 +84,6 @@ module.exports.reconstructKeys = (keyfile) => {
|
||||||
return keys;
|
return keys;
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.readKey = (path) => {
|
|
||||||
let secretPath = `${ssbFolder()}${path}`;
|
|
||||||
|
|
||||||
let keyfile = fs.readFileSync(secretPath, "utf8");
|
|
||||||
return module.exports.reconstructKeys(keyfile);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.uploadPicture = async (ssbClient, picture) => {
|
module.exports.uploadPicture = async (ssbClient, picture) => {
|
||||||
const maxSize = 5 * 1024 * 1024; // 5 MB
|
const maxSize = 5 * 1024 * 1024; // 5 MB
|
||||||
if (picture.size > maxSize) throw "Max size exceeded";
|
if (picture.size > maxSize) throw "Max size exceeded";
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
"ssb-device-address": "^1.1.6",
|
"ssb-device-address": "^1.1.6",
|
||||||
"ssb-friends": "^4.1.4",
|
"ssb-friends": "^4.1.4",
|
||||||
"ssb-gossip": "^1.1.1",
|
"ssb-gossip": "^1.1.1",
|
||||||
"ssb-identities": "^2.1.1",
|
|
||||||
"ssb-invite": "^2.1.4",
|
"ssb-invite": "^2.1.4",
|
||||||
"ssb-keys": "^7.2.2",
|
"ssb-keys": "^7.2.2",
|
||||||
"ssb-master": "^1.0.3",
|
"ssb-master": "^1.0.3",
|
||||||
|
|
Loading…
Reference in New Issue