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