-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathstorage.js
126 lines (106 loc) · 3.31 KB
/
storage.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
"use strict";
var fs = require("fs");
var mkdirp = require("mkdirp");
var path = require("path");
var u = require("./util");
function isObject(o) {
return "object" === typeof o;
}
function isFunction(f) {
return "function" === typeof f;
}
function empty(v) {
return !!v;
}
function toFile(filename) {
if (isObject(filename)) return path.join(filename.path, "secret");
return filename;
}
module.exports = function (generate) {
if (!fs || !fs.readFile) return require("./local-storage")(generate);
var exports = {};
//(DE)SERIALIZE KEYS
function constructKeys(keys, legacy) {
if (!keys) throw new Error("*must* pass in keys");
return `# WARNING: Never show this to anyone.
# WARNING: Never edit it or use it on multiple devices at once.
#
# 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.
#
${legacy ? keys.private : JSON.stringify(keys, null, 2)}
#
# The only part of this file that's safe to share is your public name:
#
# ${keys.id}`;
}
function reconstructKeys(keyfile) {
var privateKey = keyfile
.replace(/\s*#[^\n]*/g, "")
.split("\n")
.filter(empty)
.join("");
//if the key is in JSON format, we are good.
try {
var keys = JSON.parse(privateKey);
if (!u.hasSigil(keys.id)) keys.id = "@" + keys.public;
return keys;
} catch (_) {
console.error(_.stack);
}
}
exports.load = function (filename, cb) {
filename = toFile(filename);
fs.readFile(filename, "ascii", function (err, privateKeyStr) {
if (err) return cb(err);
var keys;
try {
keys = reconstructKeys(privateKeyStr);
} catch (err) {
return cb(err);
}
cb(null, keys);
});
};
exports.loadSync = function (filename) {
filename = toFile(filename);
return reconstructKeys(fs.readFileSync(filename, "ascii"));
};
function curveOrOpts(opts) {
return !opts ? {} : isObject(opts) ? opts : { curve: opts };
}
exports.create = function (filename, generateOpts, legacy, cb) {
if (isFunction(legacy)) (cb = legacy), (legacy = null);
if (isFunction(generateOpts)) (cb = generateOpts), (generateOpts = null);
const { curve, seed, feedFormat } = curveOrOpts(generateOpts);
filename = toFile(filename);
var keys = generate(curve, seed, feedFormat);
var keyfile = constructKeys(keys, legacy);
mkdirp(path.dirname(filename), function (err) {
if (err) return cb(err);
fs.writeFile(
filename,
keyfile,
{ mode: 0x100, flag: "wx" },
function (err) {
if (err) return cb(err);
cb(null, keys);
}
);
});
};
exports.createSync = function (filename, generateOpts, legacy) {
const { curve, seed, feedFormat } = curveOrOpts(generateOpts);
filename = toFile(filename);
var keys = generate(curve, seed, feedFormat);
var keyfile = constructKeys(keys, legacy);
mkdirp.sync(path.dirname(filename));
fs.writeFileSync(filename, keyfile, { mode: 0x100, flag: "wx" });
return keys;
};
return exports;
};