mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-02-19 21:24:22 +01:00
Merge pull request #6659 from NicolasDorier/restore-invite
Restore behavior: Invite non existing users when adding a store user
This commit is contained in:
@@ -9,11 +9,14 @@ using BTCPayServer.Client;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Events;
|
||||
using BTCPayServer.Models.StoreViewModels;
|
||||
using BTCPayServer.Security;
|
||||
using BTCPayServer.Services;
|
||||
using BTCPayServer.Services.Mails;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Localization;
|
||||
using NicolasDorier.RateLimits;
|
||||
using static BTCPayServer.Services.Stores.StoreRepository;
|
||||
|
||||
namespace BTCPayServer.Controllers;
|
||||
@@ -28,8 +31,15 @@ public partial class UIStoresController
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
enum StoreUsersAction
|
||||
{
|
||||
Added,
|
||||
Updated,
|
||||
Invited
|
||||
}
|
||||
[HttpPost("{storeId}/users")]
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
||||
[RateLimitsFilter(ZoneLimits.Register, Scope = RateLimitsScope.RemoteAddress)]
|
||||
public async Task<IActionResult> StoreUsers(string storeId, StoreUsersViewModel vm)
|
||||
{
|
||||
await FillUsers(vm);
|
||||
@@ -44,39 +54,90 @@ public partial class UIStoresController
|
||||
ModelState.AddModelError(nameof(vm.Role), StringLocalizer["Invalid role"]);
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
|
||||
StoreUsersAction action;
|
||||
string? inviteInfo = null;
|
||||
var user = await _userManager.FindByEmailAsync(vm.Email);
|
||||
if (user is null)
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.Email), StringLocalizer["This user does not exist"]);
|
||||
action = StoreUsersAction.Invited;
|
||||
if (!_policiesSettings.LockSubscription || await IsAdmin())
|
||||
{
|
||||
user = new ApplicationUser
|
||||
{
|
||||
UserName = vm.Email,
|
||||
Email = vm.Email,
|
||||
RequiresEmailConfirmation = _policiesSettings.RequiresConfirmedEmail,
|
||||
RequiresApproval = _policiesSettings.RequiresUserApproval,
|
||||
Created = DateTimeOffset.UtcNow
|
||||
};
|
||||
var currentUser = await _userManager.GetUserAsync(HttpContext.User);
|
||||
|
||||
if (currentUser is not null &&
|
||||
(await _userManager.CreateAsync(user)) is { Succeeded: true } result)
|
||||
{
|
||||
var invitationEmail = await _emailSenderFactory.IsComplete();
|
||||
var evt = await UserEvent.Invited.Create(user!, currentUser, _callbackGenerator, Request, invitationEmail);
|
||||
_eventAggregator.Publish(evt);
|
||||
inviteInfo = invitationEmail
|
||||
? StringLocalizer["An invitation email has been sent.<br/>You may alternatively share this link with them: <a class='alert-link' href='{0}'>{0}</a>", evt.InvitationLink]
|
||||
: StringLocalizer["An invitation email has not been sent, because the server does not have an email server configured.<br/> You need to share this link with them: <a class='alert-link' href='{0}'>{0}</a>", evt.InvitationLink];
|
||||
user = await _userManager.FindByEmailAsync(vm.Email);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
action = (await _storeRepo.GetStoreUser(storeId, user.Id)) is not null
|
||||
? StoreUsersAction.Updated
|
||||
: StoreUsersAction.Added;
|
||||
}
|
||||
|
||||
if (user is null)
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.Email), StringLocalizer["User not found"]);
|
||||
return View(vm);
|
||||
}
|
||||
var isExistingStoreUser = await _storeRepo.GetStoreUser(storeId, user.Id) is not null;
|
||||
|
||||
var res = await _storeRepo.AddOrUpdateStoreUser(CurrentStore.Id, user.Id, roleId);
|
||||
if (res is AddOrUpdateStoreUserResult.Success)
|
||||
{
|
||||
|
||||
var res = await _storeRepo.AddOrUpdateStoreUser(CurrentStore.Id, user.Id, roleId);
|
||||
if (res is AddOrUpdateStoreUserResult.Success)
|
||||
{
|
||||
TempData.SetStatusMessageModel(new StatusMessageModel
|
||||
{
|
||||
Severity = StatusMessageModel.StatusSeverity.Success,
|
||||
AllowDismiss = false,
|
||||
Message = isExistingStoreUser
|
||||
? StringLocalizer["The user has been updated successfully."].Value
|
||||
: StringLocalizer["The user has been added successfully."].Value,
|
||||
Message = action switch
|
||||
{
|
||||
StoreUsersAction.Added => StringLocalizer["The user has been added successfully."].Value,
|
||||
StoreUsersAction.Updated => StringLocalizer["The user has been updated successfully."].Value,
|
||||
StoreUsersAction.Invited => null,
|
||||
_ => throw new ArgumentOutOfRangeException(action.ToString())
|
||||
},
|
||||
Html = action switch
|
||||
{
|
||||
StoreUsersAction.Invited => inviteInfo,
|
||||
_ => null
|
||||
}
|
||||
});
|
||||
return RedirectToAction(nameof(StoreUsers));
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.Email),
|
||||
isExistingStoreUser
|
||||
? StringLocalizer["The user could not be updated: {0}", res.ToString()]
|
||||
: StringLocalizer["The user could not be added: {0}", res.ToString()]
|
||||
);
|
||||
action switch
|
||||
{
|
||||
StoreUsersAction.Updated => StringLocalizer["The user could not be updated: {0}", res.ToString()],
|
||||
StoreUsersAction.Added => StringLocalizer["The user could not be added: {0}", res.ToString()],
|
||||
StoreUsersAction.Invited => StringLocalizer["The user could not be invited: {0}", res.ToString()],
|
||||
_ => throw new ArgumentOutOfRangeException(action.ToString())
|
||||
});
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> IsAdmin()
|
||||
=> (await _authorizationService.AuthorizeAsync(User, null, new PolicyRequirement(Policies.CanCreateUser))).Succeeded;
|
||||
|
||||
[HttpPost("{storeId}/users/{userId}")]
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
||||
public async Task<IActionResult> UpdateStoreUser(string storeId, string userId, StoreUsersViewModel.StoreUserViewModel vm)
|
||||
|
||||
@@ -36,7 +36,6 @@ namespace BTCPayServer.Services
|
||||
"{0} Node": "",
|
||||
"{0} provider is not supported": "",
|
||||
"{0} selected": "",
|
||||
"{0} Settings": "",
|
||||
"{0} Status": "",
|
||||
"{0} Store": "",
|
||||
"{0} Stores": "",
|
||||
@@ -79,7 +78,6 @@ namespace BTCPayServer.Services
|
||||
"Access Type": "",
|
||||
"Account": "",
|
||||
"Account created.": "",
|
||||
"Account Index": "",
|
||||
"Account key": "",
|
||||
"Account Key": "",
|
||||
"Account key path": "",
|
||||
@@ -88,7 +86,6 @@ namespace BTCPayServer.Services
|
||||
"Actions": "",
|
||||
"Active": "",
|
||||
"Add": "",
|
||||
"Add account": "",
|
||||
"Add additional fee (network fee) to invoice …": "",
|
||||
"Add Address": "",
|
||||
"Add an email address or an external URL where users can contact you for support requests through a \"Contact Us\" button, displayed at the bottom of the public facing pages.": "",
|
||||
@@ -146,6 +143,8 @@ namespace BTCPayServer.Services
|
||||
"Amount requested": "",
|
||||
"An error occurred while resetting user password": "",
|
||||
"An error occurred while saving: {0}": "",
|
||||
"An invitation email has been sent.<br/>You may alternatively share this link with them: <a class='alert-link' href='{0}'>{0}</a>": "",
|
||||
"An invitation email has not been sent, because the server does not have an email server configured.<br/> You need to share this link with them: <a class='alert-link' href='{0}'>{0}</a>": "",
|
||||
"An invoice must be paid within a defined time interval at a fixed exchange rate to protect the issuer from price fluctuations.": "",
|
||||
"Animation": "",
|
||||
"Any amount": "",
|
||||
@@ -181,8 +180,6 @@ namespace BTCPayServer.Services
|
||||
"archived": "",
|
||||
"Archived": "",
|
||||
"Archived Stores": "",
|
||||
"At Least One": "",
|
||||
"At Least Ten": "",
|
||||
"Authenticator code": "",
|
||||
"Authorize a public key to access Bitpay compatible Invoice API.": "",
|
||||
"Authorize app": "",
|
||||
@@ -200,7 +197,6 @@ namespace BTCPayServer.Services
|
||||
"Available placeholders: <code>{StoreName} {ItemDescription} {OrderId}</code>": "",
|
||||
"Awaiting": "",
|
||||
"Azure Blob Storage": "",
|
||||
"Back to list": "",
|
||||
"Backend's language": "",
|
||||
"Balance": "",
|
||||
"Batch size": "",
|
||||
@@ -232,6 +228,7 @@ namespace BTCPayServer.Services
|
||||
"Buyer Email": "",
|
||||
"Callback Notification URL": "",
|
||||
"Campaign not active": "",
|
||||
"Can create a new cold wallet": "",
|
||||
"Can use hot wallet": "",
|
||||
"Can use RPC import": "",
|
||||
"Cancel": "",
|
||||
@@ -252,6 +249,7 @@ namespace BTCPayServer.Services
|
||||
"Change your {0} provider.": "",
|
||||
"Change your password": "",
|
||||
"Changes to the SSH settings are now permanently disabled in the BTCPay Server user interface": "",
|
||||
"Changing the role of user {0} failed: {1}": "",
|
||||
"Charge": "",
|
||||
"Cheat Mode: Send funds to this wallet": "",
|
||||
"Check if NFC is supported and enabled on this device": "",
|
||||
@@ -286,7 +284,6 @@ namespace BTCPayServer.Services
|
||||
"Combine": "",
|
||||
"Combine PSBT": "",
|
||||
"Compatible wallets": "",
|
||||
"Complete the email setup to send test emails.": "",
|
||||
"Completed": "",
|
||||
"CONFIDENTIAL: This QR Code is confidential, close this window as soon as you don't need it anymore.": "",
|
||||
"Config file was not in the correct format": "",
|
||||
@@ -301,6 +298,7 @@ namespace BTCPayServer.Services
|
||||
"Confirm addresses": "",
|
||||
"Confirm broadcasting this transaction": "",
|
||||
"Confirm in the next …": "",
|
||||
"Confirm Lightning Payout": "",
|
||||
"Confirm new password": "",
|
||||
"Confirm passphrase": "",
|
||||
"Confirm password": "",
|
||||
@@ -337,11 +335,8 @@ namespace BTCPayServer.Services
|
||||
"Copy Tor URL": "",
|
||||
"Core Lightning {0}": "",
|
||||
"Could not access your camera. Is it already in use?": "",
|
||||
"Could not create a new account.": "",
|
||||
"Could not create new account.": "",
|
||||
"Could not generate invoice: {0}": "",
|
||||
"Could not load log files": "",
|
||||
"Could not open the wallet: {0}": "",
|
||||
"Could not save CSS file: {0}": "",
|
||||
"Could not save image: {0}": "",
|
||||
"Could not save logo: {0}": "",
|
||||
@@ -350,6 +345,7 @@ namespace BTCPayServer.Services
|
||||
"Create": "",
|
||||
"Create {0} Hot Wallet": "",
|
||||
"Create {0} Watch-Only Wallet": "",
|
||||
"Create a new {0}": "",
|
||||
"Create a new app": "",
|
||||
"Create a new store": "",
|
||||
"Create a new wallet": "",
|
||||
@@ -363,9 +359,11 @@ namespace BTCPayServer.Services
|
||||
"Create invoice to pay custom amount": "",
|
||||
"Create New Token": "",
|
||||
"Create Payment Request": "",
|
||||
"Create pending transaction": "",
|
||||
"Create Pull Payment": "",
|
||||
"Create refund": "",
|
||||
"Create Request": "",
|
||||
"Create role": "",
|
||||
"Create Store": "",
|
||||
"Create temporary file link": "",
|
||||
"Create Token": "",
|
||||
@@ -383,6 +381,7 @@ namespace BTCPayServer.Services
|
||||
"Currency": "",
|
||||
"Currency is invalid": "",
|
||||
"Currency pairs to test against your rule": "",
|
||||
"Current effective fee rate": "",
|
||||
"Current password": "",
|
||||
"Current Rates source is": "",
|
||||
"Currently active!": "",
|
||||
@@ -512,7 +511,6 @@ namespace BTCPayServer.Services
|
||||
"Edit pull payment": "",
|
||||
"Edit Pull Payment": "",
|
||||
"Editor": "",
|
||||
"Either recipient or \"Send the email to the buyer\" is required": "",
|
||||
"Either your {0} wallet is not configured, or it is not a hot wallet. This processor cannot function until a hot wallet is configured in your store.": "",
|
||||
"Email": "",
|
||||
"Email address": "",
|
||||
@@ -523,8 +521,6 @@ namespace BTCPayServer.Services
|
||||
"Email password reset functionality is not configured for this server. Please contact the server administrator to assist with account recovery.": "",
|
||||
"email rules": "",
|
||||
"Email Rules": "",
|
||||
"Create Email Rule": "",
|
||||
"Edit Email Rule": "",
|
||||
"Email rules allow BTCPay Server to send customized emails from your store based on events.": "",
|
||||
"Email sent to {0}. Please verify you received it.": "",
|
||||
"Email Server": "",
|
||||
@@ -566,7 +562,6 @@ namespace BTCPayServer.Services
|
||||
"Enter wallet seed": "",
|
||||
"Enter your extended public key": "",
|
||||
"Error": "",
|
||||
"Error sending test email: {0}": "",
|
||||
"Error updating profile": "",
|
||||
"Error updating user": "",
|
||||
"Error while broadcasting: {0}": "",
|
||||
@@ -592,6 +587,7 @@ namespace BTCPayServer.Services
|
||||
"Feature disabled": "",
|
||||
"Featured Image URL": "",
|
||||
"Fee block target": "",
|
||||
"Fee bump method": "",
|
||||
"Fee rate": "",
|
||||
"Fee rate (sat/vB)": "",
|
||||
"Fee will be shown for BTC and LTC onchain payments only.": "",
|
||||
@@ -728,7 +724,6 @@ namespace BTCPayServer.Services
|
||||
"Invalid destination or payment method": "",
|
||||
"Invalid email": "",
|
||||
"Invalid login attempt.": "",
|
||||
"Invalid mailbox address provided. Valid formats are: '{0}' or '{1}'": "",
|
||||
"Invalid network": "",
|
||||
"Invalid passphrase confirmation": "",
|
||||
"Invalid payout method": "",
|
||||
@@ -794,6 +789,7 @@ namespace BTCPayServer.Services
|
||||
"Lightning network settings": "",
|
||||
"Lightning node (LNURL Auth)": "",
|
||||
"Lightning Payout Processor": "",
|
||||
"Lightning Payout Result": "",
|
||||
"Lightning Services": "",
|
||||
"Limit": "",
|
||||
"Link": "",
|
||||
@@ -864,7 +860,7 @@ namespace BTCPayServer.Services
|
||||
"Network Fee": "",
|
||||
"Never add network fee": "",
|
||||
"New {0} plugin version {1} released!": "",
|
||||
"New account label": "",
|
||||
"New effective fee rate": "",
|
||||
"New password": "",
|
||||
"New role": "",
|
||||
"New user {0} requires approval.": "",
|
||||
@@ -875,7 +871,6 @@ namespace BTCPayServer.Services
|
||||
"Next": "",
|
||||
"NFC detected.": "",
|
||||
"No access tokens yet.": "",
|
||||
"No accounts available on the current wallet": "",
|
||||
"No claim made yet.": "",
|
||||
"No contributions allowed after the goal has been reached": "",
|
||||
"No contributions have been made yet.": "",
|
||||
@@ -904,11 +899,13 @@ namespace BTCPayServer.Services
|
||||
"Node headers height: {0}": "",
|
||||
"Node Info": "",
|
||||
"Non-admins can access the User Creation API Endpoint": "",
|
||||
"Non-admins can create Cold Wallets for their Store": "",
|
||||
"Non-admins can create Hot Wallets for their Store": "",
|
||||
"Non-admins can import Hot Wallets for their Store": "",
|
||||
"Non-admins can use the Internal Lightning Node for their Store": "",
|
||||
"Non-admins cannot access the User Creation API Endpoint": "",
|
||||
"Non-supported state of invoice": "",
|
||||
"None of the selected transaction can be fee bumped": "",
|
||||
"Not all payout methods are supported": "",
|
||||
"Not allowed to cancel this invoice": "",
|
||||
"Not recommended": "",
|
||||
@@ -1012,6 +1009,7 @@ namespace BTCPayServer.Services
|
||||
"Pending Approval": "",
|
||||
"Pending Email Verification": "",
|
||||
"Pending Invitation": "",
|
||||
"Pending Transaction": "",
|
||||
"percent": "",
|
||||
"Percentage must be a numeric value between 0 and 100": "",
|
||||
"Permanent Url": "",
|
||||
@@ -1029,6 +1027,7 @@ namespace BTCPayServer.Services
|
||||
"Please note that creating a hot wallet is not supported by this instance for non administrators.": "",
|
||||
"Please note that creating a wallet is not supported by your instance.": "",
|
||||
"Please note that not all text is translatable, and future updates may modify existing translations or introduce new translatable phrases.": "",
|
||||
"Please note that this instance does not support creating a new cold wallet for non-administrators. However, you can import one from other wallet software.": "",
|
||||
"Please provide a connection string": "",
|
||||
"Please provide a destination": "",
|
||||
"Please provide an amount greater than 0": "",
|
||||
@@ -1036,10 +1035,8 @@ namespace BTCPayServer.Services
|
||||
"Please provide your extended public key": "",
|
||||
"Please remove the NFC from the card reader": "",
|
||||
"Please select an option before proceeding": "",
|
||||
"Please select the view-only wallet file": "",
|
||||
"Please select the view-only wallet keys file": "",
|
||||
"Please select the wallet file": "",
|
||||
"Please select the wallet.keys file": "",
|
||||
"Please set NBXPlorer's PostgreSQL connection string to make this feature available.": "",
|
||||
"Please wait for your node to be synched": "",
|
||||
"Plugin action cancelled.": "",
|
||||
"Plugin scheduled to be installed.": "",
|
||||
"Plugin scheduled to be uninstalled.": "",
|
||||
@@ -1146,12 +1143,12 @@ namespace BTCPayServer.Services
|
||||
"Remove Store Permission": "",
|
||||
"Remove store user": "",
|
||||
"Remove the translation from this dictionary.": "",
|
||||
"Remove this email rule": "",
|
||||
"Remove wallet": "",
|
||||
"Removing this user would result in the store having no owner.": "",
|
||||
"REPLACE": "",
|
||||
"Replace {0} wallet": "",
|
||||
"Replace wallet": "",
|
||||
"Replacements": "",
|
||||
"Reporting": "",
|
||||
"Request": "",
|
||||
"Request contributor data on checkout": "",
|
||||
@@ -1159,7 +1156,6 @@ namespace BTCPayServer.Services
|
||||
"Request Pairing": "",
|
||||
"Requests": "",
|
||||
"Requests may be paid in partial. They will remain valid until time expires or when paid what is due.": "",
|
||||
"Required Confirmations": "",
|
||||
"Required Field": "",
|
||||
"Rescan Wallet": "",
|
||||
"Rescan wallet for missing transactions": "",
|
||||
@@ -1312,6 +1308,7 @@ namespace BTCPayServer.Services
|
||||
"Sign the transaction": "",
|
||||
"Sign transaction": "",
|
||||
"Sign using our Vault application": "",
|
||||
"Signed out": "",
|
||||
"SIN": "",
|
||||
"Slider": "",
|
||||
"SMTP Server": "",
|
||||
@@ -1347,14 +1344,12 @@ namespace BTCPayServer.Services
|
||||
"Storage Provider": "",
|
||||
"Storage settings updated successfully": "",
|
||||
"Store": "",
|
||||
"Store email rules saved.": "",
|
||||
"Store has not enabled Pay Button": "",
|
||||
"Store Id": "",
|
||||
"Store Name": "",
|
||||
"Store Overview": "",
|
||||
"Store removed successfully": "",
|
||||
"Store Settings": "",
|
||||
"Store Speed Policy": "",
|
||||
"Store successfully created": "",
|
||||
"Store successfully updated": "",
|
||||
"Store Users": "",
|
||||
@@ -1382,9 +1377,7 @@ namespace BTCPayServer.Services
|
||||
"Test": "",
|
||||
"Test connection": "",
|
||||
"Test Email": "",
|
||||
"Test email sent — please verify you received it.": "",
|
||||
"Test Results:": "",
|
||||
"Test this email rule": "",
|
||||
"Testing": "",
|
||||
"Text": "",
|
||||
"Text to display in the tip input": "",
|
||||
@@ -1403,6 +1396,8 @@ namespace BTCPayServer.Services
|
||||
"The batch size make sure the scan do not consume too much RAM at once by rescanning several time with smaller subset of addresses.": "",
|
||||
"The brand color needs to be a valid hex color code": "",
|
||||
"The card is now configured": "",
|
||||
"The change output is too small to pay for additional fee.": "",
|
||||
"The change output is too small to pay for additional fee. (Missing {0} BTC)": "",
|
||||
"The chosen field's selected value will be copied to this field upon submission.": "",
|
||||
"The combination of words below are called your recovery phrase. The recovery phrase allows you to access and restore your wallet. Write them down on a piece of paper in the exact order:": "",
|
||||
"The configured name means the value of this field will adjust the invoice amount by multiplying it for public forms and the point of sale app.": "",
|
||||
@@ -1468,7 +1463,12 @@ namespace BTCPayServer.Services
|
||||
"The uploaded sound file needs to be an audio file": "",
|
||||
"The uploaded sound file should be less than {0}": "",
|
||||
"The URL to post purchase data.": "",
|
||||
"The user could not be added: {0}": "",
|
||||
"The user could not be invited: {0}": "",
|
||||
"The user could not be updated: {0}": "",
|
||||
"The user declined access to the vault.": "",
|
||||
"The user has been added successfully.": "",
|
||||
"The user has been updated successfully.": "",
|
||||
"The user will be permanently deleted. This action will also delete all stores, invoices, apps and data associated with your user.": "",
|
||||
"The user will not be able to change the field's value": "",
|
||||
"The values being mirrored from another field will be mapped to another value if configured.": "",
|
||||
@@ -1498,8 +1498,7 @@ namespace BTCPayServer.Services
|
||||
"There are no stores yet.": "",
|
||||
"There are no wallets yet. You can add wallets in the store setup.": "",
|
||||
"There are no webhooks yet.": "",
|
||||
"There is already an active wallet configured for {0}. Replacing it would break any existing invoices!": "",
|
||||
"There isn't any UTXO available to bump fee": "",
|
||||
"There isn't any UTXO available to bump fee with CPFP": "",
|
||||
"There was an error generating your wallet: {0}": "",
|
||||
"This account has been locked out because of multiple invalid login attempts. Please try again later.": "",
|
||||
"This account has been locked out. Please try again": "",
|
||||
@@ -1542,7 +1541,9 @@ namespace BTCPayServer.Services
|
||||
"This QR Code is only valid for 10 minutes": "",
|
||||
"This store is ready to accept transactions, good job!": "",
|
||||
"This store will still be accessible to users sharing it": "",
|
||||
"This transaction can't be RBF'd": "",
|
||||
"This transaction will change your balance:": "",
|
||||
"This version of NBXplorer is not compatible. Please update to 2.5.22 or above": "",
|
||||
"This webhook will be removed from this store.": "",
|
||||
"This webhook will be removed from this store. Are you sure?": "",
|
||||
"This will approve the user <strong>{0}</strong>.": "",
|
||||
@@ -1580,6 +1581,7 @@ namespace BTCPayServer.Services
|
||||
"Transaction broadcasted successfully ({0})": "",
|
||||
"Transaction Details": "",
|
||||
"Transaction fee rate:": "",
|
||||
"Transaction Id": "",
|
||||
"transactions": "",
|
||||
"Translations": "",
|
||||
"Translations are formatted as JSON; for example, <b>{0}</b> translates <b>{1}</b> to <b>{2}</b>.": "",
|
||||
@@ -1587,6 +1589,7 @@ namespace BTCPayServer.Services
|
||||
"Two-Factor Authentication": "",
|
||||
"Two-Factor Authentication (2FA) is an additional measure to protect your account. In addition to your password you will be asked for a second proof on login. This can be provided by an app (such as Google or Microsoft Authenticator) or a security device (like a Yubikey or your hardware wallet supporting FIDO2).": "",
|
||||
"Type": "",
|
||||
"Unable to create the replacement transaction ({0})": "",
|
||||
"Unarchive": "",
|
||||
"Unarchive this app": "",
|
||||
"Unarchive this invoice": "",
|
||||
@@ -1610,6 +1613,7 @@ namespace BTCPayServer.Services
|
||||
"Update Crowdfund": "",
|
||||
"Update Password": "",
|
||||
"Update Point of Sale": "",
|
||||
"Update Role": "",
|
||||
"Update to the latest version of BTCPay Server.": "",
|
||||
"Update Webhook": "",
|
||||
"Update your account": "",
|
||||
@@ -1619,7 +1623,6 @@ namespace BTCPayServer.Services
|
||||
"Upload Plugin": "",
|
||||
"Upload PSBT from file…": "",
|
||||
"Upload the file exported from your wallet.": "",
|
||||
"Upload Wallet": "",
|
||||
"Uploaded By": "",
|
||||
"Url": "",
|
||||
"URL": "",
|
||||
@@ -1640,7 +1643,6 @@ namespace BTCPayServer.Services
|
||||
"Use the store’s default": "",
|
||||
"User": "",
|
||||
"User {0} accepted the invite to {1}.": "",
|
||||
"User {0} is the last owner. Their role cannot be changed.": "",
|
||||
"User accepted invitation": "",
|
||||
"User approved": "",
|
||||
"User can input custom amount": "",
|
||||
@@ -1650,6 +1652,7 @@ namespace BTCPayServer.Services
|
||||
"User enabled": "",
|
||||
"User is admin": "",
|
||||
"User is approved": "",
|
||||
"User not found": "",
|
||||
"User removed successfully.": "",
|
||||
"User successfully updated": "",
|
||||
"User unapproved": "",
|
||||
@@ -1686,15 +1689,11 @@ namespace BTCPayServer.Services
|
||||
"View all supporters": "",
|
||||
"View Invite": "",
|
||||
"View seed": "",
|
||||
"View-Only Wallet File": "",
|
||||
"View-only wallet files uploaded. The wallet will soon become available.": "",
|
||||
"Waiting for NFC to be presented...": "",
|
||||
"Wallet": "",
|
||||
"Wallet Balance": "",
|
||||
"Wallet file": "",
|
||||
"Wallet file content": "",
|
||||
"Wallet Keys File": "",
|
||||
"Wallet Password": "",
|
||||
"Wallet Recovery Seed": "",
|
||||
"Wallet settings for {0} have been updated.": "",
|
||||
"Wallet's private key is erased from the server. Higher security. To spend, you have to manually input the private key or import it into an external wallet.": "",
|
||||
@@ -1776,8 +1775,7 @@ namespace BTCPayServer.Services
|
||||
"Your password has been set.": "",
|
||||
"Your profile has been updated": "",
|
||||
"Your two-factor authenticator app will provide you with a unique code.": "",
|
||||
"Your wallet has been generated.": "",
|
||||
"Zero Confirmation": ""
|
||||
"Your wallet has been generated.": ""
|
||||
}
|
||||
""";
|
||||
Default = Translations.CreateFromJson(knownTranslations);
|
||||
|
||||
Reference in New Issue
Block a user