Files: b1b65011b395cada507b007a22398f4ad4d3f532 / storage.js
3252 bytesRaw
1 | var fs = require('fs') |
2 | var mkdirp = require('mkdirp') |
3 | var path = require('path') |
4 | var u = require('./util') |
5 | |
6 | function isObject (o) { |
7 | return 'object' === typeof o |
8 | } |
9 | |
10 | function isFunction (f) { |
11 | return 'function' === typeof f |
12 | } |
13 | |
14 | function empty(v) { return !!v } |
15 | |
16 | function toFile (filename) { |
17 | if(isObject(filename)) |
18 | return path.join(filename.path, 'secret') |
19 | return filename |
20 | } |
21 | |
22 | module.exports = function (generate) { |
23 | |
24 | if(!fs || !fs.readFile) |
25 | return require('./local-storage')(generate) |
26 | |
27 | var exports = {} |
28 | |
29 | //(DE)SERIALIZE KEYS |
30 | |
31 | function constructKeys(keys, legacy) { |
32 | if(!keys) throw new Error('*must* pass in keys') |
33 | |
34 | return [ |
35 | '# this is your SECRET name.', |
36 | '# this name gives you magical powers.', |
37 | '# with it you can mark your messages so that your friends can verify', |
38 | '# that they really did come from you.', |
39 | '#', |
40 | '# if any one learns this name, they can use it to destroy your identity', |
41 | '# NEVER show this to anyone!!!', |
42 | '', |
43 | legacy ? keys.private : JSON.stringify(keys, null, 2), |
44 | '', |
45 | '# WARNING! It\'s vital that you DO NOT edit OR share your secret name', |
46 | '# instead, share your public name', |
47 | '# your public name: ' + keys.id |
48 | ].join('\n') |
49 | } |
50 | |
51 | function reconstructKeys(keyfile) { |
52 | var privateKey = keyfile |
53 | .replace(/\s*\#[^\n]*/g, '') |
54 | .split('\n').filter(empty).join('') |
55 | |
56 | //if the key is in JSON format, we are good. |
57 | try { |
58 | var keys = JSON.parse(privateKey) |
59 | if(!u.hasSigil(keys.id)) keys.id = '@' + keys.public |
60 | return keys |
61 | } catch (_) { console.error(_.stack) } |
62 | |
63 | //else, reconstruct legacy curve... |
64 | |
65 | var curve = u.getTag(privateKey) |
66 | |
67 | if(curve !== 'k256') |
68 | throw new Error('expected legacy curve (k256) but found:' + curve) |
69 | |
70 | var fool_browserify = require |
71 | var ecc = fool_browserify('./eccjs') |
72 | |
73 | return u.keysToJSON(ecc.restore(u.toBuffer(privateKey)), 'k256') |
74 | } |
75 | |
76 | exports.load = function(filename, cb) { |
77 | filename = toFile(filename, 'secret') |
78 | fs.readFile(filename, 'ascii', function(err, privateKeyStr) { |
79 | if (err) return cb(err) |
80 | var keys |
81 | try { keys = reconstructKeys(privateKeyStr) } |
82 | catch (err) { return cb(err) } |
83 | cb(null, keys) |
84 | }) |
85 | } |
86 | |
87 | exports.loadSync = function(filename) { |
88 | filename = toFile(filename, 'secret') |
89 | return reconstructKeys(fs.readFileSync(filename, 'ascii')) |
90 | } |
91 | |
92 | exports.create = function(filename, curve, legacy, cb) { |
93 | if(isFunction(legacy)) |
94 | cb = legacy, legacy = null |
95 | if(isFunction(curve)) |
96 | cb = curve, curve = null |
97 | |
98 | filename = toFile(filename, 'secret') |
99 | var keys = generate(curve) |
100 | var keyfile = constructKeys(keys, legacy) |
101 | mkdirp(path.dirname(filename), function (err) { |
102 | if(err) return cb(err) |
103 | fs.writeFile(filename, keyfile, {mode: 0400}, function(err) { |
104 | if (err) return cb(err) |
105 | cb(null, keys) |
106 | }) |
107 | }) |
108 | } |
109 | |
110 | exports.createSync = function(filename, curve, legacy) { |
111 | filename = toFile(filename, 'secret') |
112 | var keys = generate(curve) |
113 | var keyfile = constructKeys(keys, legacy) |
114 | mkdirp.sync(path.dirname(filename)) |
115 | fs.writeFileSync(filename, keyfile, {mode: 0400}) |
116 | return keys |
117 | } |
118 | |
119 | return exports |
120 | } |
121 |
Built with git-ssb-web