This repository has been archived by the owner on Sep 30, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathidentities.js
99 lines (84 loc) · 3.1 KB
/
identities.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
'use strict'
const Identity = require('./identity')
const OrbitDBIdentityProvider = require('./orbit-db-identity-provider')
const Keystore = require('orbit-db-keystore')
const type = 'orbitdb'
const identityKeysPath = './orbitdb/identity/identitykeys'
let supportedTypes = {
'orbitdb': OrbitDBIdentityProvider
}
const getHandlerFor = (type) => {
if (!Identities.isSupported(type)) {
throw new Error(`IdentityProvider type '${type}' is not supported`)
}
return supportedTypes[type]
}
class Identities {
constructor (keystore) {
this._keystore = keystore
}
async sign (identity, data) {
const signingKey = await this._keystore.getKey(identity.id)
if (!signingKey) {
throw new Error(`Private signing key not found from Keystore`)
}
const sig = await this._keystore.sign(signingKey, data)
return sig
}
async verify (signature, publicKey, data, verifier = 'v1') {
return this._keystore.verify(signature, publicKey, data, verifier)
}
async createIdentity (options = {}) {
const IdentityProvider = getHandlerFor(options.type)
const identityProvider = new IdentityProvider(options)
const id = await identityProvider.getId(options)
if (options.migrate) {
await options.migrate({ targetPath: this._keystore.path, targetId: id })
}
const { publicKey, idSignature } = await this.signId(id)
const pubKeyIdSignature = await identityProvider.signIdentity(publicKey + idSignature, options)
return new Identity(id, publicKey, idSignature, pubKeyIdSignature, IdentityProvider.type, this)
}
async signId (id) {
const keystore = this._keystore
const key = await keystore.getKey(id) || await keystore.createKey(id)
const publicKey = keystore.getPublic(key)
const idSignature = await keystore.sign(key, id)
return { publicKey, idSignature }
}
async verifyIdentity (identity) {
const verified = await this._keystore.verify(
identity.signatures.id,
identity.publicKey,
identity.id
)
return verified && Identities.verifyIdentity(identity)
}
static async verifyIdentity (identity) {
const IdentityProvider = getHandlerFor(identity.type)
return IdentityProvider.verifyIdentity(identity)
}
static async createIdentity (options = {}) {
const keystore = options.keystore || Keystore.create(options.identityKeysPath || identityKeysPath)
options = Object.assign({}, { type }, options)
const identities = new Identities(keystore)
return identities.createIdentity(options)
}
static isSupported (type) {
return Object.keys(supportedTypes).includes(type)
}
static addIdentityProvider (IdentityProvider) {
if (!IdentityProvider) {
throw new Error('IdentityProvider class needs to be given as an option')
}
if (!IdentityProvider.type ||
typeof IdentityProvider.type !== 'string') {
throw new Error('Given IdentityProvider class needs to implement: static get type() { /* return a string */}.')
}
supportedTypes[IdentityProvider.type] = IdentityProvider
}
static removeIdentityProvider (type) {
delete supportedTypes[type]
}
}
module.exports = Identities