prettier, update to the dependencies (latest), remove nip26 and its artifacts, cleanup and renew
This commit is contained in:
@@ -188,7 +188,6 @@
|
||||
941B042F2978CDF900CA291E /* Icon-16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-16.png"; sourceTree = "<group>"; };
|
||||
941B04302978CDF900CA291E /* Icon-64.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-64.png"; sourceTree = "<group>"; };
|
||||
944A6E02299F2FBB0032C2E3 /* experimental */ = {isa = PBXFileReference; lastKnownFileType = folder; path = experimental; sourceTree = "<group>"; };
|
||||
944A6E0D299F32070032C2E3 /* wizards */ = {isa = PBXFileReference; lastKnownFileType = folder; path = wizards; sourceTree = "<group>"; };
|
||||
944A6E12299F39D30032C2E3 /* permission */ = {isa = PBXFileReference; lastKnownFileType = folder; path = permission; sourceTree = "<group>"; };
|
||||
944A6E38299F46270032C2E3 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
|
||||
944A6E3E299F46D30032C2E3 /* NostoreApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NostoreApp.swift; sourceTree = "<group>"; };
|
||||
@@ -294,7 +293,6 @@
|
||||
children = (
|
||||
9471E91E29A470C700EA623B /* event_history */,
|
||||
944A6E12299F39D30032C2E3 /* permission */,
|
||||
944A6E0D299F32070032C2E3 /* wizards */,
|
||||
944A6E02299F2FBB0032C2E3 /* experimental */,
|
||||
948C69E4297F8BA600FB3574 /* options.build.css */,
|
||||
948C69E1297F891F00FB3574 /* options.build.js */,
|
||||
@@ -461,7 +459,7 @@
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastSwiftUpdateCheck = 1420;
|
||||
LastUpgradeCheck = 1500;
|
||||
LastUpgradeCheck = 1600;
|
||||
TargetAttributes = {
|
||||
941B03AE296FA90400CA291E = {
|
||||
CreatedOnToolsVersion = 14.2;
|
||||
@@ -503,7 +501,6 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
944A6E0E299F32070032C2E3 /* wizards in Resources */,
|
||||
941B03E0296FA90400CA291E /* Icon.png in Resources */,
|
||||
944A6E03299F2FBB0032C2E3 /* experimental in Resources */,
|
||||
941B03DE296FA90400CA291E /* Main.html in Resources */,
|
||||
@@ -520,7 +517,6 @@
|
||||
files = (
|
||||
941B03E1296FA90400CA291E /* Icon.png in Resources */,
|
||||
941B03E3296FA90400CA291E /* Style.css in Resources */,
|
||||
944A6E0F299F32070032C2E3 /* wizards in Resources */,
|
||||
941B03E5296FA90400CA291E /* Script.js in Resources */,
|
||||
944A6E14299F39D30032C2E3 /* permission in Resources */,
|
||||
941B03E9296FA90400CA291E /* Assets.xcassets in Resources */,
|
||||
@@ -534,7 +530,6 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9471E91F29A470C700EA623B /* event_history in Resources */,
|
||||
944A6E10299F32070032C2E3 /* wizards in Resources */,
|
||||
941B0413297110F100CA291E /* background.build.js in Resources */,
|
||||
944A6E15299F39D30032C2E3 /* permission in Resources */,
|
||||
948C69E82982DFE900FB3574 /* background.html in Resources */,
|
||||
@@ -572,7 +567,6 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9471E92029A470C700EA623B /* event_history in Resources */,
|
||||
944A6E11299F32070032C2E3 /* wizards in Resources */,
|
||||
941B0414297110F100CA291E /* background.build.js in Resources */,
|
||||
944A6E16299F39D30032C2E3 /* permission in Resources */,
|
||||
948C69E92982DFE900FB3574 /* background.html in Resources */,
|
||||
@@ -860,7 +854,6 @@
|
||||
941B0403296FA90400CA291E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
@@ -902,7 +895,6 @@
|
||||
941B0404296FA90400CA291E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
@@ -960,7 +952,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 1.2.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"-framework",
|
||||
@@ -993,7 +985,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@executable_path/../../../../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 1.2.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"-framework",
|
||||
@@ -1011,7 +1003,6 @@
|
||||
941B040A296FA90400CA291E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = "macOS (App)/nostore.entitlements";
|
||||
@@ -1048,7 +1039,6 @@
|
||||
941B040B296FA90400CA291E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = "macOS (App)/nostore.entitlements";
|
||||
|
||||
@@ -4,10 +4,10 @@ This is a [NIP-07][nip07] compatible extension for signing nostr events.
|
||||
|
||||
## Features
|
||||
|
||||
* Login with nostr (`getPublicKey`).
|
||||
* Post nostr event (`signEvent`).
|
||||
* Encrypted direct messages (`nip04.encrypt` and `nip04.decrypt`).
|
||||
* Multiple profiles.
|
||||
- Login with nostr (`getPublicKey`).
|
||||
- Post nostr event (`signEvent`).
|
||||
- Encrypted direct messages (`nip04.encrypt` and `nip04.decrypt`).
|
||||
- Multiple profiles.
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "display-p3",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.665",
|
||||
"green" : "0.271",
|
||||
"red" : "0.509"
|
||||
"colors": [
|
||||
{
|
||||
"color": {
|
||||
"color-space": "display-p3",
|
||||
"components": {
|
||||
"alpha": "1.000",
|
||||
"blue": "0.665",
|
||||
"green": "0.271",
|
||||
"red": "0.509"
|
||||
}
|
||||
},
|
||||
"idiom": "universal"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,74 +1,74 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "iOS-Icon-1024.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-16.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-32.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-32 1.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-64.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-128.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-256.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-256 1.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-512.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-512 1.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "512x512"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-1024.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "512x512"
|
||||
"images": [
|
||||
{
|
||||
"filename": "iOS-Icon-1024.png",
|
||||
"idiom": "universal",
|
||||
"platform": "ios",
|
||||
"size": "1024x1024"
|
||||
},
|
||||
{
|
||||
"filename": "Icon-16.png",
|
||||
"idiom": "mac",
|
||||
"scale": "1x",
|
||||
"size": "16x16"
|
||||
},
|
||||
{
|
||||
"filename": "Icon-32.png",
|
||||
"idiom": "mac",
|
||||
"scale": "2x",
|
||||
"size": "16x16"
|
||||
},
|
||||
{
|
||||
"filename": "Icon-32 1.png",
|
||||
"idiom": "mac",
|
||||
"scale": "1x",
|
||||
"size": "32x32"
|
||||
},
|
||||
{
|
||||
"filename": "Icon-64.png",
|
||||
"idiom": "mac",
|
||||
"scale": "2x",
|
||||
"size": "32x32"
|
||||
},
|
||||
{
|
||||
"filename": "Icon-128.png",
|
||||
"idiom": "mac",
|
||||
"scale": "1x",
|
||||
"size": "128x128"
|
||||
},
|
||||
{
|
||||
"filename": "Icon-256.png",
|
||||
"idiom": "mac",
|
||||
"scale": "2x",
|
||||
"size": "128x128"
|
||||
},
|
||||
{
|
||||
"filename": "Icon-256 1.png",
|
||||
"idiom": "mac",
|
||||
"scale": "1x",
|
||||
"size": "256x256"
|
||||
},
|
||||
{
|
||||
"filename": "Icon-512.png",
|
||||
"idiom": "mac",
|
||||
"scale": "2x",
|
||||
"size": "256x256"
|
||||
},
|
||||
{
|
||||
"filename": "Icon-512 1.png",
|
||||
"idiom": "mac",
|
||||
"scale": "1x",
|
||||
"size": "512x512"
|
||||
},
|
||||
{
|
||||
"filename": "Icon-1024.png",
|
||||
"idiom": "mac",
|
||||
"scale": "2x",
|
||||
"size": "512x512"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"images": [
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Icon-512.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"images": [
|
||||
{
|
||||
"filename": "Icon-512.png",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "ipad-menu.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"images": [
|
||||
{
|
||||
"filename": "ipad-menu.png",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "ipad-popup.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"images": [
|
||||
{
|
||||
"filename": "ipad-popup.png",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "ipad-url-bar.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"images": [
|
||||
{
|
||||
"filename": "ipad-url-bar.png",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "iphone-menu.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"images": [
|
||||
{
|
||||
"filename": "iphone-menu.png",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "iphone-popup.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"images": [
|
||||
{
|
||||
"filename": "iphone-popup.png",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "iphone-url-bar.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"images": [
|
||||
{
|
||||
"filename": "iphone-url-bar.png",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "default-popup.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"images": [
|
||||
{
|
||||
"filename": "default-popup.png",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "toolbar-inactive.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
"images": [
|
||||
{
|
||||
"filename": "toolbar-inactive.png",
|
||||
"idiom": "universal",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"idiom": "universal",
|
||||
"scale": "3x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'"
|
||||
/>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, user-scalable=no"
|
||||
/>
|
||||
|
||||
<link rel="stylesheet" href="../Style.css">
|
||||
<script src="../Script.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<img src="../Icon.png" width="128" height="128" alt="Nostore Icon">
|
||||
<p class="platform-ios">You can turn on Nostore’s Safari extension in Settings.</p>
|
||||
<p class="platform-mac state-unknown">You can turn on Nostore’s extension in Safari Extensions preferences.</p>
|
||||
<p class="platform-mac state-on">Nostore’s extension is currently on. You can turn it off in Safari Extensions preferences.</p>
|
||||
<p class="platform-mac state-off">Nostore’s extension is currently off. You can turn it on in Safari Extensions preferences.</p>
|
||||
<button class="platform-mac open-preferences">Quit and Open Safari Extensions Preferences…</button>
|
||||
</body>
|
||||
<link rel="stylesheet" href="../Style.css" />
|
||||
<script src="../Script.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<img src="../Icon.png" width="128" height="128" alt="Nostore Icon" />
|
||||
<p class="platform-ios">
|
||||
You can turn on Nostore’s Safari extension in Settings.
|
||||
</p>
|
||||
<p class="platform-mac state-unknown">
|
||||
You can turn on Nostore’s extension in Safari Extensions
|
||||
preferences.
|
||||
</p>
|
||||
<p class="platform-mac state-on">
|
||||
Nostore’s extension is currently on. You can turn it off in Safari
|
||||
Extensions preferences.
|
||||
</p>
|
||||
<p class="platform-mac state-off">
|
||||
Nostore’s extension is currently off. You can turn it on in Safari
|
||||
Extensions preferences.
|
||||
</p>
|
||||
<button class="platform-mac open-preferences">
|
||||
Quit and Open Safari Extensions Preferences…
|
||||
</button>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,13 +2,20 @@ function show(platform, enabled, useSettingsInsteadOfPreferences) {
|
||||
document.body.classList.add(`platform-${platform}`);
|
||||
|
||||
if (useSettingsInsteadOfPreferences) {
|
||||
document.getElementsByClassName('platform-mac state-on')[0].innerText = "Nostore’s extension is currently on. You can turn it off in the Extensions section of Safari Settings.";
|
||||
document.getElementsByClassName('platform-mac state-off')[0].innerText = "Nostore’s extension is currently off. You can turn it on in the Extensions section of Safari Settings.";
|
||||
document.getElementsByClassName('platform-mac state-unknown')[0].innerText = "You can turn on Nostore’s extension in the Extensions section of Safari Settings.";
|
||||
document.getElementsByClassName('platform-mac open-preferences')[0].innerText = "Quit and Open Safari Settings…";
|
||||
document.getElementsByClassName('platform-mac state-on')[0].innerText =
|
||||
'Nostore’s extension is currently on. You can turn it off in the Extensions section of Safari Settings.';
|
||||
document.getElementsByClassName('platform-mac state-off')[0].innerText =
|
||||
'Nostore’s extension is currently off. You can turn it on in the Extensions section of Safari Settings.';
|
||||
document.getElementsByClassName(
|
||||
'platform-mac state-unknown'
|
||||
)[0].innerText =
|
||||
'You can turn on Nostore’s extension in the Extensions section of Safari Settings.';
|
||||
document.getElementsByClassName(
|
||||
'platform-mac open-preferences'
|
||||
)[0].innerText = 'Quit and Open Safari Settings…';
|
||||
}
|
||||
|
||||
if (typeof enabled === "boolean") {
|
||||
if (typeof enabled === 'boolean') {
|
||||
document.body.classList.toggle(`state-on`, enabled);
|
||||
document.body.classList.toggle(`state-off`, !enabled);
|
||||
} else {
|
||||
@@ -18,7 +25,9 @@ function show(platform, enabled, useSettingsInsteadOfPreferences) {
|
||||
}
|
||||
|
||||
function openPreferences() {
|
||||
webkit.messageHandlers.controller.postMessage("open-preferences");
|
||||
webkit.messageHandlers.controller.postMessage('open-preferences');
|
||||
}
|
||||
|
||||
document.querySelector("button.open-preferences").addEventListener("click", openPreferences);
|
||||
document
|
||||
.querySelector('button.open-preferences')
|
||||
.addEventListener('click', openPreferences);
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import {
|
||||
generatePrivateKey,
|
||||
getPublicKey,
|
||||
signEvent,
|
||||
nip04,
|
||||
nip19,
|
||||
nip26,
|
||||
getEventHash,
|
||||
generateSecretKey,
|
||||
getPublicKey,
|
||||
finalizeEvent,
|
||||
} from 'nostr-tools';
|
||||
import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
|
||||
import { Mutex } from 'async-mutex';
|
||||
import {
|
||||
getProfileIndex,
|
||||
@@ -14,7 +13,6 @@ import {
|
||||
getProfile,
|
||||
getPermission,
|
||||
setPermission,
|
||||
feature,
|
||||
} from './utilities/utils';
|
||||
import { saveEvent } from './utilities/db';
|
||||
|
||||
@@ -40,15 +38,13 @@ browser.runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
||||
deny(message);
|
||||
return Promise.resolve(true);
|
||||
case 'generatePrivateKey':
|
||||
return Promise.resolve(generatePrivateKey());
|
||||
return Promise.resolve(generatePrivateKey_());
|
||||
case 'savePrivateKey':
|
||||
return savePrivateKey(message.payload);
|
||||
case 'getNpub':
|
||||
return getNpub(message.payload);
|
||||
case 'getNsec':
|
||||
return getNsec(message.payload);
|
||||
case 'createDelegation':
|
||||
return createDelegation(message.payload);
|
||||
case 'calcPubKey':
|
||||
return Promise.resolve(getPublicKey(message.payload));
|
||||
case 'npubEncode':
|
||||
@@ -63,7 +59,7 @@ browser.runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
||||
case 'nip04.decrypt':
|
||||
case 'getRelays':
|
||||
validations[uuid] = sendResponse;
|
||||
setDelegation(message).then(() => ask(uuid, message));
|
||||
ask(uuid, message);
|
||||
setTimeout(() => {
|
||||
prompt.release?.();
|
||||
}, 10_000);
|
||||
@@ -88,6 +84,11 @@ async function forceRelease() {
|
||||
}
|
||||
}
|
||||
|
||||
async function generatePrivateKey_() {
|
||||
const sk = generateSecretKey();
|
||||
return bytesToHex(sk);
|
||||
}
|
||||
|
||||
async function ask(uuid, { kind, host, payload }) {
|
||||
await forceRelease(); // Clean up previous tab if it closed without cleaning itself up
|
||||
prompt.release = await prompt.mutex.acquire();
|
||||
@@ -178,35 +179,32 @@ async function savePrivateKey([index, privKey]) {
|
||||
privKey = nip19.decode(privKey).data;
|
||||
}
|
||||
let profiles = await get('profiles');
|
||||
profiles[index].privKey = privKey;
|
||||
profiles[index].privKey = bytesToHex(privKey);
|
||||
await storage.set({ profiles });
|
||||
return true;
|
||||
}
|
||||
|
||||
async function getNsec(index) {
|
||||
let profile = await getProfile(index);
|
||||
let nsec = nip19.nsecEncode(profile.privKey);
|
||||
let nsec = nip19.nsecEncode(hexToBytes(profile.privKey));
|
||||
return nsec;
|
||||
}
|
||||
|
||||
async function getNpub(index) {
|
||||
let profile = await getProfile(index);
|
||||
let pubKey = getPublicKey(profile.privKey);
|
||||
let pubKey = getPublicKey(hexToBytes(profile.privKey));
|
||||
let npub = nip19.npubEncode(pubKey);
|
||||
return npub;
|
||||
}
|
||||
|
||||
async function getPrivKey() {
|
||||
let profile = await currentProfile();
|
||||
return profile.privKey;
|
||||
return hexToBytes(profile.privKey);
|
||||
}
|
||||
|
||||
async function getPubKey() {
|
||||
let pi = await getProfileIndex();
|
||||
let profile = await getProfile(pi);
|
||||
if (profile.delegate) {
|
||||
return profile.delegator;
|
||||
}
|
||||
let privKey = await getPrivKey();
|
||||
let pubKey = getPublicKey(privKey);
|
||||
return pubKey;
|
||||
@@ -220,11 +218,8 @@ async function currentProfile() {
|
||||
|
||||
async function signEvent_(event, host) {
|
||||
event = JSON.parse(JSON.stringify(event));
|
||||
let privKey = await getPrivKey();
|
||||
let pubKey = getPublicKey(privKey);
|
||||
event.pubkey = pubKey;
|
||||
event.id = getEventHash(event);
|
||||
event.sig = signEvent(event, privKey);
|
||||
let sk = await getPrivKey();
|
||||
event = finalizeEvent(event, sk);
|
||||
saveEvent({
|
||||
event,
|
||||
metadata: { host, signed_at: Math.round(Date.now() / 1000) },
|
||||
@@ -253,42 +248,3 @@ async function getRelays() {
|
||||
});
|
||||
return relayObj;
|
||||
}
|
||||
|
||||
function createDelegation({
|
||||
kind,
|
||||
delegatorPrivKey,
|
||||
delegateePubKey,
|
||||
until,
|
||||
since,
|
||||
}) {
|
||||
delegatorPrivKey = nip19.decode(delegatorPrivKey).data;
|
||||
let delegation = nip26.createDelegation(delegatorPrivKey, {
|
||||
pubkey: delegateePubKey,
|
||||
until,
|
||||
// kind,
|
||||
// since,
|
||||
});
|
||||
return Promise.resolve(delegation);
|
||||
}
|
||||
|
||||
async function setDelegation({ payload }) {
|
||||
if (!payload) return;
|
||||
let active = await feature('delegation');
|
||||
if (!active) return;
|
||||
|
||||
let { delegate, delegation } = await currentProfile();
|
||||
|
||||
// Nothing to do if this is not a delegate
|
||||
if (!delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
payload.tags = payload.tags || [];
|
||||
|
||||
payload.tags.push([
|
||||
'delegation',
|
||||
delegation.from,
|
||||
delegation.cond,
|
||||
delegation.sig,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,142 +1,228 @@
|
||||
<!DOCTYPE html>
|
||||
<!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="event_history.build.js"></script>
|
||||
<link rel="stylesheet" href="/options.build.css" />
|
||||
<title>Event History</title>
|
||||
|
||||
<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="event_history.build.js"></script>
|
||||
<link rel="stylesheet" href="/options.build.css">
|
||||
<title>Event History</title>
|
||||
<style>
|
||||
label {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<style>
|
||||
label {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="text-fuchsia-900 p-3.5 lg:p-32" x-data="eventLog">
|
||||
<p>
|
||||
<a href="/options.html" class="border-none hover:underline"
|
||||
>← Back</a
|
||||
>
|
||||
</p>
|
||||
|
||||
<body class="text-fuchsia-900 p-3.5 lg:p-32" x-data="eventLog">
|
||||
<p>
|
||||
<a href="/options.html" class="border-none hover:underline">← Back</a>
|
||||
</p>
|
||||
<h1 class="section-header">Event History</h1>
|
||||
|
||||
<h1 class="section-header">Event History</h1>
|
||||
<div class="section">
|
||||
<div class="section-header">Filters</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">Filters</div>
|
||||
<div class="grid grid-cols-2 xl:grid-cols-4 gap-4">
|
||||
<div>
|
||||
<label for="view">View</label>
|
||||
<select
|
||||
id="view"
|
||||
class="input"
|
||||
x-model="view"
|
||||
@change="reload"
|
||||
>
|
||||
<option value="created_at">created_at</option>
|
||||
<option value="kind">kind</option>
|
||||
<option value="host">host</option>
|
||||
<option value="pubkey">pubkey</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 xl:grid-cols-4 gap-4">
|
||||
<div>
|
||||
<label for="view">View</label>
|
||||
<select id="view" class="input" x-model="view" @change="reload">
|
||||
<option value="created_at">created_at</option>
|
||||
<option value="kind">kind</option>
|
||||
<option value="host">host</option>
|
||||
<option value="pubkey">pubkey</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="sort">Order</label>
|
||||
<select
|
||||
id="sort"
|
||||
x-model="sort"
|
||||
class="input"
|
||||
@change="reload"
|
||||
>
|
||||
<option value="asc">Ascending</option>
|
||||
<option value="desc">Descending</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="sort">Order</label>
|
||||
<select id="sort" x-model="sort" class="input" @change="reload">
|
||||
<option value="asc">Ascending</option>
|
||||
<option value="desc">Descending</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="max">Max</label>
|
||||
<input
|
||||
type="number"
|
||||
x-model.number="max"
|
||||
@input.debounce.750ms="reload"
|
||||
class="input"
|
||||
min="10"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="max">Max</label>
|
||||
<input type="number" x-model.number="max" @input.debounce.750ms="reload" class="input" min="10">
|
||||
</div>
|
||||
<div></div>
|
||||
|
||||
<div></div>
|
||||
<div x-show="view === 'created_at'" x-cloak>
|
||||
<label for="fromCreatedAt">From</label>
|
||||
<input
|
||||
type="date"
|
||||
id="fromCreatedAt"
|
||||
x-model="fromCreatedAt"
|
||||
class="input"
|
||||
@change="reload"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div x-show="view === 'created_at'" x-cloak>
|
||||
<label for="fromCreatedAt">From</label>
|
||||
<input type="date" id="fromCreatedAt" x-model="fromCreatedAt" class="input" @change="reload">
|
||||
</div>
|
||||
<div x-show="view === 'created_at'" x-cloak>
|
||||
<label for="toCreatedAt">To</label>
|
||||
<input
|
||||
type="date"
|
||||
id="toCreatedAt"
|
||||
x-model="toCreatedAt"
|
||||
class="input"
|
||||
@change="reload"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div x-show="view === 'created_at'" x-cloak>
|
||||
<label for="toCreatedAt">To</label>
|
||||
<input type="date" id="toCreatedAt" x-model="toCreatedAt" class="input" @change="reload">
|
||||
</div>
|
||||
<div x-show="view === 'kind'" x-cloak>
|
||||
<label for="kindShortcut">Quick Select</label>
|
||||
<select
|
||||
id="kindShortcut"
|
||||
class="input"
|
||||
@change="quickKindSelect"
|
||||
x-model="quickKind"
|
||||
>
|
||||
<option></option>
|
||||
<template x-for="k in kinds">
|
||||
<option :value="k[0]" x-text="k[1]"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div x-show="view === 'kind'" x-cloak>
|
||||
<label for="kindShortcut">Quick Select</label>
|
||||
<select id="kindShortcut" class="input" @change="quickKindSelect" x-model="quickKind">
|
||||
<option></option>
|
||||
<template x-for="k in kinds">
|
||||
<option :value="k[0]" x-text="k[1]"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div x-show="view === 'kind'" x-cloak>
|
||||
<label for="fromKind">From</label>
|
||||
<input
|
||||
type="number"
|
||||
id="fromKind"
|
||||
x-model.number="fromKind"
|
||||
class="input"
|
||||
@change="reload"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div x-show="view === 'kind'" x-cloak>
|
||||
<label for="fromKind">From</label>
|
||||
<input type="number" id="fromKind" x-model.number="fromKind" class="input" @change="reload">
|
||||
</div>
|
||||
<div x-show="view === 'kind'" x-cloak>
|
||||
<label for="toKind">To</label>
|
||||
<input
|
||||
type="number"
|
||||
id="toKind"
|
||||
x-model.number="toKind"
|
||||
class="input"
|
||||
@change="reload"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div x-show="view === 'kind'" x-cloak>
|
||||
<label for="toKind">To</label>
|
||||
<input type="number" id="toKind" x-model.number="toKind" class="input" @change="reload">
|
||||
</div>
|
||||
<div x-show="view === 'host'" x-cloak>
|
||||
<label for="host">Host</label>
|
||||
<select
|
||||
id="host"
|
||||
class="input"
|
||||
x-model="host"
|
||||
@change="reload"
|
||||
>
|
||||
<option value=""></option>
|
||||
<template x-for="h in allHosts">
|
||||
<option :value="h" x-text="h"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div x-show="view === 'host'" x-cloak>
|
||||
<label for="host">Host</label>
|
||||
<select id="host" class="input" x-model="host" @change="reload">
|
||||
<option value=""></option>
|
||||
<template x-for="h in allHosts">
|
||||
<option :value="h" x-text="h"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div x-show="view === 'pubkey'" x-cloak>
|
||||
<label for="profiles">Profiles</label>
|
||||
<select
|
||||
id="profiles"
|
||||
class="input"
|
||||
x-model="profile"
|
||||
@change="pkFromProfile"
|
||||
>
|
||||
<option value=""></option>
|
||||
<template x-for="p in profileNames">
|
||||
<option :value="p" x-text="p"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div x-show="view === 'pubkey'" x-cloak>
|
||||
<label for="profiles">Profiles</label>
|
||||
<select id="profiles" class="input" x-model="profile" @change="pkFromProfile">
|
||||
<option value=""></option>
|
||||
<template x-for="p in profileNames">
|
||||
<option :value="p" x-text="p"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div x-show="view === 'pubkey'" x-cloak>
|
||||
<label for="pubkey">Pubkey</label>
|
||||
<input
|
||||
type="text"
|
||||
class="input"
|
||||
x-model="pubkey"
|
||||
@input.debounce="reload"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div x-show="view === 'pubkey'" x-cloak>
|
||||
<label for="pubkey">Pubkey</label>
|
||||
<input type="text" class="input" x-model="pubkey" @input.debounce="reload">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button class="button mt-3" @click="saveAll">Save all</button>
|
||||
<button class="button mt-3" @click="deleteAll">
|
||||
Delete all
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button class="button mt-3" @click="saveAll">Save all</button>
|
||||
<button class="button mt-3" @click="deleteAll">Delete all</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm italic mt-1 text-right">
|
||||
Click/tap event body to copy the raw event.
|
||||
</div>
|
||||
|
||||
<div class="text-sm italic mt-1 text-right">Click/tap event body to copy the raw event.</div>
|
||||
<template x-for="(event, index) in events">
|
||||
<div class="mt-3 border-solid border border-fuchsia-700 rounded-lg">
|
||||
<div
|
||||
class="select-none flex cursor-pointer text-sm md:text-xl"
|
||||
@click="selected = selected === index ? null : index"
|
||||
>
|
||||
<div
|
||||
class="flex-none w-14 p-4 font-extrabold"
|
||||
x-text="selected === index ? '-' : '+'"
|
||||
></div>
|
||||
<div
|
||||
class="flex-1 w-64 p-4"
|
||||
x-text="formatDate(event.metadata.signed_at)"
|
||||
></div>
|
||||
<div
|
||||
class="flex-1 w-64 p-4"
|
||||
x-text="event.metadata.host"
|
||||
></div>
|
||||
<div
|
||||
class="flex-1 w-64 p-4"
|
||||
x-text="formatKind(event.event.kind)"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<template x-for="(event, index) in events">
|
||||
<div class="mt-3 border-solid border border-fuchsia-700 rounded-lg">
|
||||
<div class="select-none flex cursor-pointer text-sm md:text-xl"
|
||||
@click="selected = selected === index ? null : index">
|
||||
<div class="flex-none w-14 p-4 font-extrabold" x-text="selected === index ? '-' : '+'"></div>
|
||||
<div class="flex-1 w-64 p-4" x-text="formatDate(event.metadata.signed_at)"></div>
|
||||
<div class="flex-1 w-64 p-4" x-text="event.metadata.host"></div>
|
||||
<div class="flex-1 w-64 p-4" x-text="formatKind(event.event.kind)"></div>
|
||||
</div>
|
||||
|
||||
<div @click.prevent="copyEvent(index)" class="cursor-pointer">
|
||||
<pre class="rounded-b-lg bg-slate-200 text-sm md:text-xl" x-html="highlight(event)" x-show="selected === index"
|
||||
x-transition:enter.opacity.delay.75ms x-transition:leave.opacity x-cloak>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="fixed top-0 right-0 bg-fuchsia-800 rounded-md p-4 text-white m-8 drop-shadow-md" x-show="copied" x-cloack>
|
||||
Event copied!
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<div @click.prevent="copyEvent(index)" class="cursor-pointer">
|
||||
<pre
|
||||
class="rounded-b-lg bg-slate-200 text-sm md:text-xl"
|
||||
x-html="highlight(event)"
|
||||
x-show="selected === index"
|
||||
x-transition:enter.opacity.delay.75ms
|
||||
x-transition:leave.opacity
|
||||
x-cloak
|
||||
></pre>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
class="fixed top-0 right-0 bg-fuchsia-800 rounded-md p-4 text-white m-8 drop-shadow-md"
|
||||
x-show="copied"
|
||||
x-cloack
|
||||
>
|
||||
Event copied!
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,34 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<!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" />
|
||||
<link rel="stylesheet" href="/options.build.css" />
|
||||
<script src="/experimental/experimental.build.js" defer></script>
|
||||
<title>Experimental Features</title>
|
||||
</head>
|
||||
|
||||
<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">
|
||||
<link rel="stylesheet" href="/options.build.css">
|
||||
<script src="/experimental/experimental.build.js" defer></script>
|
||||
<title>Experimental Features</title>
|
||||
</head>
|
||||
<body class="text-fuchsia-900 p-3.5 lg:p-32" x-data="experimental">
|
||||
<p>
|
||||
<a href="/options.html" class="border-none hover:underline"
|
||||
>← Back</a
|
||||
>
|
||||
</p>
|
||||
<h1 class="text-3xl lg:text-6xl font-bold md:text-center">
|
||||
Experimental Features
|
||||
</h1>
|
||||
<p class="mt-3 text-center font-bold italic">
|
||||
These things may only work partially, or not work at all. Caveat
|
||||
emptor!
|
||||
</p>
|
||||
|
||||
<body class="text-fuchsia-900 p-3.5 lg:p-32" x-data="experimental">
|
||||
<p>
|
||||
<a href="/options.html" class="border-none hover:underline">← Back</a>
|
||||
</p>
|
||||
<h1 class="text-3xl lg:text-6xl font-bold md:text-center">Experimental Features</h1>
|
||||
<p class="mt-3 text-center font-bold italic">
|
||||
These things may only work partially, or not
|
||||
work at all. Caveat
|
||||
emptor!
|
||||
</p>
|
||||
|
||||
<template x-for="feature in features" :key="feature[0]">
|
||||
<div class="mt-4">
|
||||
<input class="checkbox" type="checkbox" :id="feature[0]" x-model="feature[1]"
|
||||
@change="change(feature[0], feature[1])">
|
||||
<label :for="feature[0]" x-text="feature[2]" class="font-bold"></label>
|
||||
<p x-text="feature[3]" class="italic"></p>
|
||||
</div>
|
||||
</template>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<template x-for="feature in features" :key="feature[0]">
|
||||
<div class="mt-4">
|
||||
<input
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
:id="feature[0]"
|
||||
x-model="feature[1]"
|
||||
@change="change(feature[0], feature[1])"
|
||||
/>
|
||||
<label
|
||||
:for="feature[0]"
|
||||
x-text="feature[2]"
|
||||
class="font-bold"
|
||||
></label>
|
||||
<p x-text="feature[3]" class="italic"></p>
|
||||
</div>
|
||||
</template>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,9 +2,9 @@ import Alpine from 'alpinejs';
|
||||
|
||||
const FEATURES = [
|
||||
[
|
||||
'delegation',
|
||||
'NIP-26 Delegation Profiles',
|
||||
'Allow user to create delegated profiles that obey the NIP-26 standard. Requires client support.',
|
||||
'none',
|
||||
'NIP-XX: None',
|
||||
'Reserved for the future use.',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
@@ -17,12 +17,8 @@
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"js": [
|
||||
"content.build.js"
|
||||
],
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
]
|
||||
"js": ["content.build.js"],
|
||||
"matches": ["<all_urls>"]
|
||||
}
|
||||
],
|
||||
"action": {
|
||||
@@ -39,10 +35,7 @@
|
||||
"options_ui": {
|
||||
"page": "options.html"
|
||||
},
|
||||
"permissions": [
|
||||
"storage",
|
||||
"clipboardWrite"
|
||||
],
|
||||
"permissions": ["storage", "clipboardWrite"],
|
||||
"web_accessible_resources": [
|
||||
{
|
||||
"resources": [
|
||||
@@ -51,25 +44,20 @@
|
||||
"options.build.js",
|
||||
"options.build.css",
|
||||
"options.html",
|
||||
"wizards/delegation/delegation.html",
|
||||
"wizards/delegation/delegation.build.js",
|
||||
"wizards/delegation/delegation.build.css",
|
||||
"experimental/experimental.html",
|
||||
"experimental/experimental.build.js",
|
||||
"event_history/event_history.html",
|
||||
"event_history/event_history.build.js"
|
||||
],
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
]
|
||||
"matches": ["<all_urls>"]
|
||||
}
|
||||
],
|
||||
"content_security_policy": {
|
||||
"extension_pages": "script-src 'self' 'unsafe-eval'"
|
||||
"extension_pages": "object-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; frame-src 'self'; font-src 'self'; media-src 'self'; child-src 'self';"
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"safari": {
|
||||
"strict_min_version": "15.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,46 +2,48 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
[x-cloak] { display: none; }
|
||||
[x-cloak] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.button {
|
||||
/* Colors */
|
||||
@apply bg-fuchsia-900 hover:bg-fuchsia-800 active:bg-fuchsia-700 text-fuchsia-200 disabled:bg-gray-200 disabled:text-black;
|
||||
.button {
|
||||
/* Colors */
|
||||
@apply bg-fuchsia-900 hover:bg-fuchsia-800 active:bg-fuchsia-700 text-fuchsia-200 disabled:bg-gray-200 disabled:text-black;
|
||||
|
||||
/* Sizing and padding */
|
||||
@apply rounded-lg p-1.5 md:w-24 min-w-fit text-center;
|
||||
}
|
||||
/* Sizing and padding */
|
||||
@apply rounded-lg p-1.5 md:w-24 min-w-fit text-center;
|
||||
}
|
||||
|
||||
.input {
|
||||
/* Colors */
|
||||
@apply bg-fuchsia-200 text-fuchsia-800 disabled:bg-gray-200 disabled:text-black focus:border-fuchsia-800;
|
||||
.input {
|
||||
/* Colors */
|
||||
@apply bg-fuchsia-200 text-fuchsia-800 disabled:bg-gray-200 disabled:text-black focus:border-fuchsia-800;
|
||||
|
||||
/* Sizing and padding */
|
||||
@apply rounded-lg p-1.5 lg:p-1.5 w-full md:w-64;
|
||||
}
|
||||
/* Sizing and padding */
|
||||
@apply rounded-lg p-1.5 lg:p-1.5 w-full md:w-64;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
/* Colors */
|
||||
@apply text-fuchsia-800 bg-fuchsia-200 rounded-full accent-fuchsia-200;
|
||||
.checkbox {
|
||||
/* Colors */
|
||||
@apply text-fuchsia-800 bg-fuchsia-200 rounded-full accent-fuchsia-200;
|
||||
|
||||
/* Sizing and padding */
|
||||
@apply w-4 h-4 lg:w-5 lg:h-5;
|
||||
}
|
||||
/* Sizing and padding */
|
||||
@apply w-4 h-4 lg:w-5 lg:h-5;
|
||||
}
|
||||
|
||||
.section {
|
||||
@apply border-2 border-fuchsia-700 rounded-lg p-1 md:p-5 mt-6 shadow-md;
|
||||
}
|
||||
.section {
|
||||
@apply border-2 border-fuchsia-700 rounded-lg p-1 md:p-5 mt-6 shadow-md;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
@apply text-2xl lg:text-5xl font-bold;
|
||||
}
|
||||
.section-header {
|
||||
@apply text-2xl lg:text-5xl font-bold;
|
||||
}
|
||||
|
||||
.subsection-header {
|
||||
@apply text-xl lg:text-4xl font-bold;
|
||||
}
|
||||
.subsection-header {
|
||||
@apply text-xl lg:text-4xl font-bold;
|
||||
}
|
||||
|
||||
a {
|
||||
@apply border-2 border-dotted text-fuchsia-800 border-fuchsia-800 hover:border-transparent;
|
||||
}
|
||||
}
|
||||
a {
|
||||
@apply border-2 border-dotted text-fuchsia-800 border-fuchsia-800 hover:border-transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,184 +1,261 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="options.build.css" />
|
||||
<script defer src="options.build.js"></script>
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="options.build.css">
|
||||
<script defer src="options.build.js"></script>
|
||||
<body x-data="options" class="text-fuchsia-900 p-3.5 lg:p-32">
|
||||
<h1 class="text-3xl lg:text-6xl font-bold md:text-center">Settings</h1>
|
||||
|
||||
</head>
|
||||
|
||||
<body x-data="options" class="text-fuchsia-900 p-3.5 lg:p-32">
|
||||
<h1 class="text-3xl lg:text-6xl font-bold md:text-center">Settings</h1>
|
||||
|
||||
<!-- PROFILES -->
|
||||
<div class="mt-6">
|
||||
<label for="profiles">Profile</label>
|
||||
<br>
|
||||
<select class="input" x-model.number="profileIndex" id="profiles">
|
||||
<template x-for="(name, index) in profileNames" :key="index">
|
||||
<option x-text="name" :value="index"></option>
|
||||
</template>
|
||||
</select>
|
||||
<div class="block md:inline p-3 pl-0 md:p-0">
|
||||
<button class="button" @click.prevent="newProfile">New</button>
|
||||
<button class="button" @click.prevent="newDelegated" x-show="delegationActive" x-cloak>New Delegate</button>
|
||||
<button class="button" @click.prevent="deleteProfile">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- KEYS -->
|
||||
<div class="section">
|
||||
<h2 class="section-header">Keys</h2>
|
||||
<p class="text-sm italic">Provide your <code class="not-italic">nsec</code> or legacy (hexadecimal) private keys.
|
||||
</p>
|
||||
<form @submit.prevent="saveProfile">
|
||||
<div class="mt-3">
|
||||
<label for="profile-name">Profile Name</label>
|
||||
<br>
|
||||
<input x-model="profileName" type="text" class="input" autocapitalize="off" autocomplete="off" spellcheck="off">
|
||||
</div>
|
||||
|
||||
<div class="mt-3" x-show="delegate" x-cloak>
|
||||
<div class="mb-1">
|
||||
<span class="text-red-700 font-bold">This is is a delegated profile.</span>
|
||||
<!-- PROFILES -->
|
||||
<div class="mt-6">
|
||||
<label for="profiles">Profile</label>
|
||||
<br />
|
||||
<select class="input" x-model.number="profileIndex" id="profiles">
|
||||
<template x-for="(name, index) in profileNames" :key="index">
|
||||
<option x-text="name" :value="index"></option>
|
||||
</template>
|
||||
</select>
|
||||
<div class="block md:inline p-3 pl-0 md:p-0">
|
||||
<button class="button" @click.prevent="newProfile">New</button>
|
||||
<button class="button" @click.prevent="deleteProfile">
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="delegator-pub-key">Delegator Public Key</label>
|
||||
<br>
|
||||
<input id="delegator-pub-key" x-model="delegator" class="input" autocapitalize="off" autocomplete="off"
|
||||
spellcheck="off" :disabled="delegate">
|
||||
</div>
|
||||
<!-- KEYS -->
|
||||
<div class="section">
|
||||
<h2 class="section-header">Keys</h2>
|
||||
<p class="text-sm italic">
|
||||
Provide your <code class="not-italic">nsec</code> or legacy
|
||||
(hexadecimal) private keys.
|
||||
</p>
|
||||
<form @submit.prevent="saveProfile">
|
||||
<div class="mt-3">
|
||||
<label for="profile-name">Profile Name</label>
|
||||
<br />
|
||||
<input
|
||||
x-model="profileName"
|
||||
type="text"
|
||||
class="input"
|
||||
autocapitalize="off"
|
||||
autocomplete="off"
|
||||
spellcheck="off"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<label for="priv-key">Private Key</label>
|
||||
<br>
|
||||
<input x-model="privKey" :type="visibilityClass" class="input" :class="validKeyClass" autocapitalize="off"
|
||||
autocomplete="off" spellcheck="off" :disabled="delegate">
|
||||
<a href="" @click.prevent="visible = !visible" x-text="(visible && 'Hide') || 'Show'" class="border-none"></a>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<label for="priv-key">Private Key</label>
|
||||
<br />
|
||||
<input
|
||||
x-model="privKey"
|
||||
:type="visibilityClass"
|
||||
class="input"
|
||||
:class="validKeyClass"
|
||||
autocapitalize="off"
|
||||
autocomplete="off"
|
||||
spellcheck="off"
|
||||
/>
|
||||
<a
|
||||
href=""
|
||||
@click.prevent="visible = !visible"
|
||||
x-text="(visible && 'Hide') || 'Show'"
|
||||
class="border-none"
|
||||
></a>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<label for="pub-key">Public Key</label>
|
||||
<br>
|
||||
<input x-model="pubKey" type="text" class="input" disabled>
|
||||
<a href="" class="border-none" @click.prevent="copyPubKey" x-text="copied ? 'Copied!' : 'Copy'"></a>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<label for="pub-key">Public Key</label>
|
||||
<br />
|
||||
<input
|
||||
x-model="pubKey"
|
||||
type="text"
|
||||
class="input"
|
||||
disabled
|
||||
/>
|
||||
<a
|
||||
href=""
|
||||
class="border-none"
|
||||
@click.prevent="copyPubKey"
|
||||
x-text="copied ? 'Copied!' : 'Copy'"
|
||||
></a>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<button class="button" :disabled="!needsSave || !validKey" @click.prevent="saveProfile">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="mt-3">
|
||||
<button
|
||||
class="button"
|
||||
:disabled="!needsSave || !validKey"
|
||||
@click.prevent="saveProfile"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- RELAYS -->
|
||||
<div class="section">
|
||||
<h2 class="section-header">Relays</h2>
|
||||
<p class="text-sm italic">Add relay suggestions for clients.</p>
|
||||
<template x-if="hasRelays">
|
||||
<table
|
||||
class="mt-3 text-xs md:text-base table-auto md:table-fixed"
|
||||
>
|
||||
<thead class="font-bold text-lg">
|
||||
<td class="p-2 text-center">URL</td>
|
||||
<td class="p-2 text-center">Read</td>
|
||||
<td class="p-2 text-center">Write</td>
|
||||
<td class="p-2 text-center">Actions</td>
|
||||
</thead>
|
||||
<template x-for="(relay, index) in relays" :key="index">
|
||||
<tr>
|
||||
<td class="p-2 w-1/3" x-text="relay.url"></td>
|
||||
<td class="p-2 text-center">
|
||||
<input
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
x-model="relay.read"
|
||||
@change="await saveRelays()"
|
||||
/>
|
||||
</td>
|
||||
<td class="p-2 text-center">
|
||||
<input
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
x-model="relay.write"
|
||||
@change="await saveRelays()"
|
||||
/>
|
||||
</td>
|
||||
<td class="p-2 text-center">
|
||||
<button
|
||||
class="button"
|
||||
@click.prevent="await deleteRelay(index)"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<!-- RELAYS -->
|
||||
<div class="section">
|
||||
<h2 class="section-header">Relays</h2>
|
||||
<p class="text-sm italic">Add relay suggestions for clients.</p>
|
||||
<template x-if="hasRelays">
|
||||
<table class="mt-3 text-xs md:text-base table-auto md:table-fixed">
|
||||
<thead class="font-bold text-lg">
|
||||
<td class="p-2 text-center">URL</td>
|
||||
<td class="p-2 text-center">Read</td>
|
||||
<td class="p-2 text-center">Write</td>
|
||||
<td class="p-2 text-center">Actions</td>
|
||||
</thead>
|
||||
<template x-for="(relay, index) in relays" :key="index">
|
||||
<tr>
|
||||
<td class="p-2 w-1/3" x-text="relay.url"></td>
|
||||
<td class="p-2 text-center">
|
||||
<input class="checkbox" type="checkbox" x-model="relay.read" @change="await saveRelays()">
|
||||
</td>
|
||||
<td class="p-2 text-center">
|
||||
<input class="checkbox" type="checkbox" x-model="relay.write" @change="await saveRelays()">
|
||||
</td>
|
||||
<td class="p-2 text-center">
|
||||
<button class="button" @click.prevent="await deleteRelay(index)">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</template>
|
||||
<template x-if="!hasRelays">
|
||||
<div class="mt-3">
|
||||
There are no relays assigned to this profile.
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template x-if="!hasRelays">
|
||||
<div class="mt-3">
|
||||
There are no relays assigned to this profile.
|
||||
</div>
|
||||
</template>
|
||||
<div class="mt-3" x-show="hasRecommendedRelays" x-cloak>
|
||||
<select x-model="recommendedRelay" class="input">
|
||||
<option value="" disabled selected>
|
||||
Recommended Relays
|
||||
</option>
|
||||
<template x-for="relay in recommendedRelays">
|
||||
<option :value="relay" x-text="relay"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mt-3" x-show="hasRecommendedRelays" x-cloak>
|
||||
<select x-model="recommendedRelay" class="input">
|
||||
<option value="" disabled selected>Recommended Relays</option>
|
||||
<template x-for="relay in recommendedRelays">
|
||||
<option :value="relay" x-text="relay"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<input
|
||||
class="mt-3 input"
|
||||
x-model="newRelay"
|
||||
type="text"
|
||||
@keyup.enter="await addRelay()"
|
||||
placeholder="wss://..."
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="off"
|
||||
spellcheck="off"
|
||||
/>
|
||||
<div class="block md:inline p-3 pl-0 md:p-0">
|
||||
<button class="button" @click="await addRelay()">Add</button>
|
||||
</div>
|
||||
<div
|
||||
class="text-red-500 font-bold"
|
||||
x-show="urlError.length > 0"
|
||||
x-text="urlError"
|
||||
x-cloak
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<input class="mt-3 input" x-model="newRelay" type="text" @keyup.enter="await addRelay()" placeholder="wss://..."
|
||||
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="off">
|
||||
<div class="block md:inline p-3 pl-0 md:p-0">
|
||||
<button class="button" @click="await addRelay()">Add</button>
|
||||
</div>
|
||||
<div class="text-red-500 font-bold" x-show="urlError.length > 0" x-text="urlError" x-cloak></div>
|
||||
</div>
|
||||
<!-- PERMISSIONS -->
|
||||
<div class="section">
|
||||
<h2 class="section-header">App Permissions</h2>
|
||||
<p class="text-sm italic">
|
||||
Permissions granted to individual applications. Everything
|
||||
defaults to <span class="font-bold">Ask</span> unless you have
|
||||
saved a different option.
|
||||
</p>
|
||||
|
||||
<div class="mt-3" x-show="permHosts.length > 0">
|
||||
<label for="app">Apps</label>
|
||||
<br />
|
||||
<select id="app" class="input" x-model="host">
|
||||
<option value=""></option>
|
||||
<template x-for="permHost in permHosts">
|
||||
<option :value="permHost" x-text="permHost"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- PERMISSIONS -->
|
||||
<div class="section">
|
||||
<h2 class="section-header">App Permissions</h2>
|
||||
<p class="text-sm italic">
|
||||
Permissions granted to individual applications.
|
||||
Everything defaults to <span class="font-bold">Ask</span> unless you have saved a different option.
|
||||
</p>
|
||||
<p x-show="permHosts.length === 0" x-cloak class="font-bold mt-3">
|
||||
You have not remembered any app requests yet.
|
||||
</p>
|
||||
|
||||
<div class="mt-3" x-show="permHosts.length > 0">
|
||||
<label for="app">Apps</label>
|
||||
<br>
|
||||
<select id="app" class="input" x-model="host">
|
||||
<option value=""></option>
|
||||
<template x-for="permHost in permHosts">
|
||||
<option :value="permHost" x-text="permHost"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<table
|
||||
class="mt-3 text-xs md:text-base table-fixed"
|
||||
x-show="hostPerms.length > 0"
|
||||
x-cloak
|
||||
>
|
||||
<thead class="font-bold text-lg">
|
||||
<td class="p-2 text-center">App Request</td>
|
||||
<td class="p-2 text-center">Action</td>
|
||||
</thead>
|
||||
<template
|
||||
x-for="[etype, humanName, perm] in hostPerms"
|
||||
:key="etype"
|
||||
>
|
||||
<tr>
|
||||
<td class="p-2 w-1/3 md:w-2/4" x-text="humanName"></td>
|
||||
<td class="p-2 text-center">
|
||||
<select
|
||||
class="input"
|
||||
:value="perm"
|
||||
@change="await setPermission(host, etype, $event.target.value, profileIndex)"
|
||||
>
|
||||
<option value="ask">Ask</option>
|
||||
<option value="allow">Allow</option>
|
||||
<option value="deny">Deny</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p x-show="permHosts.length === 0" x-cloak class="font-bold mt-3">You have not remembered any app requests yet.</p>
|
||||
<div class="mt-6">
|
||||
<button class="button" @click.prevent="closeOptions">Close</button>
|
||||
<button class="button" @click.prevent="clearData">
|
||||
Clear Data
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table class="mt-3 text-xs md:text-base table-fixed" x-show="hostPerms.length > 0" x-cloak>
|
||||
<thead class="font-bold text-lg">
|
||||
<td class="p-2 text-center">App Request</td>
|
||||
<td class="p-2 text-center">Action</td>
|
||||
</thead>
|
||||
<template x-for="[etype, humanName, perm] in hostPerms" :key="etype">
|
||||
<tr>
|
||||
<td class="p-2 w-1/3 md:w-2/4" x-text="humanName"></td>
|
||||
<td class="p-2 text-center">
|
||||
<select class="input" :value="perm"
|
||||
@change="await setPermission(host, etype, $event.target.value, profileIndex)">
|
||||
<option value="ask">Ask</option>
|
||||
<option value="allow">Allow</option>
|
||||
<option value="deny">Deny</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<button class="button" @click.prevent="closeOptions">Close</button>
|
||||
<button class="button" @click.prevent="clearData">Clear Data</button>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<a href="experimental/experimental.html" class="border-none hover:underline">Experimental
|
||||
features →</a>
|
||||
<br>
|
||||
<a href="event_history/event_history.html" class="border-none hover:underline">Event history →</a>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<div class="mt-6">
|
||||
<a
|
||||
href="experimental/experimental.html"
|
||||
class="border-none hover:underline"
|
||||
>Experimental features →</a
|
||||
>
|
||||
<br />
|
||||
<a
|
||||
href="event_history/event_history.html"
|
||||
class="border-none hover:underline"
|
||||
>Event history →</a
|
||||
>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -16,8 +16,6 @@ import {
|
||||
KINDS,
|
||||
humanPermission,
|
||||
validateKey,
|
||||
feature,
|
||||
getDelegator,
|
||||
} from './utilities/utils';
|
||||
|
||||
const log = console.log;
|
||||
@@ -42,10 +40,7 @@ Alpine.data('options', () => ({
|
||||
host: '',
|
||||
permHosts: [],
|
||||
hostPerms: [],
|
||||
delegationActive: false,
|
||||
visible: false,
|
||||
delegate: false,
|
||||
delegator: '',
|
||||
copied: false,
|
||||
setPermission,
|
||||
go,
|
||||
@@ -77,8 +72,6 @@ Alpine.data('options', () => ({
|
||||
await this.getProfileIndex();
|
||||
this.setProfileIndexFromSearch();
|
||||
await this.refreshProfile();
|
||||
|
||||
this.delegationActive = await feature('delegation');
|
||||
},
|
||||
|
||||
async refreshProfile() {
|
||||
@@ -88,7 +81,6 @@ Alpine.data('options', () => ({
|
||||
await this.getNpub();
|
||||
await this.getRelays();
|
||||
await this.getPermissions();
|
||||
await this.getDelegate();
|
||||
},
|
||||
|
||||
// Profile functions
|
||||
@@ -117,27 +109,12 @@ Alpine.data('options', () => ({
|
||||
this.profileIndex = await getProfileIndex();
|
||||
},
|
||||
|
||||
async getDelegate() {
|
||||
let [delegate, delegator] = await getDelegator(this.profileIndex);
|
||||
this.delegate = delegate;
|
||||
this.delegator = await browser.runtime.sendMessage({
|
||||
kind: 'npubEncode',
|
||||
payload: delegator,
|
||||
});
|
||||
},
|
||||
|
||||
async newProfile() {
|
||||
let newIndex = await newProfile();
|
||||
await this.getProfileNames();
|
||||
this.profileIndex = newIndex;
|
||||
},
|
||||
|
||||
newDelegated() {
|
||||
window.location = browser.runtime.getURL(
|
||||
'wizards/delegation/delegation.html'
|
||||
);
|
||||
},
|
||||
|
||||
async deleteProfile() {
|
||||
if (
|
||||
confirm(
|
||||
|
||||
@@ -1,43 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<!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="permission.build.js"></script>
|
||||
<link rel="stylesheet" href="/options.build.css" />
|
||||
<title>Permission Requested</title>
|
||||
</head>
|
||||
|
||||
<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="permission.build.js"></script>
|
||||
<link rel="stylesheet" href="/options.build.css">
|
||||
<title>Permission Requested</title>
|
||||
</head>
|
||||
<body x-data="permission">
|
||||
<div class="text-center">
|
||||
<h1 class="section-header mt-5 text-center">
|
||||
App is requesting permission
|
||||
</h1>
|
||||
<p class="mt-6 text-center">
|
||||
The host
|
||||
<span class="text-lg font-bold" x-text="host"></span>
|
||||
is requesting the following permission:
|
||||
<span class="text-lg font-bold" x-text="humanPermission"></span
|
||||
>.
|
||||
</p>
|
||||
<p x-show="isSigningEvent">
|
||||
Event kind is
|
||||
<a
|
||||
:href="eventInfo.nip"
|
||||
class="text-lg font-bold"
|
||||
x-text="eventInfo.desc"
|
||||
@click.prevent="await openNip()"
|
||||
></a
|
||||
>.
|
||||
</p>
|
||||
|
||||
<body x-data="permission">
|
||||
<div class="text-center">
|
||||
|
||||
<h1 class="section-header mt-5 text-center">App is requesting permission</h1>
|
||||
<p class="mt-6 text-center">
|
||||
The host
|
||||
<span class="text-lg font-bold" x-text="host"></span>
|
||||
is requesting the following permission:
|
||||
<span class="text-lg font-bold" x-text="humanPermission"></span>.
|
||||
</p>
|
||||
<p x-show="isSigningEvent">
|
||||
Event kind is <a :href="eventInfo.nip" class="text-lg font-bold" x-text="eventInfo.desc"
|
||||
@click.prevent="await openNip()"></a>.
|
||||
</p>
|
||||
|
||||
<template x-if="isSigningEvent">
|
||||
<div class="inline-block text-left">
|
||||
<pre class="mt-6" x-html="humanEvent"></pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="mt-6 text-center">
|
||||
<button class="button" @click="await allow()">Allow</button>
|
||||
<button class="button" @click="await deny()">Deny</button>
|
||||
<input class="checkbox" type="checkbox" id="remember" x-model="remember">
|
||||
<label for="remember">Remember selection<span x-show="isSigningEvent" x-cloak> (by event kind)</span></label>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<template x-if="isSigningEvent">
|
||||
<div class="inline-block text-left">
|
||||
<pre class="mt-6" x-html="humanEvent"></pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="mt-6 text-center">
|
||||
<button class="button" @click="await allow()">Allow</button>
|
||||
<button class="button" @click="await deny()">Deny</button>
|
||||
<input
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
id="remember"
|
||||
x-model="remember"
|
||||
/>
|
||||
<label for="remember"
|
||||
>Remember selection<span x-show="isSigningEvent" x-cloak>
|
||||
(by event kind)</span
|
||||
></label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
color-scheme: light dark;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
width: 300px;
|
||||
padding: 15px;
|
||||
@@ -24,4 +23,4 @@ body {
|
||||
margin-top: 10px;
|
||||
font-size: 50%;
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +1,87 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<link rel="stylesheet" href="popup.css" />
|
||||
<link rel="stylesheet" href="options.build.css" />
|
||||
<script defer src="popup.build.js"></script>
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<link rel="stylesheet" href="popup.css">
|
||||
<link rel="stylesheet" href="options.build.css">
|
||||
<script defer src="popup.build.js"></script>
|
||||
</head>
|
||||
|
||||
<body x-data="popup">
|
||||
<div class="profiles">
|
||||
<label for="profile">Active Profile</label>
|
||||
<div class="profile-buttons flex flex-row gap-2">
|
||||
<div class="grow">
|
||||
<select x-model.number="profileIndex" name="profile" id="profile" class="input">
|
||||
<template x-for="(prof, index) in profileNames" :key="index">
|
||||
<option x-text="prof" :value="index"></option>
|
||||
</template>
|
||||
</select>
|
||||
<body x-data="popup">
|
||||
<div class="profiles">
|
||||
<label for="profile">Active Profile</label>
|
||||
<div class="profile-buttons flex flex-row gap-2">
|
||||
<div class="grow">
|
||||
<select
|
||||
x-model.number="profileIndex"
|
||||
name="profile"
|
||||
id="profile"
|
||||
class="input"
|
||||
>
|
||||
<template
|
||||
x-for="(prof, index) in profileNames"
|
||||
:key="index"
|
||||
>
|
||||
<option x-text="prof" :value="index"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<button
|
||||
class="button p-1.5"
|
||||
@click.prevent="await copyNpub()"
|
||||
style="display: block"
|
||||
title="Copy npub"
|
||||
>
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg
|
||||
width="24px"
|
||||
height="24px"
|
||||
stroke-width="1.5"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
color="#000000"
|
||||
>
|
||||
<path
|
||||
d="M19.4 20H9.6a.6.6 0 01-.6-.6V9.6a.6.6 0 01.6-.6h9.8a.6.6 0 01.6.6v9.8a.6.6 0 01-.6.6z"
|
||||
stroke="#f5d0fe"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
></path>
|
||||
<path
|
||||
d="M15 9V4.6a.6.6 0 00-.6-.6H4.6a.6.6 0 00-.6.6v9.8a.6.6 0 00.6.6H9"
|
||||
stroke="#f5d0fe"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<button class="button p-1.5" @click.prevent="await copyNpub()" style="display: block;" title="Copy npub">
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" stroke-width="1.5"
|
||||
viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#000000">
|
||||
<path d="M19.4 20H9.6a.6.6 0 01-.6-.6V9.6a.6.6 0 01.6-.6h9.8a.6.6 0 01.6.6v9.8a.6.6 0 01-.6.6z"
|
||||
stroke="#f5d0fe" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M15 9V4.6a.6.6 0 00-.6-.6H4.6a.6.6 0 00-.6.6v9.8a.6.6 0 00.6.6H9" stroke="#f5d0fe"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="relay" x-show="relayCount < 1 && showRelayReminder" x-cloak>
|
||||
<span>
|
||||
You do not have any relays setup for this profile. Would you
|
||||
like to add some recommended relays now?
|
||||
</span>
|
||||
<br />
|
||||
<button class="button" @click="await addRelays()">
|
||||
Add Relays
|
||||
</button>
|
||||
<button class="button" @click="noThanks">No Thanks</button>
|
||||
</div>
|
||||
|
||||
<div class="help">
|
||||
<button class="button p-1.5" @click="await openOptions()">
|
||||
Settings
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relay" x-show="relayCount < 1 && showRelayReminder" x-cloak>
|
||||
<span>
|
||||
You do not have any relays setup for this profile. Would you like to add some recommended
|
||||
relays now?
|
||||
</span>
|
||||
<br>
|
||||
<button class="button" @click="await addRelays()">Add Relays</button>
|
||||
<button class="button" @click="noThanks">No Thanks</button>
|
||||
</div>
|
||||
|
||||
<div class="help">
|
||||
<button class="button p-1.5" @click="await openOptions()">Settings</button>
|
||||
</div>
|
||||
|
||||
<div class="disclaimer">
|
||||
No user data is collected or transmitted.
|
||||
All private keys are stored in the extension's sequestered local browser storage.
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<div class="disclaimer">
|
||||
No user data is collected or transmitted. All private keys are
|
||||
stored in the extension's sequestered local browser storage.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -9,59 +9,59 @@ export const RECOMMENDED_RELAYS = [
|
||||
];
|
||||
// prettier-ignore
|
||||
export const KINDS = [
|
||||
[0, 'Metadata', 'https://github.com/nostr-protocol/nips/blob/master/01.md'],
|
||||
[1, 'Text', 'https://github.com/nostr-protocol/nips/blob/master/01.md'],
|
||||
[2, 'Recommend Relay', 'https://github.com/nostr-protocol/nips/blob/master/01.md'],
|
||||
[3, 'Contacts', 'https://github.com/nostr-protocol/nips/blob/master/02.md'],
|
||||
[4, 'Encrypted Direct Messages', 'https://github.com/nostr-protocol/nips/blob/master/04.md'],
|
||||
[5, 'Event Deletion', 'https://github.com/nostr-protocol/nips/blob/master/09.md'],
|
||||
[6, 'Repost', 'https://github.com/nostr-protocol/nips/blob/master/18.md'],
|
||||
[7, 'Reaction', 'https://github.com/nostr-protocol/nips/blob/master/25.md'],
|
||||
[8, 'Badge Award', 'https://github.com/nostr-protocol/nips/blob/master/58.md'],
|
||||
[16, 'Generic Repost', 'https://github.com/nostr-protocol/nips/blob/master/18.md'],
|
||||
[40, 'Channel Creation', 'https://github.com/nostr-protocol/nips/blob/master/28.md'],
|
||||
[41, 'Channel Metadata', 'https://github.com/nostr-protocol/nips/blob/master/28.md'],
|
||||
[42, 'Channel Message', 'https://github.com/nostr-protocol/nips/blob/master/28.md'],
|
||||
[43, 'Channel Hide Message', 'https://github.com/nostr-protocol/nips/blob/master/28.md'],
|
||||
[44, 'Channel Mute User', 'https://github.com/nostr-protocol/nips/blob/master/28.md'],
|
||||
[1063, 'File Metadata', 'https://github.com/nostr-protocol/nips/blob/master/94.md'],
|
||||
[1311, 'Live Chat Message', 'https://github.com/nostr-protocol/nips/blob/master/53.md'],
|
||||
[1984, 'Reporting', 'https://github.com/nostr-protocol/nips/blob/master/56.md'],
|
||||
[1985, 'Label', 'https://github.com/nostr-protocol/nips/blob/master/32.md'],
|
||||
[4550, 'Community Post Approval', 'https://github.com/nostr-protocol/nips/blob/master/72.md'],
|
||||
[7000, 'Job Feedback', 'https://github.com/nostr-protocol/nips/blob/master/90.md'],
|
||||
[9041, 'Zap Goal', 'https://github.com/nostr-protocol/nips/blob/master/75.md'],
|
||||
[9734, 'Zap Request', 'https://github.com/nostr-protocol/nips/blob/master/57.md'],
|
||||
[9735, 'Zap', 'https://github.com/nostr-protocol/nips/blob/master/57.md'],
|
||||
[10000, 'Mute List', 'https://github.com/nostr-protocol/nips/blob/master/51.md'],
|
||||
[10001, 'Pin List', 'https://github.com/nostr-protocol/nips/blob/master/51.md'],
|
||||
[10002, 'Relay List Metadata', 'https://github.com/nostr-protocol/nips/blob/master/65.md'],
|
||||
[13194, 'Wallet Info', 'https://github.com/nostr-protocol/nips/blob/master/47.md'],
|
||||
[22242, 'Client Authentication', 'https://github.com/nostr-protocol/nips/blob/master/42.md'],
|
||||
[23194, 'Wallet Request', 'https://github.com/nostr-protocol/nips/blob/master/47.md'],
|
||||
[23195, 'Wallet Response', 'https://github.com/nostr-protocol/nips/blob/master/47.md'],
|
||||
[24133, 'Nostr Connect', 'https://github.com/nostr-protocol/nips/blob/master/46.md'],
|
||||
[27235, 'HTTP Auth', 'https://github.com/nostr-protocol/nips/blob/master/98.md'],
|
||||
[30000, 'Categorized People List', 'https://github.com/nostr-protocol/nips/blob/master/51.md'],
|
||||
[30001, 'Categorized Bookmark List', 'https://github.com/nostr-protocol/nips/blob/master/51.md'],
|
||||
[30008, 'Profile Badges', 'https://github.com/nostr-protocol/nips/blob/master/58.md'],
|
||||
[30009, 'Badge Definition', 'https://github.com/nostr-protocol/nips/blob/master/58.md'],
|
||||
[30017, 'Create or update a stall', 'https://github.com/nostr-protocol/nips/blob/master/15.md'],
|
||||
[30018, 'Create or update a product', 'https://github.com/nostr-protocol/nips/blob/master/15.md'],
|
||||
[30023, 'Long-Form Content', 'https://github.com/nostr-protocol/nips/blob/master/23.md'],
|
||||
[30024, 'Draft Long-form Content', 'https://github.com/nostr-protocol/nips/blob/master/23.md'],
|
||||
[30078, 'Application-specific Data', 'https://github.com/nostr-protocol/nips/blob/master/78.md'],
|
||||
[30311, 'Live Event', 'https://github.com/nostr-protocol/nips/blob/master/53.md'],
|
||||
[30315, 'User Statuses', 'https://github.com/nostr-protocol/nips/blob/master/38.md'],
|
||||
[30402, 'Classified Listing', 'https://github.com/nostr-protocol/nips/blob/master/99.md'],
|
||||
[30403, 'Draft Classified Listing', 'https://github.com/nostr-protocol/nips/blob/master/99.md'],
|
||||
[31922, 'Date-Based Calendar Event', 'https://github.com/nostr-protocol/nips/blob/master/52.md'],
|
||||
[31923, 'Time-Based Calendar Event', 'https://github.com/nostr-protocol/nips/blob/master/52.md'],
|
||||
[31924, 'Calendar', 'https://github.com/nostr-protocol/nips/blob/master/52.md'],
|
||||
[31925, 'Calendar Event RSVP', 'https://github.com/nostr-protocol/nips/blob/master/52.md'],
|
||||
[31989, 'Handler recommendation', 'https://github.com/nostr-protocol/nips/blob/master/89.md'],
|
||||
[31990, 'Handler information', 'https://github.com/nostr-protocol/nips/blob/master/89.md'],
|
||||
[34550, 'Community Definition', 'https://github.com/nostr-protocol/nips/blob/master/72.md'],
|
||||
[0, 'Metadata', 'https://github.com/nostr-protocol/nips/blob/master/01.md'],
|
||||
[1, 'Text', 'https://github.com/nostr-protocol/nips/blob/master/01.md'],
|
||||
[2, 'Recommend Relay', 'https://github.com/nostr-protocol/nips/blob/master/01.md'],
|
||||
[3, 'Contacts', 'https://github.com/nostr-protocol/nips/blob/master/02.md'],
|
||||
[4, 'Encrypted Direct Messages', 'https://github.com/nostr-protocol/nips/blob/master/04.md'],
|
||||
[5, 'Event Deletion', 'https://github.com/nostr-protocol/nips/blob/master/09.md'],
|
||||
[6, 'Repost', 'https://github.com/nostr-protocol/nips/blob/master/18.md'],
|
||||
[7, 'Reaction', 'https://github.com/nostr-protocol/nips/blob/master/25.md'],
|
||||
[8, 'Badge Award', 'https://github.com/nostr-protocol/nips/blob/master/58.md'],
|
||||
[16, 'Generic Repost', 'https://github.com/nostr-protocol/nips/blob/master/18.md'],
|
||||
[40, 'Channel Creation', 'https://github.com/nostr-protocol/nips/blob/master/28.md'],
|
||||
[41, 'Channel Metadata', 'https://github.com/nostr-protocol/nips/blob/master/28.md'],
|
||||
[42, 'Channel Message', 'https://github.com/nostr-protocol/nips/blob/master/28.md'],
|
||||
[43, 'Channel Hide Message', 'https://github.com/nostr-protocol/nips/blob/master/28.md'],
|
||||
[44, 'Channel Mute User', 'https://github.com/nostr-protocol/nips/blob/master/28.md'],
|
||||
[1063, 'File Metadata', 'https://github.com/nostr-protocol/nips/blob/master/94.md'],
|
||||
[1311, 'Live Chat Message', 'https://github.com/nostr-protocol/nips/blob/master/53.md'],
|
||||
[1984, 'Reporting', 'https://github.com/nostr-protocol/nips/blob/master/56.md'],
|
||||
[1985, 'Label', 'https://github.com/nostr-protocol/nips/blob/master/32.md'],
|
||||
[4550, 'Community Post Approval', 'https://github.com/nostr-protocol/nips/blob/master/72.md'],
|
||||
[7000, 'Job Feedback', 'https://github.com/nostr-protocol/nips/blob/master/90.md'],
|
||||
[9041, 'Zap Goal', 'https://github.com/nostr-protocol/nips/blob/master/75.md'],
|
||||
[9734, 'Zap Request', 'https://github.com/nostr-protocol/nips/blob/master/57.md'],
|
||||
[9735, 'Zap', 'https://github.com/nostr-protocol/nips/blob/master/57.md'],
|
||||
[10000, 'Mute List', 'https://github.com/nostr-protocol/nips/blob/master/51.md'],
|
||||
[10001, 'Pin List', 'https://github.com/nostr-protocol/nips/blob/master/51.md'],
|
||||
[10002, 'Relay List Metadata', 'https://github.com/nostr-protocol/nips/blob/master/65.md'],
|
||||
[13194, 'Wallet Info', 'https://github.com/nostr-protocol/nips/blob/master/47.md'],
|
||||
[22242, 'Client Authentication', 'https://github.com/nostr-protocol/nips/blob/master/42.md'],
|
||||
[23194, 'Wallet Request', 'https://github.com/nostr-protocol/nips/blob/master/47.md'],
|
||||
[23195, 'Wallet Response', 'https://github.com/nostr-protocol/nips/blob/master/47.md'],
|
||||
[24133, 'Nostr Connect', 'https://github.com/nostr-protocol/nips/blob/master/46.md'],
|
||||
[27235, 'HTTP Auth', 'https://github.com/nostr-protocol/nips/blob/master/98.md'],
|
||||
[30000, 'Categorized People List', 'https://github.com/nostr-protocol/nips/blob/master/51.md'],
|
||||
[30001, 'Categorized Bookmark List', 'https://github.com/nostr-protocol/nips/blob/master/51.md'],
|
||||
[30008, 'Profile Badges', 'https://github.com/nostr-protocol/nips/blob/master/58.md'],
|
||||
[30009, 'Badge Definition', 'https://github.com/nostr-protocol/nips/blob/master/58.md'],
|
||||
[30017, 'Create or update a stall', 'https://github.com/nostr-protocol/nips/blob/master/15.md'],
|
||||
[30018, 'Create or update a product', 'https://github.com/nostr-protocol/nips/blob/master/15.md'],
|
||||
[30023, 'Long-Form Content', 'https://github.com/nostr-protocol/nips/blob/master/23.md'],
|
||||
[30024, 'Draft Long-form Content', 'https://github.com/nostr-protocol/nips/blob/master/23.md'],
|
||||
[30078, 'Application-specific Data', 'https://github.com/nostr-protocol/nips/blob/master/78.md'],
|
||||
[30311, 'Live Event', 'https://github.com/nostr-protocol/nips/blob/master/53.md'],
|
||||
[30315, 'User Statuses', 'https://github.com/nostr-protocol/nips/blob/master/38.md'],
|
||||
[30402, 'Classified Listing', 'https://github.com/nostr-protocol/nips/blob/master/99.md'],
|
||||
[30403, 'Draft Classified Listing', 'https://github.com/nostr-protocol/nips/blob/master/99.md'],
|
||||
[31922, 'Date-Based Calendar Event', 'https://github.com/nostr-protocol/nips/blob/master/52.md'],
|
||||
[31923, 'Time-Based Calendar Event', 'https://github.com/nostr-protocol/nips/blob/master/52.md'],
|
||||
[31924, 'Calendar', 'https://github.com/nostr-protocol/nips/blob/master/52.md'],
|
||||
[31925, 'Calendar Event RSVP', 'https://github.com/nostr-protocol/nips/blob/master/52.md'],
|
||||
[31989, 'Handler recommendation', 'https://github.com/nostr-protocol/nips/blob/master/89.md'],
|
||||
[31990, 'Handler information', 'https://github.com/nostr-protocol/nips/blob/master/89.md'],
|
||||
[34550, 'Community Definition', 'https://github.com/nostr-protocol/nips/blob/master/72.md'],
|
||||
];
|
||||
|
||||
export async function initialize() {
|
||||
@@ -87,7 +87,6 @@ async function migrate(version, goal) {
|
||||
if (version === 1) {
|
||||
console.log('migrating to version 2.');
|
||||
let profiles = await getProfiles();
|
||||
profiles.forEach(profile => (profile.delegate = false));
|
||||
await storage.set({ profiles });
|
||||
return version + 1;
|
||||
}
|
||||
@@ -156,7 +155,6 @@ export async function generateProfile(name = 'Default') {
|
||||
privKey: await generatePrivateKey(),
|
||||
hosts: {},
|
||||
relays: [],
|
||||
delegate: false,
|
||||
relayReminder: true,
|
||||
};
|
||||
}
|
||||
@@ -293,13 +291,6 @@ export async function toggleRelayReminder() {
|
||||
await storage.set({ profiles });
|
||||
}
|
||||
|
||||
export async function getDelegator(index) {
|
||||
let profiles = await getProfiles();
|
||||
let profile = profiles[index];
|
||||
console.log(profile);
|
||||
return [profile.delegate, profile.delegator];
|
||||
}
|
||||
|
||||
export async function getNpub() {
|
||||
let index = await getProfileIndex();
|
||||
return await browser.runtime.sendMessage({
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
<!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>
|
||||
@@ -1,86 +0,0 @@
|
||||
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();
|
||||
13
build.js
13
build.js
@@ -1,15 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
let watch =
|
||||
process.argv[2] === 'watch'
|
||||
? {
|
||||
onRebuild(error, result) {
|
||||
if (error) console.error('watch rebuild failed: ', error);
|
||||
else console.log('watch rebuild succeeded: ', result);
|
||||
},
|
||||
}
|
||||
: false;
|
||||
|
||||
require('esbuild')
|
||||
.build({
|
||||
entryPoints: {
|
||||
@@ -22,8 +12,6 @@ require('esbuild')
|
||||
'./Shared (Extension)/Resources/permission/permission.js',
|
||||
'experimental/experimental.build':
|
||||
'./Shared (Extension)/Resources/experimental/experimental.js',
|
||||
'wizards/delegation/delegation.build':
|
||||
'./Shared (Extension)/Resources/wizards/delegation/delegation.js',
|
||||
'event_history/event_history.build':
|
||||
'./Shared (Extension)/Resources/event_history/event_history.js',
|
||||
},
|
||||
@@ -31,6 +19,5 @@ require('esbuild')
|
||||
sourcemap: 'inline',
|
||||
bundle: true,
|
||||
// minify: true,
|
||||
watch,
|
||||
})
|
||||
.catch(() => process.exit(1));
|
||||
|
||||
3396
package-lock.json
generated
3396
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
63
package.json
63
package.json
@@ -1,32 +1,33 @@
|
||||
{
|
||||
"name": "nostore",
|
||||
"version": "1.2.0",
|
||||
"description": "",
|
||||
"source": [
|
||||
"background.js",
|
||||
"content.js",
|
||||
"nostr.js",
|
||||
"popup.html"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "./build.js",
|
||||
"watch": "./build.js watch",
|
||||
"watch-tailwind": "tailwindcss -i './Shared (Extension)/Resources/options.css' -o './Shared (Extension)/Resources/options.build.css' --watch",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"alpinejs": "^3.10.5",
|
||||
"async-mutex": "^0.4.0",
|
||||
"idb": "^7.1.1",
|
||||
"json-format-highlight": "^1.0.4",
|
||||
"nostr-tools": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/forms": "^0.5.3",
|
||||
"esbuild": "^0.16.17",
|
||||
"prettier": "^2.8.3",
|
||||
"tailwindcss": "^3.2.4"
|
||||
}
|
||||
}
|
||||
"name": "nostore",
|
||||
"version": "1.2.0",
|
||||
"description": "",
|
||||
"source": [
|
||||
"background.js",
|
||||
"content.js",
|
||||
"nostr.js",
|
||||
"popup.html"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tailwindcss -i './Shared (Extension)/Resources/options.css' -o './Shared (Extension)/Resources/options.build.css' && ./build.js",
|
||||
"watch": "./build.js watch",
|
||||
"watch-tailwind": "tailwindcss -i './Shared (Extension)/Resources/options.css' -o './Shared (Extension)/Resources/options.build.css' --watch",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@alpinejs/csp": "^3.14.1",
|
||||
"alpinejs": "^3.14.1",
|
||||
"async-mutex": "^0.5.0",
|
||||
"idb": "^8.0.0",
|
||||
"json-format-highlight": "^1.0.4",
|
||||
"nostr-tools": "^2.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"esbuild": "^0.23.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tailwindcss": "^3.4.12"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user