|
@ -1,23 +1,24 @@ |
|
|
|
|
|
/* eslint-disable no-console */ |
|
|
|
|
|
/* eslint-disable no-return-await */ |
|
|
|
|
|
import IdentityProvider from 'orbit-db-identity-provider'; |
|
|
import { getIdentitySignaturePubKey, storeIdentitySignaturePubKey } from './levelUtils'; |
|
|
import { getIdentitySignaturePubKey, storeIdentitySignaturePubKey } from './levelUtils'; |
|
|
import IdentityProvider from "orbit-db-identity-provider"; |
|
|
|
|
|
|
|
|
|
|
|
const LOGGING_PREFIX = 'EthereumIdentityProvider: '; |
|
|
const LOGGING_PREFIX = 'EthereumIdentityProvider: '; |
|
|
|
|
|
|
|
|
class EthereumIdentityProvider extends IdentityProvider { |
|
|
class EthereumIdentityProvider extends IdentityProvider { |
|
|
constructor(options = {}) { |
|
|
constructor(options = {}) { |
|
|
if(!EthereumIdentityProvider.web3) |
|
|
if (!EthereumIdentityProvider.web3) { |
|
|
throw new Error(LOGGING_PREFIX + "Couldn't create identity, because web3 wasn't set. " + |
|
|
throw new Error(`${LOGGING_PREFIX}Couldn't create identity, because web3 wasn't set. ` |
|
|
"Please use setWeb3(web3) first!"); |
|
|
+ 'Please use setWeb3(web3) first!'); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
super(options); |
|
|
super(options); |
|
|
|
|
|
|
|
|
// Orbit's Identity Id (user's Ethereum address) - Optional (will be grabbed later if omitted)
|
|
|
// Orbit's Identity Id (user's Ethereum address) - Optional (will be grabbed later if omitted)
|
|
|
const id = options.id; |
|
|
const { id } = options; |
|
|
if (id) { |
|
|
if (id) { |
|
|
if(EthereumIdentityProvider.web3.utils.isAddress(id)) |
|
|
if (EthereumIdentityProvider.web3.utils.isAddress(id)) this.id = options.id; |
|
|
this.id = options.id; |
|
|
else throw new Error(`${LOGGING_PREFIX}Couldn't create identity, because an invalid id was supplied.`); |
|
|
else |
|
|
|
|
|
throw new Error(LOGGING_PREFIX + "Couldn't create identity, because an invalid id was supplied."); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -27,17 +28,19 @@ class EthereumIdentityProvider extends IdentityProvider{ |
|
|
// Id wasn't in the constructor, grab it now
|
|
|
// Id wasn't in the constructor, grab it now
|
|
|
if (!this.id) { |
|
|
if (!this.id) { |
|
|
const accounts = await EthereumIdentityProvider.web3.eth.getAccounts(); |
|
|
const accounts = await EthereumIdentityProvider.web3.eth.getAccounts(); |
|
|
if(!accounts[0]) |
|
|
if (!accounts[0]) { |
|
|
throw new Error(LOGGING_PREFIX + "Couldn't create identity, because no web3 accounts were found (locked Metamask?)."); |
|
|
throw new Error(`${LOGGING_PREFIX}Couldn't create identity, because no web3 accounts were found (
|
|
|
|
|
|
locked Metamask?).`);
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
this.id = accounts[0]; |
|
|
[this.id] = accounts; |
|
|
} |
|
|
} |
|
|
return this.id; |
|
|
return this.id; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
async signIdentity(data) { |
|
|
async signIdentity(data) { |
|
|
if (process.env.NODE_ENV === 'development') { // Don't sign repeatedly while in development
|
|
|
if (process.env.NODE_ENV === 'development') { // Don't sign repeatedly while in development
|
|
|
console.debug(LOGGING_PREFIX + 'Attempting to find stored Orbit identity data...'); |
|
|
console.debug(`${LOGGING_PREFIX}Attempting to find stored Orbit identity data...`); |
|
|
const signaturePubKey = await getIdentitySignaturePubKey(data); |
|
|
const signaturePubKey = await getIdentitySignaturePubKey(data); |
|
|
if (signaturePubKey) { |
|
|
if (signaturePubKey) { |
|
|
const identityInfo = { |
|
|
const identityInfo = { |
|
@ -46,55 +49,54 @@ class EthereumIdentityProvider extends IdentityProvider{ |
|
|
signaturePubKey, |
|
|
signaturePubKey, |
|
|
}; |
|
|
}; |
|
|
if (await EthereumIdentityProvider.verifyIdentityInfo(identityInfo)) { |
|
|
if (await EthereumIdentityProvider.verifyIdentityInfo(identityInfo)) { |
|
|
console.debug(LOGGING_PREFIX + 'Found and verified stored Orbit identity data!'); |
|
|
console.debug(`${LOGGING_PREFIX}Found and verified stored Orbit identity data!`); |
|
|
return signaturePubKey; |
|
|
return signaturePubKey; |
|
|
} |
|
|
} |
|
|
console.debug(LOGGING_PREFIX + "Stored Orbit identity data couldn't be verified."); |
|
|
console.debug(`${LOGGING_PREFIX}Stored Orbit identity data couldn't be verified.`); |
|
|
} else |
|
|
} else console.debug(`${LOGGING_PREFIX}No stored Orbit identity data were found.`); |
|
|
console.debug(LOGGING_PREFIX + 'No stored Orbit identity data were found.'); |
|
|
|
|
|
} |
|
|
} |
|
|
return await this.doSignIdentity(data); |
|
|
return await this.doSignIdentity(data); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// eslint-disable-next-line consistent-return
|
|
|
async doSignIdentity(data) { |
|
|
async doSignIdentity(data) { |
|
|
try { |
|
|
try { |
|
|
const signaturePubKey = await EthereumIdentityProvider.web3.eth.personal.sign(data, this.id, ''); |
|
|
const signaturePubKey = await EthereumIdentityProvider.web3.eth.personal.sign(data, this.id, ''); |
|
|
if (process.env.NODE_ENV === 'development') { |
|
|
if (process.env.NODE_ENV === 'development') { |
|
|
storeIdentitySignaturePubKey(data, signaturePubKey) |
|
|
storeIdentitySignaturePubKey(data, signaturePubKey) |
|
|
.then(() => { |
|
|
.then(() => { |
|
|
console.debug(LOGGING_PREFIX + 'Successfully stored current Orbit identity data.'); |
|
|
console.debug(`${LOGGING_PREFIX}Successfully stored current Orbit identity data.`); |
|
|
}) |
|
|
}) |
|
|
.catch(() => { |
|
|
.catch(() => { |
|
|
console.warn(LOGGING_PREFIX + "Couldn't store current Orbit identity data..."); |
|
|
console.warn(`${LOGGING_PREFIX}Couldn't store current Orbit identity data...`); |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
return signaturePubKey; // Password not required for MetaMask
|
|
|
return signaturePubKey; // Password not required for MetaMask
|
|
|
} catch (error) { |
|
|
} catch (error) { |
|
|
if (error.code && error.code === 4001) { |
|
|
if (error.code && error.code === 4001) { |
|
|
console.debug(LOGGING_PREFIX + 'User denied message signature.'); |
|
|
console.debug(`${LOGGING_PREFIX}User denied message signature.`); |
|
|
return await this.doSignIdentity(data); |
|
|
return await this.doSignIdentity(data); |
|
|
} |
|
|
} |
|
|
else{ |
|
|
|
|
|
console.error(LOGGING_PREFIX + 'Failed to sign data.'); |
|
|
console.error(`${LOGGING_PREFIX}Failed to sign data.`); |
|
|
console.error(error); |
|
|
console.error(error); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static async verifyIdentity(identity) { |
|
|
static async verifyIdentity(identity) { |
|
|
// Verify that identity was signed by the ID
|
|
|
// Verify that identity was signed by the ID
|
|
|
return new Promise(resolve => { |
|
|
return new Promise((resolve) => { |
|
|
resolve(EthereumIdentityProvider.web3.eth.accounts.recover(identity.publicKey + identity.signatures.id, |
|
|
resolve(EthereumIdentityProvider.web3.eth.accounts.recover(identity.publicKey + identity.signatures.id, |
|
|
identity.signatures.publicKey) === identity.id) |
|
|
identity.signatures.publicKey) === identity.id); |
|
|
}) |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static async verifyIdentityInfo(identityInfo) { |
|
|
static async verifyIdentityInfo(identityInfo) { |
|
|
// Verify that identity was signed by the ID
|
|
|
// Verify that identity was signed by the ID
|
|
|
return new Promise(resolve => { |
|
|
return new Promise((resolve) => { |
|
|
resolve(EthereumIdentityProvider.web3.eth.accounts.recover(identityInfo.pubKeySignId, |
|
|
resolve(EthereumIdentityProvider.web3.eth.accounts.recover(identityInfo.pubKeySignId, |
|
|
identityInfo.signaturePubKey) === identityInfo.id) |
|
|
identityInfo.signaturePubKey) === identityInfo.id); |
|
|
}) |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Initialize by supplying a web3 object
|
|
|
// Initialize by supplying a web3 object
|
|
|