diff --git a/README.md b/README.md
index d3e62418..1f22caed 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# kickstart-for-time-pwa
+# TimeSafari.app - Crowd-Funder for Time - PWA
## Project setup
@@ -13,6 +13,11 @@ npm install
npm run serve
```
+### Lints and fixes files
+```
+npm run lint
+```
+
### Compiles and minifies for production
If you are deploying in a subdirectory, add it to `publicPath` in vue.config.js, eg: `publicPath: "/app/time-tracker/",`
@@ -21,41 +26,19 @@ If you are deploying in a subdirectory, add it to `publicPath` in vue.config.js,
npm run build
```
-### Lints and fixes files
-```
-npm run lint
-```
-
-## Tests
+... then copy the contents of the `sw_scripts` folder to the `dist` folder - except additional_scripts.js.
-###
-For your own web-push tests, change the 'vapid' URL in App.vue, and install apps on the same domain.
-### Test key contents
-
-See [this page](openssl_signing_console.rst)
+## Tests
### 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
playing one of two ways:
-- Import the keys for the test User `did:ethr:0x000Ee5654b9742f6Fe18ea970e32b97ee2247B51` by importing this seed phrase:
- `seminar accuse mystery assist delay law thing deal image undo guard initial shallow wrestle list fragile borrow velvet tomorrow awake explain test offer control`
+- Import the keys for the test User `did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F` by importing this seed phrase:
+ `rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage`
(Other test users are found [here](https://github.com/trentlarson/endorser-ch/blob/master/test/util.js).)
- Alternatively, register someone else under User #0 automatically:
@@ -66,14 +49,35 @@ playing one of two ways:
### 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
-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 for a new user.
+ - See that it's using the test API.
+ - On each page, verify the messaging.
+ - On the home page, see the feed without names, and see a message prompting to generate an ID.
+ - On the discovery page, check that they can see projects, and set a search area to see projects nearby.
+- As User #0 in another browser on the test API, add a give & a project. (See User #0 details above.)
+ - With the new user on the home page, see the feed that shows User #0 in network but without the name.
+- As the new user on the contacts page, add User #0 as a contact.
+ - On the home page, see the feed that shows User #0 with a name.
+- 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.
+ - On the contacts page, check that they cannot register someone else yet.
+- Walk through the functions on each page.
-### Customize Vue configuration
-See [Configuration Reference](https://cli.vuejs.org/config/).
## Scenarios
@@ -88,12 +92,13 @@ See [Configuration Reference](https://cli.vuejs.org/config/).
- Click on the "Registration Unknown" button and register that person to be able to make claims as them.
-### Clear data & restart
+### Clear/Reset data & restart
-* Clear cache for localhost, then go to http://localhost:8080/start
- (because it'll generate a new one automatically if you start on the `/account` page).
+* Clear cache for localhost.
* Unregister service worker (in Chrome, go to `chrome://serviceworker-internals/`; in Firefox, go to `about:serviceworkers` or `about:debugging`).
-* Clear notifications (in Chrome, go to `chrome://settings/content/notifications`; in Firefox, go to `about:preferences` and search).
+* Clear notification permission (in Chrome, go to `chrome://settings/content/notifications`; in Firefox, go to `about:preferences` and search).
+
+
## Other
@@ -103,110 +108,10 @@ See [Configuration Reference](https://cli.vuejs.org/config/).
* 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.
-```
-// 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) => {
-
- // 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, [])
-}
-```
+* [Customize Vue configuration](https://cli.vuejs.org/config/).
+
-## Kudos
+### Kudos
Gifts make the world go 'round!
diff --git a/openssl_signing_console.rst b/openssl_signing_console.rst
index 28a272ab..8b7befdf 100644
--- a/openssl_signing_console.rst
+++ b/openssl_signing_console.rst
@@ -1,8 +1,11 @@
-Prerequisites:
+JWT Creation & Verification
-jq
+To run this in a script, see ./openssl_signing_console.sh
-You can create a JWT using a library or by encoding the header and payload base64Url and signing it with a secret using a ES256K algorithm. Here is an example of how you can create a JWT using the jq and openssl command line utilities:
+Prerequisites: openssl, jq
+
+You can create a JWT using a library or by encoding the header and payload base64Url and signing it with a secret using
+a ES256K algorithm. Here is an example of how you can create a JWT using the jq and openssl command line utilities:
Here is an example of how you can use openssl to sign a JWT with the ES256K algorithm:
@@ -15,20 +18,22 @@ openssl ec -in private.pem -pubout -out public.pem
header='{"alg":"ES256K", "issuer": "", "typ":"JWT"}'
- Next, create a payload object as a JSON object containing the claims you want to include in the JWT. For example schema.org :
+ Next, create a payload object as a JSON object containing the claims you want to include in the JWT.
+ For example schema.org :
payload='{"@context": "http://schema.org", "@type": "PlanAction", "identifier": "did:ethr:0xb86913f83A867b5Ef04902419614A6FF67466c12", "name": "Test", "description": "Me"}'
Encode the header and payload objects as base64Url strings. You can use the jq command line utility to do this:
-header_b64=$(echo -n "$header" | jq -c -M . | tr -d '\n')
-payload_b64=$(echo -n "$payload" | jq -c -M . | tr -d '\n')
+header_b64=$(echo -n "$header" | jq -c -M . | tr -d '\n' | base64 | tr -d '=' | tr '+' '-' | tr '/' '_')
+payload_b64=$(echo -n "$payload" | jq -c -M . | tr -d '\n' | base64 | tr -d '=' | tr '+' '-' | tr '/' '_')
Concatenate the encoded header, payload, and a secret to create the signing input:
signing_input="$header_b64.$payload_b64"
- Create the signature by signing the signing input with a ES256K algorithm and your secret. You can use the openssl command line utility to do this:
+ Create the signature by signing the signing input with a ES256K algorithm and your secret.
+ You can use the openssl command line utility to do this:
signature=$(echo -n "$signing_input" | openssl dgst -sha256 -sign private.pem)
@@ -43,7 +48,7 @@ Authorization: Bearer $jwt
To verify the JWT, you can use the openssl utility with the public key:
-openssl dgst -sha256 -verify public.pem -signature <(echo -n "$signature") "$signing_input"
-
- This will verify the signature and output Verified OK if the signature is valid. If the signature is not valid, it will output an error.
+echo -n "$signing_input" | openssl dgst -sha256 -verify public.pem -signature <(echo -n "$signature")
+ This will verify the signature and output "Verified OK" if the signature is valid.
+ If the signature is not valid, it will give an error response and output "Verification failure".
diff --git a/openssl_signing_console.sh b/openssl_signing_console.sh
index acdda689..b459dad0 100755
--- a/openssl_signing_console.sh
+++ b/openssl_signing_console.sh
@@ -1,25 +1,39 @@
#!/bin/bash
+# Generate a JWT, with signature verified using OpenSSL
+#
+# Prerequisites: openssl, jq
+#
+# Usage: source ./openssl_signing_console.sh
+#
+# For a more complete explanation, see ./openssl_signing_console.rst
+
+
+# Generate a key and extract the public part
openssl ecparam -name secp256k1 -genkey -noout -out private.pem
openssl ec -in private.pem -pubout -out public.pem
+# Use test data
header='{"alg":"ES256K", "issuer": "", "typ":"JWT"}'
-
payload='{"@context": "http://schema.org", "@type": "PlanAction", "identifier": "did:ethr:0xb86913f83A867b5Ef04902419614A6FF67466c12", "name": "Test", "description": "Me"}'
-header_b64=$(echo -n "$header" | jq -c -M . | tr -d '\n')
-payload_b64=$(echo -n "$payload" | jq -c -M . | tr -d '\n')
+header_b64=$(echo -n "$header" | jq -c -M . | tr -d '\n' | base64 | tr -d '=' | tr '+' '-' | tr '/' '_')
+payload_b64=$(echo -n "$payload" | jq -c -M . | tr -d '\n' | base64 | tr -d '=' | tr '+' '-' | tr '/' '_')
signing_input="$header_b64.$payload_b64"
-echo -n "$signing_input" | openssl dgst -sha256 -sign private.pem -out signature.bin
+signature=$(echo -n "$signing_input" | openssl dgst -sha256 -sign private.pem | openssl base64 -e)
-# Read binary signature from file and encode it to Base64 URL-Safe format
-signature_b64=$(base64 -w 0 < signature.bin | tr -d '=' | tr '+' '-' | tr '/' '_')
+echo -n "$signing_input" | openssl dgst -sha256 -verify public.pem -signature <(echo -n "$signature" | openssl base64 -d)
-# Construct the JWT
-jwt="$signing_input.$signature_b64"
-openssl dgst -sha256 -verify public.pem -signature signature.bin -out verified.txt <(echo -n "$signing_input")
+
+# Read binary signature and encode it to Base64 URL-Safe format
+signature_b64=$(echo -n "$signature" | base64 | tr -d '=' | tr '+' '-' | tr '/' '_')
+
+# Construct the JWT
+jwt="$signing_input.$signature_b64"
+
+echo Resulting JWT: $jwt
diff --git a/package-lock.json b/package-lock.json
index 17450802..75f460e7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
- "name": "kickstart-for-time-pwa",
- "version": "0.1.3",
+ "name": "crowd-funder-for-time-pwa",
+ "version": "0.1.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "kickstart-for-time-pwa",
- "version": "0.1.3",
+ "name": "crowd-funder-for-time-pwa",
+ "version": "0.1.4",
"dependencies": {
"@ethersproject/hdnode": "^5.7.0",
"@fortawesome/fontawesome-svg-core": "^6.4.2",
diff --git a/package.json b/package.json
index c96b1bfd..0abdcc40 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
- "name": "kickstart-for-time-pwa",
- "version": "0.1.3",
+ "name": "crowd-funder-for-time-pwa",
+ "version": "0.1.4",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@@ -72,13 +72,13 @@
"@vue/cli-service": "~5.0.8",
"@vue/eslint-config-typescript": "^11.0.3",
"autoprefixer": "^10.4.15",
- "eslint": "^8.48.0",
+ "eslint": "^8.53.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-vue": "^9.17.0",
"leaflet": "^1.9.4",
"postcss": "^8.4.29",
- "prettier": "^3.0.3",
+ "prettier": "^3.1.0",
"tailwindcss": "^3.3.3",
"typescript": "~5.2.2"
}
diff --git a/project.task.yaml b/project.task.yaml
index af1c65bf..9b565845 100644
--- a/project.task.yaml
+++ b/project.task.yaml
@@ -1,55 +1,45 @@
tasks:
+- remove hard-coded anomalistlabs.com
+
+- don't show "Give" & "Offer" on project screen if they don't have an identifier
+- allow some gives even if they aren't registered
+
- in endorser-push-server - mount folder for persistent sqlite DB outside of container
+- extract private_key_hex in webpush.py
- 40 notifications :
- push, where we trigger a ServiceWorker(?) in the app to reach out and check for new data assignee:matthew
-- 01 Replace Gifted/Give in ContactsView with GiftedDialog assignee:matthew
-
-- 01 fix the Discovery map display to not show on top of bottom icons (and any other UI tweaks on the map flow) assignee-group:ui
-- .1 add instructions for map location selection
-
-- 01 Show pop-up or some message confirming that settings & contacts download has been initiated/finished
-
+- .2 change the "claims" verbiage in feeds (eg. safari-notifications.js)
+- .5 allow to manage their notifications even without an identity
- 01 Ensure each action sent to the server has a confirmation - eg registration (ie a toast something that dismisses after 5-10s)
+- .3 fix the Project-location-selection map display to not show on top of bottom icons (and any other UI tweaks on the map flow) assignee-group:ui
-- Home Feed & Quick Give screen :
- - 01 save the feed-viewed status in settings storage ("afterQuery")
- - 01 quick action - send action, maybe choose via canvas tool
- - SEE: https://github.com/konvajs/vue-konva
-
-- 24 Move to Vite assignee:matthew
-
-- .5 switch so DiscoverView shows anywhere by default, and no number unless search is done (and maybe a better filter UI, including "mine" to consolidate with ProjectsView)
-- .2 fit as many icons as possible on home & project view screens but only going halfway down the page assignee-group:ui
- .5 Add infinite scroll to gifts on the home page
- .5 bug - search for "Safari" does not find the project, but if already on the "Anywhere" tab it shows all
- .2 figure out why endorser-mobile search doesn't find recently created PlanAction
- .1 when creating a plan, select location and then make sure you can deselect on Android
-- .5 add link to further project / people when a project pays ahead
-- .5 add project ID to the URL of the project-view, to make a project publicly-accessible
- .5 fix where user 0 sees no txns from user 1 on contacts page but sees them on list page
-- .2 on ProjectViewView, show different messages for "to" and "from" sections if none exist
-- .2 fix rate limit verbiage (with the new one-per-day allowance) assignee:trent
-- .1 remove the logic to exclude beforeId in list of plans after server has commit 26b25af605e715600d4f12b6416ed9fd7142d164
+- .1 remove the logic to exclude beforeId in list of plans after server has commit 26b25af605e715600d4f12b6416ed9fd7142d164 assignee:trent
- .2 in SeedBackupView, don't load the mnemonic and keep it in memory; only load it when they click "show"
-- .1 Make give description text box into something that expands as they type
-- .1 Make contact info specific to Time Safari - rather pointing at CommunityCred.org
+- fix cert generation (since it didn't happen automatically for Nov 30)
- Discuss whether the remaining tasks are worthwhile before MVP release.
+- .1 Make give description text box into something that expands as they type?
- 04 allow user to download claims, mine + ones I can see about me from others
-- 02 allow user to create new DIDs from the same seed phrase (ie. increment derivation path)
-- .5 on ProjectView page, show immediate feedback when a gift is given (on list?) -- and consider the same for Home & Contacts pages
- .5 customize favicon assignee-group:ui
- .2 Show a warning if both giver and recipient are the same (but still allow?)
- 01 Would it look better to shrink the buttons on many pages so they don't expand to the width of the screen? assignee-group:ui
- .5 Display a more appealing confirmation on the map when erasing the marker
-- .5 make a VC details page
+- .5 make a VC details page, or link to endorser.ch
- .1 Add units or different icon to the coins (to distinguish $, BTC, hours, etc)
-- .5 include the hash of the latest commit on help page next to version
+- .5 include the hash of the latest commit on help page next to version (maybe Trent's git-hash branch)
- .5 remove references to localStorage for projectId (now that it's pulling from the path)
+- bug (that is hard to reproduce) - on the second 'give' recorded on prod it showed me as the agent
+- make identicons for contacts into more-memorable faces (and maybe change project identicons, too)
+- allow download of each VC (to show that they can actually own their data)
- contacts v+ :
- 01 Import all the non-sensitive data (ie. contacts & settings).
@@ -58,14 +48,17 @@ tasks:
- stats v1 :
- 01 show numeric stats
- - 04 show different graphic for projects vs people on world
+ - 04 show different graphic for projects vs people (gnome?) on world
- 01 link to world for specific stats
- .5 don't load another instance of a bush if it already exists
- maybe - allow type annotations in World.js & landmarks.js (since we get this error - "Types are not supported by current JavaScript version")
- 08 convert to cleaner implementation (maybe Drie -- https://github.com/janvorisek/drie)
- Release Minimum Viable Product :
+ - generate new webpush.db entries, data/webpush.db private_key_hex & subscription_info & vapid_claims email
+ - .5 deploy endorser.ch server above Dec 1 (to get plan searches by names as well as descriptions)
- 08 thorough testing for errors & edge cases
+ - 01 ensure ability to recover server remotely, and add redundant access
- Turn off stats-world or ensure it's usable (eg. cannot zoom out too far and lose world, cannot screenshot).
- Add disclaimers.
- Switch default server to the public server.
@@ -75,7 +68,9 @@ tasks:
blocks: ref:https://raw.githubusercontent.com/trentlarson/lives-of-gifts/master/project.yaml#kickstarter%20for%20time
- .5 show seed phrase in a QR code for transfer to another device
+- .5 on DiscoverView, switch to a filter UI (eg. just from friend
+- 24 Move to Vite
- 32 accept images for projects
- 32 accept images for contacts
@@ -85,6 +80,10 @@ tasks:
- for subtasks: fulfills (is it really the same?), feeds, contributes to, supplies, boosts, advances
- for blocking: blocks, precedes, comes before, is sought by -- vs follows, seeks, builds on ("contributes to" isn't specific enough, "succeeds" has different, possibly confusing meaning)
+- .5 add "back" button to all screens that aren't part of the bottom tray
+- .5 fit as many icons as possible on home & project view screens but only going halfway down the page assignee-group:ui
+- .5 Replace Gifted/Give in ContactsView with GiftedDialog
+
- Stats :
- 01 point out user's location on the world
- 01 present a credential selected from the stats
@@ -101,11 +100,10 @@ tasks:
- Multiple identities
-- Peer DID
-
-- DIDComm
-
-- Write to or read from a different ledger (eg. private ACDC, attest.sh)
+- Support KERI AIDs
+- Support Peer DIDs
+- Support messaging through DIDComm
+- Write to or read from a different ledger (eg. private ACDC, EAS & attest.sh)
- Do we want split first name & last name?
@@ -113,6 +111,7 @@ tasks:
- pull, w/ scheduled runs
- 01 On nearby search, if user starts changing their box but cancels and goes back to the map it is zoomed far out. Fix to fit the box better.
+- 16 From the home screen, make the quick action even easier.
log:
- videos for multiple identities https://youtu.be/p8L87AeD76w and for adding time to contacts https://youtu.be/7Yylczevp10 done:2023-03-29
diff --git a/sample.txt b/sample.txt
deleted file mode 100644
index efe20be6..00000000
--- a/sample.txt
+++ /dev/null
@@ -1,177 +0,0 @@
-
-> kickstart-for-time-pwa@0.1.0 build
-> vue-cli-service build
-
-All browser targets in the browserslist configuration have supported ES module.
-Therefore we don't build two separate bundles for differential loading.
-
-
- WARNING Compiled with 5 warnings6:06:43 PM
-
-[eslint]
-/home/matthew/projects/kick-starter-for-time-pwa/src/components/World/components/objects/landmarks.js
- 98:11 warning Unexpected console statement no-console
- 133:7 warning Unexpected console statement no-console
- 144:5 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/router/index.ts
- 210:3 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/AccountViewView.vue
- 362:7 warning Unexpected console statement no-console
- 375:7 warning Unexpected console statement no-console
- 404:7 warning Unexpected console statement no-console
- 516:7 warning Unexpected console statement no-console
- 536:7 warning Unexpected console statement no-console
- 630:5 warning Unexpected console statement no-console
- 682:7 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/ContactAmountsView.vue
- 206:9 warning Unexpected console statement no-console
- 233:9 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/ContactGiftingView.vue
- 244:9 warning Unexpected console statement no-console
- 267:7 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/ContactsView.vue
- 340:9 warning Unexpected console statement no-console
- 577:9 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/DiscoverView.vue
- 315:9 warning Unexpected console statement no-console
- 343:7 warning Unexpected console statement no-console
- 390:9 warning Unexpected console statement no-console
- 423:7 warning Unexpected console statement no-console
- 532:9 warning Unexpected console statement no-console
- 575:7 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/HomeView.vue
- 349:9 warning Unexpected console statement no-console
- 498:9 warning Unexpected console statement no-console
- 521:7 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/IdentitySwitcherView.vue
- 142:7 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/ImportAccountView.vue
- 123:9 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/ImportDerivedAccountView.vue
- 159:7 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/NewEditProjectView.vue
- 183:9 warning Unexpected console statement no-console
- 215:7 warning Unexpected console statement no-console
- 297:13 warning Unexpected console statement no-console
- 320:11 warning Unexpected console statement no-console
- 345:7 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/ProjectViewView.vue
- 387:9 warning Unexpected console statement no-console
- 421:7 warning Unexpected console statement no-console
- 457:7 warning Unexpected console statement no-console
- 552:9 warning Unexpected console statement no-console
- 554:11 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/ProjectsView.vue
- 131:9 warning Unexpected console statement no-console
- 144:7 warning Unexpected console statement no-console
- 221:9 warning Unexpected console statement no-console
- 237:7 warning Unexpected console statement no-console
-
-/home/matthew/projects/kick-starter-for-time-pwa/src/views/SeedBackupView.vue
- 94:7 warning Unexpected console statement no-console
-
-✖ 44 problems (0 errors, 44 warnings)
-
-
-You may use special comments to disable some warnings.
-Use // eslint-disable-next-line to ignore the next line.
-Use /* eslint-disable */ to ignore all warnings in a file.
- warning
-
-/models/lupine_plant/textures/lambert2SG_baseColor.png is 3.75 MB, and won't be precached. Configure maximumFileSizeToCacheInBytes to change this limit.
-
- warning
-
-/models/lupine_plant/textures/lambert2SG_normal.png is 4.91 MB, and won't be precached. Configure maximumFileSizeToCacheInBytes to change this limit.
-
- warning
-
-asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
-This can impact web performance.
-Assets:
- js/project.44f30c9f.js (318 KiB)
- js/statistics.8a97010a.js (586 KiB)
- js/chunk-vendors.a4845bfb.js (411 KiB)
- js/705.f6a6ce2a.js (252 KiB)
- img/textures/leafy-autumn-forest-floor.jpg (705 KiB)
- models/lupine_plant/textures/lambert2SG_baseColor.png (3.58 MiB)
- models/lupine_plant/textures/lambert2SG_normal.png (4.69 MiB)
-
- warning
-
-entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
-Entrypoints:
- app (447 KiB)
- js/chunk-vendors.a4845bfb.js
- css/app.8f21529c.css
- js/app.8833cebc.js
-
-
- File Size Gzipped
-
- dist/js/statistics.8a97010a.js 585.72 KiB 148.80 KiB
- dist/js/chunk-vendors.a4845bfb.js 411.44 KiB 137.82 KiB
- dist/js/project.44f30c9f.js 317.61 KiB 78.67 KiB
- dist/js/705.f6a6ce2a.js 251.66 KiB 87.12 KiB
- dist/js/891.33615e4f.js 147.32 KiB 42.09 KiB
- dist/js/153.e2c8e249.js 146.26 KiB 42.21 KiB
- dist/js/820.13565d16.js 66.10 KiB 18.33 KiB
- dist/js/contact-qr.e170ec33.js 54.85 KiB 15.63 KiB
- dist/js/772.7b4c53a7.js 30.29 KiB 7.21 KiB
- dist/js/361.898a4525.js 27.40 KiB 8.19 KiB
- dist/js/account.77d86130.js 17.51 KiB 5.93 KiB
- dist/js/app.8833cebc.js 17.31 KiB 5.84 KiB
- dist/js/contacts.3fc90ff8.js 16.94 KiB 5.52 KiB
- dist/js/discover.24106939.js 15.30 KiB 5.22 KiB
- dist/js/536.3bb13201.js 15.23 KiB 4.84 KiB
- dist/workbox-5b385ed2.js 14.11 KiB 4.93 KiB
- dist/js/home.218b99dd.js 13.89 KiB 4.97 KiB
- dist/js/help.50d3117b.js 12.49 KiB 4.38 KiB
- dist/js/projects.417a6cb7.js 8.71 KiB 3.00 KiB
- dist/js/contact-amounts.a32b0ccd.js 8.44 KiB 3.25 KiB
- dist/js/229.120e09bf.js 7.99 KiB 2.72 KiB
- dist/js/identity-switcher.c7937333.js 7.44 KiB 2.52 KiB
- dist/js/new-edit-project.0552181b.js 7.36 KiB 3.11 KiB
- dist/js/300.dcaeb2a3.js 6.56 KiB 3.24 KiB
- dist/js/seed-backup.76a0f7b3.js 3.99 KiB 1.97 KiB
- dist/js/import-derive.c688d4b8.js 3.81 KiB 1.82 KiB
- dist/js/import-account.c3fa35fd.js 3.54 KiB 1.66 KiB
- dist/js/new-edit-account.bb763be2.js 3.39 KiB 1.51 KiB
- dist/js/431.5a6d64e0.js 3.38 KiB 2.56 KiB
- dist/service-worker.js 3.37 KiB 1.38 KiB
- dist/js/scan-contact.46be989a.js 2.79 KiB 1.18 KiB
- dist/js/start.091a7740.js 2.70 KiB 1.30 KiB
- dist/js/new-identifier.bb379420.js 2.12 KiB 1.18 KiB
- dist/js/93.b873dbbf.js 2.08 KiB 1.61 KiB
- dist/js/new-edit-commitment.9248d367.j 1.96 KiB 1.05 KiB
- s
- dist/js/confirm-contact.02004d1d.js 1.89 KiB 1.04 KiB
- dist/js/858.ae4c08ec.js 0.97 KiB 0.78 KiB
- dist/css/app.8f21529c.css 18.41 KiB 4.39 KiB
- dist/css/discover.73ee9bd3.css 14.77 KiB 6.25 KiB
- dist/css/new-edit-project.73ee9bd3.css 14.77 KiB 6.25 KiB
- dist/css/contacts.abb5e493.css 0.40 KiB 0.23 KiB
- dist/css/contact-amounts.5b26ccd4.css 0.31 KiB 0.20 KiB
- dist/css/home.828bc66e.css 0.25 KiB 0.19 KiB
- dist/css/project.828bc66e.css 0.25 KiB 0.19 KiB
- dist/css/statistics.828bc66e.css 0.25 KiB 0.19 KiB
-
- Images and other types of assets omitted.
- Build at: 2023-09-07T10:06:43.972Z - Hash: 2b39fcd4d0e78263 - Time: 32016ms
-
- DONE Build complete. The dist directory is ready to be deployed.
- INFO Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html
-
diff --git a/src/App.vue b/src/App.vue
index 2486884b..585cdcc9 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -262,6 +262,28 @@
+
+
diff --git a/src/libs/endorserServer.ts b/src/libs/endorserServer.ts
index 628d5bac..8db51eb8 100644
--- a/src/libs/endorserServer.ts
+++ b/src/libs/endorserServer.ts
@@ -59,17 +59,40 @@ export interface GiveServerRecord {
unit: string;
}
+export interface OfferServerRecord {
+ amount: number;
+ amountGiven: number;
+ offeredByDid: string;
+ recipientDid: string;
+ requirementsMet: boolean;
+ unit: string;
+ validThrough: string;
+}
+
export interface GiveVerifiableCredential {
"@context"?: string; // optional when embedded, eg. in an Agree
- "@type": string;
+ "@type": "GiveAction";
agent?: { identifier: string };
description?: string;
- fulfills?: { "@type": string; identifier: string };
+ fulfills?: { "@type": string; identifier?: string; lastClaimId?: string };
identifier?: string;
object?: { amountOfThisGood: number; unitCode: string };
recipient?: { identifier: string };
}
+export interface OfferVerifiableCredential {
+ "@context"?: string; // optional when embedded, eg. in an Agree
+ "@type": "Offer";
+ description?: string;
+ includesObject?: { amountOfThisGood: number; unitCode: string };
+ itemOffered?: {
+ description?: string;
+ isPartOf?: { identifier?: string; lastClaimId?: string; "@type"?: string };
+ };
+ offeredBy?: { identifier: string };
+ validThrough?: string;
+}
+
export interface PlanVerifiableCredential {
"@context": "https://schema.org";
"@type": "PlanAction";
@@ -152,7 +175,7 @@ export interface ErrorResult {
error: InternalError;
}
-export type CreateAndSubmitGiveResult = SuccessResult | ErrorResult;
+export type CreateAndSubmitClaimResult = SuccessResult | ErrorResult;
/**
* For result, see https://api.endorser.ch/api-docs/#/claims/post_api_v2_claim
@@ -172,20 +195,81 @@ export async function createAndSubmitGive(
description?: string,
hours?: number,
fulfillsProjectHandleId?: string,
-): Promise {
- try {
- const vcClaim: GiveVerifiableCredential = {
- "@context": "https://schema.org",
- "@type": "GiveAction",
- recipient: toDid ? { identifier: toDid } : undefined,
- agent: fromDid ? { identifier: fromDid } : undefined,
- description: description || undefined,
- object: hours ? { amountOfThisGood: hours, unitCode: "HUR" } : undefined,
- fulfills: fulfillsProjectHandleId
- ? { "@type": "PlanAction", identifier: fulfillsProjectHandleId }
- : undefined,
+): Promise {
+ const vcClaim: GiveVerifiableCredential = {
+ "@context": "https://schema.org",
+ "@type": "GiveAction",
+ recipient: toDid ? { identifier: toDid } : undefined,
+ agent: fromDid ? { identifier: fromDid } : undefined,
+ description: description || undefined,
+ object: hours ? { amountOfThisGood: hours, unitCode: "HUR" } : undefined,
+ fulfills: fulfillsProjectHandleId
+ ? { "@type": "PlanAction", identifier: fulfillsProjectHandleId }
+ : undefined,
+ };
+ return createAndSubmitClaim(
+ vcClaim as GenericClaim,
+ identity,
+ apiServer,
+ axios,
+ );
+}
+
+/**
+ * For result, see https://api.endorser.ch/api-docs/#/claims/post_api_v2_claim
+ *
+ * @param identity
+ * @param description may be null; should have this or hours
+ * @param hours may be null; should have this or description
+ * @param expirationDate ISO 8601 date string YYYY-MM-DD (may be null)
+ * @param fulfillsProjectHandleId ID of project to which this contributes (may be null)
+ */
+export async function createAndSubmitOffer(
+ axios: Axios,
+ apiServer: string,
+ identity: IIdentifier,
+ description?: string,
+ hours?: number,
+ expirationDate?: string,
+ fulfillsProjectHandleId?: string,
+): Promise {
+ const vcClaim: OfferVerifiableCredential = {
+ "@context": "https://schema.org",
+ "@type": "Offer",
+ offeredBy: { identifier: identity.did },
+ validThrough: expirationDate || undefined,
+ };
+ if (hours) {
+ vcClaim.includesObject = {
+ amountOfThisGood: hours,
+ unitCode: "HUR",
};
+ }
+ if (description) {
+ vcClaim.itemOffered = { description };
+ }
+ if (fulfillsProjectHandleId) {
+ vcClaim.itemOffered = vcClaim.itemOffered || {};
+ vcClaim.itemOffered.isPartOf = {
+ "@type": "PlanAction",
+ identifier: fulfillsProjectHandleId,
+ };
+ }
+ return createAndSubmitClaim(
+ vcClaim as GenericClaim,
+ identity,
+ apiServer,
+ axios,
+ );
+}
+export async function createAndSubmitClaim(
+ vcClaim: GenericClaim,
+ identity: IIdentifier,
+ apiServer: string,
+ axios: Axios,
+): Promise {
+ try {
const vcPayload = {
vc: {
"@context": ["https://www.w3.org/2018/credentials/v1"],
@@ -226,15 +310,11 @@ export async function createAndSubmitGive(
});
return { type: "success", response };
- } catch (error: unknown) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ } catch (error: any) {
+ console.log("Error creating claim:", error);
const errorMessage: string =
- error === null
- ? "Null error"
- : error instanceof Error
- ? error.message
- : typeof error === "object" && error !== null && "message" in error
- ? (error as { message: string }).message
- : "Unknown error";
+ error.response?.data?.error?.message || error.message || "Unknown error";
return {
type: "error",
diff --git a/src/registerServiceWorker.ts b/src/registerServiceWorker.ts
index 5b60bb7d..22ca9b9a 100644
--- a/src/registerServiceWorker.ts
+++ b/src/registerServiceWorker.ts
@@ -3,7 +3,7 @@
import { register } from "register-service-worker";
if (process.env.NODE_ENV === "production") {
- register(`${process.env.BASE_URL}service-worker.js`, {
+ register("/additional-scripts.js", {
ready() {
console.log(
"App is being served from cache by a service worker.\n" +
diff --git a/src/router/index.ts b/src/router/index.ts
index 8868f60d..49b33760 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -168,6 +168,14 @@ const routes: Array = [
/* webpackChunkName: "scan-contact" */ "../views/ContactScanView.vue"
),
},
+ {
+ path: "/search-area",
+ name: "search-area",
+ component: () =>
+ import(
+ /* webpackChunkName: "search-area" */ "../views/SearchAreaView.vue"
+ ),
+ },
{
path: "/seed-backup",
name: "seed-backup",
diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue
index 08083fb0..e33d0d2e 100644
--- a/src/views/AccountViewView.vue
+++ b/src/views/AccountViewView.vue
@@ -186,8 +186,9 @@
You have done {{ limits.doneRegistrationsThisMonth }} registrations
- out of {{ limits.maxRegistrationsPerMonth }} for this month. Your
- registrations counter resets at
+ out of {{ limits.maxRegistrationsPerMonth }} for this month. (You can
+ register nobody on your first day, and after that only one a day in
+ your first month.) Your registration counter resets at
{{ readableTime(limits.nextMonthBeginDateTime) }}
@@ -700,11 +701,11 @@ export default class AccountViewView extends Vue {
this.$notify(
{
group: "alert",
- type: "toast",
+ type: "success",
title: "Download Started",
text: "See your downloads directory for the backup.",
},
- 5000,
+ -1,
);
}
diff --git a/src/views/ContactAmountsView.vue b/src/views/ContactAmountsView.vue
index 385a2851..897505c1 100644
--- a/src/views/ContactAmountsView.vue
+++ b/src/views/ContactAmountsView.vue
@@ -2,8 +2,11 @@
-
-
+
+
+
+
+ Given with {{ contact?.name }}
+
-
- Given with {{ contact?.name }}
-
(Only 50 most recent)
@@ -358,7 +362,10 @@ export default class ContactsView extends Vue {