diff --git a/BTCPayServer.Tests/BTCPayServer.Tests.csproj b/BTCPayServer.Tests/BTCPayServer.Tests.csproj
index 5951f6af1..b0c7b0e26 100644
--- a/BTCPayServer.Tests/BTCPayServer.Tests.csproj
+++ b/BTCPayServer.Tests/BTCPayServer.Tests.csproj
@@ -24,7 +24,7 @@
-
+
all
diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs
index bd641793d..e2a1a253b 100644
--- a/BTCPayServer.Tests/SeleniumTests.cs
+++ b/BTCPayServer.Tests/SeleniumTests.cs
@@ -2332,10 +2332,27 @@ namespace BTCPayServer.Tests
s.Server.ActivateLightning();
await s.StartAsync();
await s.Server.EnsureChannelsSetup();
+
+ // Create users
+ var user = s.RegisterNewUser();
+ var userAccount = s.AsTestAccount();
+ s.GoToHome();
+ s.Logout();
+ s.GoToRegister();
s.RegisterNewUser(true);
+
+ // Setup store and associate user
s.CreateNewStore();
s.GoToStore();
s.AddLightningNode(LightningConnectionType.CLightning, false);
+ s.GoToStore(StoreNavPages.Users);
+ s.Driver.FindElement(By.Id("Email")).Clear();
+ s.Driver.FindElement(By.Id("Email")).SendKeys(user);
+ new SelectElement(s.Driver.FindElement(By.Id("Role"))).SelectByValue("Guest");
+ s.Driver.FindElement(By.Id("AddUser")).Click();
+ Assert.Contains("User added successfully", s.FindAlertMessage().Text);
+
+ // Setup POS
s.Driver.FindElement(By.Id("StoreNav-CreatePointOfSale")).Click();
s.Driver.FindElement(By.Id("AppName")).SendKeys(Guid.NewGuid().ToString());
s.Driver.FindElement(By.Id("Create")).Click();
@@ -2360,6 +2377,8 @@ namespace BTCPayServer.Tests
s.Driver.WaitForElement(By.ClassName("keypad"));
// basic checks
+ var keypadUrl = s.Driver.Url;
+ s.Driver.FindElement(By.Id("RecentTransactionsToggle"));
Assert.Contains("EUR", s.Driver.FindElement(By.Id("Currency")).Text);
Assert.Contains("0,00", s.Driver.FindElement(By.Id("Amount")).Text);
Assert.Equal("", s.Driver.FindElement(By.Id("Calculation")).Text);
@@ -2405,6 +2424,19 @@ namespace BTCPayServer.Tests
s.Driver.FindElement(By.Id("DetailsToggle")).Click();
s.Driver.WaitForElement(By.Id("PaymentDetails-TotalFiat"));
Assert.Contains("1 222,21 €", s.Driver.FindElement(By.Id("PaymentDetails-TotalFiat")).Text);
+
+ // Guest user can access recent transactions
+ s.GoToHome();
+ s.Logout();
+ s.LogIn(user, userAccount.RegisterDetails.Password);
+ s.GoToUrl(keypadUrl);
+ s.Driver.FindElement(By.Id("RecentTransactionsToggle"));
+ s.GoToHome();
+ s.Logout();
+
+ // Unauthenticated user can't access recent transactions
+ s.GoToUrl(keypadUrl);
+ s.Driver.ElementDoesNotExist(By.Id("RecentTransactionsToggle"));
}
[Fact]
diff --git a/BTCPayServer/Security/CookieAuthorizationHandler.cs b/BTCPayServer/Security/CookieAuthorizationHandler.cs
index 15c3180be..9391f4866 100644
--- a/BTCPayServer/Security/CookieAuthorizationHandler.cs
+++ b/BTCPayServer/Security/CookieAuthorizationHandler.cs
@@ -1,5 +1,4 @@
using System;
-using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Constants;
using BTCPayServer.Abstractions.Contracts;
@@ -74,10 +73,10 @@ namespace BTCPayServer.Security
// resolve from app
if (routeData.Values.TryGetValue("appId", out var vAppId) && vAppId is string appId)
{
- app = await _appService.GetAppDataIfOwner(userId, appId);
+ app = await _appService.GetAppData(userId, appId);
if (storeId == null)
{
- storeId = app?.StoreDataId ?? String.Empty;
+ storeId = app?.StoreDataId ?? string.Empty;
}
else if (app?.StoreDataId != storeId)
{
@@ -90,7 +89,7 @@ namespace BTCPayServer.Security
paymentRequest = await _paymentRequestRepository.FindPaymentRequest(payReqId, userId);
if (storeId == null)
{
- storeId = paymentRequest?.StoreDataId ?? String.Empty;
+ storeId = paymentRequest?.StoreDataId ?? string.Empty;
}
else if (paymentRequest?.StoreDataId != storeId)
{
@@ -103,7 +102,7 @@ namespace BTCPayServer.Security
invoice = await _invoiceRepository.GetInvoice(invoiceId);
if (storeId == null)
{
- storeId = invoice?.StoreId ?? String.Empty;
+ storeId = invoice?.StoreId ?? string.Empty;
}
else if (invoice?.StoreId != storeId)
{
diff --git a/BTCPayServer/Services/Apps/AppService.cs b/BTCPayServer/Services/Apps/AppService.cs
index b5c678c40..6b0422701 100644
--- a/BTCPayServer/Services/Apps/AppService.cs
+++ b/BTCPayServer/Services/Apps/AppService.cs
@@ -371,10 +371,26 @@ namespace BTCPayServer.Services.Apps
return null;
await using var ctx = _ContextFactory.CreateContext();
var app = await ctx.UserStore
- .Include(store => store.StoreRole)
- .Where(us => us.ApplicationUserId == userId && us.StoreRole.Permissions.Contains(Policies.CanModifyStoreSettings))
- .SelectMany(us => us.StoreData.Apps.Where(a => a.Id == appId))
- .FirstOrDefaultAsync();
+ .Include(store => store.StoreRole)
+ .Where(us => us.ApplicationUserId == userId && us.StoreRole.Permissions.Contains(Policies.CanModifyStoreSettings))
+ .SelectMany(us => us.StoreData.Apps.Where(a => a.Id == appId))
+ .FirstOrDefaultAsync();
+ if (app == null)
+ return null;
+ if (type != null && type != app.AppType)
+ return null;
+ return app;
+ }
+
+ public async Task GetAppData(string userId, string appId, string? type = null)
+ {
+ if (userId == null || appId == null)
+ return null;
+ await using var ctx = _ContextFactory.CreateContext();
+ var app = await ctx.UserStore
+ .Where(us => us.ApplicationUserId == userId && us.StoreData != null && us.StoreData.UserStores.Any(u => u.ApplicationUserId == userId))
+ .SelectMany(us => us.StoreData.Apps.Where(a => a.Id == appId))
+ .FirstOrDefaultAsync();
if (app == null)
return null;
if (type != null && type != app.AppType)
diff --git a/BTCPayServer/Views/UIStores/StoreUsers.cshtml b/BTCPayServer/Views/UIStores/StoreUsers.cshtml
index 35247dcc6..db996040e 100644
--- a/BTCPayServer/Views/UIStores/StoreUsers.cshtml
+++ b/BTCPayServer/Views/UIStores/StoreUsers.cshtml
@@ -33,7 +33,7 @@
-
+