@ -26,31 +26,13 @@ npm run build
npm run lint
npm run lint
```
```
## Tests
### Web-push
For your own web-push tests, change the 'vapid' URL in App.vue, and install apps on the same domain.
### Test key contents
## Tests
See [this page ](openssl_signing_console.rst )
### Register new user on test server
### Register new user on test server
New users require registration. This can be done with a claim payload like this
by an existing user:
```
const vcClaim = {
"@context": "https://schema.org",
"@type": "RegisterAction",
agent: { identifier: identity0.did },
object: SERVICE_ID,
participant: { identifier: newIdentity.did },
};
```
On the test server, User #0 has rights to register others, so you can start
On the test server, User #0 has rights to register others, so you can start
playing one of two ways:
playing one of two ways:
@ -66,14 +48,37 @@ playing one of two ways:
### Create multiple identifiers
### Create multiple identifiers
Go to /start and create or import a new one. Then switch identifiers on the bottom of the Your Identity page .
Under the "Your Identity" screen, click "Advanced", click "Switch Identity / No Identity", then "Add Another Identity..." .
### Create keys with alternate tools
### Create keys with alternate tools
See [this page ](openssl_signing_console.rst )
[This page ](openssl_signing_console.rst ) is a tool to create a JWT from a locally-generated keypair.
### Web-push
For your own web-push tests, change the 'vapid' URL in App.vue, and install apps on the same domain.
### Manual walk-through
- Clear the browser cache for localhost to be a new user.
- On each page, verify the messaging.
- On the home page, see message prompting to generate an ID.
- As User #0 in another browser, add a give record. (See User #0 details above.)
- With the new user on the home page, see the feed that shows users without names.
- As the new user on the contacts page, add a contact.
- On the discovery page, check that they can see projects.
- Choose a search area and see items show nearby.
- Generate an ID.
- On the home page, check that it now prompts them to get registered.
- On the account page, check that they see messages on limits.
- Register the ID from User #0 .
- As the new user on the home page, check that they can now record a gift.
Also that they see a hint on the user name in the feed (since user #0 is visible to them).
- On the contacts page, check that they cannot register someone else yet.
- As the new user, add User #0 to contacts.
- On the home page, see the name of user #0 info in the feed.
- Walk through the functions on each page.
### Customize Vue configuration
See [Configuration Reference ](https://cli.vuejs.org/config/ ).
## Scenarios
## Scenarios
@ -90,8 +95,8 @@ See [Configuration Reference](https://cli.vuejs.org/config/).
### Clear data & restart
### Clear data & restart
Clear cache for localhost, then go to http://localhost:8080/start
Clear the browser cache for localhost.
(because it'll generate a new one automatically if you start on the `/account` page).
@ -102,110 +107,10 @@ Clear cache for localhost, then go to http://localhost:8080/start
* Notifications can be type of `toast` (self-dismiss), `info` , `success` , `warning` , and `danger` .
* Notifications can be type of `toast` (self-dismiss), `info` , `success` , `warning` , and `danger` .
They are done via [notiwind ](https://www.npmjs.com/package/notiwind ) and set up in App.vue.
They are done via [notiwind ](https://www.npmjs.com/package/notiwind ) and set up in App.vue.
```
* [Customize Vue configuration ](https://cli.vuejs.org/config/ ).
// reference material from https://github.com/trentlarson/endorser-mobile/blob/8dc8e0353e0cc80ffa7ed89ded15c8b0da92726b/src/utility/idUtility.ts#L83
// Import an existing ID
export const importAndStoreIdentifier = async (mnemonic: string, mnemonicPassword: string, toLowercase: boolean, previousIdentifiers: Array< IIdentifier > ) => {
// just to get rid of variability that might cause an error
mnemonic = mnemonic.trim().toLowerCase()
/**
// an approach I pieced together
// requires: yarn add elliptic
// ... plus:
// const EC = require('elliptic').ec
// const secp256k1 = new EC('secp256k1')
//
const keyHex: string = bip39.mnemonicToEntropy(mnemonic)
// returns a KeyPair from the elliptic.ec library
const keyPair = secp256k1.keyFromPrivate(keyHex, 'hex')
// this code is from did-provider-eth createIdentifier
const privateHex = keyPair.getPrivate('hex')
const publicHex = keyPair.getPublic('hex')
const address = didJwt.toEthereumAddress(publicHex)
** /
/**
// from https://github.com/uport-project/veramo/discussions/346#discussioncomment-302234
// ... which almost works but the didJwt.toEthereumAddress is wrong
// requires: yarn add bip32
// ... plus: import * as bip32 from 'bip32'
//
const seed: Buffer = await bip39.mnemonicToSeed(mnemonic)
const root = bip32.fromSeed(seed)
const node = root.derivePath(UPORT_ROOT_DERIVATION_PATH)
const privateHex = node.privateKey.toString("hex")
const publicHex = node.publicKey.toString("hex")
const address = didJwt.toEthereumAddress('0x' + publicHex)
** /
/**
// from https://github.com/uport-project/veramo/discussions/346#discussioncomment-302234
// requires: yarn add @ethersproject/hdnode
// ... plus: import { HDNode } from '@ethersproject/hdnode'
** /
const hdnode: HDNode = HDNode.fromMnemonic(mnemonic)
const rootNode: HDNode = hdnode.derivePath(UPORT_ROOT_DERIVATION_PATH)
const privateHex = rootNode.privateKey.substring(2) // original starts with '0x'
const publicHex = rootNode.publicKey.substring(2) // original starts with '0x'
let address = rootNode.address
const prevIds = previousIdentifiers || [];
if (toLowercase) {
const foundEqual = R.find(
(id) => utility.rawAddressOfDid(id.did) === address,
prevIds
)
if (foundEqual) {
// They're trying to create a lowercase version of one that exists in normal case.
// (We really should notify the user.)
appStore.dispatch(appSlice.actions.addLog({log: true, msg: "Will create a normal-case version of the DID since a regular version exists."}))
} else {
address = address.toLowerCase()
}
} else {
// They're not trying to convert to lowercase.
const foundLower = R.find((id) =>
utility.rawAddressOfDid(id.did) === address.toLowerCase(),
prevIds
)
if (foundLower) {
// They're trying to create a normal case version of one that exists in lowercase.
// (We really should notify the user.)
appStore.dispatch(appSlice.actions.addLog({log: true, msg: "Will create a lowercase version of the DID since a lowercase version exists."}))
address = address.toLowerCase()
}
}
appStore.dispatch(appSlice.actions.addLog({log: false, msg: "... derived keys and address..."}))
const newId = newIdentifier(address, publicHex, privateHex, UPORT_ROOT_DERIVATION_PATH)
appStore.dispatch(appSlice.actions.addLog({log: false, msg: "... created new ID..."}))
// awaiting because otherwise the UI may not see that a mnemonic was created
const savedId = await storeIdentifier(newId, mnemonic, mnemonicPassword)
appStore.dispatch(appSlice.actions.addLog({log: false, msg: "... stored new ID..."}))
return savedId
}
// Create a totally new ID
export const createAndStoreIdentifier = async (mnemonicPassword) => {
// This doesn't give us the entropy/seed.
//const id = await agent.didManagerCreate()
const entropy = crypto.randomBytes(32)
const mnemonic = bip39.entropyToMnemonic(entropy)
appStore.dispatch(appSlice.actions.addLog({log: false, msg: "... generated mnemonic..."}))
return importAndStoreIdentifier(mnemonic, mnemonicPassword, false, [])
}
```
## Kudos
### Kudos
Gifts make the world go 'round!
Gifts make the world go 'round!