update nostr message to include signature for public key
This commit is contained in:
@@ -6,12 +6,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
|
||||||
|
## [0.3.29-beta]
|
||||||
|
### Changed
|
||||||
|
- Send signed data to nostr endpoints to verify public key ownership.
|
||||||
|
### Changed in DB or environment
|
||||||
|
- Uses Endorser.ch version 4.1.1
|
||||||
|
|
||||||
|
|
||||||
## [0.3.28]
|
## [0.3.28]
|
||||||
### Added
|
### Added
|
||||||
- Posting to nostr apps Trustroots & TripHopping
|
- Posting to nostr apps Trustroots & TripHopping
|
||||||
- Display of providers on claim view page
|
- Display of providers on claim view page
|
||||||
### Changed
|
### Changed
|
||||||
- Switched BVC-meeting-ending gift to be a gift from the group.
|
- Switched BVC-meeting-ending gift to be a gift from the group.
|
||||||
|
### Changed in DB or environment
|
||||||
|
- Requires Endorser.ch version 4.1.0
|
||||||
|
|
||||||
|
|
||||||
## [0.3.27] - 2024.09.22 - ee23e6f005e47f5bd6f04d804599f6395371b0e4
|
## [0.3.27] - 2024.09.22 - ee23e6f005e47f5bd6f04d804599f6395371b0e4
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ npm run build
|
|||||||
|
|
||||||
* `rsync -azvu -e "ssh -i ~/.ssh/..." dist ubuntutest@test.timesafari.app:time-safari`
|
* `rsync -azvu -e "ssh -i ~/.ssh/..." dist ubuntutest@test.timesafari.app:time-safari`
|
||||||
|
|
||||||
* Commit changes. Record the new hash in the changelog. Edit package.json to increment version & add "-beta", `npm install`, and commit. Also record what version is on production.
|
* Record the new hash in the changelog. Edit package.json to increment version & add "-beta", `npm install`, and commit. Also record what version is on production.
|
||||||
|
|
||||||
* [Tag with the new version.](https://gitea.anomalistdesign.com/trent_larson/crowd-funder-for-time-pwa/releases)
|
* [Tag with the new version.](https://gitea.anomalistdesign.com/trent_larson/crowd-funder-for-time-pwa/releases)
|
||||||
|
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "TimeSafari",
|
"name": "TimeSafari",
|
||||||
"version": "0.3.28",
|
"version": "0.3.28-beta",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "TimeSafari",
|
"name": "TimeSafari",
|
||||||
"version": "0.3.28",
|
"version": "0.3.28-beta",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dicebear/collection": "^5.4.1",
|
"@dicebear/collection": "^5.4.1",
|
||||||
"@dicebear/core": "^5.4.1",
|
"@dicebear/core": "^5.4.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "TimeSafari",
|
"name": "TimeSafari",
|
||||||
"version": "0.3.28",
|
"version": "0.3.28-beta",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"serve": "vite preview",
|
"serve": "vite preview",
|
||||||
|
|||||||
@@ -105,13 +105,11 @@
|
|||||||
<span class="col-span-1 w-full flex justify-center">{{ zoneName }}</span>
|
<span class="col-span-1 w-full flex justify-center">{{ zoneName }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center mb-4">
|
<div
|
||||||
<input
|
class="flex items-center mb-4"
|
||||||
type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
v-model="includeLocation"
|
|
||||||
@click="includeLocation = !includeLocation"
|
@click="includeLocation = !includeLocation"
|
||||||
/>
|
>
|
||||||
|
<input type="checkbox" class="mr-2" v-model="includeLocation" />
|
||||||
<label for="includeLocation">Include Location</label>
|
<label for="includeLocation">Include Location</label>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="includeLocation" class="mb-4 aspect-video">
|
<div v-if="includeLocation" class="mb-4 aspect-video">
|
||||||
@@ -149,22 +147,12 @@
|
|||||||
v-if="showGeneralAdvanced && includeLocation"
|
v-if="showGeneralAdvanced && includeLocation"
|
||||||
class="items-center mb-4"
|
class="items-center mb-4"
|
||||||
>
|
>
|
||||||
<div class="flex">
|
<div class="flex" @click="sendToTrustroots = !sendToTrustroots">
|
||||||
<input
|
<input type="checkbox" class="mr-2" v-model="sendToTrustroots" />
|
||||||
type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
v-model="sendToTrustroots"
|
|
||||||
@click="sendToTrustroots = !sendToTrustroots"
|
|
||||||
/>
|
|
||||||
<label>Send to Trustroots</label>
|
<label>Send to Trustroots</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex">
|
<div class="flex" @click="sendToTripHopping = !sendToTripHopping">
|
||||||
<input
|
<input type="checkbox" class="mr-2" v-model="sendToTripHopping" />
|
||||||
type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
v-model="sendToTripHopping"
|
|
||||||
@click="sendToTripHopping = !sendToTripHopping"
|
|
||||||
/>
|
|
||||||
<label>Send to TripHopping</label>
|
<label>Send to TripHopping</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -202,7 +190,10 @@
|
|||||||
import "leaflet/dist/leaflet.css";
|
import "leaflet/dist/leaflet.css";
|
||||||
import { AxiosError, AxiosRequestHeaders } from "axios";
|
import { AxiosError, AxiosRequestHeaders } from "axios";
|
||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
|
import { hexToBytes } from "@noble/hashes/utils";
|
||||||
|
import type { EventTemplate, VerifiedEvent } from "nostr-tools/lib/types/core";
|
||||||
import { accountFromSeedWords } from "nostr-tools/nip06";
|
import { accountFromSeedWords } from "nostr-tools/nip06";
|
||||||
|
import { finalizeEvent, serializeEvent } from "nostr-tools/pure";
|
||||||
import { Component, Vue } from "vue-facing-decorator";
|
import { Component, Vue } from "vue-facing-decorator";
|
||||||
import { LMap, LMarker, LTileLayer } from "@vue-leaflet/vue-leaflet";
|
import { LMap, LMarker, LTileLayer } from "@vue-leaflet/vue-leaflet";
|
||||||
import { Router } from "vue-router";
|
import { Router } from "vue-router";
|
||||||
@@ -456,18 +447,25 @@ export default class NewEditProjectView extends Vue {
|
|||||||
|
|
||||||
const projectPath = encodeURIComponent(resp.data.success.handleId);
|
const projectPath = encodeURIComponent(resp.data.success.handleId);
|
||||||
|
|
||||||
|
let signedPayload: VerifiedEvent; // sign something to prove ownership of pubkey
|
||||||
if (this.sendToTrustroots) {
|
if (this.sendToTrustroots) {
|
||||||
|
signedPayload = await this.signPayload();
|
||||||
this.sendToNostrPartner(
|
this.sendToNostrPartner(
|
||||||
"NOSTR-EVENT-TRUSTROOTS",
|
"NOSTR-EVENT-TRUSTROOTS",
|
||||||
"Trustroots",
|
"Trustroots",
|
||||||
resp.data.success.claimId,
|
resp.data.success.claimId,
|
||||||
|
signedPayload,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (this.sendToTripHopping) {
|
if (this.sendToTripHopping) {
|
||||||
|
if (!signedPayload) {
|
||||||
|
signedPayload = await this.signPayload();
|
||||||
|
}
|
||||||
this.sendToNostrPartner(
|
this.sendToNostrPartner(
|
||||||
"NOSTR-EVENT-TRIPHOPPING",
|
"NOSTR-EVENT-TRIPHOPPING",
|
||||||
"TripHopping",
|
"TripHopping",
|
||||||
resp.data.success.claimId,
|
resp.data.success.claimId,
|
||||||
|
signedPayload,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,10 +533,38 @@ export default class NewEditProjectView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async signPayload(): Promise<VerifiedEvent> {
|
||||||
|
const account = await getAccount(this.activeDid);
|
||||||
|
// get the last number of the derivationPath
|
||||||
|
const finalDerNum = account?.derivationPath?.split?.("/")?.reverse()[0];
|
||||||
|
// remove any trailing '
|
||||||
|
const finalDerNumNoApostrophe = finalDerNum?.replace(/'/g, "");
|
||||||
|
const accountNum = Number(finalDerNumNoApostrophe || 0);
|
||||||
|
const pubPri = accountFromSeedWords(
|
||||||
|
account?.mnemonic as string,
|
||||||
|
"",
|
||||||
|
accountNum,
|
||||||
|
);
|
||||||
|
const privateBytes = hexToBytes(pubPri?.privateKey);
|
||||||
|
// No real content is necessary, we just want something signed,
|
||||||
|
// so we might as well use nostr libs for nostr functions.
|
||||||
|
// Besides: someday we may create real content that we can relay.
|
||||||
|
const event: EventTemplate = {
|
||||||
|
kind: 30402,
|
||||||
|
tags: [[]],
|
||||||
|
content: "",
|
||||||
|
created_at: 0,
|
||||||
|
};
|
||||||
|
// Why does IntelliJ not see matching types?
|
||||||
|
const signedEvent = finalizeEvent(event, privateBytes);
|
||||||
|
return signedEvent;
|
||||||
|
}
|
||||||
|
|
||||||
private async sendToNostrPartner(
|
private async sendToNostrPartner(
|
||||||
linkCode: string,
|
linkCode: string,
|
||||||
serviceName: string,
|
serviceName: string,
|
||||||
jwtId: string,
|
jwtId: string,
|
||||||
|
signedPayload: VerifiedEvent,
|
||||||
) {
|
) {
|
||||||
// first, get the public key for nostr
|
// first, get the public key for nostr
|
||||||
const account = await getAccount(this.activeDid);
|
const account = await getAccount(this.activeDid);
|
||||||
@@ -557,11 +583,15 @@ export default class NewEditProjectView extends Vue {
|
|||||||
const trustrootsUrl = DEFAULT_PARTNER_API_SERVER + "/api/partner/link";
|
const trustrootsUrl = DEFAULT_PARTNER_API_SERVER + "/api/partner/link";
|
||||||
const timeSafariUrl = window.location.origin + "/claim/" + jwtId;
|
const timeSafariUrl = window.location.origin + "/claim/" + jwtId;
|
||||||
const content = this.fullClaim.name + " - see " + timeSafariUrl;
|
const content = this.fullClaim.name + " - see " + timeSafariUrl;
|
||||||
|
// Why does IntelliJ not see matching types?
|
||||||
|
const payload = serializeEvent(signedPayload);
|
||||||
const trustrootsParams = {
|
const trustrootsParams = {
|
||||||
jwtId: jwtId,
|
jwtId: jwtId,
|
||||||
linkCode: linkCode,
|
linkCode: linkCode,
|
||||||
inputJson: JSON.stringify(content),
|
inputJson: JSON.stringify(content),
|
||||||
nostrPubKeyHex: nostrPubKey,
|
pubKeyHex: nostrPubKey,
|
||||||
|
pubKeyImage: payload,
|
||||||
|
pubKeySigHex: signedPayload.sig,
|
||||||
};
|
};
|
||||||
const fullTrustrootsUrl = trustrootsUrl;
|
const fullTrustrootsUrl = trustrootsUrl;
|
||||||
const headers = await getHeaders(this.activeDid);
|
const headers = await getHeaders(this.activeDid);
|
||||||
|
|||||||
Reference in New Issue
Block a user