Hi,
Can you create a new project to reproduce it and share with me? I will check it. thanks. shiwei.liang@volosoft.com
Hi,
Is this something that can be built into the current ABP.io Blob storage wrapper?
We have no plan to implement this feature yet.
For large files, it is recommended that you upload directly from the browser to the Azure Blob,
Here are some links:
https://techcommunity.microsoft.com/t5/apps-on-azure-blog/azure-storage-blob-upload-from-browser/ba-p/392687 https://learn.microsoft.com/en-us/azure/storage/blobs/quickstart-blobs-javascript-browser
Hi,
Because two applications are running on the localhost
domain, the browser will share the cookies.
you can try put the abp.swagger.js
file in wwwroot/swagger/ui
, It refreshes the CSRF token for every request。
var abp = abp || {};
(function() {
abp.SwaggerUIBundle = function(configObject) {
var excludeUrl = ["swagger.json", "connect/token"]
var firstRequest = true;
abp.appPath = configObject.baseUrl || abp.appPath;
var requestInterceptor = configObject.requestInterceptor;
configObject.requestInterceptor = async function(request) {
if (request.url.includes(excludeUrl[1])) {
firstRequest = true;
}
if (!excludeUrl.some(url => request.url.includes(url))) {
await fetch(`${abp.appPath}abp/Swashbuckle/SetCsrfCookie`, {
headers: request.headers
});
}
var antiForgeryToken = abp.security.antiForgery.getToken();
if (antiForgeryToken) {
request.headers[abp.security.antiForgery.tokenHeaderName] = antiForgeryToken;
}
if (!request.headers["X-Requested-With"]) {
request.headers["X-Requested-With"] = "XMLHttpRequest";
}
if (requestInterceptor) {
requestInterceptor(request);
}
return request;
};
return SwaggerUIBundle(configObject);
}
})();
Hi @cellero
You can try to change the namespace Volo.Abp.AspNetCore........ApplicationLayout.TopMenu
to Volo.Abp.AspNetCore........ApplicationLayout.SideMenu
You can remove the file when the next patch(7.0.2) version is released.
See: https://support.abp.io/QA/Questions/4469/Entering-invalid-phone-number-locks-you-out-of-the-system#answer-e1ededc6-2ed4-c0e9-61dd-3a09383bd39e
Hi,
Yes, it's a problem. we will fix it in the next version.
You can try put the Default.js
file in your Pages\Account\Components\ProfileManagementGroup\\PersonalInfo
path.
Default.js
(function ($) {
$(function () {
var l = abp.localization.getResource("AbpAccount");
var _profileService = volo.abp.account.profile;
var _accountService = volo.abp.account.account;
var _confirmPhoneNumberModal = new abp.ModalManager(
abp.appPath + "Account/Components/ProfileManagementGroup/PersonalInfo/ConfirmPhoneNumberModal"
);
var $email = $('#PersonalSettingsForm').find("#Email");
var $verifyEmail = $("#VerifyEmailButton");
var $emailVerified = $("#EmailVerified");
var $emailNotVerified = $("#EmailNotVerified");
var $phone = $('#PersonalSettingsForm').find("#PhoneNumber");
var $verifyPhone = $("#VerifyPhoneButton");
var $phoneVerified = $("#PhoneVerified");
var $phoneNotVerified = $("#PhoneNotVerified");
$('#PersonalSettingsForm').find("#Email").keyup(function () {
if ($(this).val() !== $(this).attr("data-saved-email")) {
$("#VerifyEmailButton").hide();
$("#EmailVerified").hide();
$("#EmailNotVerified").show();
} else if ($(this).attr("data-email-verified") === "False") {
$("#VerifyEmailButton").show();
$("#EmailNotVerified").hide();
} else if ($(this).attr("data-email-verified") === "True") {
$("#EmailVerified").show();
$("#EmailNotVerified").hide();
}
});
$('#PersonalSettingsForm').find("#PhoneNumber").keyup(function () {
if ($(this).val() !== $(this).attr("data-saved-phone")) {
$("#VerifyPhoneButton").hide();
$("#PhoneVerified").hide();
if ($(this).val() !== "") {
$("#PhoneNotVerified").show();
} else {
$("#PhoneNotVerified").hide();
}
} else if ($(this).attr("data-phone-verified") === "False") {
if ($(this).val() !== "") {
$("#VerifyPhoneButton").show();
}
$("#PhoneNotVerified").hide();
} else if ($(this).attr("data-phone-verified") === "True") {
if ($(this).val() !== "") {
$("#PhoneVerified").show();
}
$("#PhoneNotVerified").hide();
}
});
$("#VerifyEmailButton").on("click", "", function () {
var returnUrl = "/";
var returnUrlLink = $("#returnUrlLink");
if(returnUrlLink.length === 1){
returnUrl = returnUrlLink.attr("href");
}
_accountService
.sendEmailConfirmationToken({
userId: $('#CurrentUserId').val(),
appName: "MVC",
returnUrl:returnUrl,
returnUrlHash: "",
})
.then(function () {
abp.notify.success(
l(
"EmailConfirmationSentMessage",
$('#PersonalSettingsForm').find("#Email").val()
)
);
$("#VerifyEmailButton").hide();
});
});
$("#VerifyPhoneButton").on("click", "", function () {
_confirmPhoneNumberModal.open();
});
var askForVerify = function () {
abp.message.confirm(
" ",
l("DoYouWantToVerifyPhoneNumberMessage"),
function (isConfirmed) {
if (isConfirmed) {
$("#VerifyPhoneButton").click();
}
}
);
};
$("#PersonalSettingsForm").submit(function (e) {
e.preventDefault();
if (!$("#PersonalSettingsForm").valid()) {
return false;
}
var input = $("#PersonalSettingsForm").serializeFormToObject(false);
_profileService.update(input).then(function (result) {
abp.notify.success(l("PersonalSettingsSaved"));
if (input.Email !== $email.attr("data-saved-email")) {
$verifyEmail.show();
$emailVerified.hide();
$email.attr("data-email-verified", "False");
}
$email.attr("data-saved-email", $email.val());
$emailNotVerified.hide();
if (!input.PhoneNumber || input.PhoneNumber === "") {
$verifyPhone.hide();
$phoneVerified.hide();
$phoneNotVerified.hide();
$phone.attr("data-saved-phone", input.PhoneNumber);
return;
}
if (
$phone.attr("data-saved-phone") === input.PhoneNumber ||
$verifyPhone.length < 1
) {
return;
}
$verifyPhone.show();
$phoneVerified.hide();
$phoneNotVerified.hide();
$phone.attr("data-saved-phone", input.PhoneNumber);
$phone.attr("data-phone-verified", "False");
askForVerify();
});
});
_confirmPhoneNumberModal.onResult(function () {
$verifyPhone.hide();
$phoneNotVerified.hide();
$phoneVerified.show();
$phone.attr("data-phone-verified", "True");
});
});
})(jQuery);
Hi,
Ok, I think the merchant is a user right? you need to custom the text template module.
EfCoreTextTemplateContentRepository
to change the GetAsync
and FindAsync
methods.For example:
[ExposeServices(typeof(IEfCoreTextTemplateContentRepository))]
public class MyEfCoreTextTemplateContentRepository : EfCoreTextTemplateContentRepository
{
public override async Task<TextTemplateContent> GetAsync(
string name,
string cultureName = null,
CancellationToken cancellationToken = default)
{
// You need to care if the user is logged in or not
var userId = currentUser.GetId();
return await GetAsync(x => x.Name == name && x.CultureName == cultureName && x.CreatorId == userId, cancellationToken: GetCancellationToken(cancellationToken));
}
//......
}
Configure<TextTemplateManagementOptions>(options =>
{
options.MinimumCacheDuration = TimeSpan.Zero; // use zero to avoid caching
});
Hi,
Can you share the .csproj
file content?
BTW, it's working for me:
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(TokenController))]
public class MyTokenController : Volo.Abp.OpenIddict.Controllers.TokenController
{
protected override Task<IActionResult> HandlePasswordAsync(OpenIddictRequest request)
{
return base.HandlePasswordAsync(request);
}
}
Hi,
The Text Template is tenant-isolated, and each tenant can customize the template.