Native app facelift, extension UI tweaks, bug fixes.
Show/Hide Button for private key in Options page. Move experimental page into separate sub-folder. Move delegation wizard to sub-folder. Move permission page into separate folder. Basic functional SwiftUI look for the app. Beginning to define the main app view. NavigationStack and Privacy Policy Show App Icon on main screen. Getting Started: macOS Getting Started: iPhone Getting Started: iPad Removing old default UIKit code. Added "No Thanks" toggle to the relay reminder. Clearly indicate in the Settings page when a profile is a delegated profile. Changed recommended relays to all public relays. Use x-cloak in all the places. Fix bundle display name to use capital N. Added copy button to pubkey in settings. Window default size. Updating event kind list. Allow events to be copied by clicking on them in the event log. Tweaking the colors for a more purple-ish look. Added Tips and Tricks view to native app. Move utilities modules into separate folder. Rename event_log files to event_history to escape some content blockers. Renamed Event Log to Event History in the UI as well.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script defer src="delegation.build.js"></script>
|
||||
<link rel="stylesheet" href="/options.build.css">
|
||||
|
||||
<title>Delegation Wizard</title>
|
||||
</head>
|
||||
|
||||
<body x-data="delegated" class="text-fuchsia-900 p-3.5 lg:p-32">
|
||||
<h1 class="text-3xl lg:text-6xl font-bold md:text-center">New Delegated Profile</h1>
|
||||
|
||||
<p class="mt-6">
|
||||
A delegated user, as laid out in the
|
||||
<a href="https://github.com/nostr-protocol/nips/blob/master/26.md" @click.prevent="openNip($event)">NIP-26
|
||||
specification</a>,
|
||||
is a user that is authorized to sign events for a different user. Additional limits can be
|
||||
put on the delegated account, such as time limits.
|
||||
</p>
|
||||
|
||||
<p class="mt-3">
|
||||
This may be useful if you wish to keep your main key stored safely offline, but still post as that user
|
||||
with a throwaway key.
|
||||
</p>
|
||||
|
||||
<div class="section">
|
||||
<h2 class="section-header">Delegator</h2>
|
||||
<p class="text-small italic">The secure account to be delegated.</p>
|
||||
|
||||
<div class="mt-3">
|
||||
<label for="delegator">Delegator Private Key</label>
|
||||
<br>
|
||||
<input type="text" class="input" x-model="privKey" :class="validKeyClass" autocapitalize="off" autocomplete="off"
|
||||
spellcheck="off">
|
||||
<p class="text-xs italic">This is not stored, but only used to sign a token which is stored instead.</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<label for="duration">Delegated Duration</label>
|
||||
<br>
|
||||
<select x-model.number="duration" class="input">
|
||||
<option value="1">1 day</option>
|
||||
<option value="7">7 days</option>
|
||||
<option value="30">30 days</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<button class="button" @click.prevent="goBack">Back</button>
|
||||
<button class="button" @click.prevent="save" :disabled="!isKeyValid">Save</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,86 @@
|
||||
import Alpine from 'alpinejs';
|
||||
import {
|
||||
generateProfile,
|
||||
getProfiles,
|
||||
validateKey,
|
||||
} from '../../utilities/utils';
|
||||
import { getPublicKey, nip26, nip19 } from 'nostr-tools';
|
||||
|
||||
const storage = browser.storage.local;
|
||||
|
||||
Alpine.data('delegated', () => ({
|
||||
privKey: '',
|
||||
duration: 7,
|
||||
profile: {},
|
||||
|
||||
async init() {
|
||||
this.profile = await generateProfile('New Delegate');
|
||||
this.profile.delegate = true;
|
||||
},
|
||||
|
||||
openNip(event) {
|
||||
browser.tabs.create({ url: event.target.href, active: true });
|
||||
},
|
||||
|
||||
goBack() {
|
||||
window.location = browser.runtime.getURL('options.html');
|
||||
},
|
||||
|
||||
async save() {
|
||||
let profiles = await getProfiles();
|
||||
|
||||
// We need to jankify this Alpine proxy object so it's in the right format
|
||||
// when we save it to storage
|
||||
let profile = JSON.parse(JSON.stringify(this.profile));
|
||||
profile.delegator = getPublicKey(this.decodedPrivKey);
|
||||
profile.delegation = this.getDelegation();
|
||||
|
||||
profiles.push(profile);
|
||||
let profileIndex = profiles.length - 1;
|
||||
await storage.set({ profiles, profileIndex });
|
||||
|
||||
window.location = `${browser.runtime.getURL(
|
||||
'options.html'
|
||||
)}?index=${profileIndex}`;
|
||||
},
|
||||
|
||||
getDelegation() {
|
||||
let pubkey = getPublicKey(this.profile.privKey);
|
||||
|
||||
let delegation = nip26.createDelegation(this.decodedPrivKey, {
|
||||
pubkey,
|
||||
until: this.until,
|
||||
since: Math.round(Date.now() / 1000) - 1,
|
||||
});
|
||||
console.log(delegation);
|
||||
return delegation;
|
||||
},
|
||||
|
||||
// Properties
|
||||
|
||||
get isKeyValid() {
|
||||
return validateKey(this.privKey);
|
||||
},
|
||||
|
||||
get validKeyClass() {
|
||||
return this.isKeyValid
|
||||
? ''
|
||||
: 'ring-2 ring-rose-500 focus:ring-2 focus:ring-rose-500 border-transparent focus:border-transparent';
|
||||
},
|
||||
|
||||
get until() {
|
||||
return Math.round(Date.now() / 1000) + 60 * 60 * 24 * this.duration;
|
||||
},
|
||||
|
||||
get decodedPrivKey() {
|
||||
if (!this.isKeyValid) {
|
||||
return null;
|
||||
}
|
||||
if (this.privKey.startsWith('nsec')) {
|
||||
return nip19.decode(this.privKey).data;
|
||||
}
|
||||
return this.privKey;
|
||||
},
|
||||
}));
|
||||
|
||||
Alpine.start();
|
||||
Reference in New Issue
Block a user