Merge pull request #21 from fishcakeday/ios18-updates
Make extension work on the latest iOS (18)
This commit is contained in:
@@ -188,7 +188,6 @@
|
|||||||
941B042F2978CDF900CA291E /* Icon-16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-16.png"; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
944A6E12299F39D30032C2E3 /* permission */ = {isa = PBXFileReference; lastKnownFileType = folder; path = permission; sourceTree = "<group>"; };
|
||||||
944A6E38299F46270032C2E3 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; 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>"; };
|
944A6E3E299F46D30032C2E3 /* NostoreApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NostoreApp.swift; sourceTree = "<group>"; };
|
||||||
@@ -294,7 +293,6 @@
|
|||||||
children = (
|
children = (
|
||||||
9471E91E29A470C700EA623B /* event_history */,
|
9471E91E29A470C700EA623B /* event_history */,
|
||||||
944A6E12299F39D30032C2E3 /* permission */,
|
944A6E12299F39D30032C2E3 /* permission */,
|
||||||
944A6E0D299F32070032C2E3 /* wizards */,
|
|
||||||
944A6E02299F2FBB0032C2E3 /* experimental */,
|
944A6E02299F2FBB0032C2E3 /* experimental */,
|
||||||
948C69E4297F8BA600FB3574 /* options.build.css */,
|
948C69E4297F8BA600FB3574 /* options.build.css */,
|
||||||
948C69E1297F891F00FB3574 /* options.build.js */,
|
948C69E1297F891F00FB3574 /* options.build.js */,
|
||||||
@@ -461,7 +459,7 @@
|
|||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = 1;
|
BuildIndependentTargetsInParallel = 1;
|
||||||
LastSwiftUpdateCheck = 1420;
|
LastSwiftUpdateCheck = 1420;
|
||||||
LastUpgradeCheck = 1500;
|
LastUpgradeCheck = 1600;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
941B03AE296FA90400CA291E = {
|
941B03AE296FA90400CA291E = {
|
||||||
CreatedOnToolsVersion = 14.2;
|
CreatedOnToolsVersion = 14.2;
|
||||||
@@ -503,7 +501,6 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
944A6E0E299F32070032C2E3 /* wizards in Resources */,
|
|
||||||
941B03E0296FA90400CA291E /* Icon.png in Resources */,
|
941B03E0296FA90400CA291E /* Icon.png in Resources */,
|
||||||
944A6E03299F2FBB0032C2E3 /* experimental in Resources */,
|
944A6E03299F2FBB0032C2E3 /* experimental in Resources */,
|
||||||
941B03DE296FA90400CA291E /* Main.html in Resources */,
|
941B03DE296FA90400CA291E /* Main.html in Resources */,
|
||||||
@@ -520,7 +517,6 @@
|
|||||||
files = (
|
files = (
|
||||||
941B03E1296FA90400CA291E /* Icon.png in Resources */,
|
941B03E1296FA90400CA291E /* Icon.png in Resources */,
|
||||||
941B03E3296FA90400CA291E /* Style.css in Resources */,
|
941B03E3296FA90400CA291E /* Style.css in Resources */,
|
||||||
944A6E0F299F32070032C2E3 /* wizards in Resources */,
|
|
||||||
941B03E5296FA90400CA291E /* Script.js in Resources */,
|
941B03E5296FA90400CA291E /* Script.js in Resources */,
|
||||||
944A6E14299F39D30032C2E3 /* permission in Resources */,
|
944A6E14299F39D30032C2E3 /* permission in Resources */,
|
||||||
941B03E9296FA90400CA291E /* Assets.xcassets in Resources */,
|
941B03E9296FA90400CA291E /* Assets.xcassets in Resources */,
|
||||||
@@ -534,7 +530,6 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
9471E91F29A470C700EA623B /* event_history in Resources */,
|
9471E91F29A470C700EA623B /* event_history in Resources */,
|
||||||
944A6E10299F32070032C2E3 /* wizards in Resources */,
|
|
||||||
941B0413297110F100CA291E /* background.build.js in Resources */,
|
941B0413297110F100CA291E /* background.build.js in Resources */,
|
||||||
944A6E15299F39D30032C2E3 /* permission in Resources */,
|
944A6E15299F39D30032C2E3 /* permission in Resources */,
|
||||||
948C69E82982DFE900FB3574 /* background.html in Resources */,
|
948C69E82982DFE900FB3574 /* background.html in Resources */,
|
||||||
@@ -572,7 +567,6 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
9471E92029A470C700EA623B /* event_history in Resources */,
|
9471E92029A470C700EA623B /* event_history in Resources */,
|
||||||
944A6E11299F32070032C2E3 /* wizards in Resources */,
|
|
||||||
941B0414297110F100CA291E /* background.build.js in Resources */,
|
941B0414297110F100CA291E /* background.build.js in Resources */,
|
||||||
944A6E16299F39D30032C2E3 /* permission in Resources */,
|
944A6E16299F39D30032C2E3 /* permission in Resources */,
|
||||||
948C69E92982DFE900FB3574 /* background.html in Resources */,
|
948C69E92982DFE900FB3574 /* background.html in Resources */,
|
||||||
@@ -860,7 +854,6 @@
|
|||||||
941B0403296FA90400CA291E /* Debug */ = {
|
941B0403296FA90400CA291E /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
@@ -902,7 +895,6 @@
|
|||||||
941B0404296FA90400CA291E /* Release */ = {
|
941B0404296FA90400CA291E /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
@@ -960,7 +952,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
MARKETING_VERSION = 1.2.0;
|
MARKETING_VERSION = 1.2.0;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
@@ -993,7 +985,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
MARKETING_VERSION = 1.2.0;
|
MARKETING_VERSION = 1.2.0;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-framework",
|
"-framework",
|
||||||
@@ -1011,7 +1003,6 @@
|
|||||||
941B040A296FA90400CA291E /* Debug */ = {
|
941B040A296FA90400CA291E /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = "macOS (App)/nostore.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "macOS (App)/nostore.entitlements";
|
||||||
@@ -1048,7 +1039,6 @@
|
|||||||
941B040B296FA90400CA291E /* Release */ = {
|
941B040B296FA90400CA291E /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = "macOS (App)/nostore.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "macOS (App)/nostore.entitlements";
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ This is a [NIP-07][nip07] compatible extension for signing nostr events.
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Login with nostr (`getPublicKey`).
|
- Login with nostr (`getPublicKey`).
|
||||||
* Post nostr event (`signEvent`).
|
- Post nostr event (`signEvent`).
|
||||||
* Encrypted direct messages (`nip04.encrypt` and `nip04.decrypt`).
|
- Encrypted direct messages (`nip04.encrypt` and `nip04.decrypt`).
|
||||||
* Multiple profiles.
|
- Multiple profiles.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"colors" : [
|
"colors": [
|
||||||
{
|
{
|
||||||
"color" : {
|
"color": {
|
||||||
"color-space" : "display-p3",
|
"color-space": "display-p3",
|
||||||
"components" : {
|
"components": {
|
||||||
"alpha" : "1.000",
|
"alpha": "1.000",
|
||||||
"blue" : "0.665",
|
"blue": "0.665",
|
||||||
"green" : "0.271",
|
"green": "0.271",
|
||||||
"red" : "0.509"
|
"red": "0.509"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom": "universal"
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
"idiom" : "universal"
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,74 +1,74 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename" : "iOS-Icon-1024.png",
|
"filename": "iOS-Icon-1024.png",
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"platform" : "ios",
|
"platform": "ios",
|
||||||
"size" : "1024x1024"
|
"size": "1024x1024"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-16.png",
|
"filename": "Icon-16.png",
|
||||||
"idiom" : "mac",
|
"idiom": "mac",
|
||||||
"scale" : "1x",
|
"scale": "1x",
|
||||||
"size" : "16x16"
|
"size": "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-32.png",
|
"filename": "Icon-32.png",
|
||||||
"idiom" : "mac",
|
"idiom": "mac",
|
||||||
"scale" : "2x",
|
"scale": "2x",
|
||||||
"size" : "16x16"
|
"size": "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-32 1.png",
|
"filename": "Icon-32 1.png",
|
||||||
"idiom" : "mac",
|
"idiom": "mac",
|
||||||
"scale" : "1x",
|
"scale": "1x",
|
||||||
"size" : "32x32"
|
"size": "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-64.png",
|
"filename": "Icon-64.png",
|
||||||
"idiom" : "mac",
|
"idiom": "mac",
|
||||||
"scale" : "2x",
|
"scale": "2x",
|
||||||
"size" : "32x32"
|
"size": "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-128.png",
|
"filename": "Icon-128.png",
|
||||||
"idiom" : "mac",
|
"idiom": "mac",
|
||||||
"scale" : "1x",
|
"scale": "1x",
|
||||||
"size" : "128x128"
|
"size": "128x128"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-256.png",
|
"filename": "Icon-256.png",
|
||||||
"idiom" : "mac",
|
"idiom": "mac",
|
||||||
"scale" : "2x",
|
"scale": "2x",
|
||||||
"size" : "128x128"
|
"size": "128x128"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-256 1.png",
|
"filename": "Icon-256 1.png",
|
||||||
"idiom" : "mac",
|
"idiom": "mac",
|
||||||
"scale" : "1x",
|
"scale": "1x",
|
||||||
"size" : "256x256"
|
"size": "256x256"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-512.png",
|
"filename": "Icon-512.png",
|
||||||
"idiom" : "mac",
|
"idiom": "mac",
|
||||||
"scale" : "2x",
|
"scale": "2x",
|
||||||
"size" : "256x256"
|
"size": "256x256"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-512 1.png",
|
"filename": "Icon-512 1.png",
|
||||||
"idiom" : "mac",
|
"idiom": "mac",
|
||||||
"scale" : "1x",
|
"scale": "1x",
|
||||||
"size" : "512x512"
|
"size": "512x512"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-1024.png",
|
"filename": "Icon-1024.png",
|
||||||
"idiom" : "mac",
|
"idiom": "mac",
|
||||||
"scale" : "2x",
|
"scale": "2x",
|
||||||
"size" : "512x512"
|
"size": "512x512"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"info" : {
|
"info": {
|
||||||
"author" : "xcode",
|
"author": "xcode",
|
||||||
"version" : 1
|
"version": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "1x"
|
"scale": "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "2x"
|
"scale": "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "3x"
|
"scale": "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename" : "Icon-512.png",
|
"filename": "Icon-512.png",
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "1x"
|
"scale": "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "2x"
|
"scale": "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "3x"
|
"scale": "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"info" : {
|
"info": {
|
||||||
"author" : "xcode",
|
"author": "xcode",
|
||||||
"version" : 1
|
"version": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename" : "ipad-menu.png",
|
"filename": "ipad-menu.png",
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "1x"
|
"scale": "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "2x"
|
"scale": "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "3x"
|
"scale": "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename" : "ipad-popup.png",
|
"filename": "ipad-popup.png",
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "1x"
|
"scale": "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "2x"
|
"scale": "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "3x"
|
"scale": "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename" : "ipad-url-bar.png",
|
"filename": "ipad-url-bar.png",
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "1x"
|
"scale": "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "2x"
|
"scale": "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "3x"
|
"scale": "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"info" : {
|
"info": {
|
||||||
"author" : "xcode",
|
"author": "xcode",
|
||||||
"version" : 1
|
"version": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename" : "iphone-menu.png",
|
"filename": "iphone-menu.png",
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "1x"
|
"scale": "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "2x"
|
"scale": "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "3x"
|
"scale": "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename" : "iphone-popup.png",
|
"filename": "iphone-popup.png",
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "1x"
|
"scale": "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "2x"
|
"scale": "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "3x"
|
"scale": "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename" : "iphone-url-bar.png",
|
"filename": "iphone-url-bar.png",
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "1x"
|
"scale": "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "2x"
|
"scale": "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "3x"
|
"scale": "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"info" : {
|
"info": {
|
||||||
"author" : "xcode",
|
"author": "xcode",
|
||||||
"version" : 1
|
"version": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename" : "default-popup.png",
|
"filename": "default-popup.png",
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "1x"
|
"scale": "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "2x"
|
"scale": "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "3x"
|
"scale": "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"filename" : "toolbar-inactive.png",
|
"filename": "toolbar-inactive.png",
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "1x"
|
"scale": "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "2x"
|
"scale": "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idiom" : "universal",
|
"idiom": "universal",
|
||||||
"scale" : "3x"
|
"scale": "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "xcode",
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,39 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
|
<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">
|
<link rel="stylesheet" href="../Style.css" />
|
||||||
<script src="../Script.js" defer></script>
|
<script src="../Script.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<img src="../Icon.png" width="128" height="128" alt="Nostore Icon">
|
<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-ios">
|
||||||
<p class="platform-mac state-unknown">You can turn on Nostore’s extension in Safari Extensions preferences.</p>
|
You can turn on Nostore’s Safari extension in Settings.
|
||||||
<p class="platform-mac state-on">Nostore’s extension is currently on. You can turn it off in Safari Extensions preferences.</p>
|
</p>
|
||||||
<p class="platform-mac state-off">Nostore’s extension is currently off. You can turn it on in Safari Extensions preferences.</p>
|
<p class="platform-mac state-unknown">
|
||||||
<button class="platform-mac open-preferences">Quit and Open Safari Extensions Preferences…</button>
|
You can turn on Nostore’s extension in Safari Extensions
|
||||||
</body>
|
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>
|
</html>
|
||||||
|
|||||||
@@ -2,13 +2,20 @@ function show(platform, enabled, useSettingsInsteadOfPreferences) {
|
|||||||
document.body.classList.add(`platform-${platform}`);
|
document.body.classList.add(`platform-${platform}`);
|
||||||
|
|
||||||
if (useSettingsInsteadOfPreferences) {
|
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-on')[0].innerText =
|
||||||
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.";
|
'Nostore’s extension is currently on. You can turn it off 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 state-off')[0].innerText =
|
||||||
document.getElementsByClassName('platform-mac open-preferences')[0].innerText = "Quit and Open Safari Settings…";
|
'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-on`, enabled);
|
||||||
document.body.classList.toggle(`state-off`, !enabled);
|
document.body.classList.toggle(`state-off`, !enabled);
|
||||||
} else {
|
} else {
|
||||||
@@ -18,7 +25,9 @@ function show(platform, enabled, useSettingsInsteadOfPreferences) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function openPreferences() {
|
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 {
|
import {
|
||||||
generatePrivateKey,
|
|
||||||
getPublicKey,
|
|
||||||
signEvent,
|
|
||||||
nip04,
|
nip04,
|
||||||
nip19,
|
nip19,
|
||||||
nip26,
|
generateSecretKey,
|
||||||
getEventHash,
|
getPublicKey,
|
||||||
|
finalizeEvent,
|
||||||
} from 'nostr-tools';
|
} from 'nostr-tools';
|
||||||
|
import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
|
||||||
import { Mutex } from 'async-mutex';
|
import { Mutex } from 'async-mutex';
|
||||||
import {
|
import {
|
||||||
getProfileIndex,
|
getProfileIndex,
|
||||||
@@ -14,7 +13,6 @@ import {
|
|||||||
getProfile,
|
getProfile,
|
||||||
getPermission,
|
getPermission,
|
||||||
setPermission,
|
setPermission,
|
||||||
feature,
|
|
||||||
} from './utilities/utils';
|
} from './utilities/utils';
|
||||||
import { saveEvent } from './utilities/db';
|
import { saveEvent } from './utilities/db';
|
||||||
|
|
||||||
@@ -40,15 +38,13 @@ browser.runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
|||||||
deny(message);
|
deny(message);
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
case 'generatePrivateKey':
|
case 'generatePrivateKey':
|
||||||
return Promise.resolve(generatePrivateKey());
|
return Promise.resolve(generatePrivateKey_());
|
||||||
case 'savePrivateKey':
|
case 'savePrivateKey':
|
||||||
return savePrivateKey(message.payload);
|
return savePrivateKey(message.payload);
|
||||||
case 'getNpub':
|
case 'getNpub':
|
||||||
return getNpub(message.payload);
|
return getNpub(message.payload);
|
||||||
case 'getNsec':
|
case 'getNsec':
|
||||||
return getNsec(message.payload);
|
return getNsec(message.payload);
|
||||||
case 'createDelegation':
|
|
||||||
return createDelegation(message.payload);
|
|
||||||
case 'calcPubKey':
|
case 'calcPubKey':
|
||||||
return Promise.resolve(getPublicKey(message.payload));
|
return Promise.resolve(getPublicKey(message.payload));
|
||||||
case 'npubEncode':
|
case 'npubEncode':
|
||||||
@@ -63,7 +59,7 @@ browser.runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
|||||||
case 'nip04.decrypt':
|
case 'nip04.decrypt':
|
||||||
case 'getRelays':
|
case 'getRelays':
|
||||||
validations[uuid] = sendResponse;
|
validations[uuid] = sendResponse;
|
||||||
setDelegation(message).then(() => ask(uuid, message));
|
ask(uuid, message);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
prompt.release?.();
|
prompt.release?.();
|
||||||
}, 10_000);
|
}, 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 }) {
|
async function ask(uuid, { kind, host, payload }) {
|
||||||
await forceRelease(); // Clean up previous tab if it closed without cleaning itself up
|
await forceRelease(); // Clean up previous tab if it closed without cleaning itself up
|
||||||
prompt.release = await prompt.mutex.acquire();
|
prompt.release = await prompt.mutex.acquire();
|
||||||
@@ -178,35 +179,32 @@ async function savePrivateKey([index, privKey]) {
|
|||||||
privKey = nip19.decode(privKey).data;
|
privKey = nip19.decode(privKey).data;
|
||||||
}
|
}
|
||||||
let profiles = await get('profiles');
|
let profiles = await get('profiles');
|
||||||
profiles[index].privKey = privKey;
|
profiles[index].privKey = bytesToHex(privKey);
|
||||||
await storage.set({ profiles });
|
await storage.set({ profiles });
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getNsec(index) {
|
async function getNsec(index) {
|
||||||
let profile = await getProfile(index);
|
let profile = await getProfile(index);
|
||||||
let nsec = nip19.nsecEncode(profile.privKey);
|
let nsec = nip19.nsecEncode(hexToBytes(profile.privKey));
|
||||||
return nsec;
|
return nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getNpub(index) {
|
async function getNpub(index) {
|
||||||
let profile = await getProfile(index);
|
let profile = await getProfile(index);
|
||||||
let pubKey = getPublicKey(profile.privKey);
|
let pubKey = getPublicKey(hexToBytes(profile.privKey));
|
||||||
let npub = nip19.npubEncode(pubKey);
|
let npub = nip19.npubEncode(pubKey);
|
||||||
return npub;
|
return npub;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPrivKey() {
|
async function getPrivKey() {
|
||||||
let profile = await currentProfile();
|
let profile = await currentProfile();
|
||||||
return profile.privKey;
|
return hexToBytes(profile.privKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPubKey() {
|
async function getPubKey() {
|
||||||
let pi = await getProfileIndex();
|
let pi = await getProfileIndex();
|
||||||
let profile = await getProfile(pi);
|
let profile = await getProfile(pi);
|
||||||
if (profile.delegate) {
|
|
||||||
return profile.delegator;
|
|
||||||
}
|
|
||||||
let privKey = await getPrivKey();
|
let privKey = await getPrivKey();
|
||||||
let pubKey = getPublicKey(privKey);
|
let pubKey = getPublicKey(privKey);
|
||||||
return pubKey;
|
return pubKey;
|
||||||
@@ -220,11 +218,8 @@ async function currentProfile() {
|
|||||||
|
|
||||||
async function signEvent_(event, host) {
|
async function signEvent_(event, host) {
|
||||||
event = JSON.parse(JSON.stringify(event));
|
event = JSON.parse(JSON.stringify(event));
|
||||||
let privKey = await getPrivKey();
|
let sk = await getPrivKey();
|
||||||
let pubKey = getPublicKey(privKey);
|
event = finalizeEvent(event, sk);
|
||||||
event.pubkey = pubKey;
|
|
||||||
event.id = getEventHash(event);
|
|
||||||
event.sig = signEvent(event, privKey);
|
|
||||||
saveEvent({
|
saveEvent({
|
||||||
event,
|
event,
|
||||||
metadata: { host, signed_at: Math.round(Date.now() / 1000) },
|
metadata: { host, signed_at: Math.round(Date.now() / 1000) },
|
||||||
@@ -253,42 +248,3 @@ async function getRelays() {
|
|||||||
});
|
});
|
||||||
return relayObj;
|
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">
|
<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>
|
<style>
|
||||||
<meta charset="UTF-8">
|
label {
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
display: block;
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
}
|
||||||
<script defer src="event_history.build.js"></script>
|
</style>
|
||||||
<link rel="stylesheet" href="/options.build.css">
|
</head>
|
||||||
<title>Event History</title>
|
|
||||||
|
|
||||||
<style>
|
<body class="text-fuchsia-900 p-3.5 lg:p-32" x-data="eventLog">
|
||||||
label {
|
<p>
|
||||||
display: block;
|
<a href="/options.html" class="border-none hover:underline"
|
||||||
}
|
>← Back</a
|
||||||
</style>
|
>
|
||||||
</head>
|
</p>
|
||||||
|
|
||||||
<body class="text-fuchsia-900 p-3.5 lg:p-32" x-data="eventLog">
|
<h1 class="section-header">Event History</h1>
|
||||||
<p>
|
|
||||||
<a href="/options.html" class="border-none hover:underline">← Back</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h1 class="section-header">Event History</h1>
|
<div class="section">
|
||||||
|
<div class="section-header">Filters</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="grid grid-cols-2 xl:grid-cols-4 gap-4">
|
||||||
<div class="section-header">Filters</div>
|
<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>
|
||||||
<div>
|
<label for="sort">Order</label>
|
||||||
<label for="view">View</label>
|
<select
|
||||||
<select id="view" class="input" x-model="view" @change="reload">
|
id="sort"
|
||||||
<option value="created_at">created_at</option>
|
x-model="sort"
|
||||||
<option value="kind">kind</option>
|
class="input"
|
||||||
<option value="host">host</option>
|
@change="reload"
|
||||||
<option value="pubkey">pubkey</option>
|
>
|
||||||
</select>
|
<option value="asc">Ascending</option>
|
||||||
</div>
|
<option value="desc">Descending</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="sort">Order</label>
|
<label for="max">Max</label>
|
||||||
<select id="sort" x-model="sort" class="input" @change="reload">
|
<input
|
||||||
<option value="asc">Ascending</option>
|
type="number"
|
||||||
<option value="desc">Descending</option>
|
x-model.number="max"
|
||||||
</select>
|
@input.debounce.750ms="reload"
|
||||||
</div>
|
class="input"
|
||||||
|
min="10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<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 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>
|
<div x-show="view === 'created_at'" x-cloak>
|
||||||
<label for="fromCreatedAt">From</label>
|
<label for="toCreatedAt">To</label>
|
||||||
<input type="date" id="fromCreatedAt" x-model="fromCreatedAt" class="input" @change="reload">
|
<input
|
||||||
</div>
|
type="date"
|
||||||
|
id="toCreatedAt"
|
||||||
|
x-model="toCreatedAt"
|
||||||
|
class="input"
|
||||||
|
@change="reload"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div x-show="view === 'created_at'" x-cloak>
|
<div x-show="view === 'kind'" x-cloak>
|
||||||
<label for="toCreatedAt">To</label>
|
<label for="kindShortcut">Quick Select</label>
|
||||||
<input type="date" id="toCreatedAt" x-model="toCreatedAt" class="input" @change="reload">
|
<select
|
||||||
</div>
|
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>
|
<div x-show="view === 'kind'" x-cloak>
|
||||||
<label for="kindShortcut">Quick Select</label>
|
<label for="fromKind">From</label>
|
||||||
<select id="kindShortcut" class="input" @change="quickKindSelect" x-model="quickKind">
|
<input
|
||||||
<option></option>
|
type="number"
|
||||||
<template x-for="k in kinds">
|
id="fromKind"
|
||||||
<option :value="k[0]" x-text="k[1]"></option>
|
x-model.number="fromKind"
|
||||||
</template>
|
class="input"
|
||||||
</select>
|
@change="reload"
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div x-show="view === 'kind'" x-cloak>
|
<div x-show="view === 'kind'" x-cloak>
|
||||||
<label for="fromKind">From</label>
|
<label for="toKind">To</label>
|
||||||
<input type="number" id="fromKind" x-model.number="fromKind" class="input" @change="reload">
|
<input
|
||||||
</div>
|
type="number"
|
||||||
|
id="toKind"
|
||||||
|
x-model.number="toKind"
|
||||||
|
class="input"
|
||||||
|
@change="reload"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div x-show="view === 'kind'" x-cloak>
|
<div x-show="view === 'host'" x-cloak>
|
||||||
<label for="toKind">To</label>
|
<label for="host">Host</label>
|
||||||
<input type="number" id="toKind" x-model.number="toKind" class="input" @change="reload">
|
<select
|
||||||
</div>
|
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>
|
<div x-show="view === 'pubkey'" x-cloak>
|
||||||
<label for="host">Host</label>
|
<label for="profiles">Profiles</label>
|
||||||
<select id="host" class="input" x-model="host" @change="reload">
|
<select
|
||||||
<option value=""></option>
|
id="profiles"
|
||||||
<template x-for="h in allHosts">
|
class="input"
|
||||||
<option :value="h" x-text="h"></option>
|
x-model="profile"
|
||||||
</template>
|
@change="pkFromProfile"
|
||||||
</select>
|
>
|
||||||
</div>
|
<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>
|
<div x-show="view === 'pubkey'" x-cloak>
|
||||||
<label for="profiles">Profiles</label>
|
<label for="pubkey">Pubkey</label>
|
||||||
<select id="profiles" class="input" x-model="profile" @change="pkFromProfile">
|
<input
|
||||||
<option value=""></option>
|
type="text"
|
||||||
<template x-for="p in profileNames">
|
class="input"
|
||||||
<option :value="p" x-text="p"></option>
|
x-model="pubkey"
|
||||||
</template>
|
@input.debounce="reload"
|
||||||
</select>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div x-show="view === 'pubkey'" x-cloak>
|
<div>
|
||||||
<label for="pubkey">Pubkey</label>
|
<button class="button mt-3" @click="saveAll">Save all</button>
|
||||||
<input type="text" class="input" x-model="pubkey" @input.debounce="reload">
|
<button class="button mt-3" @click="deleteAll">
|
||||||
</div>
|
Delete all
|
||||||
</div>
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div class="text-sm italic mt-1 text-right">
|
||||||
<button class="button mt-3" @click="saveAll">Save all</button>
|
Click/tap event body to copy the raw event.
|
||||||
<button class="button mt-3" @click="deleteAll">Delete all</button>
|
</div>
|
||||||
</div>
|
|
||||||
</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 @click.prevent="copyEvent(index)" class="cursor-pointer">
|
||||||
<div class="mt-3 border-solid border border-fuchsia-700 rounded-lg">
|
<pre
|
||||||
<div class="select-none flex cursor-pointer text-sm md:text-xl"
|
class="rounded-b-lg bg-slate-200 text-sm md:text-xl"
|
||||||
@click="selected = selected === index ? null : index">
|
x-html="highlight(event)"
|
||||||
<div class="flex-none w-14 p-4 font-extrabold" x-text="selected === index ? '-' : '+'"></div>
|
x-show="selected === index"
|
||||||
<div class="flex-1 w-64 p-4" x-text="formatDate(event.metadata.signed_at)"></div>
|
x-transition:enter.opacity.delay.75ms
|
||||||
<div class="flex-1 w-64 p-4" x-text="event.metadata.host"></div>
|
x-transition:leave.opacity
|
||||||
<div class="flex-1 w-64 p-4" x-text="formatKind(event.event.kind)"></div>
|
x-cloak
|
||||||
</div>
|
></pre>
|
||||||
|
</div>
|
||||||
<div @click.prevent="copyEvent(index)" class="cursor-pointer">
|
</div>
|
||||||
<pre class="rounded-b-lg bg-slate-200 text-sm md:text-xl" x-html="highlight(event)" x-show="selected === index"
|
</template>
|
||||||
x-transition:enter.opacity.delay.75ms x-transition:leave.opacity x-cloak>
|
<div
|
||||||
</pre>
|
class="fixed top-0 right-0 bg-fuchsia-800 rounded-md p-4 text-white m-8 drop-shadow-md"
|
||||||
|
x-show="copied"
|
||||||
</div>
|
x-cloack
|
||||||
</div>
|
>
|
||||||
</template>
|
Event copied!
|
||||||
<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>
|
</div>
|
||||||
Event copied!
|
</body>
|
||||||
</div>
|
</html>
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
|
|||||||
@@ -1,34 +1,44 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<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>
|
<body class="text-fuchsia-900 p-3.5 lg:p-32" x-data="experimental">
|
||||||
<meta charset="UTF-8">
|
<p>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<a href="/options.html" class="border-none hover:underline"
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
>← Back</a
|
||||||
<link rel="stylesheet" href="/options.build.css">
|
>
|
||||||
<script src="/experimental/experimental.build.js" defer></script>
|
</p>
|
||||||
<title>Experimental Features</title>
|
<h1 class="text-3xl lg:text-6xl font-bold md:text-center">
|
||||||
</head>
|
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">
|
<template x-for="feature in features" :key="feature[0]">
|
||||||
<p>
|
<div class="mt-4">
|
||||||
<a href="/options.html" class="border-none hover:underline">← Back</a>
|
<input
|
||||||
</p>
|
class="checkbox"
|
||||||
<h1 class="text-3xl lg:text-6xl font-bold md:text-center">Experimental Features</h1>
|
type="checkbox"
|
||||||
<p class="mt-3 text-center font-bold italic">
|
:id="feature[0]"
|
||||||
These things may only work partially, or not
|
x-model="feature[1]"
|
||||||
work at all. Caveat
|
@change="change(feature[0], feature[1])"
|
||||||
emptor!
|
/>
|
||||||
</p>
|
<label
|
||||||
|
:for="feature[0]"
|
||||||
<template x-for="feature in features" :key="feature[0]">
|
x-text="feature[2]"
|
||||||
<div class="mt-4">
|
class="font-bold"
|
||||||
<input class="checkbox" type="checkbox" :id="feature[0]" x-model="feature[1]"
|
></label>
|
||||||
@change="change(feature[0], feature[1])">
|
<p x-text="feature[3]" class="italic"></p>
|
||||||
<label :for="feature[0]" x-text="feature[2]" class="font-bold"></label>
|
</div>
|
||||||
<p x-text="feature[3]" class="italic"></p>
|
</template>
|
||||||
</div>
|
</body>
|
||||||
</template>
|
</html>
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import Alpine from 'alpinejs';
|
|||||||
|
|
||||||
const FEATURES = [
|
const FEATURES = [
|
||||||
[
|
[
|
||||||
'delegation',
|
'none',
|
||||||
'NIP-26 Delegation Profiles',
|
'NIP-XX: None',
|
||||||
'Allow user to create delegated profiles that obey the NIP-26 standard. Requires client support.',
|
'Reserved for the future use.',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,8 @@
|
|||||||
},
|
},
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"js": [
|
"js": ["content.build.js"],
|
||||||
"content.build.js"
|
"matches": ["<all_urls>"]
|
||||||
],
|
|
||||||
"matches": [
|
|
||||||
"<all_urls>"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"action": {
|
"action": {
|
||||||
@@ -39,10 +35,7 @@
|
|||||||
"options_ui": {
|
"options_ui": {
|
||||||
"page": "options.html"
|
"page": "options.html"
|
||||||
},
|
},
|
||||||
"permissions": [
|
"permissions": ["storage", "clipboardWrite"],
|
||||||
"storage",
|
|
||||||
"clipboardWrite"
|
|
||||||
],
|
|
||||||
"web_accessible_resources": [
|
"web_accessible_resources": [
|
||||||
{
|
{
|
||||||
"resources": [
|
"resources": [
|
||||||
@@ -51,25 +44,20 @@
|
|||||||
"options.build.js",
|
"options.build.js",
|
||||||
"options.build.css",
|
"options.build.css",
|
||||||
"options.html",
|
"options.html",
|
||||||
"wizards/delegation/delegation.html",
|
|
||||||
"wizards/delegation/delegation.build.js",
|
|
||||||
"wizards/delegation/delegation.build.css",
|
|
||||||
"experimental/experimental.html",
|
"experimental/experimental.html",
|
||||||
"experimental/experimental.build.js",
|
"experimental/experimental.build.js",
|
||||||
"event_history/event_history.html",
|
"event_history/event_history.html",
|
||||||
"event_history/event_history.build.js"
|
"event_history/event_history.build.js"
|
||||||
],
|
],
|
||||||
"matches": [
|
"matches": ["<all_urls>"]
|
||||||
"<all_urls>"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"content_security_policy": {
|
"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": {
|
"browser_specific_settings": {
|
||||||
"safari": {
|
"safari": {
|
||||||
"strict_min_version": "15.4"
|
"strict_min_version": "15.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,46 +2,48 @@
|
|||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
[x-cloak] { display: none; }
|
[x-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
.button {
|
.button {
|
||||||
/* Colors */
|
/* Colors */
|
||||||
@apply bg-fuchsia-900 hover:bg-fuchsia-800 active:bg-fuchsia-700 text-fuchsia-200 disabled:bg-gray-200 disabled:text-black;
|
@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 */
|
/* Sizing and padding */
|
||||||
@apply rounded-lg p-1.5 md:w-24 min-w-fit text-center;
|
@apply rounded-lg p-1.5 md:w-24 min-w-fit text-center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
/* Colors */
|
/* Colors */
|
||||||
@apply bg-fuchsia-200 text-fuchsia-800 disabled:bg-gray-200 disabled:text-black focus:border-fuchsia-800;
|
@apply bg-fuchsia-200 text-fuchsia-800 disabled:bg-gray-200 disabled:text-black focus:border-fuchsia-800;
|
||||||
|
|
||||||
/* Sizing and padding */
|
/* Sizing and padding */
|
||||||
@apply rounded-lg p-1.5 lg:p-1.5 w-full md:w-64;
|
@apply rounded-lg p-1.5 lg:p-1.5 w-full md:w-64;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox {
|
.checkbox {
|
||||||
/* Colors */
|
/* Colors */
|
||||||
@apply text-fuchsia-800 bg-fuchsia-200 rounded-full accent-fuchsia-200;
|
@apply text-fuchsia-800 bg-fuchsia-200 rounded-full accent-fuchsia-200;
|
||||||
|
|
||||||
/* Sizing and padding */
|
/* Sizing and padding */
|
||||||
@apply w-4 h-4 lg:w-5 lg:h-5;
|
@apply w-4 h-4 lg:w-5 lg:h-5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section {
|
.section {
|
||||||
@apply border-2 border-fuchsia-700 rounded-lg p-1 md:p-5 mt-6 shadow-md;
|
@apply border-2 border-fuchsia-700 rounded-lg p-1 md:p-5 mt-6 shadow-md;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-header {
|
.section-header {
|
||||||
@apply text-2xl lg:text-5xl font-bold;
|
@apply text-2xl lg:text-5xl font-bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subsection-header {
|
.subsection-header {
|
||||||
@apply text-xl lg:text-4xl font-bold;
|
@apply text-xl lg:text-4xl font-bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@apply border-2 border-dotted text-fuchsia-800 border-fuchsia-800 hover:border-transparent;
|
@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">
|
<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>
|
<body x-data="options" class="text-fuchsia-900 p-3.5 lg:p-32">
|
||||||
<meta charset="UTF-8">
|
<h1 class="text-3xl lg:text-6xl font-bold md:text-center">Settings</h1>
|
||||||
<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>
|
<!-- PROFILES -->
|
||||||
|
<div class="mt-6">
|
||||||
<body x-data="options" class="text-fuchsia-900 p-3.5 lg:p-32">
|
<label for="profiles">Profile</label>
|
||||||
<h1 class="text-3xl lg:text-6xl font-bold md:text-center">Settings</h1>
|
<br />
|
||||||
|
<select class="input" x-model.number="profileIndex" id="profiles">
|
||||||
<!-- PROFILES -->
|
<template x-for="(name, index) in profileNames" :key="index">
|
||||||
<div class="mt-6">
|
<option x-text="name" :value="index"></option>
|
||||||
<label for="profiles">Profile</label>
|
</template>
|
||||||
<br>
|
</select>
|
||||||
<select class="input" x-model.number="profileIndex" id="profiles">
|
<div class="block md:inline p-3 pl-0 md:p-0">
|
||||||
<template x-for="(name, index) in profileNames" :key="index">
|
<button class="button" @click.prevent="newProfile">New</button>
|
||||||
<option x-text="name" :value="index"></option>
|
<button class="button" @click.prevent="deleteProfile">
|
||||||
</template>
|
Delete
|
||||||
</select>
|
</button>
|
||||||
<div class="block md:inline p-3 pl-0 md:p-0">
|
</div>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label for="delegator-pub-key">Delegator Public Key</label>
|
<!-- KEYS -->
|
||||||
<br>
|
<div class="section">
|
||||||
<input id="delegator-pub-key" x-model="delegator" class="input" autocapitalize="off" autocomplete="off"
|
<h2 class="section-header">Keys</h2>
|
||||||
spellcheck="off" :disabled="delegate">
|
<p class="text-sm italic">
|
||||||
</div>
|
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">
|
<div class="mt-3">
|
||||||
<label for="priv-key">Private Key</label>
|
<label for="priv-key">Private Key</label>
|
||||||
<br>
|
<br />
|
||||||
<input x-model="privKey" :type="visibilityClass" class="input" :class="validKeyClass" autocapitalize="off"
|
<input
|
||||||
autocomplete="off" spellcheck="off" :disabled="delegate">
|
x-model="privKey"
|
||||||
<a href="" @click.prevent="visible = !visible" x-text="(visible && 'Hide') || 'Show'" class="border-none"></a>
|
:type="visibilityClass"
|
||||||
</div>
|
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">
|
<div class="mt-3">
|
||||||
<label for="pub-key">Public Key</label>
|
<label for="pub-key">Public Key</label>
|
||||||
<br>
|
<br />
|
||||||
<input x-model="pubKey" type="text" class="input" disabled>
|
<input
|
||||||
<a href="" class="border-none" @click.prevent="copyPubKey" x-text="copied ? 'Copied!' : 'Copy'"></a>
|
x-model="pubKey"
|
||||||
</div>
|
type="text"
|
||||||
|
class="input"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
class="border-none"
|
||||||
|
@click.prevent="copyPubKey"
|
||||||
|
x-text="copied ? 'Copied!' : 'Copy'"
|
||||||
|
></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<button class="button" :disabled="!needsSave || !validKey" @click.prevent="saveProfile">Save</button>
|
<button
|
||||||
</div>
|
class="button"
|
||||||
</form>
|
: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 -->
|
<template x-if="!hasRelays">
|
||||||
<div class="section">
|
<div class="mt-3">
|
||||||
<h2 class="section-header">Relays</h2>
|
There are no relays assigned to this profile.
|
||||||
<p class="text-sm italic">Add relay suggestions for clients.</p>
|
</div>
|
||||||
<template x-if="hasRelays">
|
</template>
|
||||||
<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" x-show="hasRecommendedRelays" x-cloak>
|
||||||
<div class="mt-3">
|
<select x-model="recommendedRelay" class="input">
|
||||||
There are no relays assigned to this profile.
|
<option value="" disabled selected>
|
||||||
</div>
|
Recommended Relays
|
||||||
</template>
|
</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>
|
<input
|
||||||
<select x-model="recommendedRelay" class="input">
|
class="mt-3 input"
|
||||||
<option value="" disabled selected>Recommended Relays</option>
|
x-model="newRelay"
|
||||||
<template x-for="relay in recommendedRelays">
|
type="text"
|
||||||
<option :value="relay" x-text="relay"></option>
|
@keyup.enter="await addRelay()"
|
||||||
</template>
|
placeholder="wss://..."
|
||||||
</select>
|
autocomplete="off"
|
||||||
</div>
|
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://..."
|
<!-- PERMISSIONS -->
|
||||||
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="off">
|
<div class="section">
|
||||||
<div class="block md:inline p-3 pl-0 md:p-0">
|
<h2 class="section-header">App Permissions</h2>
|
||||||
<button class="button" @click="await addRelay()">Add</button>
|
<p class="text-sm italic">
|
||||||
</div>
|
Permissions granted to individual applications. Everything
|
||||||
<div class="text-red-500 font-bold" x-show="urlError.length > 0" x-text="urlError" x-cloak></div>
|
defaults to <span class="font-bold">Ask</span> unless you have
|
||||||
</div>
|
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 -->
|
<p x-show="permHosts.length === 0" x-cloak class="font-bold mt-3">
|
||||||
<div class="section">
|
You have not remembered any app requests yet.
|
||||||
<h2 class="section-header">App Permissions</h2>
|
</p>
|
||||||
<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">
|
<table
|
||||||
<label for="app">Apps</label>
|
class="mt-3 text-xs md:text-base table-fixed"
|
||||||
<br>
|
x-show="hostPerms.length > 0"
|
||||||
<select id="app" class="input" x-model="host">
|
x-cloak
|
||||||
<option value=""></option>
|
>
|
||||||
<template x-for="permHost in permHosts">
|
<thead class="font-bold text-lg">
|
||||||
<option :value="permHost" x-text="permHost"></option>
|
<td class="p-2 text-center">App Request</td>
|
||||||
</template>
|
<td class="p-2 text-center">Action</td>
|
||||||
</select>
|
</thead>
|
||||||
</div>
|
<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>
|
<div class="mt-6">
|
||||||
<thead class="font-bold text-lg">
|
<a
|
||||||
<td class="p-2 text-center">App Request</td>
|
href="experimental/experimental.html"
|
||||||
<td class="p-2 text-center">Action</td>
|
class="border-none hover:underline"
|
||||||
</thead>
|
>Experimental features →</a
|
||||||
<template x-for="[etype, humanName, perm] in hostPerms" :key="etype">
|
>
|
||||||
<tr>
|
<br />
|
||||||
<td class="p-2 w-1/3 md:w-2/4" x-text="humanName"></td>
|
<a
|
||||||
<td class="p-2 text-center">
|
href="event_history/event_history.html"
|
||||||
<select class="input" :value="perm"
|
class="border-none hover:underline"
|
||||||
@change="await setPermission(host, etype, $event.target.value, profileIndex)">
|
>Event history →</a
|
||||||
<option value="ask">Ask</option>
|
>
|
||||||
<option value="allow">Allow</option>
|
</div>
|
||||||
<option value="deny">Deny</option>
|
</body>
|
||||||
</select>
|
</html>
|
||||||
</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>
|
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ import {
|
|||||||
KINDS,
|
KINDS,
|
||||||
humanPermission,
|
humanPermission,
|
||||||
validateKey,
|
validateKey,
|
||||||
feature,
|
|
||||||
getDelegator,
|
|
||||||
} from './utilities/utils';
|
} from './utilities/utils';
|
||||||
|
|
||||||
const log = console.log;
|
const log = console.log;
|
||||||
@@ -42,10 +40,7 @@ Alpine.data('options', () => ({
|
|||||||
host: '',
|
host: '',
|
||||||
permHosts: [],
|
permHosts: [],
|
||||||
hostPerms: [],
|
hostPerms: [],
|
||||||
delegationActive: false,
|
|
||||||
visible: false,
|
visible: false,
|
||||||
delegate: false,
|
|
||||||
delegator: '',
|
|
||||||
copied: false,
|
copied: false,
|
||||||
setPermission,
|
setPermission,
|
||||||
go,
|
go,
|
||||||
@@ -77,8 +72,6 @@ Alpine.data('options', () => ({
|
|||||||
await this.getProfileIndex();
|
await this.getProfileIndex();
|
||||||
this.setProfileIndexFromSearch();
|
this.setProfileIndexFromSearch();
|
||||||
await this.refreshProfile();
|
await this.refreshProfile();
|
||||||
|
|
||||||
this.delegationActive = await feature('delegation');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async refreshProfile() {
|
async refreshProfile() {
|
||||||
@@ -88,7 +81,6 @@ Alpine.data('options', () => ({
|
|||||||
await this.getNpub();
|
await this.getNpub();
|
||||||
await this.getRelays();
|
await this.getRelays();
|
||||||
await this.getPermissions();
|
await this.getPermissions();
|
||||||
await this.getDelegate();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Profile functions
|
// Profile functions
|
||||||
@@ -117,27 +109,12 @@ Alpine.data('options', () => ({
|
|||||||
this.profileIndex = await getProfileIndex();
|
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() {
|
async newProfile() {
|
||||||
let newIndex = await newProfile();
|
let newIndex = await newProfile();
|
||||||
await this.getProfileNames();
|
await this.getProfileNames();
|
||||||
this.profileIndex = newIndex;
|
this.profileIndex = newIndex;
|
||||||
},
|
},
|
||||||
|
|
||||||
newDelegated() {
|
|
||||||
window.location = browser.runtime.getURL(
|
|
||||||
'wizards/delegation/delegation.html'
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
async deleteProfile() {
|
async deleteProfile() {
|
||||||
if (
|
if (
|
||||||
confirm(
|
confirm(
|
||||||
|
|||||||
@@ -1,43 +1,58 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<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>
|
<body x-data="permission">
|
||||||
<meta charset="UTF-8">
|
<div class="text-center">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<h1 class="section-header mt-5 text-center">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
App is requesting permission
|
||||||
<script defer src="permission.build.js"></script>
|
</h1>
|
||||||
<link rel="stylesheet" href="/options.build.css">
|
<p class="mt-6 text-center">
|
||||||
<title>Permission Requested</title>
|
The host
|
||||||
</head>
|
<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">
|
<template x-if="isSigningEvent">
|
||||||
<div class="text-center">
|
<div class="inline-block text-left">
|
||||||
|
<pre class="mt-6" x-html="humanEvent"></pre>
|
||||||
<h1 class="section-header mt-5 text-center">App is requesting permission</h1>
|
</div>
|
||||||
<p class="mt-6 text-center">
|
</template>
|
||||||
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>
|
|
||||||
|
|
||||||
|
<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>
|
</html>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
color-scheme: light dark;
|
color-scheme: light dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
@@ -24,4 +23,4 @@ body {
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
font-size: 50%;
|
font-size: 50%;
|
||||||
color: green;
|
color: green;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,55 +1,87 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<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>
|
<body x-data="popup">
|
||||||
<meta charset="UTF-8">
|
<div class="profiles">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
<label for="profile">Active Profile</label>
|
||||||
<link rel="stylesheet" href="popup.css">
|
<div class="profile-buttons flex flex-row gap-2">
|
||||||
<link rel="stylesheet" href="options.build.css">
|
<div class="grow">
|
||||||
<script defer src="popup.build.js"></script>
|
<select
|
||||||
</head>
|
x-model.number="profileIndex"
|
||||||
|
name="profile"
|
||||||
<body x-data="popup">
|
id="profile"
|
||||||
<div class="profiles">
|
class="input"
|
||||||
<label for="profile">Active Profile</label>
|
>
|
||||||
<div class="profile-buttons flex flex-row gap-2">
|
<template
|
||||||
<div class="grow">
|
x-for="(prof, index) in profileNames"
|
||||||
<select x-model.number="profileIndex" name="profile" id="profile" class="input">
|
:key="index"
|
||||||
<template x-for="(prof, index) in profileNames" :key="index">
|
>
|
||||||
<option x-text="prof" :value="index"></option>
|
<option x-text="prof" :value="index"></option>
|
||||||
</template>
|
</template>
|
||||||
</select>
|
</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>
|
</div>
|
||||||
<button class="button p-1.5" @click.prevent="await copyNpub()" style="display: block;" title="Copy npub">
|
</div>
|
||||||
<?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">
|
<div class="relay" x-show="relayCount < 1 && showRelayReminder" x-cloak>
|
||||||
<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"
|
<span>
|
||||||
stroke="#f5d0fe" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
|
You do not have any relays setup for this profile. Would you
|
||||||
<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"
|
like to add some recommended relays now?
|
||||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
|
</span>
|
||||||
</svg>
|
<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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="relay" x-show="relayCount < 1 && showRelayReminder" x-cloak>
|
<div class="disclaimer">
|
||||||
<span>
|
No user data is collected or transmitted. All private keys are
|
||||||
You do not have any relays setup for this profile. Would you like to add some recommended
|
stored in the extension's sequestered local browser storage.
|
||||||
relays now?
|
</div>
|
||||||
</span>
|
</body>
|
||||||
<br>
|
</html>
|
||||||
<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>
|
|
||||||
|
|||||||
@@ -9,59 +9,59 @@ export const RECOMMENDED_RELAYS = [
|
|||||||
];
|
];
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
export const KINDS = [
|
export const KINDS = [
|
||||||
[0, 'Metadata', 'https://github.com/nostr-protocol/nips/blob/master/01.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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[6, 'Repost', 'https://github.com/nostr-protocol/nips/blob/master/18.md'],
|
||||||
[7, 'Reaction', 'https://github.com/nostr-protocol/nips/blob/master/25.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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[1984, 'Reporting', 'https://github.com/nostr-protocol/nips/blob/master/56.md'],
|
||||||
[1985, 'Label', 'https://github.com/nostr-protocol/nips/blob/master/32.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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[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'],
|
[34550, 'Community Definition', 'https://github.com/nostr-protocol/nips/blob/master/72.md'],
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function initialize() {
|
export async function initialize() {
|
||||||
@@ -87,7 +87,6 @@ async function migrate(version, goal) {
|
|||||||
if (version === 1) {
|
if (version === 1) {
|
||||||
console.log('migrating to version 2.');
|
console.log('migrating to version 2.');
|
||||||
let profiles = await getProfiles();
|
let profiles = await getProfiles();
|
||||||
profiles.forEach(profile => (profile.delegate = false));
|
|
||||||
await storage.set({ profiles });
|
await storage.set({ profiles });
|
||||||
return version + 1;
|
return version + 1;
|
||||||
}
|
}
|
||||||
@@ -156,7 +155,6 @@ export async function generateProfile(name = 'Default') {
|
|||||||
privKey: await generatePrivateKey(),
|
privKey: await generatePrivateKey(),
|
||||||
hosts: {},
|
hosts: {},
|
||||||
relays: [],
|
relays: [],
|
||||||
delegate: false,
|
|
||||||
relayReminder: true,
|
relayReminder: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -293,13 +291,6 @@ export async function toggleRelayReminder() {
|
|||||||
await storage.set({ profiles });
|
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() {
|
export async function getNpub() {
|
||||||
let index = await getProfileIndex();
|
let index = await getProfileIndex();
|
||||||
return await browser.runtime.sendMessage({
|
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
|
#!/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')
|
require('esbuild')
|
||||||
.build({
|
.build({
|
||||||
entryPoints: {
|
entryPoints: {
|
||||||
@@ -22,8 +12,6 @@ require('esbuild')
|
|||||||
'./Shared (Extension)/Resources/permission/permission.js',
|
'./Shared (Extension)/Resources/permission/permission.js',
|
||||||
'experimental/experimental.build':
|
'experimental/experimental.build':
|
||||||
'./Shared (Extension)/Resources/experimental/experimental.js',
|
'./Shared (Extension)/Resources/experimental/experimental.js',
|
||||||
'wizards/delegation/delegation.build':
|
|
||||||
'./Shared (Extension)/Resources/wizards/delegation/delegation.js',
|
|
||||||
'event_history/event_history.build':
|
'event_history/event_history.build':
|
||||||
'./Shared (Extension)/Resources/event_history/event_history.js',
|
'./Shared (Extension)/Resources/event_history/event_history.js',
|
||||||
},
|
},
|
||||||
@@ -31,6 +19,5 @@ require('esbuild')
|
|||||||
sourcemap: 'inline',
|
sourcemap: 'inline',
|
||||||
bundle: true,
|
bundle: true,
|
||||||
// minify: true,
|
// minify: true,
|
||||||
watch,
|
|
||||||
})
|
})
|
||||||
.catch(() => process.exit(1));
|
.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",
|
"name": "nostore",
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"source": [
|
"source": [
|
||||||
"background.js",
|
"background.js",
|
||||||
"content.js",
|
"content.js",
|
||||||
"nostr.js",
|
"nostr.js",
|
||||||
"popup.html"
|
"popup.html"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "./build.js",
|
"build": "tailwindcss -i './Shared (Extension)/Resources/options.css' -o './Shared (Extension)/Resources/options.build.css' && ./build.js",
|
||||||
"watch": "./build.js watch",
|
"watch": "./build.js watch",
|
||||||
"watch-tailwind": "tailwindcss -i './Shared (Extension)/Resources/options.css' -o './Shared (Extension)/Resources/options.build.css' --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"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"alpinejs": "^3.10.5",
|
"@alpinejs/csp": "^3.14.1",
|
||||||
"async-mutex": "^0.4.0",
|
"alpinejs": "^3.14.1",
|
||||||
"idb": "^7.1.1",
|
"async-mutex": "^0.5.0",
|
||||||
"json-format-highlight": "^1.0.4",
|
"idb": "^8.0.0",
|
||||||
"nostr-tools": "^1.3.0"
|
"json-format-highlight": "^1.0.4",
|
||||||
},
|
"nostr-tools": "^2.7.2"
|
||||||
"devDependencies": {
|
},
|
||||||
"@tailwindcss/forms": "^0.5.3",
|
"devDependencies": {
|
||||||
"esbuild": "^0.16.17",
|
"@tailwindcss/forms": "^0.5.9",
|
||||||
"prettier": "^2.8.3",
|
"esbuild": "^0.23.1",
|
||||||
"tailwindcss": "^3.2.4"
|
"prettier": "^3.3.3",
|
||||||
}
|
"tailwindcss": "^3.4.12"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user