|
// alas this generates the warning `user.pair() IS DEPRECATED AND WILL BE DELETED!!!` |
|
// |
|
// put a value shared between two users |
|
// user and this user (classic public key encryption, except that a session |
|
// key is used instead of encrypting the data with the public key. |
|
// analagous to `openssl pkeyutl -derive -inkey key.pem -peerkey pubkey.pem -out secret` |
|
// |
|
// @param: key - the key where the value is stored |
|
// @param: value - the value to store at index key |
|
// @param: otherUser - the info or public key of the other user to share the value with |
|
// |
|
// @returns: encrypted version that was put into the database |
|
// |
|
gundb.userPutShared = async function(key, value, otherUser) { |
|
const thisPair = this.gun.user().pair(); |
|
const otherPub = otherUser.pub || otherUser; |
|
|
|
const encryptedValue = await Sea.encrypt(value, await Sea.secret(otherUser, thisPair)); |
|
//console.log('--enc value'); |
|
//console.log(encryptedValue); |
|
return await this.userPut(key, encryptedValue); |
|
} |
|
|
|
/* |
|
* get a value shared from another user |
|
* (classic public key encryption, except that a session * key is used) |
|
* |
|
* @param: key - the key where the value is stored |
|
* @param: otherUser - the info or public key of the other user who shared this value with us |
|
* |
|
* @returns: plaintext version of what was shared into the database |
|
*/ |
|
gundb.userGetShared = async function(key, otherUser) { |
|
const thisPair = this.gun.user().pair(); |
|
const otherPub = otherUser.pub || otherUser; |
|
|
|
const encryptedValue = await this.userGet(key, otherPub); |
|
const result = await Sea.decrypt(encryptedValue, await Sea.secret(otherUser, thisPair)); |
|
return result; |
|
} |
|
|
|
/* |
|
* get a value to the key in the current user's or other user's keyspace |
|
* |
|
* @param key - the unique key where the value is put |
|
* @pubKey - optional pubKey or result of user.is if attempting to get another user's info |
|
* The default user is the user currently attached to this gundb instance |
|
*/ |
|
gundb.userGet = async function(key, pubKey) { |
|
let value; |
|
if (pubKey) { |
|
const actualPubKey = pubKey.pub || pubKey; |
|
value = await this.gun.user(actualPubKey).get(key).then() |
|
} else { |
|
value = await this.gun.user().get(key).then(); |
|
} |
|
|
|
try { |
|
return JSON.parse(Base64.decode(value)); |
|
} catch (e) { |
|
console.log(`---unabletoparse: ${value}`); |
|
console.log(JSON.stringify(value, null, 2)); |
|
return undefined |
|
} |
|
}; |
|
|
|
/* |
|
* put a value to the key in the current user's keyspace |
|
* |
|
* @param key - the unique key where the value is put |
|
* @param value - the value to be put. |
|
*/ |
|
gundb.userPut = async function(key, value) { |
|
const encoded = Base64.encode(JSON.stringify(value)); |
|
const finalValue = await this.gun.user().get(key).put(encoded).then(); |
|
return JSON.parse(Base64.decode(finalValue)); |
|
}; |
|
|
|
|
|
|
|
///-------------------- unit test |
|
test('share secret data between two users', async function(t) { |
|
const username1 = random.string(16) + '@example.com'; |
|
const password1 = 'password1'; |
|
const username2 = random.string(16) + '@example.com'; |
|
const password2 = 'password2'; |
|
const username3 = random.string(16) + '@example.com'; |
|
const password3 = 'password3'; |
|
const key = 'key' + random.string(16); |
|
const value = 'value' + random.string(16); |
|
|
|
// create three gun instances, two pointing at one |
|
const gundb1 = Object.create(gundb); |
|
const gundb2 = Object.create(gundb); |
|
const gundb3 = Object.create(gundb); |
|
gundb1.init({port: 8080}); |
|
gundb2.init({port: 8081, peers: ['http://localhost:8080/gun']}); |
|
gundb3.init({port: 8082, peers: ['http://localhost:8080/gun']}); |
|
|
|
// create and authorize a user per gundb |
|
const userInfo1 = await gundb1.userCreate(username1, password1); |
|
const userInfo2 = await gundb2.userCreate(username2, password2); |
|
const userInfo3 = await gundb3.userCreate(username3, password3); |
|
|
|
// now put something there. Hopefully it gets encrypted? |
|
//const putResult = await gundb1.userPut(key, value); |
|
|
|
const result = await gundb1.userPutShared(key, value, userInfo2); |
|
//t.equal(result, value, 'value from grant was what was put'); |
|
|
|
|
|
const otherUserGetResult = await gundb2.userGetShared(key, userInfo1); |
|
t.equal(otherUserGetResult, value, 'value the other user sees was what was granted'); |
|
|
|
const thirdUserGetResult = await gundb3.userGetShared(key, userInfo1); |
|
t.equal(thirdUserGetResult, undefined, 'value the third user sees is undefined as they were not granted the right to see it'); |
|
|
|
//console.log(getResult); |
|
gundb1.shutdown(); |
|
gundb2.shutdown(); |
|
gundb3.shutdown(); |
|
}); |