aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--back-end/plugins/nvault/src/Endpoints/Endpoint.cs88
-rw-r--r--back-end/plugins/nvault/src/Model/NostrContext.cs29
-rw-r--r--back-end/plugins/nvault/src/Model/NostrEvent.cs2
-rw-r--r--back-end/plugins/nvault/src/Model/NostrEventEntry.cs47
-rw-r--r--back-end/plugins/nvault/src/Model/NostrEventHistoryStore.cs69
-rw-r--r--back-end/plugins/nvault/src/Model/NostrKeyMetaStore.cs9
-rw-r--r--back-end/plugins/nvault/src/Model/NostrRelayStore.cs11
-rw-r--r--back-end/plugins/nvault/src/NVault.csproj6
-rw-r--r--extension/package-lock.json933
-rw-r--r--extension/package.json2
-rw-r--r--extension/src/components/ListBox.vue86
-rw-r--r--extension/src/components/Pagination.vue36
-rw-r--r--extension/src/entries/contentScript/primary/components/PromptPopup.vue88
-rw-r--r--extension/src/entries/contentScript/primary/main.js2
-rw-r--r--extension/src/entries/contentScript/util.ts4
-rw-r--r--extension/src/entries/options/App.vue32
-rw-r--r--extension/src/entries/options/components/Activity.vue121
-rw-r--r--extension/src/entries/options/components/AutoRules.vue54
-rw-r--r--extension/src/entries/options/components/EvHistoryTable.vue6
-rw-r--r--extension/src/entries/options/components/EventHistory.vue222
-rw-r--r--extension/src/entries/options/components/Identities.vue27
-rw-r--r--extension/src/entries/options/components/SiteSettings.vue21
-rw-r--r--extension/src/entries/options/main.js2
-rw-r--r--extension/src/entries/popup/Components/IdentitySelection.vue4
-rw-r--r--extension/src/entries/store/features.ts13
-rw-r--r--extension/src/entries/store/identity.ts7
-rw-r--r--extension/src/entries/store/index.ts5
-rw-r--r--extension/src/entries/store/types.ts3
-rw-r--r--extension/src/features/auth-api.ts5
-rw-r--r--extension/src/features/framework/index.ts26
-rw-r--r--extension/src/features/history.ts64
-rw-r--r--extension/src/features/identity-api.ts8
-rw-r--r--extension/src/features/index.ts6
-rw-r--r--extension/src/features/nip07allow-api.ts7
-rw-r--r--extension/src/features/nostr-api.ts28
-rw-r--r--extension/src/features/permissions.ts158
-rw-r--r--extension/src/features/server-api/index.ts25
-rw-r--r--extension/src/features/settings.ts13
-rw-r--r--extension/src/features/tagfilter-api.ts138
-rw-r--r--extension/src/features/types.ts25
-rw-r--r--extension/src/features/util.ts85
-rw-r--r--lib/NVault.Crypto.Noscrypt/src/LibNoscrypt.cs107
-rw-r--r--lib/NVault.Crypto.Noscrypt/src/NVault.Crypto.Noscrypt.csproj27
-rw-r--r--lib/NVault.Crypto.Secp256k1/src/ContextExtensions.cs (renamed from back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs)0
-rw-r--r--lib/NVault.Crypto.Secp256k1/src/IRandomSource.cs (renamed from back-end/libs/NVault.Crypto.Secp256k1/src/IRandomSource.cs)0
-rw-r--r--lib/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs (renamed from back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs)0
-rw-r--r--lib/NVault.Crypto.Secp256k1/src/NVault.Crypto.Secp256k1.csproj (renamed from back-end/libs/NVault.Crypto.Secp256k1/src/NVault.Crypto.Secp256k1.csproj)4
-rw-r--r--lib/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs (renamed from back-end/libs/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs)0
-rw-r--r--lib/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs (renamed from back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs)0
-rw-r--r--lib/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs (renamed from back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs)0
-rw-r--r--lib/NVault.Crypto.Secp256k1/src/UnmanagedRandomSource.cs (renamed from back-end/libs/NVault.Crypto.Secp256k1/src/UnmanagedRandomSource.cs)0
-rw-r--r--lib/NVault.VaultExtensions/src/IClientAccessScope.cs (renamed from back-end/libs/NVault.VaultExtensions/src/IClientAccessScope.cs)0
-rw-r--r--lib/NVault.VaultExtensions/src/IKvVaultStore.cs (renamed from back-end/libs/NVault.VaultExtensions/src/IKvVaultStore.cs)0
-rw-r--r--lib/NVault.VaultExtensions/src/IVaultClientScope.cs (renamed from back-end/libs/NVault.VaultExtensions/src/IVaultClientScope.cs)0
-rw-r--r--lib/NVault.VaultExtensions/src/IVaultKvClientScope.cs (renamed from back-end/libs/NVault.VaultExtensions/src/IVaultKvClientScope.cs)0
-rw-r--r--lib/NVault.VaultExtensions/src/KvVaultStorage.cs (renamed from back-end/libs/NVault.VaultExtensions/src/KvVaultStorage.cs)0
-rw-r--r--lib/NVault.VaultExtensions/src/NVault.VaultExtensions.csproj (renamed from back-end/libs/NVault.VaultExtensions/src/NVault.VaultExtensions.csproj)0
-rw-r--r--lib/NVault.VaultExtensions/src/VaultClientExtensions.cs (renamed from back-end/libs/NVault.VaultExtensions/src/VaultClientExtensions.cs)0
-rw-r--r--lib/NVault.VaultExtensions/src/VaultUserScope.cs (renamed from back-end/libs/NVault.VaultExtensions/src/VaultUserScope.cs)0
-rw-r--r--nvault.build.sln33
60 files changed, 1767 insertions, 921 deletions
diff --git a/back-end/plugins/nvault/src/Endpoints/Endpoint.cs b/back-end/plugins/nvault/src/Endpoints/Endpoint.cs
index b8aa0c9..5e8bf09 100644
--- a/back-end/plugins/nvault/src/Endpoints/Endpoint.cs
+++ b/back-end/plugins/nvault/src/Endpoints/Endpoint.cs
@@ -59,6 +59,7 @@ namespace NVault.Plugins.Vault.Endpoints
private readonly INostrOperations _vault;
private readonly NostrRelayStore _relays;
private readonly NostrKeyMetaStore _publicKeyStore;
+ private readonly NostrEventHistoryStore _eventHistoryStore;
private readonly bool AllowDelete;
private readonly ILogProvider? _abnoxiousLog;
@@ -69,12 +70,13 @@ namespace NVault.Plugins.Vault.Endpoints
AllowDelete = config.TryGetValue("allow_delete", out JsonElement adEl) && adEl.GetBoolean();
-
- DbContextOptions options = plugin.GetContextOptions();
+ IAsyncLazy<DbContextOptions> options = plugin.GetContextOptionsAsync();
_relays = new NostrRelayStore(options);
_publicKeyStore = new NostrKeyMetaStore(options);
- _vault = new NostrOpProvider(plugin);
+ _eventHistoryStore = new NostrEventHistoryStore(options);
+
+ _vault = new NostrOpProvider(plugin);
//Check for obnoxious logging
if (plugin.HostArgs.HasArgument("--nvault-obnoxious"))
@@ -118,6 +120,22 @@ namespace NVault.Plugins.Vault.Endpoints
return VfReturnType.VirtualSkip;
}
+ if(entity.QueryArgs.IsArgumentSet("type", "getEvents"))
+ {
+ //Get the event history
+ List<NostrEventEntry> events = _eventHistoryStore.ListRental.Rent();
+
+ //Get the first page of events for the user
+ await _eventHistoryStore.GetUserPageAsync(events, entity.Session.UserID, 0, 100);
+
+ //Return all events for the user
+ entity.CloseResponseJson(HttpStatusCode.OK, events);
+
+ _eventHistoryStore.ListRental.Return(events);
+
+ return VfReturnType.VirtualSkip;
+ }
+
return VfReturnType.NotFound;
}
@@ -174,6 +192,15 @@ namespace NVault.Plugins.Vault.Endpoints
return VirtualOk(entity, webm);
}
+ //Create new event entry and store it
+ NostrEventEntry newEvent = NostrEventEntry.FromEvent(entity.Session.UserID, nEvent);
+ result = await _eventHistoryStore.CreateUserRecordAsync(newEvent, entity.Session.UserID, entity.EventCancellation);
+
+ if (!result)
+ {
+ Log.Warn("Failed to store event in history, {evid} for user {userid}", nEvent.Id, entity.Session.UserID[..8]);
+ }
+
webm.Result = nEvent;
webm.Success = true;
@@ -443,21 +470,23 @@ namespace NVault.Plugins.Vault.Endpoints
{
ValErrWebMessage webMessage = new ();
- if(entity.QueryArgs.IsArgumentSet("type", "identity"))
+ //common id argument
+ string? id = entity.QueryArgs.GetValueOrDefault("id");
+
+ if (entity.QueryArgs.IsArgumentSet("type", "identity"))
{
if (webMessage.Assert(AllowDelete, "Deleting identies are now allowed"))
{
return VirtualClose(entity, webMessage, HttpStatusCode.Forbidden);
}
- if (!entity.QueryArgs.TryGetNonEmptyValue("key_id", out string? keyId))
+ if (webMessage.Assert(id != null, "No key id specified"))
{
- webMessage.Result = "No key id specified";
return VirtualClose(entity, webMessage, HttpStatusCode.BadRequest);
}
//Get the key metadata
- NostrKeyMeta? meta = await _publicKeyStore.GetSingleUserRecordAsync(keyId, entity.Session.UserID);
+ NostrKeyMeta? meta = await _publicKeyStore.GetSingleUserRecordAsync(id, entity.Session.UserID);
if (webMessage.Assert(meta != null, "Key metadata not found"))
{
@@ -471,13 +500,56 @@ namespace NVault.Plugins.Vault.Endpoints
await _vault.DeleteCredentialAsync(scope, meta, entity.EventCancellation);
//Remove the key metadata
- await _publicKeyStore.DeleteUserRecordAsync(keyId, entity.Session.UserID);
+ await _publicKeyStore.DeleteUserRecordAsync(id, entity.Session.UserID);
webMessage.Result = "Successfully deleted identity";
webMessage.Success = true;
return VirtualOk(entity, webMessage);
}
+ if(entity.QueryArgs.IsArgumentSet("type", "relay"))
+ {
+ if(webMessage.Assert(id != null, "No relay id specified"))
+ {
+ return VirtualClose(entity, webMessage, HttpStatusCode.BadRequest);
+ }
+
+ //Delete the relay
+ if(await _relays.DeleteUserRecordAsync(id, entity.Session.UserID))
+ {
+ webMessage.Result = "Successfully deleted relay";
+ webMessage.Success = true;
+ }
+ else
+ {
+ webMessage.Result = "Failed to delete relay";
+ }
+
+ return VirtualOk(entity, webMessage);
+ }
+
+ if(entity.QueryArgs.IsArgumentSet("type", "event"))
+ {
+ //Internal event id is required
+ if(webMessage.Assert(id != null, "No event id specified"))
+ {
+ return VirtualClose(entity, webMessage, HttpStatusCode.BadRequest);
+ }
+
+ //Delete the event
+ if(await _eventHistoryStore.DeleteUserRecordAsync(id, entity.Session.UserID))
+ {
+ webMessage.Result = "Successfully deleted event";
+ webMessage.Success = true;
+ }
+ else
+ {
+ webMessage.Result = "Failed to delete event";
+ }
+
+ return VirtualOk(entity, webMessage);
+ }
+
return VfReturnType.NotFound;
}
diff --git a/back-end/plugins/nvault/src/Model/NostrContext.cs b/back-end/plugins/nvault/src/Model/NostrContext.cs
index 15900e2..bdd1319 100644
--- a/back-end/plugins/nvault/src/Model/NostrContext.cs
+++ b/back-end/plugins/nvault/src/Model/NostrContext.cs
@@ -25,7 +25,9 @@ namespace NVault.Plugins.Vault.Model
{
public DbSet<NostrRelay> Relays { get; set; }
- public DbSet<NostrKeyMeta> PublicKeys { get; set; }
+ public DbSet<NostrKeyMeta> NostrPublicKeys { get; set; }
+
+ public DbSet<NostrEventEntry> NostrEvents { get; set; }
public NostrContext()
{ }
@@ -68,7 +70,7 @@ namespace NVault.Plugins.Vault.Model
.WithColumn(r => r.Version);
//Setup public key table
- builder.DefineTable<NostrKeyMeta>(nameof(PublicKeys))
+ builder.DefineTable<NostrKeyMeta>(nameof(NostrPublicKeys))
.WithColumn(r => r.Id)
.Next()
@@ -95,6 +97,29 @@ namespace NVault.Plugins.Vault.Model
//Finally, version, it should be set to the timestamp from annotations
.WithColumn(r => r.Version);
+
+ //Setup event table
+ builder.DefineTable<NostrEventEntry>(nameof(NostrEvents))
+ .WithColumn(r => r.Id) //PK attribute is set from model base
+ .Next()
+
+ .WithColumn(r => r.UserId)
+ .Next()
+
+ .WithColumn(r => r.EventData)
+ .AllowNull(true)
+ .Next()
+
+ .WithColumn(r => r.Created)
+ .AllowNull(false)
+ .Next()
+
+ .WithColumn(r => r.LastModified)
+ .AllowNull(false)
+ .Next()
+
+ //Finally, version, it should be set to the timestamp from annotations
+ .WithColumn(r => r.Version);
}
}
}
diff --git a/back-end/plugins/nvault/src/Model/NostrEvent.cs b/back-end/plugins/nvault/src/Model/NostrEvent.cs
index 9bbfd63..ca01e1a 100644
--- a/back-end/plugins/nvault/src/Model/NostrEvent.cs
+++ b/back-end/plugins/nvault/src/Model/NostrEvent.cs
@@ -22,6 +22,7 @@ using VNLib.Plugins.Extensions.Validation;
namespace NVault.Plugins.Vault.Model
{
+
internal sealed class NostrEvent
{
public const int MAX_CONTENT_LENGTH = 16 * 1024;
@@ -86,5 +87,6 @@ namespace NVault.Plugins.Vault.Model
return val;
}
+
}
} \ No newline at end of file
diff --git a/back-end/plugins/nvault/src/Model/NostrEventEntry.cs b/back-end/plugins/nvault/src/Model/NostrEventEntry.cs
new file mode 100644
index 0000000..9fa5aa2
--- /dev/null
+++ b/back-end/plugins/nvault/src/Model/NostrEventEntry.cs
@@ -0,0 +1,47 @@
+// Copyright (C) 2024 Vaughn Nugent
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+using VNLib.Plugins.Extensions.Data;
+using VNLib.Plugins.Extensions.Data.Abstractions;
+
+
+namespace NVault.Plugins.Vault.Model
+{
+ internal sealed class NostrEventEntry : DbModelBase, IUserEntity
+ {
+ public override string Id { get; set; }
+
+ public override DateTime Created { get; set; }
+
+ public override DateTime LastModified { get; set; }
+
+ //Never share userids with the client
+ [JsonIgnore]
+ public string? UserId { get; set; }
+
+ public string? EventData { get; set; }
+
+ public static NostrEventEntry FromEvent(string userId, NostrEvent @event) => new()
+ {
+ EventData= JsonSerializer.Serialize(@event),
+ UserId = userId,
+ };
+
+ }
+} \ No newline at end of file
diff --git a/back-end/plugins/nvault/src/Model/NostrEventHistoryStore.cs b/back-end/plugins/nvault/src/Model/NostrEventHistoryStore.cs
new file mode 100644
index 0000000..68b13f7
--- /dev/null
+++ b/back-end/plugins/nvault/src/Model/NostrEventHistoryStore.cs
@@ -0,0 +1,69 @@
+// Copyright (C) 2024 Vaughn Nugent
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+using System;
+using System.Linq;
+
+using Microsoft.EntityFrameworkCore;
+
+using VNLib.Plugins.Extensions.Data;
+using VNLib.Plugins.Extensions.Data.Abstractions;
+using VNLib.Plugins.Extensions.Loading;
+
+namespace NVault.Plugins.Vault.Model
+{
+ internal class NostrEventHistoryStore(IAsyncLazy<DbContextOptions> Options) : DbStore<NostrEventEntry>
+ {
+ ///<inheritdoc/>
+ public override IDbQueryLookup<NostrEventEntry> QueryTable { get; } = new DbQueries();
+
+ ///<inheritdoc/>
+ public override IDbContextHandle GetNewContext() => new NostrContext(Options.Value);
+
+ ///<inheritdoc/>
+ public override string GetNewRecordId() => Guid.NewGuid().ToString("N");
+
+ public override void OnRecordUpdate(NostrEventEntry newRecord, NostrEventEntry existing)
+ {
+ existing.EventData = newRecord.EventData;
+ existing.UserId = newRecord.UserId;
+ newRecord.LastModified = DateTime.UtcNow;
+ }
+
+ sealed record class DbQueries() : IDbQueryLookup<NostrEventEntry>
+ {
+ public IQueryable<NostrEventEntry> GetCollectionQueryBuilder(IDbContextHandle context, params string[] constraints)
+ {
+ string userId = constraints[0];
+
+ return from r in context.Set<NostrEventEntry>()
+ where r.UserId == userId
+ orderby r.LastModified descending
+ select r;
+ }
+
+ public IQueryable<NostrEventEntry> GetSingleQueryBuilder(IDbContextHandle context, params string[] constraints)
+ {
+ string id = constraints[0];
+ string userId = constraints[1];
+
+ //Get entity for the given user by its id
+ return from r in context.Set<NostrEventEntry>()
+ where r.Id == id && r.UserId == userId
+ select r;
+ }
+ }
+ }
+}
diff --git a/back-end/plugins/nvault/src/Model/NostrKeyMetaStore.cs b/back-end/plugins/nvault/src/Model/NostrKeyMetaStore.cs
index bfb6a26..b57d021 100644
--- a/back-end/plugins/nvault/src/Model/NostrKeyMetaStore.cs
+++ b/back-end/plugins/nvault/src/Model/NostrKeyMetaStore.cs
@@ -20,20 +20,17 @@ using Microsoft.EntityFrameworkCore;
using VNLib.Plugins.Extensions.Data;
using VNLib.Plugins.Extensions.Data.Abstractions;
+using VNLib.Plugins.Extensions.Loading;
namespace NVault.Plugins.Vault.Model
{
- internal sealed class NostrKeyMetaStore : DbStore<NostrKeyMeta>
+ internal sealed class NostrKeyMetaStore(IAsyncLazy<DbContextOptions> Options) : DbStore<NostrKeyMeta>
{
- private readonly DbContextOptions _options;
-
- public NostrKeyMetaStore(DbContextOptions options) => _options = options;
-
///<inheritdoc/>
public override IDbQueryLookup<NostrKeyMeta> QueryTable { get; } = new DbQueries();
///<inheritdoc/>
- public override IDbContextHandle GetNewContext() => new NostrContext(_options);
+ public override IDbContextHandle GetNewContext() => new NostrContext(Options.Value);
///<inheritdoc/>
public override string GetNewRecordId() => Guid.NewGuid().ToString("N");
diff --git a/back-end/plugins/nvault/src/Model/NostrRelayStore.cs b/back-end/plugins/nvault/src/Model/NostrRelayStore.cs
index 699124b..799492a 100644
--- a/back-end/plugins/nvault/src/Model/NostrRelayStore.cs
+++ b/back-end/plugins/nvault/src/Model/NostrRelayStore.cs
@@ -20,23 +20,18 @@ using Microsoft.EntityFrameworkCore;
using VNLib.Plugins.Extensions.Data;
using VNLib.Plugins.Extensions.Data.Abstractions;
+using VNLib.Plugins.Extensions.Loading;
namespace NVault.Plugins.Vault.Model
{
- internal class NostrRelayStore : DbStore<NostrRelay>
+ internal class NostrRelayStore(IAsyncLazy<DbContextOptions> Options) : DbStore<NostrRelay>
{
- private readonly DbContextOptions _options;
-
- public NostrRelayStore(DbContextOptions options)
- {
- _options = options;
- }
///<inheritdoc/>
public override IDbQueryLookup<NostrRelay> QueryTable { get; } = new DbQueries();
///<inheritdoc/>
- public override IDbContextHandle GetNewContext() => new NostrContext(_options);
+ public override IDbContextHandle GetNewContext() => new NostrContext(Options.Value);
///<inheritdoc/>
public override string GetNewRecordId() => Guid.NewGuid().ToString("N");
diff --git a/back-end/plugins/nvault/src/NVault.csproj b/back-end/plugins/nvault/src/NVault.csproj
index d83dd2f..e876eec 100644
--- a/back-end/plugins/nvault/src/NVault.csproj
+++ b/back-end/plugins/nvault/src/NVault.csproj
@@ -27,9 +27,11 @@
</ItemGroup>
<ItemGroup>
- <ProjectReference Include="..\..\..\libs\NVault.Crypto.Secp256k1\src\NVault.Crypto.Secp256k1.csproj" />
- <ProjectReference Include="..\..\..\libs\NVault.VaultExtensions\src\NVault.VaultExtensions.csproj" />
+ <ProjectReference Include="..\..\..\..\lib\NVault.Crypto.Noscrypt\src\NVault.Crypto.Noscrypt.csproj" />
+ <ProjectReference Include="..\..\..\..\lib\NVault.Crypto.Secp256k1\src\NVault.Crypto.Secp256k1.csproj" />
+ <ProjectReference Include="..\..\..\..\lib\NVault.VaultExtensions\src\NVault.VaultExtensions.csproj" />
</ItemGroup>
+
<ItemGroup>
<None Update="NVault.example.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
diff --git a/extension/package-lock.json b/extension/package-lock.json
index bf558a0..aa48e32 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -17,7 +17,7 @@
"@fortawesome/vue-fontawesome": "^3.0.3",
"@headlessui/vue": "^1.7.x",
"@kyvg/vue3-notification": "^3.0.x",
- "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/0ca26fc63cc5311298575209b124516139f58206/@vnuge-vnlib.browser/release.tgz",
+ "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/df7dc615532d3441f527374d18664c1a5a336de6/@vnuge-vnlib.browser/release.tgz",
"@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0",
"@vueuse/core": "^10.3.2",
@@ -239,9 +239,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
- "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
+ "version": "7.23.9",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
+ "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -317,9 +317,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz",
- "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
+ "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
"cpu": [
"ppc64"
],
@@ -332,9 +332,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz",
- "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
+ "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
"cpu": [
"arm"
],
@@ -347,9 +347,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz",
- "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
+ "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
"cpu": [
"arm64"
],
@@ -362,9 +362,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz",
- "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
+ "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
"cpu": [
"x64"
],
@@ -377,9 +377,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz",
- "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
+ "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
"cpu": [
"arm64"
],
@@ -392,9 +392,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz",
- "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
+ "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
"cpu": [
"x64"
],
@@ -407,9 +407,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz",
- "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
+ "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
"cpu": [
"arm64"
],
@@ -422,9 +422,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz",
- "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
+ "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
"cpu": [
"x64"
],
@@ -437,9 +437,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz",
- "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
+ "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
"cpu": [
"arm"
],
@@ -452,9 +452,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz",
- "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
+ "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
"cpu": [
"arm64"
],
@@ -467,9 +467,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz",
- "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
+ "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
"cpu": [
"ia32"
],
@@ -482,9 +482,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz",
- "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
+ "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
"cpu": [
"loong64"
],
@@ -497,9 +497,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz",
- "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
+ "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
"cpu": [
"mips64el"
],
@@ -512,9 +512,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz",
- "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
+ "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
"cpu": [
"ppc64"
],
@@ -527,9 +527,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz",
- "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
+ "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
"cpu": [
"riscv64"
],
@@ -542,9 +542,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz",
- "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
+ "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
"cpu": [
"s390x"
],
@@ -557,9 +557,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz",
- "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
+ "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
"cpu": [
"x64"
],
@@ -572,9 +572,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz",
- "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
"cpu": [
"x64"
],
@@ -587,9 +587,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz",
- "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
"cpu": [
"x64"
],
@@ -602,9 +602,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz",
- "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
+ "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
"cpu": [
"x64"
],
@@ -617,9 +617,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz",
- "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
+ "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
"cpu": [
"arm64"
],
@@ -632,9 +632,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz",
- "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
+ "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
"cpu": [
"ia32"
],
@@ -647,9 +647,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz",
- "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
+ "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
"cpu": [
"x64"
],
@@ -783,9 +783,12 @@
}
},
"node_modules/@headlessui/vue": {
- "version": "1.7.16",
- "resolved": "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.16.tgz",
- "integrity": "sha512-nKT+nf/q6x198SsyK54mSszaQl/z+QxtASmgMEJtpxSX2Q0OPJX0upS/9daDyiECpeAsvjkoOrm2O/6PyBQ+Qg==",
+ "version": "1.7.17",
+ "resolved": "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.17.tgz",
+ "integrity": "sha512-hmJChv8HzKorxd9F70RGnECAwZfkvmmwOqreuKLWY/19d5qbWnSdw+DNbuA/Uo6X5rb4U5B3NrT+qBKPmjhRqw==",
+ "dependencies": {
+ "@tanstack/vue-virtual": "^3.0.0-beta.60"
+ },
"engines": {
"node": ">=10"
},
@@ -794,12 +797,12 @@
}
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.11.13",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
- "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
+ "version": "0.11.14",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+ "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
"dependencies": {
- "@humanwhocodes/object-schema": "^2.0.1",
- "debug": "^4.1.1",
+ "@humanwhocodes/object-schema": "^2.0.2",
+ "debug": "^4.3.1",
"minimatch": "^3.0.5"
},
"engines": {
@@ -819,9 +822,9 @@
}
},
"node_modules/@humanwhocodes/object-schema": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
- "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw=="
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
+ "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw=="
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
@@ -905,9 +908,9 @@
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.20",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
- "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
+ "version": "0.3.22",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
+ "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -923,9 +926,9 @@
}
},
"node_modules/@mdn/browser-compat-data": {
- "version": "5.4.3",
- "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.4.3.tgz",
- "integrity": "sha512-+VnaO5zYUwFQVuRqp2qLPGR5GwhhJ/lrp0yEmamJ/nI15P2GKwGBEWRDiITZR8i6AYxeiQSu2rOi/gqxehnPuA==",
+ "version": "5.5.7",
+ "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.5.7.tgz",
+ "integrity": "sha512-DoHTZ/TjtNfUu9eiqJd+x3IcCQrhS+yOYU436TKUnlE36jZwNbK535D1CmTsSYdi/UcdCWNm5KRQZ9g1tlZCPw==",
"dev": true
},
"node_modules/@nodelib/fs.scandir": {
@@ -1008,9 +1011,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.2.tgz",
- "integrity": "sha512-RKzxFxBHq9ysZ83fn8Iduv3A283K7zPPYuhL/z9CQuyFrjwpErJx0h4aeb/bnJ+q29GRLgJpY66ceQ/Wcsn3wA==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz",
+ "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==",
"cpu": [
"arm"
],
@@ -1020,9 +1023,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.2.tgz",
- "integrity": "sha512-yZ+MUbnwf3SHNWQKJyWh88ii2HbuHCFQnAYTeeO1Nb8SyEiWASEi5dQUygt3ClHWtA9My9RQAYkjvrsZ0WK8Xg==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz",
+ "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==",
"cpu": [
"arm64"
],
@@ -1032,9 +1035,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.2.tgz",
- "integrity": "sha512-vqJ/pAUh95FLc/G/3+xPqlSBgilPnauVf2EXOQCZzhZJCXDXt/5A8mH/OzU6iWhb3CNk5hPJrh8pqJUPldN5zw==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz",
+ "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==",
"cpu": [
"arm64"
],
@@ -1044,9 +1047,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.2.tgz",
- "integrity": "sha512-otPHsN5LlvedOprd3SdfrRNhOahhVBwJpepVKUN58L0RnC29vOAej1vMEaVU6DadnpjivVsNTM5eNt0CcwTahw==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz",
+ "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==",
"cpu": [
"x64"
],
@@ -1056,9 +1059,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.2.tgz",
- "integrity": "sha512-ewG5yJSp+zYKBYQLbd1CUA7b1lSfIdo9zJShNTyc2ZP1rcPrqyZcNlsHgs7v1zhgfdS+kW0p5frc0aVqhZCiYQ==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz",
+ "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==",
"cpu": [
"arm"
],
@@ -1068,9 +1071,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.2.tgz",
- "integrity": "sha512-pL6QtV26W52aCWTG1IuFV3FMPL1m4wbsRG+qijIvgFO/VBsiXJjDPE/uiMdHBAO6YcpV4KvpKtd0v3WFbaxBtg==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz",
+ "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==",
"cpu": [
"arm64"
],
@@ -1080,9 +1083,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.2.tgz",
- "integrity": "sha512-On+cc5EpOaTwPSNetHXBuqylDW+765G/oqB9xGmWU3npEhCh8xu0xqHGUA+4xwZLqBbIZNcBlKSIYfkBm6ko7g==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz",
+ "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==",
"cpu": [
"arm64"
],
@@ -1092,9 +1095,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.2.tgz",
- "integrity": "sha512-Wnx/IVMSZ31D/cO9HSsU46FjrPWHqtdF8+0eyZ1zIB5a6hXaZXghUKpRrC4D5DcRTZOjml2oBhXoqfGYyXKipw==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz",
+ "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==",
"cpu": [
"riscv64"
],
@@ -1104,9 +1107,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.2.tgz",
- "integrity": "sha512-ym5x1cj4mUAMBummxxRkI4pG5Vht1QMsJexwGP8547TZ0sox9fCLDHw9KCH9c1FO5d9GopvkaJsBIOkTKxksdw==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz",
+ "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==",
"cpu": [
"x64"
],
@@ -1116,9 +1119,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.2.tgz",
- "integrity": "sha512-m0hYELHGXdYx64D6IDDg/1vOJEaiV8f1G/iO+tejvRCJNSwK4jJ15e38JQy5Q6dGkn1M/9KcyEOwqmlZ2kqaZg==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz",
+ "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==",
"cpu": [
"x64"
],
@@ -1128,9 +1131,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.2.tgz",
- "integrity": "sha512-x1CWburlbN5JjG+juenuNa4KdedBdXLjZMp56nHFSHTOsb/MI2DYiGzLtRGHNMyydPGffGId+VgjOMrcltOksA==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz",
+ "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==",
"cpu": [
"arm64"
],
@@ -1140,9 +1143,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.2.tgz",
- "integrity": "sha512-VVzCB5yXR1QlfsH1Xw1zdzQ4Pxuzv+CPr5qpElpKhVxlxD3CRdfubAG9mJROl6/dmj5gVYDDWk8sC+j9BI9/kQ==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz",
+ "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==",
"cpu": [
"ia32"
],
@@ -1152,9 +1155,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.2.tgz",
- "integrity": "sha512-SYRedJi+mweatroB+6TTnJYLts0L0bosg531xnQWtklOI6dezEagx4Q0qDyvRdK+qgdA3YZpjjGuPFtxBmddBA==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz",
+ "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==",
"cpu": [
"x64"
],
@@ -1216,10 +1219,34 @@
"node": ">=14.16"
}
},
+ "node_modules/@tanstack/virtual-core": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.0.0.tgz",
+ "integrity": "sha512-SYXOBTjJb05rXa2vl55TTwO40A6wKu0R5i1qQwhJYNDIqaIGF7D0HsLw+pJAyi2OvntlEIVusx3xtbbgSUi6zg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/vue-virtual": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.0.2.tgz",
+ "integrity": "sha512-1iFpX+yZswHuf4wrA6GU9yJ/YzQ/8SacABwqghwCkcwrkZbOPLlRSdOAqZ1WQ50SftmfhZpaiZl2KmpV7cgfMQ==",
+ "dependencies": {
+ "@tanstack/virtual-core": "3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "vue": "^2.7.0 || ^3.0.0"
+ }
+ },
"node_modules/@types/chrome": {
- "version": "0.0.254",
- "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.254.tgz",
- "integrity": "sha512-svkOGKwA+6ZZuk9xtrYun8MYpNY/9hD17rgZ19v3KunhsK1ZOKaMESw12/1AXLh1u3UPA8jQIRi2370DXv9wgw==",
+ "version": "0.0.259",
+ "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.259.tgz",
+ "integrity": "sha512-WP1HsLqKgoUwR/4dYiTfmOSUG5B05+xrPLbqboO15nuaUC+aBYxwB9ixVyLPYY9D+vocJK9rzH5g1lpqVrJqhg==",
"dev": true,
"dependencies": {
"@types/filesystem": "*",
@@ -1231,6 +1258,11 @@
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
},
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
+ },
"node_modules/@types/etag": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/@types/etag/-/etag-1.8.3.tgz",
@@ -1278,9 +1310,9 @@
"integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ=="
},
"node_modules/@types/node": {
- "version": "20.10.6",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz",
- "integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==",
+ "version": "20.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.10.tgz",
+ "integrity": "sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -1311,9 +1343,9 @@
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
},
"node_modules/@vitejs/plugin-vue": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.2.tgz",
- "integrity": "sha512-kEjJHrLb5ePBvjD0SPZwJlw1QTRcjjCA9sB5VyfonoXVBxTS7TMnqL6EkLt1Eu61RDeiuZ/WN9Hf6PxXhPI2uA==",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.3.tgz",
+ "integrity": "sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==",
"dev": true,
"engines": {
"node": "^18.0.0 || >=20.0.0"
@@ -1325,8 +1357,8 @@
},
"node_modules/@vnuge/vnlib.browser": {
"version": "0.1.13",
- "resolved": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/0ca26fc63cc5311298575209b124516139f58206/@vnuge-vnlib.browser/release.tgz",
- "integrity": "sha512-iivHn8FYtHiLnnID/iUwJlDOluuJeno6OUiqS1z1i93gHRFEKvnTiLHKVZAWzu97GQmA96DMtg2Ni26O/jJLFg==",
+ "resolved": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/df7dc615532d3441f527374d18664c1a5a336de6/@vnuge-vnlib.browser/release.tgz",
+ "integrity": "sha512-Ddm0cVV4GeNaO5Dd8ycMklswnXBY4L+7gOSu2W1vOOabc8YDaP2XsTaA+xImFVLXj86hQbBTRUUKF9Ebacx+WQ==",
"license": "MIT",
"peerDependencies": {
"@vueuse/core": "^10.x",
@@ -1387,55 +1419,55 @@
}
},
"node_modules/@vscode/l10n": {
- "version": "0.0.16",
- "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.16.tgz",
- "integrity": "sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg==",
+ "version": "0.0.18",
+ "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz",
+ "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==",
"dev": true
},
"node_modules/@vue/compiler-core": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.3.tgz",
- "integrity": "sha512-u8jzgFg0EDtSrb/hG53Wwh1bAOQFtc1ZCegBpA/glyvTlgHl+tq13o1zvRfLbegYUw/E4mSTGOiCnAJ9SJ+lsg==",
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.15.tgz",
+ "integrity": "sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==",
"dependencies": {
"@babel/parser": "^7.23.6",
- "@vue/shared": "3.4.3",
+ "@vue/shared": "3.4.15",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.0.2"
}
},
"node_modules/@vue/compiler-dom": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.3.tgz",
- "integrity": "sha512-oGF1E9/htI6JWj/lTJgr6UgxNCtNHbM6xKVreBWeZL9QhRGABRVoWGAzxmtBfSOd+w0Zi5BY0Es/tlJrN6WgEg==",
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.15.tgz",
+ "integrity": "sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==",
"dependencies": {
- "@vue/compiler-core": "3.4.3",
- "@vue/shared": "3.4.3"
+ "@vue/compiler-core": "3.4.15",
+ "@vue/shared": "3.4.15"
}
},
"node_modules/@vue/compiler-sfc": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.3.tgz",
- "integrity": "sha512-NuJqb5is9I4uzv316VRUDYgIlPZCG8D+ARt5P4t5UDShIHKL25J3TGZAUryY/Aiy0DsY7srJnZL5ryB6DD63Zw==",
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.15.tgz",
+ "integrity": "sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==",
"dependencies": {
"@babel/parser": "^7.23.6",
- "@vue/compiler-core": "3.4.3",
- "@vue/compiler-dom": "3.4.3",
- "@vue/compiler-ssr": "3.4.3",
- "@vue/shared": "3.4.3",
+ "@vue/compiler-core": "3.4.15",
+ "@vue/compiler-dom": "3.4.15",
+ "@vue/compiler-ssr": "3.4.15",
+ "@vue/shared": "3.4.15",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.5",
- "postcss": "^8.4.32",
+ "postcss": "^8.4.33",
"source-map-js": "^1.0.2"
}
},
"node_modules/@vue/compiler-ssr": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.3.tgz",
- "integrity": "sha512-wnYQtMBkeFSxgSSQbYGQeXPhQacQiog2c6AlvMldQH6DB+gSXK/0F6DVXAJfEiuBSgBhUc8dwrrG5JQcqwalsA==",
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.15.tgz",
+ "integrity": "sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==",
"dependencies": {
- "@vue/compiler-dom": "3.4.3",
- "@vue/shared": "3.4.3"
+ "@vue/compiler-dom": "3.4.15",
+ "@vue/shared": "3.4.15"
}
},
"node_modules/@vue/devtools-api": {
@@ -1493,48 +1525,48 @@
}
},
"node_modules/@vue/reactivity": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.3.tgz",
- "integrity": "sha512-q5f9HLDU+5aBKizXHAx0w4whkIANs1Muiq9R5YXm0HtorSlflqv9u/ohaMxuuhHWCji4xqpQ1eL04WvmAmGnFg==",
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.15.tgz",
+ "integrity": "sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==",
"dependencies": {
- "@vue/shared": "3.4.3"
+ "@vue/shared": "3.4.15"
}
},
"node_modules/@vue/runtime-core": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.3.tgz",
- "integrity": "sha512-C1r6QhB1qY7D591RCSFhMULyzL9CuyrGc+3PpB0h7dU4Qqw6GNyo4BNFjHZVvsWncrUlKX3DIKg0Y7rNNr06NQ==",
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.15.tgz",
+ "integrity": "sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==",
"dependencies": {
- "@vue/reactivity": "3.4.3",
- "@vue/shared": "3.4.3"
+ "@vue/reactivity": "3.4.15",
+ "@vue/shared": "3.4.15"
}
},
"node_modules/@vue/runtime-dom": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.3.tgz",
- "integrity": "sha512-wrsprg7An5Ec+EhPngWdPuzkp0BEUxAKaQtN9dPU/iZctPyD9aaXmVtehPJerdQxQale6gEnhpnfywNw3zOv2A==",
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.15.tgz",
+ "integrity": "sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==",
"dependencies": {
- "@vue/runtime-core": "3.4.3",
- "@vue/shared": "3.4.3",
+ "@vue/runtime-core": "3.4.15",
+ "@vue/shared": "3.4.15",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.3.tgz",
- "integrity": "sha512-BUxt8oVGMKKsqSkM1uU3d3Houyfy4WAc2SpSQRebNd+XJGATVkW/rO129jkyL+kpB/2VRKzE63zwf5RtJ3XuZw==",
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.15.tgz",
+ "integrity": "sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==",
"dependencies": {
- "@vue/compiler-ssr": "3.4.3",
- "@vue/shared": "3.4.3"
+ "@vue/compiler-ssr": "3.4.15",
+ "@vue/shared": "3.4.15"
},
"peerDependencies": {
- "vue": "3.4.3"
+ "vue": "3.4.15"
}
},
"node_modules/@vue/shared": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.3.tgz",
- "integrity": "sha512-rIwlkkP1n4uKrRzivAKPZIEkHiuwY5mmhMJ2nZKCBLz8lTUlE73rQh4n1OnnMurXt1vcUNyH4ZPfdh8QweTjpQ=="
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz",
+ "integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g=="
},
"node_modules/@vuelidate/core": {
"version": "2.0.3",
@@ -1621,13 +1653,13 @@
}
},
"node_modules/@vueuse/core": {
- "version": "10.7.1",
- "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.1.tgz",
- "integrity": "sha512-74mWHlaesJSWGp1ihg76vAnfVq9NTv1YT0SYhAQ6zwFNdBkkP+CKKJmVOEHcdSnLXCXYiL5e7MaewblfiYLP7g==",
+ "version": "10.7.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.2.tgz",
+ "integrity": "sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ==",
"dependencies": {
"@types/web-bluetooth": "^0.0.20",
- "@vueuse/metadata": "10.7.1",
- "@vueuse/shared": "10.7.1",
+ "@vueuse/metadata": "10.7.2",
+ "@vueuse/shared": "10.7.2",
"vue-demi": ">=0.14.6"
},
"funding": {
@@ -1660,12 +1692,12 @@
}
},
"node_modules/@vueuse/integrations": {
- "version": "10.7.1",
- "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.7.1.tgz",
- "integrity": "sha512-cKo5LEeKVHdBRBtMTOrDPdR0YNtrmN9IBfdcnY2P3m5LHVrsD0xiHUtAH1WKjHQRIErZG6rJUa6GA4tWZt89Og==",
+ "version": "10.7.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.7.2.tgz",
+ "integrity": "sha512-+u3RLPFedjASs5EKPc69Ge49WNgqeMfSxFn+qrQTzblPXZg6+EFzhjarS5edj2qAf6xQ93f95TUxRwKStXj/sQ==",
"dependencies": {
- "@vueuse/core": "10.7.1",
- "@vueuse/shared": "10.7.1",
+ "@vueuse/core": "10.7.2",
+ "@vueuse/shared": "10.7.2",
"vue-demi": ">=0.14.6"
},
"funding": {
@@ -1750,17 +1782,17 @@
}
},
"node_modules/@vueuse/metadata": {
- "version": "10.7.1",
- "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.1.tgz",
- "integrity": "sha512-jX8MbX5UX067DYVsbtrmKn6eG6KMcXxLRLlurGkZku5ZYT3vxgBjui2zajvUZ18QLIjrgBkFRsu7CqTAg18QFw==",
+ "version": "10.7.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.2.tgz",
+ "integrity": "sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ==",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
- "version": "10.7.1",
- "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.1.tgz",
- "integrity": "sha512-v0jbRR31LSgRY/C5i5X279A/WQjD6/JsMzGa+eqt658oJ75IvQXAeONmwvEMrvJQKnRElq/frzBR7fhmWY5uLw==",
+ "version": "10.7.2",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.2.tgz",
+ "integrity": "sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==",
"dependencies": {
"vue-demi": ">=0.14.6"
},
@@ -1825,35 +1857,35 @@
}
},
"node_modules/addons-linter": {
- "version": "6.19.0",
- "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-6.19.0.tgz",
- "integrity": "sha512-Yz5YRfIQ12dIqXKmEoHNwoS/L1xIve2hdm9UEesOEsov5W0zeWMOWCnqdvJNVNy7f1FnPu1lnqzylelkTBS7dA==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-6.21.0.tgz",
+ "integrity": "sha512-4GBn14BR16FZE7dog6uz+1HO6V3B+mAVxmbwxRhed2y5eyrwIW832TmEpku+5A5bbovBZ4gilXEtBsl6A1AMmg==",
"dev": true,
"dependencies": {
"@fluent/syntax": "0.19.0",
- "@mdn/browser-compat-data": "5.4.3",
+ "@mdn/browser-compat-data": "5.5.7",
"addons-moz-compare": "1.3.0",
- "addons-scanner-utils": "9.8.0",
+ "addons-scanner-utils": "9.9.0",
"ajv": "8.12.0",
"chalk": "4.1.2",
"cheerio": "1.0.0-rc.12",
"columnify": "1.6.0",
"common-tags": "1.8.2",
"deepmerge": "4.3.1",
- "eslint": "8.55.0",
+ "eslint": "8.56.0",
"eslint-plugin-no-unsanitized": "4.0.2",
"eslint-visitor-keys": "3.4.3",
"espree": "9.6.1",
"esprima": "4.0.1",
"fast-json-patch": "3.1.1",
"glob": "10.3.10",
- "image-size": "1.0.2",
+ "image-size": "1.1.1",
"is-mergeable-object": "1.1.1",
"jed": "1.1.1",
"json-merge-patch": "1.0.2",
"os-locale": "5.0.0",
- "pino": "8.16.2",
- "postcss": "8.4.32",
+ "pino": "8.17.2",
+ "postcss": "8.4.33",
"relaxed-json": "1.0.3",
"semver": "7.5.4",
"sha.js": "2.4.11",
@@ -1870,19 +1902,10 @@
"node": ">=16.0.0"
}
},
- "node_modules/addons-linter/node_modules/@eslint/js": {
- "version": "8.55.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz",
- "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
"node_modules/addons-linter/node_modules/addons-scanner-utils": {
- "version": "9.8.0",
- "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.8.0.tgz",
- "integrity": "sha512-nJJ4QazrtMImyb2OK9SGZlNtinNu25dzOR0lhWthhJQN2iDOf3yqHdSiVBEeZvCwuT/sS1cU6me4O4kgEATjFQ==",
+ "version": "9.9.0",
+ "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.9.0.tgz",
+ "integrity": "sha512-YDP10U3sEZMuIgnjXMiAYgUU64jTbxmhpUXMlhi1nKO4Etz+ctGWoTUst7IQRoLWaY9y2r1KZDG3jALxLA1n7Q==",
"dev": true,
"dependencies": {
"@types/yauzl": "2.10.3",
@@ -1958,83 +1981,6 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
- "node_modules/addons-linter/node_modules/eslint": {
- "version": "8.55.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz",
- "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==",
- "dev": true,
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.55.0",
- "@humanwhocodes/config-array": "^0.11.13",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@nodelib/fs.walk": "^1.2.8",
- "@ungap/structured-clone": "^1.2.0",
- "ajv": "^6.12.4",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.2",
- "debug": "^4.3.2",
- "doctrine": "^3.0.0",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.2.2",
- "eslint-visitor-keys": "^3.4.3",
- "espree": "^9.6.1",
- "esquery": "^1.4.2",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "globals": "^13.19.0",
- "graphemer": "^1.4.0",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "is-path-inside": "^3.0.3",
- "js-yaml": "^4.1.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "levn": "^0.4.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3",
- "strip-ansi": "^6.0.1",
- "text-table": "^0.2.0"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/addons-linter/node_modules/eslint/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/addons-linter/node_modules/eslint/node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
- },
"node_modules/addons-linter/node_modules/glob": {
"version": "10.3.10",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
@@ -2057,7 +2003,13 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/addons-linter/node_modules/glob/node_modules/minimatch": {
+ "node_modules/addons-linter/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "node_modules/addons-linter/node_modules/minimatch": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
@@ -2072,12 +2024,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/addons-linter/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
- },
"node_modules/addons-linter/node_modules/node-fetch": {
"version": "2.6.11",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
@@ -2346,9 +2292,9 @@
}
},
"node_modules/autoprefixer": {
- "version": "10.4.16",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz",
- "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==",
+ "version": "10.4.17",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz",
+ "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==",
"dev": true,
"funding": [
{
@@ -2365,9 +2311,9 @@
}
],
"dependencies": {
- "browserslist": "^4.21.10",
- "caniuse-lite": "^1.0.30001538",
- "fraction.js": "^4.3.6",
+ "browserslist": "^4.22.2",
+ "caniuse-lite": "^1.0.30001578",
+ "fraction.js": "^4.3.7",
"normalize-range": "^0.1.2",
"picocolors": "^1.0.0",
"postcss-value-parser": "^4.2.0"
@@ -2398,11 +2344,11 @@
"dev": true
},
"node_modules/axios": {
- "version": "1.6.3",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz",
- "integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==",
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
+ "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
"dependencies": {
- "follow-redirects": "^1.15.0",
+ "follow-redirects": "^1.15.4",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
@@ -2536,9 +2482,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.22.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
- "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
+ "version": "4.22.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz",
+ "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==",
"dev": true,
"funding": [
{
@@ -2555,8 +2501,8 @@
}
],
"dependencies": {
- "caniuse-lite": "^1.0.30001565",
- "electron-to-chromium": "^1.4.601",
+ "caniuse-lite": "^1.0.30001580",
+ "electron-to-chromium": "^1.4.648",
"node-releases": "^2.0.14",
"update-browserslist-db": "^1.0.13"
},
@@ -2716,9 +2662,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001572",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001572.tgz",
- "integrity": "sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw==",
+ "version": "1.0.30001581",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz",
+ "integrity": "sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==",
"dev": true,
"funding": [
{
@@ -3486,9 +3432,9 @@
}
},
"node_modules/dotenv": {
- "version": "16.3.1",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
- "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
+ "version": "16.4.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz",
+ "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==",
"dev": true,
"engines": {
"node": ">=12"
@@ -3535,9 +3481,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.616",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz",
- "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==",
+ "version": "1.4.648",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.648.tgz",
+ "integrity": "sha512-EmFMarXeqJp9cUKu/QEciEApn0S/xRcpZWuAm32U7NgoZCimjsilKXHRO9saeEW55eHZagIDg6XTUOv32w9pjg==",
"dev": true
},
"node_modules/emoji-regex": {
@@ -3594,9 +3540,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.19.11",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz",
- "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==",
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
+ "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
@@ -3605,29 +3551,29 @@
"node": ">=12"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.19.11",
- "@esbuild/android-arm": "0.19.11",
- "@esbuild/android-arm64": "0.19.11",
- "@esbuild/android-x64": "0.19.11",
- "@esbuild/darwin-arm64": "0.19.11",
- "@esbuild/darwin-x64": "0.19.11",
- "@esbuild/freebsd-arm64": "0.19.11",
- "@esbuild/freebsd-x64": "0.19.11",
- "@esbuild/linux-arm": "0.19.11",
- "@esbuild/linux-arm64": "0.19.11",
- "@esbuild/linux-ia32": "0.19.11",
- "@esbuild/linux-loong64": "0.19.11",
- "@esbuild/linux-mips64el": "0.19.11",
- "@esbuild/linux-ppc64": "0.19.11",
- "@esbuild/linux-riscv64": "0.19.11",
- "@esbuild/linux-s390x": "0.19.11",
- "@esbuild/linux-x64": "0.19.11",
- "@esbuild/netbsd-x64": "0.19.11",
- "@esbuild/openbsd-x64": "0.19.11",
- "@esbuild/sunos-x64": "0.19.11",
- "@esbuild/win32-arm64": "0.19.11",
- "@esbuild/win32-ia32": "0.19.11",
- "@esbuild/win32-x64": "0.19.11"
+ "@esbuild/aix-ppc64": "0.19.12",
+ "@esbuild/android-arm": "0.19.12",
+ "@esbuild/android-arm64": "0.19.12",
+ "@esbuild/android-x64": "0.19.12",
+ "@esbuild/darwin-arm64": "0.19.12",
+ "@esbuild/darwin-x64": "0.19.12",
+ "@esbuild/freebsd-arm64": "0.19.12",
+ "@esbuild/freebsd-x64": "0.19.12",
+ "@esbuild/linux-arm": "0.19.12",
+ "@esbuild/linux-arm64": "0.19.12",
+ "@esbuild/linux-ia32": "0.19.12",
+ "@esbuild/linux-loong64": "0.19.12",
+ "@esbuild/linux-mips64el": "0.19.12",
+ "@esbuild/linux-ppc64": "0.19.12",
+ "@esbuild/linux-riscv64": "0.19.12",
+ "@esbuild/linux-s390x": "0.19.12",
+ "@esbuild/linux-x64": "0.19.12",
+ "@esbuild/netbsd-x64": "0.19.12",
+ "@esbuild/openbsd-x64": "0.19.12",
+ "@esbuild/sunos-x64": "0.19.12",
+ "@esbuild/win32-arm64": "0.19.12",
+ "@esbuild/win32-ia32": "0.19.12",
+ "@esbuild/win32-x64": "0.19.12"
}
},
"node_modules/escalade": {
@@ -3725,9 +3671,9 @@
}
},
"node_modules/eslint-plugin-vue": {
- "version": "9.19.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.19.2.tgz",
- "integrity": "sha512-CPDqTOG2K4Ni2o4J5wixkLVNwgctKXFu6oBpVJlpNq7f38lh9I80pRTouZSJ2MAebPJlINU/KTFSXyQfBUlymA==",
+ "version": "9.20.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.20.1.tgz",
+ "integrity": "sha512-GyCs8K3lkEvoyC1VV97GJhP1SvqsKCiWGHnbn0gVUYiUhaH2+nB+Dv1uekv1THFMPbBfYxukrzQdltw950k+LQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
@@ -3735,7 +3681,7 @@
"nth-check": "^2.1.1",
"postcss-selector-parser": "^6.0.13",
"semver": "^7.5.4",
- "vue-eslint-parser": "^9.3.1",
+ "vue-eslint-parser": "^9.4.0",
"xml-name-validator": "^4.0.0"
},
"engines": {
@@ -3967,9 +3913,9 @@
}
},
"node_modules/fastq": {
- "version": "1.16.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz",
- "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==",
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz",
+ "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==",
"dependencies": {
"reusify": "^1.0.4"
}
@@ -4112,9 +4058,9 @@
"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ=="
},
"node_modules/follow-redirects": {
- "version": "1.15.4",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
- "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
+ "version": "1.15.5",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
+ "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
"funding": [
{
"type": "individual",
@@ -4217,7 +4163,6 @@
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
- "dev": true,
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
@@ -4255,9 +4200,9 @@
}
},
"node_modules/fx-runner": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/fx-runner/-/fx-runner-1.3.0.tgz",
- "integrity": "sha512-5b37H4GCyhF+Nf8xk9mylXoDq4wb7pbGAXxlCXp/631UTeeZomWSYcEGXumY4wk8g2QAqjPMGdWW+RbNt8PUcA==",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/fx-runner/-/fx-runner-1.4.0.tgz",
+ "integrity": "sha512-rci1g6U0rdTg6bAaBboP7XdRu01dzTAaKXxFf+PUqGuCv6Xu7o8NZdY1D5MvKGIjb6EdS1g3VlXOgksir1uGkg==",
"dependencies": {
"commander": "2.9.0",
"shell-quote": "1.7.3",
@@ -4682,9 +4627,9 @@
}
},
"node_modules/image-size": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz",
- "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz",
+ "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==",
"dev": true,
"dependencies": {
"queue": "6.0.2"
@@ -4693,7 +4638,7 @@
"image-size": "bin/image-size.js"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=16.x"
}
},
"node_modules/immediate": {
@@ -4702,9 +4647,9 @@
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
},
"node_modules/immutable": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",
- "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==",
+ "version": "4.3.5",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
+ "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==",
"devOptional": true
},
"node_modules/import-fresh": {
@@ -5943,9 +5888,9 @@
}
},
"node_modules/otpauth": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/otpauth/-/otpauth-9.2.1.tgz",
- "integrity": "sha512-/MRvcm63pzK20NCsIOe8Btun42/yWNylPbUo/h5dMpSRJpoAJstWodEUjm4zUDeT1+Vbqif2E8IcP4trl1U4gQ==",
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/otpauth/-/otpauth-9.2.2.tgz",
+ "integrity": "sha512-2VcnYRUmq1dNckIfySNYP32ITWp1bvTeAEW0BSCR6G3GBf3a5zb9E+ubY62t3Dma9RjoHlvd7QpmzHfJZRkiNg==",
"dependencies": {
"jssha": "~3.3.1"
},
@@ -6154,9 +6099,9 @@
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz",
- "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==",
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
+ "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
"dev": true,
"engines": {
"node": "14 || >=16.14"
@@ -6251,9 +6196,9 @@
}
},
"node_modules/pino": {
- "version": "8.16.2",
- "resolved": "https://registry.npmjs.org/pino/-/pino-8.16.2.tgz",
- "integrity": "sha512-2advCDGVEvkKu9TTVSa/kWW7Z3htI/sBKEZpqiHk6ive0i/7f5b1rsU8jn0aimxqfnSz5bj/nOYkwhBUn5xxvg==",
+ "version": "8.17.2",
+ "resolved": "https://registry.npmjs.org/pino/-/pino-8.17.2.tgz",
+ "integrity": "sha512-LA6qKgeDMLr2ux2y/YiUt47EfgQ+S9LznBWOJdN3q1dx2sv0ziDLUBeVpyVv17TEcGCBuWf0zNtg3M5m1NhhWQ==",
"dev": true,
"dependencies": {
"atomic-sleep": "^1.0.0",
@@ -6261,7 +6206,7 @@
"on-exit-leak-free": "^2.1.0",
"pino-abstract-transport": "v1.1.0",
"pino-std-serializers": "^6.0.0",
- "process-warning": "^2.0.0",
+ "process-warning": "^3.0.0",
"quick-format-unescaped": "^4.0.3",
"real-require": "^0.2.0",
"safe-stable-stringify": "^2.3.1",
@@ -6307,9 +6252,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.32",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
- "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
+ "version": "8.4.33",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
+ "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
"funding": [
{
"type": "opencollective",
@@ -6506,9 +6451,9 @@
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"node_modules/process-warning": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz",
- "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz",
+ "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==",
"dev": true
},
"node_modules/promise-toolbox": {
@@ -7002,9 +6947,12 @@
}
},
"node_modules/rollup": {
- "version": "4.9.2",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.2.tgz",
- "integrity": "sha512-66RB8OtFKUTozmVEh3qyNfH+b+z2RXBVloqO2KCC/pjFaGaHtxP9fVfOQKPSGXg2mElmjmxjW/fZ7iKrEpMH5Q==",
+ "version": "4.9.6",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz",
+ "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==",
+ "dependencies": {
+ "@types/estree": "1.0.5"
+ },
"bin": {
"rollup": "dist/bin/rollup"
},
@@ -7013,19 +6961,19 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.9.2",
- "@rollup/rollup-android-arm64": "4.9.2",
- "@rollup/rollup-darwin-arm64": "4.9.2",
- "@rollup/rollup-darwin-x64": "4.9.2",
- "@rollup/rollup-linux-arm-gnueabihf": "4.9.2",
- "@rollup/rollup-linux-arm64-gnu": "4.9.2",
- "@rollup/rollup-linux-arm64-musl": "4.9.2",
- "@rollup/rollup-linux-riscv64-gnu": "4.9.2",
- "@rollup/rollup-linux-x64-gnu": "4.9.2",
- "@rollup/rollup-linux-x64-musl": "4.9.2",
- "@rollup/rollup-win32-arm64-msvc": "4.9.2",
- "@rollup/rollup-win32-ia32-msvc": "4.9.2",
- "@rollup/rollup-win32-x64-msvc": "4.9.2",
+ "@rollup/rollup-android-arm-eabi": "4.9.6",
+ "@rollup/rollup-android-arm64": "4.9.6",
+ "@rollup/rollup-darwin-arm64": "4.9.6",
+ "@rollup/rollup-darwin-x64": "4.9.6",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.9.6",
+ "@rollup/rollup-linux-arm64-gnu": "4.9.6",
+ "@rollup/rollup-linux-arm64-musl": "4.9.6",
+ "@rollup/rollup-linux-riscv64-gnu": "4.9.6",
+ "@rollup/rollup-linux-x64-gnu": "4.9.6",
+ "@rollup/rollup-linux-x64-musl": "4.9.6",
+ "@rollup/rollup-win32-arm64-msvc": "4.9.6",
+ "@rollup/rollup-win32-ia32-msvc": "4.9.6",
+ "@rollup/rollup-win32-x64-msvc": "4.9.6",
"fsevents": "~2.3.2"
}
},
@@ -7093,9 +7041,9 @@
"dev": true
},
"node_modules/sass": {
- "version": "1.69.6",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.6.tgz",
- "integrity": "sha512-qbRr3k9JGHWXCvZU77SD2OTwUlC+gNT+61JOLcmLm+XqH4h/5D+p4IIsxvpkB89S9AwJOyb5+rWNpIucaFxSFQ==",
+ "version": "1.70.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz",
+ "integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==",
"devOptional": true,
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
@@ -7174,15 +7122,16 @@
"peer": true
},
"node_modules/set-function-length": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
- "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz",
+ "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==",
"dev": true,
"dependencies": {
"define-data-property": "^1.1.1",
- "get-intrinsic": "^1.2.1",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.2",
"gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.0"
+ "has-property-descriptors": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -7239,6 +7188,7 @@
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/sign-addon/-/sign-addon-5.3.0.tgz",
"integrity": "sha512-7nHlCzhQgVMLBNiXVEgbG/raq48awOW0lYMN5uo1BaB3mp0+k8M8pvDwbfTlr3apcxZJsk9HQsAW1POwoJugpQ==",
+ "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"dev": true,
"dependencies": {
"common-tags": "1.8.2",
@@ -7259,9 +7209,9 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
"node_modules/sonic-boom": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz",
- "integrity": "sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.0.tgz",
+ "integrity": "sha512-ybz6OYOUjoQQCQ/i4LU8kaToD8ACtYP+Cj5qd2AO36bwbdewxWJ3ArmJ2cr6AvxlL2o0PqnCcPGUgkILbfkaCA==",
"dev": true,
"dependencies": {
"atomic-sleep": "^1.0.0"
@@ -7619,9 +7569,9 @@
}
},
"node_modules/tailwindcss": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz",
- "integrity": "sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA==",
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
+ "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==",
"dev": true,
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
@@ -8017,9 +7967,9 @@
}
},
"node_modules/universal-cookie": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-7.0.0.tgz",
- "integrity": "sha512-T3XwZ2cUbHRU+UNfPSaPd0zti50tVIvk6onLA90pa+qKwsP8ksn5pwYM7rWMODoX1OCA9qPAN8uK88Avq5YbtQ==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-7.0.2.tgz",
+ "integrity": "sha512-EC9PA+1nojhJtVnKW2Z7WYah01jgYJApqhX+Y8XU97TnFd7KaoxWTHiTZFtfpfV50jEF1L8V5p64ZxIx3Q67dg==",
"dependencies": {
"@types/cookie": "^0.6.0",
"cookie": "^0.6.0"
@@ -8147,9 +8097,9 @@
}
},
"node_modules/vite": {
- "version": "5.0.10",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.10.tgz",
- "integrity": "sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==",
+ "version": "5.0.12",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz",
+ "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==",
"dependencies": {
"esbuild": "^0.19.3",
"postcss": "^8.4.32",
@@ -8289,12 +8239,12 @@
}
},
"node_modules/vscode-html-languageservice": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.1.1.tgz",
- "integrity": "sha512-JenrspIIG/Q+93R6G3L6HdK96itSisMynE0glURqHpQbL3dKAKzdm8L40lAHNkwJeBg+BBPpAshZKv/38onrTQ==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.1.2.tgz",
+ "integrity": "sha512-wkWfEx/IIR3s2P5yD4aTGHiOb8IAzFxgkSt1uSC3itJ4oDAm23yG7o0L29JljUdnXDDgLafPAvhv8A2I/8riHw==",
"dev": true,
"dependencies": {
- "@vscode/l10n": "^0.0.16",
+ "@vscode/l10n": "^0.0.18",
"vscode-languageserver-textdocument": "^1.0.11",
"vscode-languageserver-types": "^3.17.5",
"vscode-uri": "^3.0.8"
@@ -8319,15 +8269,15 @@
"dev": true
},
"node_modules/vue": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.3.tgz",
- "integrity": "sha512-GjN+culMAGv/mUbkIv8zMKItno8npcj5gWlXkSxf1SPTQf8eJ4A+YfHIvQFyL1IfuJcMl3soA7SmN1fRxbf/wA==",
+ "version": "3.4.15",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.15.tgz",
+ "integrity": "sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==",
"dependencies": {
- "@vue/compiler-dom": "3.4.3",
- "@vue/compiler-sfc": "3.4.3",
- "@vue/runtime-dom": "3.4.3",
- "@vue/server-renderer": "3.4.3",
- "@vue/shared": "3.4.3"
+ "@vue/compiler-dom": "3.4.15",
+ "@vue/compiler-sfc": "3.4.15",
+ "@vue/runtime-dom": "3.4.15",
+ "@vue/server-renderer": "3.4.15",
+ "@vue/shared": "3.4.15"
},
"peerDependencies": {
"typescript": "*"
@@ -8339,9 +8289,9 @@
}
},
"node_modules/vue-eslint-parser": {
- "version": "9.3.2",
- "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz",
- "integrity": "sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==",
+ "version": "9.4.2",
+ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+ "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
"dev": true,
"dependencies": {
"debug": "^4.3.4",
@@ -8437,14 +8387,14 @@
}
},
"node_modules/web-ext": {
- "version": "7.9.0",
- "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.9.0.tgz",
- "integrity": "sha512-oWMiM3e+u5E8X7aUMgQ0BCGjlbZt4XwF6ExAXsXx9Btdz3nLmUY/4eKEZA1J+2T7WhCdRwN7Pdh2VKMej/pthQ==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.11.0.tgz",
+ "integrity": "sha512-EG6YXHITNDJB/h6Rc5FF08eMoN45sZPBBIIlEraBzxJ0RdJZ8Z3xvUUawbDwt+mowfv9X0XRWlLSwdWbRKgojg==",
"dev": true,
"dependencies": {
"@babel/runtime": "7.21.0",
"@devicefarmer/adbkit": "3.2.3",
- "addons-linter": "6.19.0",
+ "addons-linter": "6.21.0",
"bunyan": "1.8.15",
"camelcase": "7.0.1",
"chrome-launcher": "0.15.1",
@@ -8453,7 +8403,7 @@
"es6-error": "4.1.1",
"firefox-profile": "4.3.2",
"fs-extra": "11.1.0",
- "fx-runner": "1.3.0",
+ "fx-runner": "1.4.0",
"import-fresh": "3.3.0",
"jose": "4.13.1",
"mkdirp": "1.0.4",
@@ -8484,19 +8434,19 @@
}
},
"node_modules/web-ext-run": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/web-ext-run/-/web-ext-run-0.1.1.tgz",
- "integrity": "sha512-9QGtlnXExhXYK+pRFaN/ZRbS4jb53YwQn7A1zOlAE4x5Lj6V7l1PD7O/wbHaGe7xkykrw7+Cv4i0ukSi7VBnsg==",
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/web-ext-run/-/web-ext-run-0.1.2.tgz",
+ "integrity": "sha512-VygO7lg10keonbku5Lbi21zEz1k91odkW+c6YB5DGb+mITcRMVM2zr/tJ+Suh6wxNUOOFNbinoqDlSUWdxt6YQ==",
"dependencies": {
- "@babel/runtime": "7.23.4",
- "@devicefarmer/adbkit": "3.2.5",
+ "@babel/runtime": "7.23.9",
+ "@devicefarmer/adbkit": "3.2.6",
"bunyan": "1.8.15",
"chrome-launcher": "0.15.1",
"debounce": "1.2.1",
"es6-error": "4.1.1",
- "firefox-profile": "4.4.0",
- "fs-extra": "11.1.1",
- "fx-runner": "1.3.0",
+ "firefox-profile": "4.5.0",
+ "fs-extra": "11.2.0",
+ "fx-runner": "1.4.0",
"mkdirp": "1.0.4",
"multimatch": "6.0.0",
"mz": "2.7.0",
@@ -8509,18 +8459,18 @@
"tmp": "0.2.1",
"update-notifier": "6.0.2",
"watchpack": "2.4.0",
- "ws": "8.14.2",
+ "ws": "8.16.0",
"zip-dir": "2.0.0"
},
"engines": {
- "node": ">=16.0.0",
+ "node": ">=18.0.0",
"npm": ">=8.0.0"
}
},
"node_modules/web-ext-run/node_modules/@babel/runtime": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz",
- "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==",
+ "version": "7.23.9",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
+ "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -8529,9 +8479,9 @@
}
},
"node_modules/web-ext-run/node_modules/@devicefarmer/adbkit": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-3.2.5.tgz",
- "integrity": "sha512-+J479WWZW3GU3t40flicDfiDrFz6vpiy2RcBQPEhFcs/3La9pOtr4Bgz2Q02E4luUG2RAL068rqIkKNUTy3tZw==",
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-3.2.6.tgz",
+ "integrity": "sha512-8lO1hSeTgtxcOHhp4tTWq/JaOysp5KNbbyFoxNEBnwkCDZu/Bji3ZfOaG++Riv9jN6c9bgdLBOZqJTC5VJPRKQ==",
"dependencies": {
"@devicefarmer/adbkit-logcat": "^2.1.2",
"@devicefarmer/adbkit-monkey": "~1.2.1",
@@ -8557,9 +8507,9 @@
}
},
"node_modules/web-ext-run/node_modules/firefox-profile": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/firefox-profile/-/firefox-profile-4.4.0.tgz",
- "integrity": "sha512-n+Wwa7yNtgJcOOWJXVOpF84rlDdPGsZ5d2dAuCZJivf3SSmx2omWFRDU85l4T5HZ3jj+FJQbyto04pX7/HWPnA==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/firefox-profile/-/firefox-profile-4.5.0.tgz",
+ "integrity": "sha512-goE2XxbmYVSafvCjcy64/AK3xOr14HCUCD4+TpYWEIMy4nrJfNAacLGzwqKwZhCW0hHI2TYMGH+G/YBvOE8L6g==",
"dependencies": {
"adm-zip": "~0.5.x",
"fs-extra": "~9.0.1",
@@ -8585,27 +8535,6 @@
"node": ">=10"
}
},
- "node_modules/web-ext-run/node_modules/firefox-profile/node_modules/universalify": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
- "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/web-ext-run/node_modules/fs-extra": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz",
- "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=14.14"
- }
- },
"node_modules/web-ext-run/node_modules/json-parse-even-better-errors": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz",
@@ -8678,10 +8607,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/web-ext-run/node_modules/universalify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
+ "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
"node_modules/web-ext-run/node_modules/ws": {
- "version": "8.14.2",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
- "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
+ "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
"engines": {
"node": ">=10.0.0"
},
@@ -8833,9 +8770,9 @@
}
},
"node_modules/web-streams-polyfill": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
- "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz",
+ "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==",
"dev": true,
"engines": {
"node": ">= 8"
diff --git a/extension/package.json b/extension/package.json
index 806d54f..ba5d172 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -44,7 +44,7 @@
"@fortawesome/vue-fontawesome": "^3.0.3",
"@headlessui/vue": "^1.7.x",
"@kyvg/vue3-notification": "^3.0.x",
- "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/0ca26fc63cc5311298575209b124516139f58206/@vnuge-vnlib.browser/release.tgz",
+ "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/df7dc615532d3441f527374d18664c1a5a336de6/@vnuge-vnlib.browser/release.tgz",
"@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0",
"@vueuse/core": "^10.3.2",
diff --git a/extension/src/components/ListBox.vue b/extension/src/components/ListBox.vue
new file mode 100644
index 0000000..704cc58
--- /dev/null
+++ b/extension/src/components/ListBox.vue
@@ -0,0 +1,86 @@
+<template>
+ <Listbox as="div" class="relative w-full">
+
+ <ListboxButton class="inline-flex items-center w-full overflow-hidden bg-white border rounded-md dark:bg-dark-800 dark:border-dark-500">
+ <span class="flex-1 px-4 py-2 text-gray-600 dark:text-inherit border-e dark:border-dark-500 text-sm/none hover:bg-gray-50 hover:text-gray-700 dark:hover:bg-dark-700 dark:hover:text-gray-100" >
+ {{ $props.modelToString(model) }}
+ </span>
+ <span class="h-full p-2 hover:bg-gray-50 hover:text-gray-700 dark:hover:bg-dark-700 dark:hover:text-gray-100">
+ <span class="sr-only">Menu</span>
+ <svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4" viewBox="0 0 20 20" fill="currentColor">
+ <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
+ </svg>
+ </span>
+ </ListboxButton>
+
+ <transition
+ leave-active-class="transition duration-100 ease-in"
+ leave-from-class="opacity-100"
+ leave-to-class="opacity-0"
+ >
+ <ListboxOptions
+ role="menu"
+ class="absolute z-10 w-full mt-1 bg-white border border-gray-100 divide-y divide-gray-100 rounded-md shadow-lg end-0 dark:divide-dark-600 dark:border-dark-500 dark:bg-dark-800"
+ >
+ <div
+ v-for="group in $props.groups"
+ :key="group.name"
+ class=""
+ >
+ <strong class="block p-2 text-xs font-medium text-gray-400 uppercase dark:text-gray-400">
+ {{ group.name }}
+ </strong>
+
+ <ListboxOption
+ v-slot="{ active, selected }"
+ v-for="option in group.options"
+ :key="option.name"
+ :value="option.value"
+ as="template"
+ @click.prevent="select(option.value)"
+ >
+ <li
+ class='relative px-6 py-1 text-sm duration-75 ease-linear cursor-default select-none'
+ :class="[active ? 'bg-blue-300 text-blue-900' : 'text-gray-900 dark:text-gray-100']"
+ >
+ <span class="block truncate" :class="[selected ? 'font-medium' : 'font-normal']">
+ {{ option.name }}
+ </span>
+
+ <span v-if="selected" class="absolute inset-y-0 left-0 flex items-center pl-3 text-amber-600">
+ <CheckIcon class="w-5 h-5" aria-hidden="true" />
+ </span>
+ </li>
+ </ListboxOption>
+ </div>
+ </ListboxOptions>
+ </transition>
+
+ </Listbox>
+</template>
+
+<script setup lang="ts">
+import { Listbox, ListboxButton, ListboxOptions, ListboxOption } from '@headlessui/vue'
+
+const model = defineModel<any>({ required: true })
+defineProps<ListboxProps<any>>();
+
+const select = (value: any) => model.value = value
+
+export interface Option<T>{
+ readonly name: string
+ readonly value: T
+}
+
+export interface OptionGroup<T>{
+ readonly name: string
+ readonly options: Option<T>[]
+}
+
+export interface ListboxProps<T>{
+ readonly modelValue: T;
+ readonly groups: OptionGroup<T>[];
+ modelToString(value:T): string;
+}
+
+</script> \ No newline at end of file
diff --git a/extension/src/components/Pagination.vue b/extension/src/components/Pagination.vue
new file mode 100644
index 0000000..9a017ed
--- /dev/null
+++ b/extension/src/components/Pagination.vue
@@ -0,0 +1,36 @@
+<template>
+ <div class="inline-flex items-center justify-center gap-3">
+ <a
+ href="#"
+ @click.prevent="$props.pages.prev()"
+ class="inline-flex items-center justify-center w-8 h-8 text-gray-900 bg-white border border-gray-100 rounded rtl:rotate-180 dark:border-gray-800 dark:bg-gray-900 dark:text-white"
+ >
+ <span class="sr-only">Next Page</span>
+ <fa-icon icon="chevron-left" class="w-4" />
+ </a>
+
+ <p class="text-xs text-gray-900 dark:text-white">
+ {{ $props.pages.currentPage }}
+ <span class="mx-0.25">/</span>
+ {{ $props.pages.pageCount }}
+ </p>
+
+ <a
+ href="#"
+ @click.prevent="$props.pages.next()"
+ class="inline-flex items-center justify-center w-8 h-8 text-gray-900 bg-white border border-gray-100 rounded rtl:rotate-180 dark:border-gray-800 dark:bg-gray-900 dark:text-white"
+ >
+ <span class="sr-only">Next Page</span>
+ <fa-icon icon="chevron-right" class="w-4" />
+ </a>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { useOffsetPagination } from '@vueuse/core';
+
+defineProps<{
+ pages: ReturnType<typeof useOffsetPagination>
+}>()
+
+</script> \ No newline at end of file
diff --git a/extension/src/entries/contentScript/primary/components/PromptPopup.vue b/extension/src/entries/contentScript/primary/components/PromptPopup.vue
index 1f62877..b2415b9 100644
--- a/extension/src/entries/contentScript/primary/components/PromptPopup.vue
+++ b/extension/src/entries/contentScript/primary/components/PromptPopup.vue
@@ -1,11 +1,12 @@
<template>
- <div v-show="event" id="nvault-ext-prompt" :class="{'dark': darkMode }">
+ <div v-show="showPrompt" id="nvault-ext-prompt" :class="{'dark': darkMode }">
<div class="fixed top-0 bottom-0 left-0 right-0 text-white" style="z-index:9147483647 !important" >
-
+
+ <!-- Only show backdrop when prompt is on the same origin -->
<div class="fixed inset-0 left-0 w-full h-full bg-black/50" @click.self="close" />
- <div v-if="store.permissions.isPopup" class="relative w-full md:max-w-[28rem] mx-auto md:mt-36 mb-auto" ref="prompt">
+ <div v-if="showPopup" class="relative w-full md:max-w-[28rem] mx-auto md:mt-36 mb-auto" ref="prompt">
<div class="w-full h-screen p-5 text-gray-800 bg-white border shadow-lg md:h-auto md:rounded dark:bg-dark-900 dark:border-dark-500 dark:text-gray-200">
<div v-if="loggedIn" class="">
@@ -49,16 +50,14 @@
</div>
<div class="flex gap-2 mt-4">
+
+ <ListBox class="max-w-40" v-model="allowRuleType" :groups="lbOptions" :modelToString="modelToString" />
+
<div class="ml-auto">
<button class="rounded btn sm" @click="close">Close</button>
</div>
<div>
- <button :disabled="selectedKey?.Id == undefined" class="rounded amber btn sm" @click="allow(true)">
- Always Allow
- </button>
- </div>
- <div>
- <button :disabled="selectedKey?.Id == undefined" class="rounded btn sm" @click="allow(false)">Allow</button>
+ <button :disabled="selectedKey?.Id == undefined" class="rounded btn sm" @click="allow()">Allow</button>
</div>
</div>
</div>
@@ -89,13 +88,14 @@
</template>
<script setup lang="ts">
-import { ref } from 'vue'
+import { ref, shallowRef } from 'vue'
import { storeToRefs } from 'pinia';
import { computed } from 'vue';
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
-import { clone, first } from 'lodash';
+import { clone, first, isEqual } from 'lodash';
import { useStore } from '../../../store';
-import { type PermissionRequest } from '../../../../features'
+import { CreateRuleType, type PermissionRequest } from '../../../../features'
+import ListBox, { Option, OptionGroup } from '../../../../components/ListBox.vue';
interface PropmtMessage extends PermissionRequest{
msg: string;
@@ -106,6 +106,7 @@ const { loggedIn, selectedKey, darkMode } = storeToRefs(store)
const keyName = computed(() => selectedKey.value?.UserName)
const prompt = ref(null)
+const allowRuleType = shallowRef<CreateRuleType>(CreateRuleType.AllowOnce)
const event = computed<PropmtMessage | undefined>(() => {
//Use a the current windowpending if set
@@ -120,16 +121,26 @@ const event = computed<PropmtMessage | undefined>(() => {
const site = computed(() => new URL(event.value?.origin || "https://example.com").host)
const evData = computed(() => JSON.stringify(event.value || {}, null, 2))
+const onSameOrigin = computed(() => isEqual(event.value?.origin, window.location.origin))
+//Only show in-page popup if the event is from the same origin
+const showPopup = computed(() => (store.permissions.isPopup || !store.settings.authPopup))
+const showPrompt = computed(() => (onSameOrigin.value || store.permissions.isPopup) && event.value)
+
const close = () => {
if(event.value){
store.plugins.permission.deny(event.value.uuid);
}
+
+ //Reset the rule type
+ allowRuleType.value = CreateRuleType.AllowOnce
}
-const allow = (addRule: boolean) => {
+const allow = () => {
if (event.value) {
- store.plugins.permission.allow(event.value.uuid, addRule);
+ store.plugins.permission.allow(event.value.uuid, allowRuleType.value);
}
+ //Reset the rule type
+ allowRuleType.value = CreateRuleType.AllowOnce
}
//Listen for events
@@ -161,4 +172,51 @@ const getPromptMessage = (perms: PermissionRequest | undefined): PropmtMessage |
return ev
}
-</script>
+const getRuleName = (rule: CreateRuleType) => {
+ switch (rule) {
+ default:
+ return 'None'
+ case CreateRuleType.AllowOnce:
+ return "Allow Once"
+ case CreateRuleType.AllowForever:
+ return "Allow Forever"
+ case CreateRuleType.FiveMinutes:
+ return "5 Minutes"
+ case CreateRuleType.OneHour:
+ return "1 Hour"
+ case CreateRuleType.OneDay:
+ return "1 Day"
+ case CreateRuleType.OneWeek:
+ return "1 Week"
+ case CreateRuleType.OneMonth:
+ return "1 Month"
+ }
+}
+
+const createOption = (rule: CreateRuleType): Option<CreateRuleType> => {
+ return { name: getRuleName(rule), value: rule }
+}
+
+const creatGroup = (name: string, options: Option<CreateRuleType>[]): OptionGroup<CreateRuleType> => {
+ return { name, options }
+}
+
+const lbOptions = ((): OptionGroup<CreateRuleType>[] => {
+ return[
+ creatGroup('Allow', [
+ createOption(CreateRuleType.AllowOnce),
+ createOption(CreateRuleType.AllowForever)
+ ]),
+ creatGroup('Allow for', [
+ createOption(CreateRuleType.FiveMinutes),
+ createOption(CreateRuleType.OneHour),
+ createOption(CreateRuleType.OneDay),
+ createOption(CreateRuleType.OneWeek),
+ createOption(CreateRuleType.OneMonth)
+ ])
+ ]
+})()
+
+const modelToString = (rule: CreateRuleType) => getRuleName(rule)
+
+</script> \ No newline at end of file
diff --git a/extension/src/entries/contentScript/primary/main.js b/extension/src/entries/contentScript/primary/main.js
index 15fc2ec..2e05ca3 100644
--- a/extension/src/entries/contentScript/primary/main.js
+++ b/extension/src/entries/contentScript/primary/main.js
@@ -19,6 +19,7 @@ import { defer } from "lodash";
import { createPinia } from 'pinia';
import { useBackgroundPiniaPlugin, identityPlugin, originPlugin, permissionsPlugin } from '../../store'
import { onLoad } from "../util";
+import ListBox from '../../../components/ListBox.vue'
import renderContent from "../renderContent";
import App from "./App.vue";
import Notification from '@kyvg/vue3-notification'
@@ -64,6 +65,7 @@ renderContent([], (appRoot, shadowRoot) => {
.use(store)
.use(Notification)
.component('fa-icon', FontAwesomeIcon)
+ .component('list-box', ListBox)
.mount(appRoot);
//Load the nostr shim
diff --git a/extension/src/entries/contentScript/util.ts b/extension/src/entries/contentScript/util.ts
index aecb7b2..192f1c1 100644
--- a/extension/src/entries/contentScript/util.ts
+++ b/extension/src/entries/contentScript/util.ts
@@ -25,7 +25,7 @@ const registerWindowHandler = (store: Store, extName: string) => {
const { selectedKey } = storeToRefs(store)
const { nostr, permission } = store.plugins;
- const onAsyncCall = async ({ source, data, origin } : MessageEvent<any>) => {
+ const onAsyncCall = async ({ data, origin } : MessageEvent<any>) => {
//clean any junk/methods with json parse/stringify
data = JSON.parse(JSON.stringify(data))
@@ -38,7 +38,7 @@ const registerWindowHandler = (store: Store, extName: string) => {
}
//Confirm the message format is correct
- if (!isEqual(source, window) || isEmpty(data) || isNil(data.type)) {
+ if (isEmpty(data) || isNil(data.type)) {
return
}
//Confirm extension is for us
diff --git a/extension/src/entries/options/App.vue b/extension/src/entries/options/App.vue
index 3dbe94d..f62795f 100644
--- a/extension/src/entries/options/App.vue
+++ b/extension/src/entries/options/App.vue
@@ -12,7 +12,7 @@
<div class="">
<h2>NVault</h2>
</div>
- <TabGroup :selected-index="selectedTab" @change="id => selectedTab = id" >
+ <TabGroup :selected-index="selectedTab" @change="selectTab" >
<TabList class="flex gap-3 pb-2 border-b border-gray-300 dark:border-dark-500">
<Tab v-slot="{ selected }">
<button class="tab-title" :class="{ selected }">
@@ -72,7 +72,7 @@
<TabPanel> <Account/> </TabPanel>
- <TabPanel> <EventHistory/> </TabPanel>
+ <TabPanel> <Activity/> </TabPanel>
<TabPanel> <Privacy/> </TabPanel>
@@ -116,7 +116,7 @@
</template>
<script setup lang="ts">
-import { ref, watchEffect } from "vue";
+import { computed, ref, watchEffect } from "vue";
import {
TabGroup,
TabList,
@@ -126,26 +126,32 @@ import {
} from '@headlessui/vue'
import { apiCall, configureNotifier } from '@vnuge/vnlib.browser';
import { storeToRefs } from "pinia";
-import { type NostrPubKey } from '../../features/';
+import { useQuery, type NostrPubKey } from '../../features/';
import { notify } from "@kyvg/vue3-notification";
-import SiteSettings from './components/SiteSettings.vue';
-import Identities from './components/Identities.vue';
-import Privacy from "./components/Privacy.vue";
+import { toSafeInteger } from "lodash";
import { useStore } from "../store";
import Account from "./components/Account.vue";
import ConfirmPrompt from "../../components/ConfirmPrompt.vue";
import PasswordPrompt from "../../components/PasswordPrompt.vue";
-import EventHistory from "./components/EventHistory.vue";
+import Activity from "./components/Activity.vue";
+import SiteSettings from './components/SiteSettings.vue';
+import Identities from './components/Identities.vue';
+import Privacy from "./components/Privacy.vue";
//Configure the notifier to use the notification library
configureNotifier({ notify, close: notify.close })
const store = useStore()
+const { identity } = store.plugins
const { allKeys, darkMode, userName } = storeToRefs(store)
-const selectedTab = ref(0)
-const keyBuffer = ref<NostrPubKey>({} as NostrPubKey)
+const keyBuffer = ref<Partial<NostrPubKey>>({} as NostrPubKey)
+
+const tabIdQuery = useQuery('t')
+const selectedTab = computed(() => toSafeInteger(tabIdQuery.asRef.value));
+const selectTab = (id: number) => tabIdQuery.set(id.toString())
+
const editKey = (key: NostrPubKey) =>{
//Goto hidden tab
@@ -158,14 +164,14 @@ const doneEditing = () =>{
//Goto hidden tab
selectedTab.value = 0
//Set selected key
- keyBuffer.value = null
+ keyBuffer.value = {}
}
const onUpdate = async () =>{
await apiCall(async ({ toaster }) => {
//Update identity
- await store.updateIdentity(keyBuffer.value)
+ await identity.updateIdentity(keyBuffer.value)
//Show success
toaster.general.success({
'title':'Success',
@@ -176,7 +182,7 @@ const onUpdate = async () =>{
//Goto hidden tab
selectedTab.value = 0
//Set selected key
- keyBuffer.value = null
+ keyBuffer.value = {}
}
const toggleDark = () => store.toggleDarkMode()
diff --git a/extension/src/entries/options/components/Activity.vue b/extension/src/entries/options/components/Activity.vue
new file mode 100644
index 0000000..c62fb83
--- /dev/null
+++ b/extension/src/entries/options/components/Activity.vue
@@ -0,0 +1,121 @@
+<template>
+ <div id="ev-history" class="flex flex-col w-full mt-4 sm:px-2">
+ <form @submit.prevent="">
+ <div class="w-full max-w-xl mx-auto">
+ <h3 class="text-center">
+ Permissions
+ </h3>
+
+ <div class="flex flex-row justify-between mt-4">
+ <div class="font-bold">
+ Pending
+ </div>
+ <div class="flex justify-center">
+ </div>
+ </div>
+
+ <div class="my-6 ">
+ <EvHistoryTable :readonly="false" :requests="pending" @deny="deny" @approve="approve" />
+ </div>
+
+ <AutoRules />
+
+ <div class="flex flex-row justify-between mt-16">
+ <div class="font-bold">
+ History
+ </div>
+ <div class="flex justify-center">
+ <pagination :pages="pages" />
+ </div>
+ </div>
+
+ <div class="mt-1">
+ <EvHistoryTable :readonly="true" :requests="permHistory" @deny="deny" @approve="approve" />
+ </div>
+
+ <div class="mt-4 ml-auto w-fit">
+ <button class="rounded btn sm red" @click="clearHistory">
+ Delete All
+ </button>
+ </div>
+
+ <h3 class="text-center">
+ History
+ </h3>
+
+ <div class="mt-1 mb-20">
+ <EventHistory />
+ </div>
+
+ </div>
+ </form>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { useConfirm } from '@vnuge/vnlib.browser';
+import { computed } from 'vue';
+import { get, useOffsetPagination } from '@vueuse/core';
+import { } from '@headlessui/vue'
+import { useStore } from '../../store';
+import { CreateRuleType, PermissionRequest, PrStatus } from '../../../features';
+import EvHistoryTable from './EvHistoryTable.vue';
+import { filter, slice } from 'lodash';
+import AutoRules from './AutoRules.vue';
+import EventHistory from './EventHistory.vue';
+
+const store = useStore()
+const { reveal } = useConfirm()
+
+const pending = computed(() => store.permissions.pending)
+const notPending = computed(() => filter(store.permissions.all, r => r.status !== PrStatus.Pending))
+
+const deny = (request: PermissionRequest) => {
+ if(request.status !== PrStatus.Pending) return
+ //push deny to store
+ store.plugins.permission.deny(request.uuid)
+}
+
+const approve = (request: PermissionRequest) => {
+ if(request.status !== PrStatus.Pending) return
+ //push allow to store
+ store.plugins.permission.allow(request.uuid, CreateRuleType.AllowOnce)
+}
+
+const pages = useOffsetPagination({
+ pageSize: 10,
+ total: computed(() => notPending.value.length)
+})
+
+const permHistory = computed(() => {
+ const start = (get(pages.currentPage) - 1) * get(pages.currentPageSize)
+ const end = start + 10
+ return slice(notPending.value, start, end)
+})
+
+const clearHistory = async () => {
+ const { isCanceled } = await reveal({
+ title: 'Clear History',
+ text: 'Are you sure you want to clear your event history?',
+ })
+
+ if(isCanceled) return
+
+ //Clear all history
+ store.plugins.permission.clearRequests()
+}
+
+</script>
+
+<style lang="scss">
+#ev-history{
+ button.page-btn{
+ @apply inline-flex items-center px-2 py-2 space-x-2 font-medium rounded-full;
+ @apply bg-white border border-gray-300 rounded-full hover:bg-gray-50 dark:bg-dark-600 dark:hover:bg-dark-500 dark:border-dark-300;
+ }
+
+ form tr {
+ @apply sm:text-sm text-xs dark:text-gray-400 text-gray-600;
+ }
+}
+</style> \ No newline at end of file
diff --git a/extension/src/entries/options/components/AutoRules.vue b/extension/src/entries/options/components/AutoRules.vue
index 16fddd3..9f46475 100644
--- a/extension/src/entries/options/components/AutoRules.vue
+++ b/extension/src/entries/options/components/AutoRules.vue
@@ -5,31 +5,10 @@
Approval Rules
</div>
<div class="flex justify-center">
- <nav aria-label="Pagination">
- <ul class="inline-flex items-center space-x-1 text-sm rounded-md">
- <li>
- <button @click="prev" class="page-btn">
- <fa-icon icon="chevron-left" class="w-4" />
- </button>
- </li>
- <li>
- <span class="inline-flex items-center px-4 py-2 space-x-1 rounded-md">
- Page
- <b class="mx-1">{{ currentPage }}</b>
- of
- <b class="ml-1">{{ pageCount }}</b>
- </span>
- </li>
- <li>
- <button @click="next" class="page-btn">
- <fa-icon icon="chevron-right" class="w-4" />
- </button>
- </li>
- </ul>
- </nav>
+ <pagination :pages="pages" />
</div>
</div>
- <div class="">
+ <div class="mt-1">
<table class="min-w-full text-sm divide-y-2 divide-gray-200 dark:divide-dark-500">
<thead class="text-left bg-gray-50 dark:bg-dark-700">
<tr>
@@ -40,7 +19,7 @@
Origin
</th>
<th class="p-2 font-medium whitespace-nowrap dark:text-white">
- Time
+ Expires
</th>
<th class="p-2"></th>
</tr>
@@ -52,10 +31,12 @@
{{ rule.type }}
</td>
<td class="p-2 whitespace-nowrap">
- {{ rule.origin }}
+ <a :href="rule.origin" target="_blank" class="text-blue-500 hover:underline">
+ {{ rule.origin }}
+ </a>
</td>
<td class="p-2 whitespace-nowrap">
- {{ createShortDateAndTime(rule) }}
+ {{ getExpiration(rule) }}
</td>
<td class="p-2 text-right whitespace-nowrap">
<div class="button-group">
@@ -73,7 +54,7 @@
<script setup lang="ts">
import { computed } from 'vue';
-import { get, useOffsetPagination } from '@vueuse/core';
+import { formatTimeAgo, get, useOffsetPagination } from '@vueuse/core';
import { } from '@headlessui/vue'
import { useStore } from '../../store';
import { storeToRefs } from 'pinia';
@@ -85,13 +66,13 @@ const { } = storeToRefs(store)
const rules = computed(() => store.permissions.rules)
-const { next, prev, currentPage, currentPageSize, pageCount } = useOffsetPagination({
+const pages = useOffsetPagination({
pageSize: 10,
total: computed(() => rules.value.length)
})
const currentRulePage = computed(() => {
- const start = (get(currentPage) - 1) * get(currentPageSize)
+ const start = (get(pages.currentPage) - 1) * get(pages.currentPageSize)
const end = start + 10
return slice(rules.value, start, end)
})
@@ -100,18 +81,13 @@ const deleteRule = (rule: AutoAllowRule) => {
store.plugins.permission.deleteRule(rule)
}
-const createShortDateAndTime = (request: { timestamp: number}) => {
- const date = new Date(request.timestamp)
- const hours = date.getHours()
- const minutes = date.getMinutes()
- const seconds = date.getSeconds()
- const day = date.getDate()
- const month = date.getMonth() + 1
- const year = date.getFullYear()
- return `${month}/${day}/${year} ${hours}:${minutes}:${seconds}`
+const getExpiration = (rule: AutoAllowRule) => {
+ if (!rule.expires) {
+ return "Never"
+ }
+ return formatTimeAgo(new Date(rule.expires))
}
-
</script>
<style lang="scss">
diff --git a/extension/src/entries/options/components/EvHistoryTable.vue b/extension/src/entries/options/components/EvHistoryTable.vue
index 6ea6cac..a0e2f30 100644
--- a/extension/src/entries/options/components/EvHistoryTable.vue
+++ b/extension/src/entries/options/components/EvHistoryTable.vue
@@ -1,5 +1,5 @@
<template>
- <table class="min-w-full divide-y-2 divide-gray-200 dark:divide-dark-500">
+ <table class="min-w-full divide-y-2 divide-gray-200 dark:divide-dark-500">
<thead class="text-left bg-gray-50 dark:bg-dark-700">
<tr>
<th class="p-2 font-medium whitespace-nowrap dark:text-white">
@@ -21,7 +21,9 @@
{{ req.requestType }}
</td>
<td class="p-2 whitespace-nowrap">
- {{ req.origin }}
+ <a :href="req.origin" target="_blank" class="text-blue-500 hover:underline">
+ {{ req.origin }}
+ </a>
</td>
<td class="p-2 whitespace-nowrap">
{{ createShortDateAndTime(req) }}
diff --git a/extension/src/entries/options/components/EventHistory.vue b/extension/src/entries/options/components/EventHistory.vue
index 0711ae6..b6cd13e 100644
--- a/extension/src/entries/options/components/EventHistory.vue
+++ b/extension/src/entries/options/components/EventHistory.vue
@@ -1,126 +1,152 @@
<template>
- <div id="ev-history" class="flex flex-col w-full mt-4 sm:px-2">
- <form @submit.prevent="">
- <div class="w-full max-w-xl mx-auto">
- <h3 class="text-center">
- Permissions
- </h3>
-
- <div class="flex flex-row justify-between mt-4">
- <div class="font-bold">
- Pending
- </div>
- <div class="flex justify-center">
- </div>
- </div>
-
- <div class="my-6 ">
- <EvHistoryTable :readonly="false" :requests="pending" @deny="deny" @approve="approve" />
- </div>
-
- <AutoRules />
-
- <div class="flex flex-row justify-between mt-16">
- <div class="font-bold">
- History
- </div>
- <div class="flex justify-center">
- <nav aria-label="Pagination">
- <ul class="inline-flex items-center space-x-1 text-sm rounded-md">
- <li>
- <button @click="prev" class="page-btn">
- <fa-icon icon="chevron-left" class="w-4" />
- </button>
- </li>
- <li>
- <span class="inline-flex items-center px-4 py-2 space-x-1 rounded-md">
- Page
- <b class="mx-1">{{ currentPage }}</b>
- of
- <b class="ml-1">{{ pageCount }}</b>
- </span>
- </li>
- <li>
- <button @click="next" class="page-btn">
- <fa-icon icon="chevron-right" class="w-4" />
- </button>
- </li>
- </ul>
- </nav>
- </div>
- </div>
-
- <div class="mt-1">
- <EvHistoryTable :readonly="true" :requests="evHistoryCurrentPage" @deny="deny" @approve="approve" />
- </div>
-
- <div class="mt-4 ml-auto w-fit">
- <button class="rounded btn sm red" @click="clearHistory">
- Delete History
- </button>
- </div>
+ <div class="">
+ <div class="flex flex-row justify-between mt-16">
+ <div class="font-bold">
+ Event History
</div>
- </form>
+ <div class="flex justify-center">
+ <pagination :pages="pagination" />
+ </div>
+ </div>
+ <div class="">
+ <table class="min-w-full text-sm divide-y-2 divide-gray-200 dark:divide-dark-500">
+ <thead class="text-left bg-gray-50 dark:bg-dark-700">
+ <tr>
+ <th class="pl-2"></th>
+ <th class="p-2 font-medium whitespace-nowrap dark:text-white">
+ Event
+ </th>
+ <th class="p-2 font-medium whitespace-nowrap dark:text-white">
+ Time
+ </th>
+ <th class="p-2"></th>
+ </tr>
+ </thead>
+
+ <tbody class="divide-y divide-gray-200 dark:divide-dark-500">
+ <tr v-for="event in evHistory" :key="event.Id" class="">
+ <td class="pl-2 whitespace-nowrap">
+ <div class="flex flex-col items-end gap-0.5">
+ <div class="">
+ ID:
+ </div>
+ <div class="">
+ EventId:
+ </div>
+ <div class="">
+ PubKey:
+ </div>
+ <div class="">
+ Content:
+ </div>
+ </div>
+ </td>
+ <td class="p-2">
+ <div class="flex flex-col flex-1 gap-0.5">
+ <div class="truncate overflow-ellipsis">
+ {{ event.Id }}
+ </div>
+
+ <div class="truncate overflow-ellipsis">
+ {{ event.id }}
+ </div>
+
+ <div class="truncate overflow-ellipsis">
+ <a href="#" @click="goToKeyView(event)" class="text-blue-500 hover:underline">
+ {{ event.pubkey }}
+ </a>
+ </div>
+ <div class="truncate overflow-ellipsis">
+ {{ event.content }}
+ </div>
+ </div>
+ </td>
+ <td class="p-2 whitespace-nowrap">
+ {{ timeAgo(event, timeStamp) }}
+ </td>
+ <td class="p-2 text-right whitespace-nowrap">
+ <div class="button-group">
+ <button class="rounded btn xs" @click="deleteEvent(event)">
+ <fa-icon icon="trash" />
+ </button>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
</div>
</template>
<script setup lang="ts">
-import { useConfirm } from '@vnuge/vnlib.browser';
+import { apiCall } from '@vnuge/vnlib.browser';
import { computed } from 'vue';
-import { get, useOffsetPagination } from '@vueuse/core';
-import { } from '@headlessui/vue'
+import { formatTimeAgo, get, useOffsetPagination, useTimestamp } from '@vueuse/core';
+import { } from '@headlessui/vue'
import { useStore } from '../../store';
-import { PermissionRequest, PrStatus } from '../../../features';
-import EvHistoryTable from './EvHistoryTable.vue';
-import { filter, slice } from 'lodash';
-import AutoRules from './AutoRules.vue';
+import { EventEntry, NostrEvent } from '../../../features';
+import { map, slice } from 'lodash';
+import { useQuery } from '../../../features/util';
const store = useStore()
-const { reveal } = useConfirm()
-
-const pending = computed(() => store.permissions.pending)
-const notPending = computed(() => filter(store.permissions.all, r => r.status !== PrStatus.Pending))
-const deny = (request: PermissionRequest) => {
- if(request.status !== PrStatus.Pending) return
- //push deny to store
- store.plugins.permission.deny(request.uuid)
-}
+const tabId = useQuery('t');
+const keyId = useQuery('kid');
-const approve = (request: PermissionRequest) => {
- if(request.status !== PrStatus.Pending) return
- //push allow to store
- store.plugins.permission.allow(request.uuid, false)
-}
-
-const { next, prev, currentPage, currentPageSize, pageCount } = useOffsetPagination({
+const pagination = useOffsetPagination({
pageSize: 10,
- total: computed(() => notPending.value.length)
+ total: computed(() => store.eventHistory.length)
})
-const evHistoryCurrentPage = computed(() => {
- const start = (get(currentPage) - 1) * get(currentPageSize)
+const explodeNote = (event: EventEntry) => JSON.parse(event.EventData) as NostrEvent
+
+const timeStamp = useTimestamp({interval: 1000})
+
+const evHistory = computed<Array<NostrEvent & EventEntry>>(() => {
+ const start = (get(pagination.currentPage) - 1) * get(pagination.currentPageSize)
const end = start + 10
- return slice(notPending.value, start, end)
+ const page = slice(store.eventHistory, start, end)
+ return map(page, event => {
+ const exploded = explodeNote(event)
+ return {
+ ...event,
+ ...exploded
+ }
+ })
})
-const clearHistory = async () => {
- const { isCanceled } = await reveal({
- title: 'Clear History',
- text: 'Are you sure you want to clear your event history?',
- })
- if(isCanceled) return
+const deleteEvent = (event: EventEntry) => {
+ //Call delete event function
+ apiCall(() => store.plugins.history.deleteEvent(event))
+}
+
+const createShortDateAndTime = (request: EventEntry) => {
+ const date = new Date(request.Created)
+ const hours = date.getHours()
+ const minutes = date.getMinutes()
+ const seconds = date.getSeconds()
+ const day = date.getDate()
+ const month = date.getMonth() + 1
+ const year = date.getFullYear()
+ return `${month}/${day}/${year} ${hours}:${minutes}:${seconds}`
+}
+
+const timeAgo = (entry: EventEntry, timeStamp: number) => {
+ return formatTimeAgo(new Date(entry.Created), { }, timeStamp)
+}
- //Clear all history
- store.plugins.permission.clearRequests()
+const goToKeyView = (key: { KeyId:string }) => {
+ //Show tab0 and set key
+ tabId.set('0')
+ keyId.set(key.KeyId);
}
</script>
<style lang="scss">
-#ev-history{
- button.page-btn{
+#ev-history {
+ button.page-btn {
@apply inline-flex items-center px-2 py-2 space-x-2 font-medium rounded-full;
@apply bg-white border border-gray-300 rounded-full hover:bg-gray-50 dark:bg-dark-600 dark:hover:bg-dark-500 dark:border-dark-300;
}
diff --git a/extension/src/entries/options/components/Identities.vue b/extension/src/entries/options/components/Identities.vue
index b7765be..8236b83 100644
--- a/extension/src/entries/options/components/Identities.vue
+++ b/extension/src/entries/options/components/Identities.vue
@@ -40,7 +40,7 @@
</div>
<div class="">
<div class="">
- <button class="rounded btn sm" @click="store.refreshIdentities()">
+ <button class="rounded btn sm" @click="identity.refreshKeys()">
<fa-icon icon="refresh" class="" />
</button>
</div>
@@ -89,8 +89,8 @@
<script setup lang="ts">
-import { isEqual, map } from 'lodash'
-import { ref } from "vue";
+import { find, isEqual, map } from 'lodash'
+import { computed, ref } from "vue";
import {
Popover,
PopoverButton,
@@ -103,6 +103,7 @@ import { notify } from "@kyvg/vue3-notification";
import { get, useClipboard } from '@vueuse/core';
import { useStore } from '../../store';
import { storeToRefs } from 'pinia';
+import { useQuery } from '../../../features/util';
const emit = defineEmits(['edit-key'])
@@ -111,13 +112,23 @@ configureNotifier({ notify, close: notify.close })
const downloadAnchor = ref<HTMLAnchorElement>()
const store = useStore()
-const { selectedKey, allKeys } = storeToRefs(store)
+const { identity } = store.plugins
+const { selectedKey } = storeToRefs(store)
const { copy } = useClipboard()
const { reveal } = useConfirm()
+const query = useQuery('kid')
const isSelected = (me : NostrPubKey) => isEqual(me, selectedKey.value)
const editKey = (key : NostrPubKey) => emit('edit-key', key);
-const selectKey = (key: NostrPubKey) => store.selectKey(key)
+const selectKey = (key: NostrPubKey) => identity.selectKey(key)
+const allKeys = computed(() => {
+ const q = query.get();
+ if(q){
+ const val = find(store.allKeys, k => k.Id === q || k.PubKey === q)
+ return val ? [val] : []
+ }
+ return store.allKeys
+})
const onCreate = async (e: Event, onClose : () => void) => {
@@ -128,7 +139,7 @@ const onCreate = async (e: Event, onClose : () => void) => {
await apiCall(async () => {
//Create new identity
- await store.createIdentity({ UserName, ExistingKey })
+ await identity.createIdentity({ UserName, ExistingKey })
})
onClose()
@@ -157,7 +168,7 @@ const onDeleteKey = async (key : NostrPubKey) => {
apiCall(async ({ toaster }) => {
//Delete identity
- await store.deleteIdentity(key)
+ await identity.deleteIdentity(key)
toaster.general.success({
'title': 'Success',
'text': `${key.UserName} has been deleted`
@@ -169,7 +180,7 @@ const onNip05Download = () => {
apiCall(async () => {
//Get all public keys from the server
const keys = get(allKeys)
- const nip05 = {}
+ const nip05 = {} as any;
//Map the keys to the NIP-05 format
map(keys, k => nip05[k.UserName] = k.PublicKey)
//create file blob
diff --git a/extension/src/entries/options/components/SiteSettings.vue b/extension/src/entries/options/components/SiteSettings.vue
index 17f41c4..a2df205 100644
--- a/extension/src/entries/options/components/SiteSettings.vue
+++ b/extension/src/entries/options/components/SiteSettings.vue
@@ -47,6 +47,24 @@
</div>
</div>
</div>
+ <div class="mt-3">
+ <div class="flex flex-row w-fit">
+ <Switch
+ v-model="v$.authPopup.$model"
+ :class="v$.authPopup.$model ? 'bg-black dark:bg-white' : 'bg-gray-200 dark:bg-dark-600'"
+ class="relative inline-flex items-center h-5 mx-auto rounded-full w-11"
+ >
+ <span class="sr-only">Permissions Popup</span>
+ <span
+ :class="v$.authPopup.$model ? 'translate-x-6' : 'translate-x-1'"
+ class="inline-block w-4 h-4 transition transform rounded-full bg-gray-50 dark:bg-dark-900"
+ />
+ </Switch>
+ <div class="my-auto ml-2 text-sm dark:text-gray-200">
+ Permissions Popup
+ </div>
+ </div>
+ </div>
</fieldset>
</div>
<h3 class="text-center">
@@ -165,6 +183,7 @@ const vRules = {
maxLength: maxLength(50),
alphaNum: helpers.withMessage('Nostr path is not a valid endpoint path that begins with /', path)
},
+ authPopup: {},
heartbeat: {},
}
@@ -176,6 +195,7 @@ const [ editMode, toggleEdit ] = useToggle(false);
const autoInject = computed(() => buffer.autoInject)
const heartbeat = computed(() => buffer.heartbeat)
+const authPopup = computed(() => buffer.authPopup)
const onSave = async () => {
@@ -218,6 +238,7 @@ const testConnection = async () =>{
//Watch for changes to autoinject value and publish changes when it does
watchDebounced(autoInject, update, { debounce: 500, immediate: false })
watchDebounced(heartbeat, update, { debounce: 500, immediate: false })
+watchDebounced(authPopup, update, { debounce: 500, immediate: false })
</script>
diff --git a/extension/src/entries/options/main.js b/extension/src/entries/options/main.js
index 3dd01cb..901dfdd 100644
--- a/extension/src/entries/options/main.js
+++ b/extension/src/entries/options/main.js
@@ -19,6 +19,7 @@ import App from "./App.vue";
import '@fontsource/noto-sans-masaram-gondi'
import "~/assets/all.scss";
import Notifications from "@kyvg/vue3-notification";
+import Pagination from '../../components/Pagination.vue';
/* FONT AWESOME CONFIG */
import { library } from '@fortawesome/fontawesome-svg-core'
@@ -43,4 +44,5 @@ createApp(App)
.use(Notifications)
.use(pinia)
.component('fa-icon', FontAwesomeIcon)
+ .component('pagination', Pagination)
.mount("#app");
diff --git a/extension/src/entries/popup/Components/IdentitySelection.vue b/extension/src/entries/popup/Components/IdentitySelection.vue
index eb08fb1..06d09a5 100644
--- a/extension/src/entries/popup/Components/IdentitySelection.vue
+++ b/extension/src/entries/popup/Components/IdentitySelection.vue
@@ -12,7 +12,7 @@
</select>
</div>
<div class="my-auto">
- <button class="btn sm borderless" @click="store.refreshIdentities()">
+ <button class="btn sm borderless" @click="store.plugins.identity.refreshKeys()">
<fa-icon icon="refresh" class="" />
</button>
</div>
@@ -35,7 +35,7 @@ const onSelected = async ({target}) =>{
//Select the key of the given id
const selected = find(allKeys.value, {Id: target.value})
if(selected){
- await store.selectKey(selected)
+ await store.plugins.identity.selectKey(selected)
}
}
diff --git a/extension/src/entries/store/features.ts b/extension/src/entries/store/features.ts
index ad83e16..d714ac6 100644
--- a/extension/src/entries/store/features.ts
+++ b/extension/src/entries/store/features.ts
@@ -68,7 +68,7 @@ const usePlugins = (context: ChannelContext) => {
export const useBackgroundPiniaPlugin = (context: ChannelContext) => {
//Create port for context
const plugins = usePlugins(context)
- const { user } = plugins;
+ const { user, settings, history } = plugins;
//Plugin store
return ({ store }: PiniaPluginContext) => {
@@ -84,10 +84,15 @@ export const useBackgroundPiniaPlugin = (context: ChannelContext) => {
}, { immediate: true })
//Wait for settings changes
- onWatchableChange(plugins.settings, async () => {
+ onWatchableChange(settings, async () => {
//Update settings and dark mode on change
- store.settings = await plugins.settings.getSiteConfig();
- store.darkMode = await plugins.settings.getDarkMode();
+ store.settings = await settings.getSiteConfig();
+ store.darkMode = await settings.getDarkMode();
+ }, { immediate: true })
+
+ onWatchableChange(history, async () => {
+ //Load event history
+ store.eventHistory = await history.getEvents();
}, { immediate: true })
return{
diff --git a/extension/src/entries/store/identity.ts b/extension/src/entries/store/identity.ts
index ade7c94..ed01f6b 100644
--- a/extension/src/entries/store/identity.ts
+++ b/extension/src/entries/store/identity.ts
@@ -22,12 +22,7 @@ import { shallowRef } from 'vue';
declare module 'pinia' {
export interface PiniaCustomStateProperties {
allKeys: NostrPubKey[];
- selectedKey: NostrPubKey | undefined;
- deleteIdentity(key: Partial<NostrPubKey>): Promise<void>;
- createIdentity(id: Partial<NostrPubKey>): Promise<NostrPubKey>;
- updateIdentity(id: NostrPubKey): Promise<NostrPubKey>;
- selectKey(key: NostrPubKey): Promise<void>;
- refreshIdentities(): Promise<void>;
+ selectedKey: NostrPubKey | undefined;
}
}
diff --git a/extension/src/entries/store/index.ts b/extension/src/entries/store/index.ts
index 8be57ff..0b4d3cd 100644
--- a/extension/src/entries/store/index.ts
+++ b/extension/src/entries/store/index.ts
@@ -31,8 +31,9 @@ export const useStore = defineStore({
state: (): NostrStoreState =>({
loggedIn: false,
userName: '',
- settings: undefined as any,
- darkMode: false
+ settings: {} as any,
+ darkMode: false,
+ eventHistory: [],
}),
actions: {
diff --git a/extension/src/entries/store/types.ts b/extension/src/entries/store/types.ts
index 7addda4..536cf04 100644
--- a/extension/src/entries/store/types.ts
+++ b/extension/src/entries/store/types.ts
@@ -1,9 +1,10 @@
import { } from "webextension-polyfill";
-import { PluginConfig } from "../../features";
+import type { PluginConfig, EventEntry } from "../../features";
export interface NostrStoreState {
loggedIn: boolean;
userName: string | null;
settings: PluginConfig;
darkMode: boolean;
+ eventHistory: EventEntry[];
} \ No newline at end of file
diff --git a/extension/src/features/auth-api.ts b/extension/src/features/auth-api.ts
index fbc9420..4e4d0ed 100644
--- a/extension/src/features/auth-api.ts
+++ b/extension/src/features/auth-api.ts
@@ -22,7 +22,7 @@ import { IMfaFlowContinuiation, totpMfaProcessor, useMfaLogin, usePkiAuth, useSe
} from "@vnuge/vnlib.browser";
import { type FeatureApi, type BgRuntime, type IFeatureExport, exportForegroundApi, popupAndOptionsOnly, popupOnly } from "./framework";
import { waitForChangeFn } from "./util";
-import type { ClientStatus } from "./types";
+import type { ClientStatus, Watchable } from "./types";
import type { AppSettings } from "./settings";
import type { JsonObject } from "type-fest";
@@ -39,12 +39,11 @@ export interface ApiMessageHandler<T extends JsonObject> {
(message: T, apiHandle: { axios: AxiosInstance }): Promise<any>
}
-export interface UserApi extends FeatureApi {
+export interface UserApi extends FeatureApi, Watchable {
login(username: string, password?: string): Promise<boolean>
logout: () => Promise<void>
getProfile: () => Promise<any>
getStatus: () => Promise<ClientStatus>
- waitForChange: () => Promise<void>
submitMfa: (submission: IMfaSubmission) => Promise<boolean>
}
diff --git a/extension/src/features/framework/index.ts b/extension/src/features/framework/index.ts
index b545335..755d27e 100644
--- a/extension/src/features/framework/index.ts
+++ b/extension/src/features/framework/index.ts
@@ -25,6 +25,7 @@ export interface BgRuntime<T> {
readonly state: T;
onInstalled(callback: () => Promise<void>): void;
onConnected(callback: () => Promise<void>): void;
+ openBackChannel<T extends FeatureApi>(name: string, callback: (feature: T | undefined) => void): void;
}
export type FeatureApi = {
@@ -84,6 +85,8 @@ export const protectMethod = <T extends Function>(func: T, ...protection: Channe
return func;
}
+type BgCallback = (feature: FeatureApi | undefined) => void
+
/**
* Creates a background runtime context for registering background
* script feature api handlers
@@ -92,12 +95,26 @@ export const useBackgroundFeatures = <TState>(state: TState): IBackgroundWrapper
const { openOnMessageChannel } = createMessageChannel('background');
const { onMessage } = openOnMessageChannel()
+
+ const backChannels = new Map<string, BgCallback>()
+
+ const openBackChannel = async (name: string, callback: BgCallback) => {
+ backChannels.set(name, callback)
+ }
+ const notifyBackChannels = (pool: Map<string, FeatureApi>) => {
+ //Loop through all features
+ for (const [name, waiter] of backChannels.entries()){
+ //Notify the waiter of the feature
+ waiter(pool.get(name))
+ }
+ }
const rt = {
state,
onConnected: runtime.onConnect.addListener,
onInstalled: runtime.onInstalled.addListener,
+ openBackChannel
} as BgRuntime<TState>
/**
@@ -109,12 +126,18 @@ export const useBackgroundFeatures = <TState>(state: TState): IBackgroundWrapper
return{
register: <TFeature extends FeatureApi>(features: FeatureConstructor<TState, TFeature>[]) => {
+
+ const featurePool = new Map<string, FeatureApi>()
+
//Loop through features
for (const feature of features) {
//Init feature
const f = feature().background(rt)
+ //Add to pool
+ featurePool.set(feature.name, f)
+
//Get all exported function
for (const externFuncName in f) {
@@ -155,6 +178,9 @@ export const useBackgroundFeatures = <TState>(state: TState): IBackgroundWrapper
});
}
}
+
+ //Notify all back channels that the load is complete
+ notifyBackChannels(featurePool)
}
}
}
diff --git a/extension/src/features/history.ts b/extension/src/features/history.ts
index 82f31c4..e00a9af 100644
--- a/extension/src/features/history.ts
+++ b/extension/src/features/history.ts
@@ -13,29 +13,67 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
-import { ref } from "vue";
-import { } from "./types";
-import { FeatureApi, BgRuntime, IFeatureExport } from "./framework";
+import { shallowRef } from "vue";
+import { watchDebounced, set, get, useToggle } from '@vueuse/core'
+import { EventEntry, NostrEvent, Watchable } from "./types";
+import { FeatureApi, BgRuntime, IFeatureExport, exportForegroundApi, optionsOnly } from "./framework";
import { AppSettings } from "./settings";
+import { waitForChangeFn } from "./util";
+import { Endpoints } from "./server-api";
+import { useSession } from "@vnuge/vnlib.browser";
+import { } from "lodash";
-export interface HistoryEvent extends Object{
-
+export interface SignedNEvent extends NostrEvent {
+ readonly signature: string
}
-export interface HistoryApi extends FeatureApi{
-
+export interface HistoryApi extends FeatureApi, Watchable{
+ getEvents: () => Promise<EventEntry[]>;
+ deleteEvent: (entry: EventEntry) => Promise<void>;
+ refresh: () => Promise<void>;
}
export const useHistoryApi = () : IFeatureExport<AppSettings, HistoryApi> => {
return{
- background: ({ }: BgRuntime<AppSettings>): HistoryApi =>{
- const evHistory = ref([]);
+ background: ({ state }: BgRuntime<AppSettings>): HistoryApi =>{
+ const { loggedIn } = useSession();
+ const { execRequest } = state.useServerApi();
+ const [ onRefresh, refresh ] = useToggle()
+
+ const history = shallowRef<EventEntry[]>([]);
+
+ //Watch for login changes and manual refreshes
+ watchDebounced([loggedIn, onRefresh], async ([li]) => {
+
+ if(!li){
+ set(history, [])
+ return
+ }
+
+ //load history from server
+ history.value = await execRequest(Endpoints.GetHistory);
+
+ }, { debounce: 1000 })
+
+ return{
+ waitForChange:waitForChangeFn([history]),
- return{ }
+ getEvents: () => Promise.resolve(history.value),
+ deleteEvent: optionsOnly(async (entry: EventEntry) => {
+ await execRequest(Endpoints.DeleteSingleEvent, entry)
+ refresh()
+ }),
+ refresh () {
+ refresh()
+ return Promise.resolve()
+ }
+ }
},
- foreground: (): HistoryApi =>{
- return { }
- }
+ foreground: exportForegroundApi<HistoryApi>([
+ 'waitForChange',
+ 'getEvents',
+ 'deleteEvent',
+ ])
}
}
diff --git a/extension/src/features/identity-api.ts b/extension/src/features/identity-api.ts
index 0b8973d..73f7ab2 100644
--- a/extension/src/features/identity-api.ts
+++ b/extension/src/features/identity-api.ts
@@ -28,10 +28,10 @@ import { shallowRef } from "vue";
import { useSession } from "@vnuge/vnlib.browser";
import { set, useToggle, watchDebounced } from "@vueuse/core";
import { isArray } from "lodash";
-import { waitForChange, waitForChangeFn } from "./util";
+import { waitForChangeFn } from "./util";
export interface IdentityApi extends FeatureApi, Watchable {
- createIdentity: (identity: NostrPubKey) => Promise<NostrPubKey>
+ createIdentity: (identity: Partial<NostrPubKey>) => Promise<NostrPubKey>
updateIdentity: (identity: NostrPubKey) => Promise<NostrPubKey>
deleteIdentity: (key: NostrPubKey) => Promise<void>
getAllKeys: () => Promise<NostrPubKey[]>;
@@ -65,9 +65,7 @@ export const useIdentityApi = (): IFeatureExport<AppSettings, IdentityApi> => {
selectedKey.value = undefined;
}
- //Wait for changes to trigger a new key-load
- await waitForChange([ loggedIn, onKeyUpdateTriggered ])
- }, { debounce: 100 })
+ }, { debounce: 100, immediate: true })
return {
//Identity is only available in options context
diff --git a/extension/src/features/index.ts b/extension/src/features/index.ts
index 0a8e182..d7e1b05 100644
--- a/extension/src/features/index.ts
+++ b/extension/src/features/index.ts
@@ -14,7 +14,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//Export all shared types
-export type { NostrPubKey, LoginMessage } from './types'
+export type { NostrPubKey, LoginMessage, NostrEvent, NostrRelay, EventEntry } from './types'
export type * from './framework'
export type { PluginConfig } from './settings'
export type { PkiPubKey, EcKeyParams, LocalPkiApi as PkiApi } from './pki-api'
@@ -33,6 +33,6 @@ export { useSettingsApi, useAppSettings } from './settings'
export { useHistoryApi } from './history'
export { useEventTagFilterApi } from './tagfilter-api'
export { useInjectAllowList } from './nip07allow-api'
-export { onWatchableChange } from './util'
+export { onWatchableChange, waitOne, useQuery } from './util'
export { useMfaConfigApi } from './mfa-api'
-export { usePermissionApi, PrStatus } from './permissions' \ No newline at end of file
+export { usePermissionApi, PrStatus, CreateRuleType } from './permissions' \ No newline at end of file
diff --git a/extension/src/features/nip07allow-api.ts b/extension/src/features/nip07allow-api.ts
index 4787437..89639d1 100644
--- a/extension/src/features/nip07allow-api.ts
+++ b/extension/src/features/nip07allow-api.ts
@@ -20,7 +20,7 @@ import { BgRuntime, FeatureApi, IFeatureExport, exportForegroundApi, popupAndOpt
import { AppSettings } from "./settings";
import { set, get, toRefs } from "@vueuse/core";
import { computed, shallowRef } from "vue";
-import { waitForChangeFn } from "./util";
+import { waitForChangeFn, push, remove } from "./util";
interface AllowedSites{
origins: string[];
@@ -99,7 +99,7 @@ export const useInjectAllowList = (): IFeatureExport<AppSettings, InjectAllowlis
//See if origin is already in the list
if (!includes(origins.value, originOnly)) {
//Add to the list
- origins.value.push(originOnly);
+ push(origins, originOnly);
//If current tab was added, reload the tab
if (!origin) {
@@ -117,10 +117,9 @@ export const useInjectAllowList = (): IFeatureExport<AppSettings, InjectAllowlis
//Get origin part of url
const delOriginOnly = new URL(delOrigin).origin
- const allowList = get(origins)
//Remove the origin
- origins.value = filter(allowList, (o) => !isEqual(o, delOriginOnly));
+ remove(origins, delOriginOnly)
//If current tab was removed, reload the tab
if (!origin) {
diff --git a/extension/src/features/nostr-api.ts b/extension/src/features/nostr-api.ts
index 4aee660..7f1bedf 100644
--- a/extension/src/features/nostr-api.ts
+++ b/extension/src/features/nostr-api.ts
@@ -17,8 +17,9 @@ import { cloneDeep } from "lodash";
import { Endpoints } from "./server-api";
import { type FeatureApi, type BgRuntime, type IFeatureExport, optionsOnly, exportForegroundApi } from "./framework";
import { type AppSettings } from "./settings";
-import { useTagFilter } from "./tagfilter-api";
+import { EventTagFilterApi } from "./tagfilter-api";
import type { NostrRelay, EncryptionRequest, NostrEvent } from './types';
+import { HistoryApi } from "./history";
/**
@@ -36,10 +37,16 @@ export interface NostrApi extends FeatureApi {
export const useNostrApi = (): IFeatureExport<AppSettings, NostrApi> => {
return{
- background: ({ state }: BgRuntime<AppSettings>) =>{
+ background: ({ state, openBackChannel }: BgRuntime<AppSettings>) =>{
const { execRequest } = state.useServerApi();
- const { filterTags } = useTagFilter(state)
+
+ let tagFilter: EventTagFilterApi | undefined;
+ let evHistory: HistoryApi | undefined;
+
+ //Register for tag filter, and history back channel
+ openBackChannel<EventTagFilterApi>('useEventTagFilterApi', (feature) => tagFilter = feature)
+ openBackChannel<HistoryApi>('useHistoryApi', (feature) => evHistory = feature)
return {
getRelays: async (): Promise<NostrRelay[]> => {
@@ -50,16 +57,21 @@ export const useNostrApi = (): IFeatureExport<AppSettings, NostrApi> => {
signEvent: async (req: NostrEvent): Promise<NostrEvent | undefined> => {
//Store copy to prevent mutation
- req = cloneDeep(req)
+ const event = cloneDeep(req)
//If tag filter is enabled, filter before continuing
- if(state.currentConfig.value.tagFilter){
- await filterTags(req)
+ if (tagFilter){
+ //Filter tags
+ await tagFilter.filterTags(event);
}
//Sign the event
- const event = await execRequest(Endpoints.SignEvent, req);
- return event;
+ const result = await execRequest(Endpoints.SignEvent, event);
+
+ //Refresh history
+ evHistory?.refresh();
+
+ return result;
},
nip04Encrypt: async (data: EncryptionRequest): Promise<string> => {
const message: EncryptionRequest = {
diff --git a/extension/src/features/permissions.ts b/extension/src/features/permissions.ts
index 5473962..82b023f 100644
--- a/extension/src/features/permissions.ts
+++ b/extension/src/features/permissions.ts
@@ -13,13 +13,13 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
-import { Mutable, get, set, toRefs } from "@vueuse/core";
+import { Mutable, get, set, toRefs, useTimestamp } from "@vueuse/core";
import { Ref } from "vue";
import { defaultTo, defaults, defer, filter, find, forEach, isEqual, isNil } from "lodash";
import { nanoid } from "nanoid";
-import { useSession } from "@vnuge/vnlib.browser";
+import { debugLog, useSession } from "@vnuge/vnlib.browser";
import { type FeatureApi, type BgRuntime, type IFeatureExport, exportForegroundApi, optionsOnly } from "./framework";
-import { waitForChangeFn, waitOne } from "./util";
+import { remove, waitForChangeFn, waitOne } from "./util";
import { windows, runtime, Windows, tabs } from "webextension-polyfill";
import type { TotpUpdateMessage, Watchable } from "./types";
import type { AppSettings } from "./settings";
@@ -27,6 +27,7 @@ import type { AppSettings } from "./settings";
export interface AutoAllowRule{
origin: string
type: string
+ readonly expires?: number
readonly timestamp: number
}
@@ -37,6 +38,16 @@ export enum PrStatus{
Denied
}
+export enum CreateRuleType{
+ AllowOnce,
+ AllowForever,
+ FiveMinutes,
+ OneHour,
+ OneDay,
+ OneWeek,
+ OneMonth,
+}
+
export interface PermissionRequest{
readonly uuid: string
readonly origin: string
@@ -49,7 +60,7 @@ export type MfaUpdateResult = TotpUpdateMessage
export interface PermissionApi extends FeatureApi, Watchable {
getRequests(): Promise<PermissionRequest[]>
- allow(requestId: string, addRule: boolean): Promise<void>
+ allow(requestId: string, addRule: CreateRuleType): Promise<void>
deny(requestId: string): Promise<void>
clearRequests(): Promise<void>
requestAndWaitResult(request: Partial<PermissionRequest>): Promise<PrStatus>
@@ -67,6 +78,24 @@ interface RuleSlot{
rules: AutoAllowRule[]
}
+const setExpirationRule = (expType: CreateRuleType): { expires?: number } => {
+ switch (expType) {
+ case CreateRuleType.AllowOnce:
+ case CreateRuleType.AllowForever:
+ return { }
+ case CreateRuleType.FiveMinutes:
+ return { expires: Date.now() + (5 * 60 * 1000) };
+ case CreateRuleType.OneHour:
+ return { expires: Date.now() + (60 * 60 * 1000) };
+ case CreateRuleType.OneDay:
+ return { expires: Date.now() + (24 * 60 * 60 * 1000) };
+ case CreateRuleType.OneWeek:
+ return { expires: Date.now() + (7 * 24 * 60 * 60 * 1000) };
+ case CreateRuleType.OneMonth:
+ return { expires: Date.now() + (30 * 24 * 60 * 60 * 1000) };
+ }
+}
+
const useRuleSet = (slot: Ref<RuleSlot>) => {
defaults(slot.value, { rules: [] })
@@ -76,6 +105,14 @@ const useRuleSet = (slot: Ref<RuleSlot>) => {
isAllowed: (request: PermissionRequest): boolean => {
//find existing rule
const rule = find(get(rules), r => isEqual(r.origin, request.origin) && isEqual(r.type, request.requestType))
+
+ //See if rule exists and is expired
+ if (rule && rule.expires && rule.expires < Date.now()) {
+ //remove expired rule
+ remove(rules, rule)
+ return false
+ }
+
return !isNil(rule)
},
addRule: (rule: Partial<AutoAllowRule>) => {
@@ -99,7 +136,12 @@ const useRuleSet = (slot: Ref<RuleSlot>) => {
const wo = filter(get(rules), r => !(isEqual(r.origin, rule.origin) && isEqual(r.type, rule.type)))
set(rules, wo)
},
- getRules:(): AutoAllowRule[] =>get(rules)
+ getRules:(): AutoAllowRule[] => {
+ //Filter all expired rules
+ const wo = filter(get(rules), r => !r.expires || r.expires > Date.now())
+ set(rules, wo)
+ return wo
+ }
}
}
@@ -110,41 +152,13 @@ const usePermissions = (slot: Ref<PermissionSlot>, rules: ReturnType<typeof useR
defaults(slot.value, { rules: [] })
const { requests } = toRefs(slot)
- const drawWindow = async ({ uuid }: Partial<PermissionRequest>): Promise<Windows.CreateCreateDataType> => {
- const current = await windows.getCurrent()
-
- const minWidth = 350
- const minHeight = 180
-
- const maxWidth = 500
- const maxHeight = 250
-
- const width = Math.min(Math.max(current.width! - 100, minWidth), maxWidth)
- const height = Math.min(Math.max(current.height! - 100, minHeight), maxHeight)
-
- //draw half way across screen minus half its width
- const left = current.left! + (current.width! / 2) - (width / 2)
-
- return {
- url: `${permPopupUrl}?uuid=${uuid}&closeable`,
- type: "popup",
- height: height,
- width: width,
- focused: true,
- allowScriptsToClose: true,
- top: 100,
- //try to center popup
- left: left,
- }
- }
-
const activePopups = new Map<number, PermissionRequest>()
const getRequest = (requestId: string): PermissionRequest | undefined => {
return find(get(requests), r => r.uuid === requestId)
}
- const updateRequest = (request: PermissionRequest, addRule: boolean) => {
+ const updateRequest = (request: PermissionRequest, addRule: CreateRuleType) => {
const current = get(requests)
const index = current.findIndex(r => r.uuid === request.uuid)
@@ -159,8 +173,14 @@ const usePermissions = (slot: Ref<PermissionSlot>, rules: ReturnType<typeof useR
set(requests, current)
//Add rule if needed
- if (addRule) {
- rules.addRule({ origin: request.origin, type: request.requestType })
+ switch (addRule) {
+ case CreateRuleType.AllowOnce:
+ //Do nothing
+ break;
+ //Compute expiration
+ default:
+ const { expires } = setExpirationRule(addRule);
+ rules.addRule({ origin: request.origin, type: request.requestType, expires })
}
}
@@ -173,6 +193,41 @@ const usePermissions = (slot: Ref<PermissionSlot>, rules: ReturnType<typeof useR
} as PermissionRequest
}
+ const showPermsWindow = async (request: PermissionRequest): Promise<void> => {
+
+ const drawWindow = async ({ uuid }: Partial<PermissionRequest>): Promise<Windows.CreateCreateDataType> => {
+ const current = await windows.getCurrent()
+
+ const minWidth = 350
+ const minHeight = 180
+
+ const maxWidth = 500
+ const maxHeight = 250
+
+ const width = Math.min(Math.max(current.width! - 100, minWidth), maxWidth)
+ const height = Math.min(Math.max(current.height! - 100, minHeight), maxHeight)
+
+ //draw half way across screen minus half its width
+ const left = current.left! + (current.width! / 2) - (width / 2)
+
+ return {
+ url: `${permPopupUrl}?uuid=${uuid}&closeable`,
+ type: "popup",
+ height: height,
+ width: width,
+ focused: true,
+ allowScriptsToClose: true,
+ top: 100,
+ //try to center popup
+ left: left,
+ }
+ }
+
+ const windowsArgs = await drawWindow(request)
+ const { id } = await windows.create(windowsArgs)
+ activePopups.set(id!, request)
+ }
+
//Listen for popup close to cleanup request
windows.onRemoved.addListener(async (id) => {
const req = activePopups.get(id)
@@ -199,12 +254,6 @@ const usePermissions = (slot: Ref<PermissionSlot>, rules: ReturnType<typeof useR
return{
getRequest,
- async showPermsWindow (request: PermissionRequest): Promise<void> {
- const windowsArgs = await drawWindow(request)
- const { id } = await windows.create(windowsArgs)
- activePopups.set(id!, request)
- },
-
pushRequest (request: Partial<PermissionRequest>, showPopup: boolean): PermissionRequest {
//Create new request
const req = initNewRequest(request)
@@ -223,13 +272,13 @@ const usePermissions = (slot: Ref<PermissionSlot>, rules: ReturnType<typeof useR
//Show popup if needed
if (showPopup) {
- this.showPermsWindow(req)
+ showPermsWindow(req)
}
return req
},
- allow (requestId: string, addRule: boolean): void {
+ allow(requestId: string, addRule: CreateRuleType): void {
const request = getRequest(requestId)
if(!request){
throw new Error("Request not found")
@@ -248,7 +297,7 @@ const usePermissions = (slot: Ref<PermissionSlot>, rules: ReturnType<typeof useR
//set denied
(request as Mutable<PermissionRequest>).status = PrStatus.Denied
//update request
- updateRequest(request, false)
+ updateRequest(request, CreateRuleType.AllowOnce)
},
clearAll: () => {
@@ -257,12 +306,13 @@ const usePermissions = (slot: Ref<PermissionSlot>, rules: ReturnType<typeof useR
//set denied
(r as Mutable<PermissionRequest>).status = PrStatus.Denied
//update request
- updateRequest(r, false)
+ updateRequest(r, CreateRuleType.AllowOnce)
})
//Then defer clear
defer(() => set(requests, []))
},
+
getAll: () => get(requests)
}
}
@@ -282,8 +332,11 @@ export const usePermissionApi = (): IFeatureExport<AppSettings, PermissionApi> =
const ruleSet = useRuleSet(ruleStore)
const permissions = usePermissions(reqStore, ruleSet)
+ //Computed current time to trigger an update every second
+ const currentTime = useTimestamp({ interval: 1000 })
+
return {
- waitForChange: waitForChangeFn([currentConfig, loggedIn, reqStore, ruleStore]),
+ waitForChange: waitForChangeFn([currentConfig, loggedIn, reqStore, ruleStore, currentTime]),
getRequests: () => Promise.resolve(permissions.getAll()),
@@ -292,7 +345,7 @@ export const usePermissionApi = (): IFeatureExport<AppSettings, PermissionApi> =
return Promise.resolve()
},
- allow(requestId: string, addRule: boolean) {
+ allow(requestId: string, addRule: CreateRuleType) {
permissions.allow(requestId, addRule)
return Promise.resolve()
},
@@ -304,8 +357,11 @@ export const usePermissionApi = (): IFeatureExport<AppSettings, PermissionApi> =
}),
async requestAndWaitResult(request: Partial<PermissionRequest>) {
- //push request
- const req = permissions.pushRequest(request, true)
+
+ debugLog("Requesting permission", request)
+
+ //push request and show popup only if enabled
+ const req = permissions.pushRequest(request, currentConfig.value.authPopup)
//See if pending
if(req.status !== PrStatus.Pending){
@@ -316,7 +372,7 @@ export const usePermissionApi = (): IFeatureExport<AppSettings, PermissionApi> =
do {
//wait for a change
- await waitOne([reqStore])
+ await waitOne([ reqStore ])
//check if request was approved
const status = permissions.getRequest(req.uuid);
diff --git a/extension/src/features/server-api/index.ts b/extension/src/features/server-api/index.ts
index b9524ed..35bed6f 100644
--- a/extension/src/features/server-api/index.ts
+++ b/extension/src/features/server-api/index.ts
@@ -19,7 +19,7 @@ import { get } from '@vueuse/core'
import { type WebMessage, type UserProfile } from "@vnuge/vnlib.browser"
import { initEndponts } from "./endpoints"
import { cloneDeep } from "lodash"
-import type { EncryptionRequest, NostrEvent, NostrPubKey, NostrRelay } from "../types"
+import type { EncryptionRequest, EventEntry, NostrEvent, NostrPubKey, NostrRelay } from "../types"
export enum Endpoints {
GetKeys = 'getKeys',
@@ -32,6 +32,8 @@ export enum Endpoints {
CreateId = 'createIdentity',
UpdateId = 'updateIdentity',
UpdateProfile = 'updateProfile',
+ GetHistory = 'getEvents',
+ DeleteSingleEvent = 'deleteSingleEvent',
}
export interface ExecRequestHandler{
@@ -45,6 +47,8 @@ export interface ExecRequestHandler{
(id: Endpoints.CreateId, identity: NostrPubKey):Promise<NostrPubKey>
(id: Endpoints.UpdateId, identity: NostrPubKey):Promise<NostrPubKey>
(id: Endpoints.UpdateProfile, profile: UserProfile):Promise<string>
+ (id: Endpoints.GetHistory):Promise<EventEntry[]>
+ (id: Endpoints.DeleteSingleEvent, evntId: EventEntry):Promise<void>
}
export interface ServerApi{
@@ -65,7 +69,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server
registerEndpoint({
id: Endpoints.DeleteKey,
method: 'DELETE',
- path: (key: NostrPubKey) => `${get(nostrUrl)}?type=identity&key_id=${key.Id}`,
+ path: (key: NostrPubKey) => `${get(nostrUrl)}?type=identity&id=${key.Id}`,
onRequest: () => Promise.resolve(),
onResponse: async (response: WebMessage) => response.getResultOrThrow()
})
@@ -147,5 +151,22 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server
onResponse: async (response: WebMessage<string>) => response.getResultOrThrow()
})
+ //History api
+ registerEndpoint({
+ id: Endpoints.GetHistory,
+ method: 'GET',
+ path: () => `${get(nostrUrl)}?type=getEvents`,
+ onRequest: () => Promise.resolve(),
+ onResponse: (response : EventEntry[]) => Promise.resolve(response) //Pass through response, should be an array of events or an error
+ })
+
+ registerEndpoint({
+ id: Endpoints.DeleteSingleEvent,
+ method: 'DELETE',
+ path: (evnt: EventEntry) => `${get(nostrUrl)}?type=event&id=${evnt.Id}`,
+ onRequest: () => Promise.resolve(),
+ onResponse: (response) => Promise.resolve(response)
+ })
+
return { execRequest }
} \ No newline at end of file
diff --git a/extension/src/features/settings.ts b/extension/src/features/settings.ts
index ca714a5..0bd7101 100644
--- a/extension/src/features/settings.ts
+++ b/extension/src/features/settings.ts
@@ -14,7 +14,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import { storage } from "webextension-polyfill"
-import { } from 'lodash'
+import { defaultsDeep } from 'lodash'
import { configureApi, debugLog } from '@vnuge/vnlib.browser'
import { MaybeRefOrGetter, readonly, Ref, shallowRef, watch } from "vue";
import { JsonObject } from "type-fest";
@@ -30,18 +30,20 @@ export interface PluginConfig extends JsonObject {
readonly nostrEndpoint: string;
readonly heartbeat: boolean;
readonly maxHistory: number;
- readonly tagFilter: boolean,
+ readonly tagFilter: boolean;
+ readonly authPopup: boolean;
}
//Default storage config
-const defaultConfig : PluginConfig = {
+const defaultConfig : PluginConfig = Object.freeze({
apiUrl: import.meta.env.VITE_API_URL,
accountBasePath: import.meta.env.VITE_ACCOUNTS_BASE_PATH,
nostrEndpoint: import.meta.env.VITE_NOSTR_ENDPOINT,
heartbeat: import.meta.env.VITE_HEARTBEAT_ENABLED === 'true',
maxHistory: 50,
tagFilter: true,
-};
+ authPopup: true,
+});
export interface AppSettings{
saveConfig(config: PluginConfig): void;
@@ -62,6 +64,9 @@ export const useAppSettings = (): AppSettings => {
const _storageBackend = storage.local;
const store = useStorage<PluginConfig>(_storageBackend, 'siteConfig', defaultConfig);
+ //Merge the default config for nullables with the current config on startyup
+ defaultsDeep(store.value, defaultConfig);
+
watch(store, (config, _) => {
//Configure the vnlib api
configureApi({
diff --git a/extension/src/features/tagfilter-api.ts b/extension/src/features/tagfilter-api.ts
index 22369d0..b8778a1 100644
--- a/extension/src/features/tagfilter-api.ts
+++ b/extension/src/features/tagfilter-api.ts
@@ -17,8 +17,8 @@ import { TaggedNostrEvent, Watchable } from "./types";
import { filter, isEmpty, isEqual, isRegExp } from "lodash";
import { BgRuntime, FeatureApi, IFeatureExport, exportForegroundApi } from "./framework";
import { AppSettings } from "./settings";
-import { get, toRefs } from "@vueuse/core";
-import { waitForChangeFn } from "./util";
+import { get, toRefs, set } from "@vueuse/core";
+import { push, remove, waitForChangeFn } from "./util";
interface EventTagFilteStorage {
filters: string[];
@@ -28,98 +28,90 @@ interface EventTagFilteStorage {
export interface EventTagFilterApi extends FeatureApi, Watchable {
filterTags(event: TaggedNostrEvent): Promise<void>;
addFilter(tag: string): Promise<void>;
+ addFilter(tags: string[]): Promise<void>;
removeFilter(tag: string): Promise<void>;
- addFilters(tags: string[]): Promise<void>;
isEnabled(): Promise<boolean>;
enable(value:boolean): Promise<void>;
}
-export const useTagFilter = (settings: AppSettings): EventTagFilterApi => {
- //use storage
- const store = settings.useStorageSlot<EventTagFilteStorage>('tag-filter-struct', { filters: [], enabled: false });
- const { filters, enabled } = toRefs(store)
-
- return {
- waitForChange: waitForChangeFn([filters, enabled]),
- filterTags: async (event: TaggedNostrEvent): Promise<void> => {
-
- if(!event.tags){
- return;
- }
+export const useEventTagFilterApi = (): IFeatureExport<AppSettings, EventTagFilterApi> => {
+ return{
+ background: ({ state }: BgRuntime<AppSettings>) => {
- if(isEmpty(event.tags)){
- return;
- }
+ //use storage
+ const store = state.useStorageSlot<EventTagFilteStorage>('tag-filter-struct', { filters: [], enabled: false });
- /*
- * Nostr events contain a nested array of tags, they may be any
- * json type. The first element of the array should be the tag name
- * and the rest of the array is the tag data.
- */
- const allowedTags = filter(event.tags, ([tagName]) => {
- if(!tagName){
- return false;
- }
+ const { filters, enabled } = toRefs(store)
- if(!filters.value.length){
- return true;
- }
+ return{
+ waitForChange: waitForChangeFn([filters, enabled]),
+ filterTags (event: TaggedNostrEvent): Promise<void> {
- const asString = tagName.toString();
+ if (!event.tags || isEmpty(event.tags)) {
+ return Promise.resolve();
+ }
- for (const filter of get(filters)) {
- //if the filter is a regex, test it, if it fails, its allowed
- if (isRegExp(filter)) {
- if (filter.test(asString)) {
+ /*
+ * Nostr events contain a nested array of tags, they may be any
+ * json type. The first element of the array should be the tag name
+ * and the rest of the array is the tag data.
+ */
+ const allowedTags = filter(event.tags, ([tagName]) => {
+ //May be an undefined tag, so ignore it
+ if (!tagName) {
return false;
}
- }
- //If the filter is a string, compare it, if it matches, it's not allowed
- if (isEqual(filter, asString)) {
- return false;
- }
- }
- //Its allowed
- return true;
- })
+ if (!filters.value.length) {
+ return true;
+ }
+
+ const asString = tagName.toString();
- //overwrite tags array
- event.tags = allowedTags;
- },
- addFilter: async (tag: string) => {
- //add new filter to list
- filters.value.push(tag);
- },
- removeFilter: async (tag: string) => {
- //remove filter from list
- filters.value = filter(filters.value, t => !isEqual(t, tag));
- },
- addFilters: async (tags: string[]) => {
- //add new filters to list
- filters.value.push(...tags);
- },
- isEnabled: async () => {
- return enabled.value;
- },
- enable: async (value:boolean) => {
- enabled.value = value;
- }
- }
-}
+ for (const filter of get(filters)) {
+ //if the filter is a regex, test it, if it fails, its allowed
+ if (isRegExp(filter)) {
+ if (filter.test(asString)) {
+ return false;
+ }
+ }
+ //If the filter is a string, compare it, if it matches, it's not allowed
+ if (isEqual(filter, asString)) {
+ return false;
+ }
+ }
-export const useEventTagFilterApi = (): IFeatureExport<AppSettings, EventTagFilterApi> => {
- return{
- background: ({ state }: BgRuntime<AppSettings>) => {
- return{
- ...useTagFilter(state)
+ //Its allowed
+ return true;
+ })
+
+ //overwrite tags array
+ event.tags = allowedTags;
+ return Promise.resolve();
+ },
+ addFilter(tags: string | string[]) {
+ //add new filter to list
+ push(filters, tags)
+ return Promise.resolve();
+ },
+ removeFilter(tag: string) {
+ //remove filter from list
+ remove(filters, tag);
+ return Promise.resolve();
+ },
+ isEnabled: () => Promise.resolve(enabled.value),
+ enable (value: boolean) {
+ set(enabled, value);
+ return Promise.resolve();
+ }
}
},
foreground: exportForegroundApi([
'filterTags',
'addFilter',
'removeFilter',
- 'addFilters',
+ 'isEnabled',
+ 'enable'
])
}
} \ No newline at end of file
diff --git a/extension/src/features/types.ts b/extension/src/features/types.ts
index fe59011..4689ccc 100644
--- a/extension/src/features/types.ts
+++ b/extension/src/features/types.ts
@@ -15,14 +15,21 @@
import { JsonObject } from "type-fest";
-export interface NostrPubKey extends JsonObject {
+export interface DbEntry extends JsonObject {
readonly Id: string,
- readonly UserName: string,
- readonly PublicKey: string,
readonly Created: string,
readonly LastModified: string
}
+export interface NostrPubKey extends DbEntry {
+ readonly UserName: string,
+ readonly PublicKey: string,
+}
+
+export interface EventEntry extends DbEntry {
+ readonly EventData: string
+}
+
export interface NostrEvent extends JsonObject {
KeyId: string,
readonly id: string,
@@ -48,12 +55,9 @@ export interface EncryptionRequest extends JsonObject {
readonly pubkey: string
}
-export interface NostrRelay extends JsonObject {
- readonly Id: string,
- readonly url: string,
- readonly flags: number,
- readonly Created: string,
- readonly LastModified: string
+export interface NostrRelay extends DbEntry {
+ readonly url: string;
+ readonly flags: number;
}
export interface LoginMessage extends JsonObject {
@@ -105,4 +109,5 @@ export interface TotpUpdateMessage extends JsonObject {
readonly period: number
readonly algorithm: string
readonly secret: string
-} \ No newline at end of file
+}
+
diff --git a/extension/src/features/util.ts b/extension/src/features/util.ts
index 6ec8f15..53f6ffd 100644
--- a/extension/src/features/util.ts
+++ b/extension/src/features/util.ts
@@ -14,24 +14,25 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
-import { defer } from "lodash";
-import { RemovableRef, SerializerAsync, StorageLikeAsync, useStorageAsync, watchOnce } from "@vueuse/core";
-import { type MaybeRefOrGetter, type WatchSource, isProxy, toRaw } from "vue";
+import { defer, filter, isEqual } from "lodash";
+import { RemovableRef, SerializerAsync, StorageLikeAsync, useStorageAsync, watchOnce, get, set } from "@vueuse/core";
+import { type MaybeRefOrGetter, type WatchSource, isProxy, toRaw, MaybeRef, shallowRef } from "vue";
import type { Watchable } from "./types";
export const waitForChange = <T extends Readonly<WatchSource<unknown>[]>>(source: [...T]):Promise<void> => {
- return new Promise((resolve) => watchOnce<any>(source, () => resolve(), { deep: true }))
+ return new Promise((resolve) => watchOnce<any>(source, () => defer(() => resolve()), { deep: true }))
}
export const waitForChangeFn = <T extends Readonly<WatchSource<unknown>[]>>(source: [...T]) => {
- return (): Promise<void> => {
- return new Promise((resolve) => watchOnce<any>(source, () => resolve(), {deep: true}))
- }
+ return (): Promise<void> => waitForChange(source)
}
-export const waitOne = <T extends Readonly<WatchSource<unknown>[]>>(source: [...T]): Promise<void> => {
- return new Promise((resolve) => watchOnce<any>(source, () => resolve(), { deep: true }))
-}
+/**
+ * Waits for a change to occur on the given watch source
+ * once.
+ * @returns A promise that resolves when the change occurs.
+ */
+export const waitOne = waitForChange;
export const useStorage = <T>(storage: any & chrome.storage.StorageArea, key: string, initialValue: MaybeRefOrGetter<T>): RemovableRef<T> => {
@@ -69,10 +70,10 @@ export const useStorage = <T>(storage: any & chrome.storage.StorageArea, key: st
}
}
- return useStorageAsync<T>(key, initialValue, wrapper, { serializer, deep: true, shallow: true });
+ return useStorageAsync<T>(key, initialValue, wrapper, { serializer, shallow: true });
}
-export const onWatchableChange = (watchable: Watchable, onChangeCallback: () => Promise<any>, controls?: { immediate: boolean }) => {
+export const onWatchableChange = ({ waitForChange }: Watchable, onChangeCallback: () => Promise<any>, controls?: { immediate: boolean }) => {
defer(async () => {
if (controls?.immediate) {
@@ -80,8 +81,66 @@ export const onWatchableChange = (watchable: Watchable, onChangeCallback: () =>
}
while (true) {
- await watchable.waitForChange();
+ await waitForChange();
await onChangeCallback();
}
})
+}
+
+export const push = <T>(arr: MaybeRef<T[]>, item: T | T[]) => {
+ //get the reactuve value first
+ const current = get(arr)
+ if (Array.isArray(item)) {
+ //push the items
+ current.push(...item)
+ } else {
+ //push the item
+ current.push(item)
+ }
+ //set the value
+ set(arr, current)
+}
+
+export const remove = <T>(arr: MaybeRef<T[]>, item: T) => {
+ //get the reactuve value first
+ const current = get(arr)
+ //Get all items that are not the item
+ const wo = filter(current, (i) => !isEqual(i, item))
+ //set the value
+ set(arr, wo)
+}
+
+export const useQuery = (query: string) => {
+
+ const get = () => {
+ const args = new URLSearchParams(window.location.search)
+ return args.get(query)
+ }
+
+ const set = (value: string) => {
+ const args = new URLSearchParams(window.location.search);
+ args.set(query, value);
+ (window as any).customHistory.replaceState({}, '', `${window.location.pathname}?${args.toString()}`)
+ }
+
+ const mutable = shallowRef<string | null>(get())
+
+ //Setup custom historu
+ if (!('customHistory' in window)) {
+ (window as any).customHistory = {
+ replaceState: (...args: any[]) => {
+ window.history.replaceState(...args)
+ window.dispatchEvent(new Event('replaceState'))
+ }
+ }
+ }
+
+ //Listen for custom history events and update the mutable state
+ window.addEventListener('replaceState', () => mutable.value = get())
+
+ return{
+ get,
+ set,
+ asRef: mutable
+ }
} \ No newline at end of file
diff --git a/lib/NVault.Crypto.Noscrypt/src/LibNoscrypt.cs b/lib/NVault.Crypto.Noscrypt/src/LibNoscrypt.cs
new file mode 100644
index 0000000..ec0ce2d
--- /dev/null
+++ b/lib/NVault.Crypto.Noscrypt/src/LibNoscrypt.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+using VNLib.Utils;
+using VNLib.Utils.Extensions;
+using VNLib.Utils.Native;
+
+using NCResult = System.Int64;
+
+namespace NVault.Crypto.Noscrypt
+{
+ public unsafe sealed class LibNoscrypt(SafeLibraryHandle Library, bool OwnsHandle) : VnDisposeable
+ {
+ //Values that match the noscrypt.h header
+ public const int NC_SEC_KEY_SIZE = 32;
+ public const int NC_SEC_PUBKEY_SIZE = 32;
+ public const int NC_ENCRYPTION_NONCE_SIZE = 32;
+ public const int NC_PUBKEY_SIZE = 32;
+ public const int NC_SIGNATURE_SIZE = 64;
+ public const int NC_CONV_KEY_SIZE = 32;
+ public const int NC_MESSAGE_KEY_SIZE = 32;
+ public const int CTX_ENTROPY_SIZE = 32;
+
+ //STRUCTS MUST MATCH THE NOSCRYPT.H HEADER
+
+ [StructLayout(LayoutKind.Sequential, Size = NC_SEC_KEY_SIZE)]
+ internal struct NCSecretKey
+ {
+ public fixed byte key[NC_SEC_KEY_SIZE];
+ }
+
+ [StructLayout(LayoutKind.Sequential, Size = NC_SEC_PUBKEY_SIZE)]
+ internal struct NCPublicKey
+ {
+ public fixed byte key[NC_SEC_PUBKEY_SIZE];
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct NCCryptoData
+ {
+ public fixed byte nonce[NC_ENCRYPTION_NONCE_SIZE];
+ public void* inputData;
+ public void* outputData;
+ public uint dataSize;
+ }
+
+ //FUCNTIONS
+ [SafeMethodName("NCGetContextStructSize")]
+ internal delegate uint NCGetContextStructSizeDelegate();
+
+ [SafeMethodName("NCInitContext")]
+ internal delegate NCResult NCInitContextDelegate(void* ctx , byte* entropy32);
+
+ [SafeMethodName("NCReInitContext")]
+ internal delegate NCResult NCReInitContextDelegate(void* ctx, byte* entropy32);
+
+ [SafeMethodName("NCDestroyContext")]
+ internal delegate NCResult NCDestroyContextDelegate(void* ctx);
+
+ [SafeMethodName("NCGetPublicKey")]
+ internal delegate NCResult NCGetPublicKeyDelegate(void* ctx, NCSecretKey* secKey, NCPublicKey* publicKey);
+
+ [SafeMethodName("NCValidateSecretKey")]
+ internal delegate NCResult NCValidateSecretKeyDelegate(void* ctx, NCSecretKey* secKey);
+
+ [SafeMethodName("NCSignData")]
+ internal delegate NCResult NCSignDataDelegate(void* ctx, NCSecretKey* secKey, byte* random32, byte* data, long dataSize, byte* sig64);
+
+ [SafeMethodName("NCVerifyData")]
+ internal delegate NCResult NCVerifyDataDelegate(void* ctx, NCPublicKey* pubKey, byte* data, long dataSize, byte* sig64);
+
+ [SafeMethodName("NCSignDigest")]
+ internal delegate NCResult NCSignDigestDelegate(void* ctx, NCSecretKey* secKey, byte* random32, byte* digest32, byte* sig64);
+
+ [SafeMethodName("NCVerifyDigest")]
+ internal delegate NCResult NCVerifyDigestDelegate(void* ctx, NCPublicKey* pubKey, byte* digest32, byte* sig64);
+
+
+
+
+ ///<inheritdoc/>
+ protected override void Free()
+ {
+ if (OwnsHandle)
+ {
+ Library.Dispose();
+ }
+ }
+
+ public static LibNoscrypt Load(string path, DllImportSearchPath search)
+ {
+ //Load the native library
+ SafeLibraryHandle handle = SafeLibraryHandle.LoadLibrary(path, search);
+
+ //Create the wrapper
+ return new LibNoscrypt(handle, true);
+ }
+
+ public static LibNoscrypt Load(string path) => Load(path, DllImportSearchPath.SafeDirectories);
+
+
+ }
+}
diff --git a/lib/NVault.Crypto.Noscrypt/src/NVault.Crypto.Noscrypt.csproj b/lib/NVault.Crypto.Noscrypt/src/NVault.Crypto.Noscrypt.csproj
new file mode 100644
index 0000000..2416535
--- /dev/null
+++ b/lib/NVault.Crypto.Noscrypt/src/NVault.Crypto.Noscrypt.csproj
@@ -0,0 +1,27 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net8.0</TargetFramework>
+ <Nullable>enable</Nullable>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <PackageReadmeFile>README.md</PackageReadmeFile>
+ <RootNamespace>NVault.Crypto.Noscrypt</RootNamespace>
+ <AssemblyName>NVault.Crypto.Noscrypt</AssemblyName>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <Authors>Vaughn Nugent</Authors>
+ <Company>Vaughn Nugent</Company>
+ <Product>NVault.Crypto.Noscrypt</Product>
+ <Description>Provides a managed library for the noscrypt native library, along with other helper types for NVault</Description>
+ <Copyright>Copyright © 2024 Vaughn Nugent</Copyright>
+ <PackageProjectUrl>https://www.vaughnnugent.com/resources/software/modules/NVault</PackageProjectUrl>
+ <RepositoryUrl>https://github.com/VnUgE/NVault/tree/master/</RepositoryUrl>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="VNLib.Hashing.Portable" Version="0.1.0-ci0114" />
+ <PackageReference Include="VNLib.Utils" Version="0.1.0-ci0114" />
+ </ItemGroup>
+
+</Project>
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs b/lib/NVault.Crypto.Secp256k1/src/ContextExtensions.cs
index bb014df..bb014df 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs
+++ b/lib/NVault.Crypto.Secp256k1/src/ContextExtensions.cs
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/IRandomSource.cs b/lib/NVault.Crypto.Secp256k1/src/IRandomSource.cs
index 4e1861d..4e1861d 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/IRandomSource.cs
+++ b/lib/NVault.Crypto.Secp256k1/src/IRandomSource.cs
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs b/lib/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs
index 8dda269..8dda269 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs
+++ b/lib/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/NVault.Crypto.Secp256k1.csproj b/lib/NVault.Crypto.Secp256k1/src/NVault.Crypto.Secp256k1.csproj
index 5014d89..efd78ab 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/NVault.Crypto.Secp256k1.csproj
+++ b/lib/NVault.Crypto.Secp256k1/src/NVault.Crypto.Secp256k1.csproj
@@ -20,8 +20,8 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="VNLib.Hashing.Portable" Version="0.1.0-ci0109" />
- <PackageReference Include="VNLib.Utils" Version="0.1.0-ci0109" />
+ <PackageReference Include="VNLib.Hashing.Portable" Version="0.1.0-ci0114" />
+ <PackageReference Include="VNLib.Utils" Version="0.1.0-ci0114" />
</ItemGroup>
</Project>
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs b/lib/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs
index c82321c..c82321c 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs
+++ b/lib/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs b/lib/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs
index dfb3ff8..dfb3ff8 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs
+++ b/lib/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs b/lib/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs
index 35734ae..35734ae 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs
+++ b/lib/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/UnmanagedRandomSource.cs b/lib/NVault.Crypto.Secp256k1/src/UnmanagedRandomSource.cs
index 360de21..360de21 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/UnmanagedRandomSource.cs
+++ b/lib/NVault.Crypto.Secp256k1/src/UnmanagedRandomSource.cs
diff --git a/back-end/libs/NVault.VaultExtensions/src/IClientAccessScope.cs b/lib/NVault.VaultExtensions/src/IClientAccessScope.cs
index c79f75e..c79f75e 100644
--- a/back-end/libs/NVault.VaultExtensions/src/IClientAccessScope.cs
+++ b/lib/NVault.VaultExtensions/src/IClientAccessScope.cs
diff --git a/back-end/libs/NVault.VaultExtensions/src/IKvVaultStore.cs b/lib/NVault.VaultExtensions/src/IKvVaultStore.cs
index 037fe6c..037fe6c 100644
--- a/back-end/libs/NVault.VaultExtensions/src/IKvVaultStore.cs
+++ b/lib/NVault.VaultExtensions/src/IKvVaultStore.cs
diff --git a/back-end/libs/NVault.VaultExtensions/src/IVaultClientScope.cs b/lib/NVault.VaultExtensions/src/IVaultClientScope.cs
index d53bc4a..d53bc4a 100644
--- a/back-end/libs/NVault.VaultExtensions/src/IVaultClientScope.cs
+++ b/lib/NVault.VaultExtensions/src/IVaultClientScope.cs
diff --git a/back-end/libs/NVault.VaultExtensions/src/IVaultKvClientScope.cs b/lib/NVault.VaultExtensions/src/IVaultKvClientScope.cs
index f763473..f763473 100644
--- a/back-end/libs/NVault.VaultExtensions/src/IVaultKvClientScope.cs
+++ b/lib/NVault.VaultExtensions/src/IVaultKvClientScope.cs
diff --git a/back-end/libs/NVault.VaultExtensions/src/KvVaultStorage.cs b/lib/NVault.VaultExtensions/src/KvVaultStorage.cs
index 8a2b9b6..8a2b9b6 100644
--- a/back-end/libs/NVault.VaultExtensions/src/KvVaultStorage.cs
+++ b/lib/NVault.VaultExtensions/src/KvVaultStorage.cs
diff --git a/back-end/libs/NVault.VaultExtensions/src/NVault.VaultExtensions.csproj b/lib/NVault.VaultExtensions/src/NVault.VaultExtensions.csproj
index e5dbe8c..e5dbe8c 100644
--- a/back-end/libs/NVault.VaultExtensions/src/NVault.VaultExtensions.csproj
+++ b/lib/NVault.VaultExtensions/src/NVault.VaultExtensions.csproj
diff --git a/back-end/libs/NVault.VaultExtensions/src/VaultClientExtensions.cs b/lib/NVault.VaultExtensions/src/VaultClientExtensions.cs
index d90941a..d90941a 100644
--- a/back-end/libs/NVault.VaultExtensions/src/VaultClientExtensions.cs
+++ b/lib/NVault.VaultExtensions/src/VaultClientExtensions.cs
diff --git a/back-end/libs/NVault.VaultExtensions/src/VaultUserScope.cs b/lib/NVault.VaultExtensions/src/VaultUserScope.cs
index 0e8796c..0e8796c 100644
--- a/back-end/libs/NVault.VaultExtensions/src/VaultUserScope.cs
+++ b/lib/NVault.VaultExtensions/src/VaultUserScope.cs
diff --git a/nvault.build.sln b/nvault.build.sln
index 9c1abc1..adafdc4 100644
--- a/nvault.build.sln
+++ b/nvault.build.sln
@@ -9,11 +9,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libs", "Libs", "{74CA17B7-C
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NVault", "back-end\plugins\nvault\src\NVault.csproj", "{7ADAE9C2-1739-4E91-B59C-DB3B07909C07}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NVault.VaultExtensions", "back-end\libs\NVault.VaultExtensions\src\NVault.VaultExtensions.csproj", "{EF924E63-9FB9-404B-94AB-D273153A917E}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B328A098-6882-4338-A563-C84D69E53F22}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NVault.Crypto.Secp256k1", "back-end\libs\NVault.Crypto.Secp256k1\src\NVault.Crypto.Secp256k1.csproj", "{BD10D3C9-6759-454D-AC33-D4546B7E0990}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NVault.Crypto.Noscrypt", "lib\NVault.Crypto.Noscrypt\src\NVault.Crypto.Noscrypt.csproj", "{686B9DB8-5BA9-49AB-9761-6B661A5027BD}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B328A098-6882-4338-A563-C84D69E53F22}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NVault.Crypto.Secp256k1", "lib\NVault.Crypto.Secp256k1\src\NVault.Crypto.Secp256k1.csproj", "{7952F25A-DA19-492E-B797-839082053DE4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NVault.VaultExtensions", "lib\NVault.VaultExtensions\src\NVault.VaultExtensions.csproj", "{91F33820-C0CE-41FA-89A5-2B45FD0CB2B1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -25,22 +27,27 @@ Global
{7ADAE9C2-1739-4E91-B59C-DB3B07909C07}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7ADAE9C2-1739-4E91-B59C-DB3B07909C07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7ADAE9C2-1739-4E91-B59C-DB3B07909C07}.Release|Any CPU.Build.0 = Release|Any CPU
- {EF924E63-9FB9-404B-94AB-D273153A917E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EF924E63-9FB9-404B-94AB-D273153A917E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EF924E63-9FB9-404B-94AB-D273153A917E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EF924E63-9FB9-404B-94AB-D273153A917E}.Release|Any CPU.Build.0 = Release|Any CPU
- {BD10D3C9-6759-454D-AC33-D4546B7E0990}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BD10D3C9-6759-454D-AC33-D4546B7E0990}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BD10D3C9-6759-454D-AC33-D4546B7E0990}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BD10D3C9-6759-454D-AC33-D4546B7E0990}.Release|Any CPU.Build.0 = Release|Any CPU
+ {686B9DB8-5BA9-49AB-9761-6B661A5027BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {686B9DB8-5BA9-49AB-9761-6B661A5027BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {686B9DB8-5BA9-49AB-9761-6B661A5027BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {686B9DB8-5BA9-49AB-9761-6B661A5027BD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7952F25A-DA19-492E-B797-839082053DE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7952F25A-DA19-492E-B797-839082053DE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7952F25A-DA19-492E-B797-839082053DE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7952F25A-DA19-492E-B797-839082053DE4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {91F33820-C0CE-41FA-89A5-2B45FD0CB2B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {91F33820-C0CE-41FA-89A5-2B45FD0CB2B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {91F33820-C0CE-41FA-89A5-2B45FD0CB2B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {91F33820-C0CE-41FA-89A5-2B45FD0CB2B1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{7ADAE9C2-1739-4E91-B59C-DB3B07909C07} = {352C778E-C12D-483D-9C10-7985D81A8E10}
- {EF924E63-9FB9-404B-94AB-D273153A917E} = {74CA17B7-CE49-4E1F-A84D-0D2ABA0C96F5}
- {BD10D3C9-6759-454D-AC33-D4546B7E0990} = {74CA17B7-CE49-4E1F-A84D-0D2ABA0C96F5}
+ {686B9DB8-5BA9-49AB-9761-6B661A5027BD} = {74CA17B7-CE49-4E1F-A84D-0D2ABA0C96F5}
+ {7952F25A-DA19-492E-B797-839082053DE4} = {74CA17B7-CE49-4E1F-A84D-0D2ABA0C96F5}
+ {91F33820-C0CE-41FA-89A5-2B45FD0CB2B1} = {74CA17B7-CE49-4E1F-A84D-0D2ABA0C96F5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {ACF01A45-B7F0-4055-84F2-A3596713C9BB}