AbpSetting kısmı ayarların uygulanması

This commit is contained in:
Sedat ÖZTÜRK 2026-06-03 17:43:41 +03:00
parent f56eccee55
commit 921c3c6d35
11 changed files with 141 additions and 72 deletions

View file

@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ConfigureAwait.Fody" Version="3.4.0" />
<PackageReference Include="ConfigureAwait.Fody" Version="3.4.0" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.9.3">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

View file

@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ConfigureAwait.Fody" Version="3.4.0" />
<PackageReference Include="ConfigureAwait.Fody" Version="3.4.0" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.9.3">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

View file

@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ConfigureAwait.Fody" Version="3.4.0" />
<PackageReference Include="ConfigureAwait.Fody" Version="3.4.0" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.9.3">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

View file

@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ConfigureAwait.Fody" Version="3.4.0" />
<PackageReference Include="ConfigureAwait.Fody" Version="3.4.0" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.9.3">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

View file

@ -3,11 +3,15 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Sozsoft.Platform.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Identity;
using Volo.Abp.TenantManagement;
using Volo.Abp.Data;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
using Sozsoft.Platform.Data.Seeds;
namespace Sozsoft.Platform.ListForms.DynamicApi;
@ -18,79 +22,128 @@ public class ListFormDynamicApiAppService : PlatformAppService, IListFormDynamic
private readonly ITenantManager tenantManager;
private readonly IIdentityUserAppService identityUserAppService;
private readonly IIdentityRoleAppService identityRoleAppService;
private readonly IdentityUserManager userManager;
private readonly IOptions<IdentityOptions> identityOptions;
public ListFormDynamicApiAppService(
ITenantRepository tenantRepository,
ITenantManager tenantManager,
IIdentityUserAppService identityUserAppService,
IIdentityRoleAppService identityRoleAppService)
IIdentityRoleAppService identityRoleAppService,
IdentityUserManager userManager,
IOptions<IdentityOptions> identityOptions)
{
this.tenantRepository = tenantRepository;
this.tenantManager = tenantManager;
this.identityUserAppService = identityUserAppService;
this.identityRoleAppService = identityRoleAppService;
this.userManager = userManager;
this.identityOptions = identityOptions;
}
[Authorize(IdentityPermissions.Users.Create)]
public async Task PostUserInsertAsync(DynamicApiBaseInput<CreateUpdateUserInput> input)
{
var user = new IdentityUserCreateDto
{
UserName = input.Data.Email,
Name = input.Data.Name,
Surname = input.Data.Surname,
Email = input.Data.Email,
PhoneNumber = input.Data.PhoneNumber,
IsActive = input.Data.IsActive ?? true,
LockoutEnabled = true,
Password = input.Data.Password,
RoleNames = [], //input.Data.RoleNames,
};
user.SetProperty(PlatformConsts.AbpIdentity.User.WorkHour, input.Data.WorkHour);
user.SetProperty(PlatformConsts.AbpIdentity.User.DepartmentId, input.Data.DepartmentId);
user.SetProperty(PlatformConsts.AbpIdentity.User.JobPositionId, input.Data.JobPositionId);
await identityOptions.SetAsync();
await identityUserAppService.CreateAsync(user);
var verifySetting = await SettingProvider.GetOrNullAsync(PlatformConsts.AbpIdentity.Profile.General.RequireVerifiedAccount);
var verify = !string.Equals(verifySetting, "true", StringComparison.OrdinalIgnoreCase);
var phoneSetting = await SettingProvider.GetOrNullAsync(PlatformConsts.AbpIdentity.SignIn.RequireConfirmedPhoneNumber);
var phoneVerified = !string.Equals(phoneSetting, "true", StringComparison.OrdinalIgnoreCase);
var user = new IdentityUser(
GuidGenerator.Create(),
input.Data.Email,
input.Data.Email,
CurrentTenant.Id)
{
Name = input.Data.Name,
Surname = input.Data.Surname
};
user.SetIsActive(input.Data.IsActive ?? true);
user.SetPhoneNumber(input.Data.PhoneNumber, phoneVerified);
user.SetWorkHour(input.Data.WorkHour);
user.SetDepartmentId(ParseGuid(input.Data.DepartmentId));
user.SetJobPositionId(ParseGuid(input.Data.JobPositionId));
user.SetIsVerified(verify);
(await userManager.CreateAsync(user, input.Data.Password)).CheckErrors();
await userManager.SetLockoutEnabledAsync(user, true);
}
private static Guid ParseGuid(string value)
{
return Guid.TryParse(value, out var id) ? id : Guid.Empty;
}
[Authorize(IdentityPermissions.Users.Update)]
public async Task PostUserUpdateAsync(DynamicApiBaseInput<CreateUpdateUserInput> input)
{
await identityOptions.SetAsync();
if (input.Keys.IsNullOrEmpty())
{
throw new UserFriendlyException(L["RecordNotFound"]);
}
var id = Guid.Parse(input.Keys[0]!.ToString()!);
var entity = await identityUserAppService.GetAsync(id) ?? throw new EntityNotFoundException(L["RecordNotFound"]);
var user = new IdentityUserUpdateDto
var user = await userManager.GetByIdAsync(id);
if (user == null)
{
UserName = input.Data.Email ?? entity.Email,
Email = input.Data.Email ?? entity.Email,
Name = input.Data.Name ?? entity.Name,
Surname = input.Data.Surname ?? entity.Surname,
PhoneNumber = input.Data.PhoneNumber ?? entity.PhoneNumber,
IsActive = input.Data.IsActive ?? entity.IsActive,
LockoutEnabled = input.Data.LockoutEnabled ?? entity.LockoutEnabled,
//RoleNames = input.Data.RoleNames ?? identity.RoleNames,
};
if (!input.Data.Password.IsNullOrWhiteSpace())
{
user.Password = input.Data.Password;
}
if (input.Data.WorkHour != null)
{
user.SetProperty(PlatformConsts.AbpIdentity.User.WorkHour, input.Data.WorkHour);
}
if (input.Data.DepartmentId != null)
{
user.SetProperty(PlatformConsts.AbpIdentity.User.DepartmentId, input.Data.DepartmentId);
}
if (input.Data.JobPositionId != null)
{
user.SetProperty(PlatformConsts.AbpIdentity.User.JobPositionId, input.Data.JobPositionId);
throw new EntityNotFoundException(L["RecordNotFound"]);
}
await identityUserAppService.UpdateAsync(id, user);
if (!input.Data.Email.IsNullOrWhiteSpace() && input.Data.Email != user.Email)
{
(await userManager.SetUserNameAsync(user, input.Data.Email)).CheckErrors();
(await userManager.SetEmailAsync(user, input.Data.Email)).CheckErrors();
}
user.Name = input.Data.Name ?? user.Name;
user.Surname = input.Data.Surname ?? user.Surname;
if (input.Data.PhoneNumber != null)
{
user.SetPhoneNumber(input.Data.PhoneNumber, user.PhoneNumberConfirmed);
}
if (input.Data.IsActive.HasValue)
{
user.SetIsActive(input.Data.IsActive.Value);
}
if (input.Data.LockoutEnabled.HasValue)
{
(await userManager.SetLockoutEnabledAsync(user, input.Data.LockoutEnabled.Value)).CheckErrors();
}
if (!input.Data.Password.IsNullOrWhiteSpace())
{
if (await userManager.HasPasswordAsync(user))
{
(await userManager.RemovePasswordAsync(user)).CheckErrors();
}
(await userManager.AddPasswordAsync(user, input.Data.Password)).CheckErrors();
}
if (input.Data.WorkHour != null)
{
user.SetWorkHour(input.Data.WorkHour);
}
if (input.Data.DepartmentId != null)
{
user.SetDepartmentId(ParseGuid(input.Data.DepartmentId));
}
if (input.Data.JobPositionId != null)
{
user.SetJobPositionId(ParseGuid(input.Data.JobPositionId));
}
(await userManager.UpdateAsync(user)).CheckErrors();
}
//RoleAppService

View file

@ -12,9 +12,9 @@
"code": "Abp.Localization.DefaultLanguage",
"nameKey": "Abp.Localization.DefaultLanguage",
"descriptionKey": "Abp.Localization.DefaultLanguage.Description",
"defaultValue": "tr",
"defaultValue": "en",
"isVisibleToClients": false,
"providers": "T|G|D",
"providers": "G|D",
"isInherited": false,
"isEncrypted": false,
"mainGroupKey": "App.SiteManagement",
@ -48,7 +48,7 @@
"descriptionKey": "Abp.Timing.TimeZone.Description",
"defaultValue": "Turkey Standard Time",
"isVisibleToClients": false,
"providers": "T|G|D",
"providers": "G|D",
"isInherited": false,
"isEncrypted": false,
"mainGroupKey": "App.SiteManagement",
@ -642,7 +642,7 @@
"code": "Abp.Account.IsSelfRegistrationEnabled",
"nameKey": "Abp.Account.IsSelfRegistrationEnabled",
"descriptionKey": "Abp.Account.IsSelfRegistrationEnabled.Description",
"defaultValue": "True",
"defaultValue": "False",
"isVisibleToClients": false,
"providers": "G|D",
"isInherited": false,
@ -754,8 +754,8 @@
"code": "Abp.Identity.Profile.General.RequireVerifiedAccount",
"nameKey": "Abp.Identity.Profile.General.RequireVerifiedAccount",
"descriptionKey": "Abp.Identity.Profile.General.RequireVerifiedAccount.Description",
"defaultValue": "True",
"isVisibleToClients": false,
"defaultValue": "False",
"isVisibleToClients": true,
"providers": "T|G|D",
"isInherited": false,
"isEncrypted": false,
@ -995,7 +995,7 @@
"nameKey": "Abp.Identity.User.IsUserNameUpdateEnabled",
"descriptionKey": "Abp.Identity.User.IsUserNameUpdateEnabled.Description",
"defaultValue": "True",
"isVisibleToClients": false,
"isVisibleToClients": true,
"providers": "G|D",
"isInherited": false,
"isEncrypted": false,
@ -1011,7 +1011,7 @@
"nameKey": "Abp.Identity.User.IsEmailUpdateEnabled",
"descriptionKey": "Abp.Identity.User.IsEmailUpdateEnabled.Description",
"defaultValue": "True",
"isVisibleToClients": false,
"isVisibleToClients": true,
"providers": "G|D",
"isInherited": false,
"isEncrypted": false,

View file

@ -797,7 +797,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
PermissionJson = DefaultPermissionJson(PlatformConsts.IdentityPermissions.Users.Create, listFormName, PlatformConsts.IdentityPermissions.Users.Update, PlatformConsts.IdentityPermissions.Users.Delete, PlatformConsts.IdentityPermissions.Users.Export, PlatformConsts.IdentityPermissions.Users.Import, PlatformConsts.IdentityPermissions.Users.Note),
DeleteCommand = $"UPDATE \"AbpUsers\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id",
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 600, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 730, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
new () { Order=1,ColCount=1,ColSpan=1,ItemType="group",Items=[
new EditingFormItemDto { Order=1, DataField="Email", ColSpan=1, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
@ -980,6 +980,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
IsActive = true,
AllowSearch = true,
ValidationRuleJson = DefaultValidationRuleRequiredJson,
EditorOptions = EditorOptionValues.PhoneEditorOptions,
ColumnCustomizationJson = DefaultColumnCustomizationJson,
PermissionJson = DefaultFieldPermissionJson(PlatformConsts.IdentityPermissions.Users.Create, PlatformConsts.IdentityPermissions.Users.Default, PlatformConsts.IdentityPermissions.Users.Update, true, true, false),

View file

@ -93,6 +93,13 @@ public static class PlatformConsts
{
public const string GroupName = $"{Prefix.Abp}.Identity";
public static class SignIn
{
public const string Default = GroupName + ".SignIn";
public const string RequireConfirmedEmail = Default + ".RequireConfirmedEmail";
public const string RequireConfirmedPhoneNumber = Default + ".RequireConfirmedPhoneNumber";
}
public static class Profile
{
public const string Default = GroupName + ".Profile";

View file

@ -34,6 +34,7 @@ import { ProfileDto, UpdateProfileDto } from '@/proxy/account/models'
import { getProfile, updateProfile } from '@/services/account.service'
import { CountryDto, getCountry } from '@/services/home.service'
import { SelectBoxOption } from '@/types/shared'
import { useSetting } from '@/utils/hooks/useSetting'
const schema = Yup.object().shape({
name: Yup.string().min(3).max(50).required(),
@ -50,6 +51,9 @@ const General = () => {
const auth = useStoreState((state) => state.auth)
const { setUser } = useStoreActions((actions) => actions.auth.user)
const { setting } = useSetting()
const isEmailUpdateEnabled = setting('Abp.Identity.User.IsEmailUpdateEnabled')
const { translate } = useLocalization()
const cropperRef = useRef<CropperRef>(null)
const previewRef = useRef<CropperPreviewRef>(null)
@ -243,7 +247,7 @@ const General = () => {
<FormItem label={translate('::Abp.Account.EmailAddress')}>
<Input
type="text"
disabled
disabled={isEmailUpdateEnabled?.toLowerCase() !== 'true'}
prefix={<FaEnvelope className="text-xl" />}
value={profileData?.email}
></Input>

View file

@ -81,6 +81,7 @@ import { AdaptableCard, ConfirmDialog, Container } from '@/components/shared'
import { AssignedClaimViewModel, UserInfoViewModel } from '@/proxy/admin/models'
import { APP_NAME, AVATAR_URL } from '@/constants/app.constant'
import { useStoreActions, useStoreState } from '@/store'
import { useSetting } from '@/utils/hooks/useSetting'
export interface ClaimTypeDto {
claimType: string
@ -100,6 +101,8 @@ function UserDetails() {
const previewRef = useRef<CropperPreviewRef>(null)
const auth = useStoreState((state) => state.auth)
const { setUser } = useStoreActions((actions) => actions.auth.user)
const { setting } = useSetting()
const isEmailUpdateEnabled = setting('Abp.Identity.User.IsEmailUpdateEnabled')
const getUser = async (syncAvatar = true) => {
const { data } = await getUserDetail(userId || '')
@ -296,7 +299,7 @@ function UserDetails() {
<FormItem label={translate('::Abp.Account.EmailAddress')}>
<Field
type="text"
disabled
disabled={isEmailUpdateEnabled?.toLowerCase() !== 'true'}
name="email"
placeholder="Email Address"
prefix={<FaEnvelope className="text-xl" />}
@ -515,13 +518,7 @@ function UserDetails() {
) : (
<img
className="cropper max-h-[300px] max-w-[300px]"
src={
image ||
AVATAR_URL(
values.id,
values.tenantId,
)
}
src={image || AVATAR_URL(values.id, values.tenantId)}
/>
)}
<div className="flex items-start gap-4">

View file

@ -22,6 +22,7 @@ import { useNavigate } from 'react-router-dom'
import * as Yup from 'yup'
import { Helmet } from 'react-helmet'
import { APP_NAME } from '@/constants/app.constant'
import { useSetting } from '@/utils/hooks/useSetting'
type SignInFormSchema = {
userName: string
@ -62,6 +63,9 @@ const Login = () => {
}, 100)
}
const { setting } = useSetting()
const isSelfRegistrationEnabled = setting('Abp.Account.IsSelfRegistrationEnabled')
const { signIn } = useAuth()
const { translate } = useLocalization()
@ -283,12 +287,15 @@ const Login = () => {
<Button block loading={isSubmitting} variant="solid" type="submit">
{isSubmitting ? 'Signing in...' : 'Sign In'}
</Button>
{/* <div className="mt-4 text-center">
<span>{translate('::Abp.Account.SignUp.Message')} </span>
<ActionLink to={ROUTES_ENUM.authenticated.register}>
{translate('::Abp.Account.Register')}
</ActionLink>
</div> */}
{isSelfRegistrationEnabled === 'true' && (
<div className="mt-4 text-center">
<span>{translate('::Abp.Account.SignUp.Message')} </span>
<ActionLink to={ROUTES_ENUM.authenticated.register}>
{translate('::Abp.Account.Register')}
</ActionLink>
</div>
)}
</FormContainer>
</Form>
)}