Browse Source

Merge branch 'master-key' of CoBox/cobox-config into development

peg 2 years ago
parent
commit
3f38c56fe3
4 changed files with 55 additions and 37 deletions
  1. 4
    1
      README.md
  2. 0
    14
      example.yaml
  3. 12
    13
      index.js
  4. 39
    9
      test/index.test.js

+ 4
- 1
README.md View File

@@ -1,6 +1,6 @@
1 1
 # cobox-config
2 2
 
3
-Stores and retrieves a YAML configuration file for use with the cobox stack.
3
+Stores and retrieves a YAML configuration file for use with the cobox stack. Also loads up master key to generate a global identity.
4 4
 
5 5
 ## Example
6 6
 
@@ -52,3 +52,6 @@ config.groups.list()
52 52
 ```
53 53
 
54 54
 List saved groups
55
+
56
+## Future Features
57
+* Store names against ID's in YAML config file for multiple identity capability

+ 0
- 14
example.yaml View File

@@ -7,17 +7,3 @@ groups:
7 7
       symmetricKey: 7790efea443b9ebee384939bbd3f43d2841212790a0180342aca16a63f199431
8 8
   byName:
9 9
     group-a: *ref_0
10
-
11
-identities:
12
-  byKey:
13
-    736a1f0369923a5f1c8710ca1713bedccd8d051c42fe28b0bb031640f5293e4c: &ref_1
14
-      name: Alice
15
-      publicKey: 736a1f0369923a5f1c8710ca1713bedccd8d051c42fe28b0bb031640f5293e4c
16
-      secretKey: 7790efea443b9ebee384939bbd3f43d2841212790a0180342aca16a63f199431
17
-    ed49273be24fac7fce884a2908708e15abfb84b608b0084808968b4c75870218: &ref_2
18
-      name: bob
19
-      publicKey: ed49273be24fac7fce884a2908708e15abfb84b608b0084808968b4c75870218
20
-      secretKey: 54ddf6b77f306749737e8115efd31ffd1e4636d1336888cdfaf9dc2f91d45c7d
21
-  byName:
22
-    Alice: *ref_1
23
-    bob: *ref_2

+ 12
- 13
index.js View File

@@ -4,10 +4,13 @@ const path = require('path')
4 4
 const os = require('os')
5 5
 const mkdirp = require('mkdirp')
6 6
 const logger = require('./logger')
7
+const crypto = require('cobox-crypto')
7 8
 
8 9
 const CONFIG_FILE = 'config.yml'
10
+const IDENTITY_SUBKEY_ID = 0
9 11
 
10 12
 module.exports = (storage, opts) => new CoBoxConfig(storage, opts)
13
+module.exports.IDENTITY_SUBKEY_ID = IDENTITY_SUBKEY_ID
11 14
 
12 15
 const KeyHandler = require('./lib/key-handler')
13 16
 const MapHandler = require('./lib/map-handler')
@@ -19,7 +22,6 @@ const defaultOptions = () => ({
19 22
 const defaultConfig = () => ({
20 23
   options: defaultOptions(),
21 24
   groups: { byKey: {}, byName: {} },
22
-  identities: { byKey: {}, byName: {} }
23 25
 })
24 26
 
25 27
 // filename-safe date (probably there is a better way to do this)
@@ -29,27 +31,31 @@ class CoBoxConfig {
29 31
   constructor (storage, opts = {}) {
30 32
     this.root = storage || path.join(os.homedir(), '.cobox')
31 33
     this.storage = path.join(this.root, CONFIG_FILE)
32
-    this.secrets = path.join(this.root, 'secret_keys')
33 34
 
34 35
     mkdirp.sync(path.join(this.root, 'logs'))
35
-    mkdirp.sync(this.secrets)
36 36
 
37 37
     var config = Object.assign(defaultConfig(), opts.seeds || {})
38 38
 
39 39
     if (!fs.existsSync(this.storage)) {
40 40
       fs.writeFileSync(this.storage, yaml.safeDump(defaultConfig(), { sortKeys: true }))
41 41
       this._groups = config.groups
42
-      this._identities = config.identities
43 42
       this._options = config.options
44 43
     } else {
45 44
       this.load()
46 45
     }
47 46
 
47
+    var masterKeyPath = path.join(this.root, 'master_key')
48
+    if (!fs.existsSync(masterKeyPath)) {
49
+      this.masterKey = crypto.masterKey()
50
+      fs.writeFileSync(masterKeyPath, this.masterKey, { mode: fs.constants.S_IRUSR })
51
+    } else {
52
+      this.masterKey = fs.readFileSync(masterKeyPath)
53
+    }
54
+
55
+    this.identity = crypto.keyPair(this.masterKey, IDENTITY_SUBKEY_ID)
48 56
     this.logger = logger(path.join(this.root, 'logs', logfile))
49 57
     this.log = this.logger('cobox-config')
50
-
51 58
     this.groups = KeyHandler(this._groups)
52
-    this.identities = KeyHandler(this._identities)
53 59
     this.options = MapHandler(this._options)
54 60
   }
55 61
 
@@ -57,7 +63,6 @@ class CoBoxConfig {
57 63
     try {
58 64
       var config = defaultConfig()
59 65
       config.groups = this._groups
60
-      config.identities = this._identities
61 66
       config.options = this._options
62 67
 
63 68
       fs.writeFileSync(this.storage, yaml.safeDump(config, { sortKeys: true }))
@@ -72,7 +77,6 @@ class CoBoxConfig {
72 77
     try {
73 78
       const config = yaml.safeLoad(fs.readFileSync(this.storage, 'utf8'))
74 79
       this._groups = config.groups
75
-      this._identities = config.identities
76 80
       this._options = config.options || defaultOptions()
77 81
       return true
78 82
     } catch (err) {
@@ -81,8 +85,3 @@ class CoBoxConfig {
81 85
     }
82 86
   }
83 87
 }
84
-
85
-function storeSecret (location, secret) {
86
-  fs.writeFileSync(secretKey, Buffer.from(secret))
87
-  return location
88
-}

+ 39
- 9
test/index.test.js View File

@@ -7,21 +7,51 @@ const yaml = require('js-yaml')
7 7
 
8 8
 const { tmp, cleanup } = require('./util')
9 9
 
10
-describe('load', (context) => {
11
-  var storage
12
-
13
-  context.beforeEach((c) => {
14
-    storage = tmp()
10
+describe('exports', (context) => {
11
+  context('IDENTITY_SUBKEY_ID', (assert, next) => {
12
+    assert.same(Config.IDENTITY_SUBKEY_ID, 0, 'exports IDENTITY_SUBKEY_ID')
13
+    next()
15 14
   })
15
+})
16 16
 
17
-  context.afterEach((c) => {
18
-    cleanup(storage)
17
+describe('load', (context) => {
18
+  context('default', (assert, next) => {
19
+    var storage = tmp()
20
+    var config = Config(storage)
21
+    assert.ok(config.groups.list() instanceof Array, 'groups list defaults to empty Array')
22
+    cleanup(storage, next)
19 23
   })
24
+})
20 25
 
26
+describe('master_key', (context) => {
21 27
   context('default', (assert, next) => {
28
+    var storage = tmp()
22 29
     var config = Config(storage)
23
-    assert.ok(config.groups.list() instanceof Array, 'groups list defaults to empty Array')
24
-    next()
30
+
31
+    var masterKey = config.masterKey
32
+    assert.ok(masterKey, 'generates a master key')
33
+
34
+    fs.readFile(path.join(storage, 'master_key'), (err, data) => {
35
+      assert.same(Buffer.from(data).toString('hex'), masterKey.toString('hex'), 'keys match')
36
+
37
+      fs.writeFile(path.join(storage, 'master_key'), 'Woof Woof', (err) => {
38
+        assert.ok(err, 'throws an error')
39
+        assert.ok(err.code, 'EACCES', 'invalid permissions')
40
+        assert.ok(err.message, `permission denied, open '${storage}'`)
41
+
42
+        cleanup(storage, next)
43
+      })
44
+    })
45
+  })
46
+
47
+  context('reload', (assert, next) => {
48
+    var storage = tmp()
49
+    var config = Config(storage)
50
+    var masterKey = config.masterKey
51
+    config = Config(storage)
52
+    var key = config.masterKey
53
+    assert.same(key, masterKey, 'reloads the same master_key')
54
+    cleanup(storage, next)
25 55
   })
26 56
 })
27 57