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