Tenantlı uygulama için Login düzenlemesi
This commit is contained in:
parent
67286232da
commit
f9c5910813
25 changed files with 226 additions and 131 deletions
|
|
@ -19,7 +19,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="Scriban" Version="7.2.0" PrivateAssets="all" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="Scriban" Version="7.2.0" PrivateAssets="all" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ public class MailTrackingManager : DomainService
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task StartAsync()
|
public async Task StartAsync()
|
||||||
{
|
{
|
||||||
|
// https://us-east-1.console.aws.amazon.com/iam/home?region=eu-central-1#/users
|
||||||
|
// https://eu-central-1.console.aws.amazon.com/ses/home?region=eu-central-1#/identities/system%40sozsoft.com?tabId=authentication
|
||||||
var accessKey = configuration.GetValue<string>(AmazonSesEmailSettingNames.AccessKey);
|
var accessKey = configuration.GetValue<string>(AmazonSesEmailSettingNames.AccessKey);
|
||||||
var accessKeyId = configuration.GetValue<string>(AmazonSesEmailSettingNames.AccessKeyId);
|
var accessKeyId = configuration.GetValue<string>(AmazonSesEmailSettingNames.AccessKeyId);
|
||||||
var region = configuration.GetValue<string>(AmazonSesEmailSettingNames.Region);
|
var region = configuration.GetValue<string>(AmazonSesEmailSettingNames.Region);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@
|
||||||
<PackageReference Include="Volo.Abp.TextTemplating.Razor" Version="10.0.0" />
|
<PackageReference Include="Volo.Abp.TextTemplating.Razor" Version="10.0.0" />
|
||||||
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="Scriban" Version="7.2.0" PrivateAssets="all" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="Scriban" Version="7.2.0" PrivateAssets="all" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ public class AmazonSesEmailSender : EmailSenderBase, ISozsoftEmailSender, ITrans
|
||||||
await BackgroundJobManager.EnqueueAsync(
|
await BackgroundJobManager.EnqueueAsync(
|
||||||
new ErpBackgroundEmailSendingJobArgs
|
new ErpBackgroundEmailSendingJobArgs
|
||||||
{
|
{
|
||||||
|
TenantId = CurrentTenant.Id,
|
||||||
To = to,
|
To = to,
|
||||||
Sender = sender,
|
Sender = sender,
|
||||||
Params = @params,
|
Params = @params,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Volo.Abp.BackgroundJobs;
|
using Volo.Abp.BackgroundJobs;
|
||||||
using Volo.Abp.DependencyInjection;
|
using Volo.Abp.DependencyInjection;
|
||||||
|
using Volo.Abp.MultiTenancy;
|
||||||
|
|
||||||
namespace Sozsoft.Sender.Mail;
|
namespace Sozsoft.Sender.Mail;
|
||||||
|
|
||||||
|
|
@ -7,13 +8,19 @@ public class ErpBackgroundEmailSendingJob :
|
||||||
AsyncBackgroundJob<ErpBackgroundEmailSendingJobArgs>, ITransientDependency
|
AsyncBackgroundJob<ErpBackgroundEmailSendingJobArgs>, ITransientDependency
|
||||||
{
|
{
|
||||||
protected ISozsoftEmailSender EmailSender { get; }
|
protected ISozsoftEmailSender EmailSender { get; }
|
||||||
|
protected ICurrentTenant CurrentTenant { get; }
|
||||||
|
|
||||||
public ErpBackgroundEmailSendingJob(ISozsoftEmailSender emailSender)
|
public ErpBackgroundEmailSendingJob(
|
||||||
|
ISozsoftEmailSender emailSender,
|
||||||
|
ICurrentTenant currentTenant)
|
||||||
{
|
{
|
||||||
EmailSender = emailSender;
|
EmailSender = emailSender;
|
||||||
|
CurrentTenant = currentTenant;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task ExecuteAsync(ErpBackgroundEmailSendingJobArgs args)
|
public override async Task ExecuteAsync(ErpBackgroundEmailSendingJobArgs args)
|
||||||
|
{
|
||||||
|
using (CurrentTenant.Change(args.TenantId))
|
||||||
{
|
{
|
||||||
//await EmailSender.SendEmailAsync(args.Template, args.To, args.Params, args.Subject);
|
//await EmailSender.SendEmailAsync(args.Template, args.To, args.Params, args.Subject);
|
||||||
await EmailSender.SendEmailAsync(
|
await EmailSender.SendEmailAsync(
|
||||||
|
|
@ -25,4 +32,4 @@ public class ErpBackgroundEmailSendingJob :
|
||||||
args.Attachments);
|
args.Attachments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
namespace Sozsoft.Sender.Mail;
|
using Volo.Abp.MultiTenancy;
|
||||||
|
|
||||||
|
namespace Sozsoft.Sender.Mail;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ErpBackgroundEmailSendingJobArgs
|
public class ErpBackgroundEmailSendingJobArgs : IMultiTenant
|
||||||
{
|
{
|
||||||
|
public Guid? TenantId { get; set; }
|
||||||
|
|
||||||
public string[] To { get; set; }
|
public string[] To { get; set; }
|
||||||
|
|
||||||
public KeyValuePair<string, string>? Sender { get; set; }
|
public KeyValuePair<string, string>? Sender { get; set; }
|
||||||
|
|
@ -14,6 +18,4 @@ public class ErpBackgroundEmailSendingJobArgs
|
||||||
public Dictionary<string, string>? Attachments { get; set; }
|
public Dictionary<string, string>? Attachments { get; set; }
|
||||||
|
|
||||||
public string? TextContent { get; set; }
|
public string? TextContent { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
|
||||||
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="Scriban" Version="7.2.0" PrivateAssets="all" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,9 @@ using System.Threading.Tasks;
|
||||||
using Sozsoft.Languages;
|
using Sozsoft.Languages;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Volo.Abp.Application.Services;
|
using Volo.Abp.Application.Services;
|
||||||
using Volo.Abp.Domain.Repositories;
|
using Volo.Abp.MultiTenancy;
|
||||||
using Volo.Abp.SettingManagement;
|
using Volo.Abp.SettingManagement;
|
||||||
using Volo.Abp.Settings;
|
using Volo.Abp.Settings;
|
||||||
using SettingDefinition = Sozsoft.Settings.Entities.SettingDefinition;
|
|
||||||
|
|
||||||
namespace Sozsoft.Settings;
|
namespace Sozsoft.Settings;
|
||||||
|
|
||||||
|
|
@ -20,17 +19,20 @@ public class SettingUiAppService : ApplicationService, ISettingUiAppService
|
||||||
private readonly ISettingDefinitionManager settingDefinitionManager;
|
private readonly ISettingDefinitionManager settingDefinitionManager;
|
||||||
private readonly ISettingManager settingManager;
|
private readonly ISettingManager settingManager;
|
||||||
private readonly ErpSettingDefinitionManager ErpSettingDefinitionManager;
|
private readonly ErpSettingDefinitionManager ErpSettingDefinitionManager;
|
||||||
|
private readonly ICurrentTenant currentTenant;
|
||||||
|
|
||||||
public SettingUiAppService(
|
public SettingUiAppService(
|
||||||
ILanguageKeyIntegrationService languageKeyIntegrationService,
|
ILanguageKeyIntegrationService languageKeyIntegrationService,
|
||||||
ISettingDefinitionManager settingDefinitionManager,
|
ISettingDefinitionManager settingDefinitionManager,
|
||||||
ISettingManager settingManager,
|
ISettingManager settingManager,
|
||||||
ErpSettingDefinitionManager ErpSettingDefinitionManager)
|
ErpSettingDefinitionManager ErpSettingDefinitionManager,
|
||||||
|
ICurrentTenant currentTenant)
|
||||||
{
|
{
|
||||||
this.languageKeyIntegrationService = languageKeyIntegrationService;
|
this.languageKeyIntegrationService = languageKeyIntegrationService;
|
||||||
this.settingDefinitionManager = settingDefinitionManager;
|
this.settingDefinitionManager = settingDefinitionManager;
|
||||||
this.settingManager = settingManager;
|
this.settingManager = settingManager;
|
||||||
this.ErpSettingDefinitionManager = ErpSettingDefinitionManager;
|
this.ErpSettingDefinitionManager = ErpSettingDefinitionManager;
|
||||||
|
this.currentTenant = currentTenant;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<List<MainGroupedSettingDto>> GetListAsync()
|
public virtual async Task<List<MainGroupedSettingDto>> GetListAsync()
|
||||||
|
|
@ -95,15 +97,18 @@ public class SettingUiAppService : ApplicationService, ISettingUiAppService
|
||||||
{
|
{
|
||||||
if (setting.Providers.IsNullOrEmpty())
|
if (setting.Providers.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
await settingManager.SetForCurrentUserAsync(setting.Name, value);
|
if (currentTenant.Id.HasValue)
|
||||||
|
{
|
||||||
|
await settingManager.SetForCurrentTenantAsync(setting.Name, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (setting.Providers.Any(p => p == UserSettingValueProvider.ProviderName))
|
await settingManager.SetGlobalAsync(setting.Name, value);
|
||||||
{
|
|
||||||
await settingManager.SetForCurrentUserAsync(setting.Name, value);
|
|
||||||
}
|
}
|
||||||
else if (setting.Providers.Any(p => p == TenantSettingValueProvider.ProviderName))
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (setting.Providers.Any(p => p == TenantSettingValueProvider.ProviderName) && currentTenant.Id.HasValue)
|
||||||
{
|
{
|
||||||
await settingManager.SetForCurrentTenantAsync(setting.Name, value);
|
await settingManager.SetForCurrentTenantAsync(setting.Name, value);
|
||||||
}
|
}
|
||||||
|
|
@ -111,6 +116,10 @@ public class SettingUiAppService : ApplicationService, ISettingUiAppService
|
||||||
{
|
{
|
||||||
await settingManager.SetGlobalAsync(setting.Name, value);
|
await settingManager.SetGlobalAsync(setting.Name, value);
|
||||||
}
|
}
|
||||||
|
else if (setting.Providers.Any(p => p == UserSettingValueProvider.ProviderName))
|
||||||
|
{
|
||||||
|
await settingManager.SetForCurrentUserAsync(setting.Name, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="Scriban" Version="7.2.0" PrivateAssets="all" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MailKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
<PackageReference Include="MimeKit" Version="4.16.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="Scriban" Version="7.2.0" PrivateAssets="all" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,7 @@
|
||||||
"code": "App.SiteManagement.General.NewMemberNotificationEmails",
|
"code": "App.SiteManagement.General.NewMemberNotificationEmails",
|
||||||
"nameKey": "App.SiteManagement.General.NewMemberNotificationEmails",
|
"nameKey": "App.SiteManagement.General.NewMemberNotificationEmails",
|
||||||
"descriptionKey": "App.SiteManagement.General.NewMemberNotificationEmails.Description",
|
"descriptionKey": "App.SiteManagement.General.NewMemberNotificationEmails.Description",
|
||||||
"defaultValue": "SYSTEM@SOZSOFT.COM",
|
"defaultValue": "system@sozsoft.com",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": "G|D",
|
"providers": "G|D",
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
|
|
@ -274,7 +274,7 @@
|
||||||
"code": "App.SiteManagement.General.TimedLoginEmails",
|
"code": "App.SiteManagement.General.TimedLoginEmails",
|
||||||
"nameKey": "App.SiteManagement.General.TimedLoginEmails",
|
"nameKey": "App.SiteManagement.General.TimedLoginEmails",
|
||||||
"descriptionKey": "App.SiteManagement.General.TimedLoginEmails.Description",
|
"descriptionKey": "App.SiteManagement.General.TimedLoginEmails.Description",
|
||||||
"defaultValue": "SYSTEM@SOZSOFT.COM",
|
"defaultValue": "system@sozsoft.com",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": "G|D",
|
"providers": "G|D",
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
|
|
@ -466,7 +466,7 @@
|
||||||
"code": "Abp.Mailing.DefaultFromAddress",
|
"code": "Abp.Mailing.DefaultFromAddress",
|
||||||
"nameKey": "Abp.Mailing.DefaultFromAddress",
|
"nameKey": "Abp.Mailing.DefaultFromAddress",
|
||||||
"descriptionKey": "Abp.Mailing.DefaultFromAddress.Description",
|
"descriptionKey": "Abp.Mailing.DefaultFromAddress.Description",
|
||||||
"defaultValue": "SYSTEM@SOZSOFT.COM",
|
"defaultValue": "system@sozsoft.com",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": "T|G|D",
|
"providers": "T|G|D",
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
|
|
@ -482,7 +482,7 @@
|
||||||
"code": "Abp.Mailing.Smtp.UserName",
|
"code": "Abp.Mailing.Smtp.UserName",
|
||||||
"nameKey": "Abp.Mailing.Smtp.UserName",
|
"nameKey": "Abp.Mailing.Smtp.UserName",
|
||||||
"descriptionKey": "Abp.Mailing.Smtp.UserName.Description",
|
"descriptionKey": "Abp.Mailing.Smtp.UserName.Description",
|
||||||
"defaultValue": "SYSTEM@SOZSOFT.COM",
|
"defaultValue": "system@sozsoft.com",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": "T|G|D",
|
"providers": "T|G|D",
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
|
|
@ -610,7 +610,7 @@
|
||||||
"code": "Abp.Mailing.AWS.AccessKey",
|
"code": "Abp.Mailing.AWS.AccessKey",
|
||||||
"nameKey": "Abp.Mailing.AWS.AccessKey",
|
"nameKey": "Abp.Mailing.AWS.AccessKey",
|
||||||
"descriptionKey": "Abp.Mailing.AWS.AccessKey.Description",
|
"descriptionKey": "Abp.Mailing.AWS.AccessKey.Description",
|
||||||
"defaultValue": "aXW8L21rP6dPO6Txj76Be2FCpWRBa25EMrSAVL76",
|
"defaultValue": "SibFBAMiSApvz+NChYmlgZmx25JNbximemIDOFps",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": "T|G|D",
|
"providers": "T|G|D",
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
|
|
@ -626,7 +626,7 @@
|
||||||
"code": "Abp.Mailing.AWS.AccessKeyId",
|
"code": "Abp.Mailing.AWS.AccessKeyId",
|
||||||
"nameKey": "Abp.Mailing.AWS.AccessKeyId",
|
"nameKey": "Abp.Mailing.AWS.AccessKeyId",
|
||||||
"descriptionKey": "Abp.Mailing.AWS.AccessKeyId.Description",
|
"descriptionKey": "Abp.Mailing.AWS.AccessKeyId.Description",
|
||||||
"defaultValue": "AKIATULUYBLX4IY3S2P1",
|
"defaultValue": "AKIA5OCSDJB5KOQY74NV",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": "T|G|D",
|
"providers": "T|G|D",
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
|
|
@ -722,7 +722,7 @@
|
||||||
"code": "Abp.Account.Captcha.SiteKey",
|
"code": "Abp.Account.Captcha.SiteKey",
|
||||||
"nameKey": "Abp.Account.Captcha.SiteKey",
|
"nameKey": "Abp.Account.Captcha.SiteKey",
|
||||||
"descriptionKey": "Abp.Account.Captcha.SiteKey.Description",
|
"descriptionKey": "Abp.Account.Captcha.SiteKey.Description",
|
||||||
"defaultValue": "0x4AAAAAAAGadwQME-GSYuJU",
|
"defaultValue": "0x4AAAAAABdEjmiXxcl0j7jp",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": "G|D",
|
"providers": "G|D",
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
|
|
@ -738,7 +738,7 @@
|
||||||
"code": "Abp.Account.Captcha.SecretKey",
|
"code": "Abp.Account.Captcha.SecretKey",
|
||||||
"nameKey": "Abp.Account.Captcha.SecretKey",
|
"nameKey": "Abp.Account.Captcha.SecretKey",
|
||||||
"descriptionKey": "Abp.Account.Captcha.SecretKey.Description",
|
"descriptionKey": "Abp.Account.Captcha.SecretKey.Description",
|
||||||
"defaultValue": "0x4AAAAAAAGad_f_WP47IcNBs9FTu5DhNX8",
|
"defaultValue": "0x4AAAAAABdEjhw1A8sJZUvQX8-CgqvB3mE",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": "G|D",
|
"providers": "G|D",
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ public class PlatformBackgroundWorkerTemplateDefinitionProvider : TemplateDefini
|
||||||
foreach (var worker in workers.Where(a =>
|
foreach (var worker in workers.Where(a =>
|
||||||
a.IsActive &&
|
a.IsActive &&
|
||||||
a.WorkerType == WorkerTypeEnum.MailQueueWorker &&
|
a.WorkerType == WorkerTypeEnum.MailQueueWorker &&
|
||||||
a.Options != null && a.Options != string.Empty).ToList())
|
a.Options != null).ToList().Where(a => !a.Options.IsNullOrWhiteSpace()))
|
||||||
{
|
{
|
||||||
var Options = JsonSerializer.Deserialize<MailQueueWorkerOptions>(worker.Options);
|
var Options = JsonSerializer.Deserialize<MailQueueWorkerOptions>(worker.Options);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ const Captcha = forwardRef((props: CaptchaProps, ref: Ref<TurnstileInstance>) =>
|
||||||
const { className, onError, onExpire, onSuccess } = props
|
const { className, onError, onExpire, onSuccess } = props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<Turnstile
|
<Turnstile
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={className ?? 'mb-4 mx-auto'}
|
className={className ?? 'mb-4 mx-auto'}
|
||||||
|
|
@ -21,7 +20,6 @@ const Captcha = forwardRef((props: CaptchaProps, ref: Ref<TurnstileInstance>) =>
|
||||||
onExpire={onExpire}
|
onExpire={onExpire}
|
||||||
onSuccess={onSuccess}
|
onSuccess={onSuccess}
|
||||||
/>
|
/>
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
Captcha.displayName = 'Captcha'
|
Captcha.displayName = 'Captcha'
|
||||||
|
|
|
||||||
148
ui/src/components/shared/TenantSelector.tsx
Normal file
148
ui/src/components/shared/TenantSelector.tsx
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
import Input from '@/components/ui/Input'
|
||||||
|
import { getTenantByNameDetail } from '@/services/tenant.service'
|
||||||
|
import { useStoreActions, useStoreState } from '@/store'
|
||||||
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
import { defaultDomain, getSubdomain } from '@/utils/subdomain'
|
||||||
|
import type { CSSProperties } from 'react'
|
||||||
|
import { useCallback, useEffect, useRef } from 'react'
|
||||||
|
|
||||||
|
const hiddenTenantStyle: CSSProperties = {
|
||||||
|
opacity: 0,
|
||||||
|
position: 'absolute',
|
||||||
|
pointerEvents: 'none',
|
||||||
|
height: 0,
|
||||||
|
margin: 0,
|
||||||
|
padding: 0,
|
||||||
|
border: 'none',
|
||||||
|
}
|
||||||
|
|
||||||
|
const TenantSelector = () => {
|
||||||
|
const { translate } = useLocalization()
|
||||||
|
const isMultiTenant = useStoreState((state) => state.abpConfig.config?.multiTenancy.isEnabled)
|
||||||
|
const tenantName = useStoreState((state) => state.locale.currentTenantName)
|
||||||
|
const { setTenantName } = useStoreActions((actions) => actions.locale)
|
||||||
|
const { setTenant } = useStoreActions((actions) => actions.auth.tenant)
|
||||||
|
const { setWarning } = useStoreActions((actions) => actions.base.messages)
|
||||||
|
const requestIdRef = useRef(0)
|
||||||
|
const lastRequestedTenantNameRef = useRef<string>()
|
||||||
|
|
||||||
|
const subDomainName = getSubdomain()
|
||||||
|
const isSubdomainTenant = !!subDomainName && subDomainName !== defaultDomain
|
||||||
|
const tenantStyle = isSubdomainTenant ? hiddenTenantStyle : undefined
|
||||||
|
|
||||||
|
const setWarningTimeout = useCallback(
|
||||||
|
(message: string) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setWarning(message)
|
||||||
|
}, 100)
|
||||||
|
},
|
||||||
|
[setWarning],
|
||||||
|
)
|
||||||
|
|
||||||
|
const redirectToMainDomain = useCallback(
|
||||||
|
(name: string) => {
|
||||||
|
setTenantName(undefined)
|
||||||
|
const parts = window.location.hostname.split('.')
|
||||||
|
const mainDomain = parts.length >= 3 ? parts.slice(1).join('.') : window.location.hostname
|
||||||
|
setWarningTimeout(
|
||||||
|
`"${name}" kurumuna ait kayıt bulunamadı.\nAna sayfaya yönlendiriliyorsunuz...`,
|
||||||
|
)
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = `${window.location.protocol}//${mainDomain}`
|
||||||
|
}, 3000)
|
||||||
|
},
|
||||||
|
[setTenantName, setWarningTimeout],
|
||||||
|
)
|
||||||
|
|
||||||
|
const fetchDataByName = useCallback(
|
||||||
|
async (name: string, isSubdomain = false) => {
|
||||||
|
if (!isSubdomain && name === lastRequestedTenantNameRef.current) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lastRequestedTenantNameRef.current = name
|
||||||
|
const requestId = requestIdRef.current + 1
|
||||||
|
requestIdRef.current = requestId
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
try {
|
||||||
|
const response = await getTenantByNameDetail(name)
|
||||||
|
|
||||||
|
if (requestId !== requestIdRef.current) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.data) {
|
||||||
|
setTenant({
|
||||||
|
tenantId: response.data.id,
|
||||||
|
tenantName: response.data.name,
|
||||||
|
menuGroup: response.data.menuGroup,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setTenant(undefined)
|
||||||
|
if (isSubdomain) redirectToMainDomain(name)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
if (requestId !== requestIdRef.current) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setTenant(undefined)
|
||||||
|
if (isSubdomain) redirectToMainDomain(name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setTenant(undefined)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[redirectToMainDomain, setTenant],
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleTenantNameChange = (value: string) => {
|
||||||
|
setTenantName(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTenantNameBlur = () => {
|
||||||
|
if (subDomainName) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchDataByName(tenantName || '')
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isMultiTenant) {
|
||||||
|
setTenant(undefined)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subDomainName) {
|
||||||
|
setTenantName(subDomainName)
|
||||||
|
fetchDataByName(subDomainName, true)
|
||||||
|
}
|
||||||
|
}, [fetchDataByName, isMultiTenant, setTenant, setTenantName, subDomainName])
|
||||||
|
|
||||||
|
if (!isMultiTenant) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<label className="form-label mb-2" style={tenantStyle}>
|
||||||
|
{translate('::Organization')}
|
||||||
|
</label>
|
||||||
|
<div className="mb-4">
|
||||||
|
<Input
|
||||||
|
placeholder={translate('::Organization')}
|
||||||
|
value={tenantName ?? ''}
|
||||||
|
onChange={(event) => handleTenantNameChange(event.target.value)}
|
||||||
|
onBlur={handleTenantNameBlur}
|
||||||
|
style={tenantStyle}
|
||||||
|
aria-hidden={isSubdomainTenant ? 'true' : 'false'}
|
||||||
|
autoFocus={!isSubdomainTenant}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TenantSelector
|
||||||
|
|
@ -19,6 +19,7 @@ export { default as SegmentItemOption } from './SegmentItemOption'
|
||||||
export { default as StickyFooter } from './StickyFooter'
|
export { default as StickyFooter } from './StickyFooter'
|
||||||
export { default as SvgIcon } from './SvgIcon'
|
export { default as SvgIcon } from './SvgIcon'
|
||||||
export { default as TableRowSkeleton } from './loaders/TableRowSkeleton'
|
export { default as TableRowSkeleton } from './loaders/TableRowSkeleton'
|
||||||
|
export { default as TenantSelector } from './TenantSelector'
|
||||||
export { default as TextBlockSkeleton } from './loaders/TextBlockSkeleton'
|
export { default as TextBlockSkeleton } from './loaders/TextBlockSkeleton'
|
||||||
export { default as TextEllipsis } from './TextEllipsis'
|
export { default as TextEllipsis } from './TextEllipsis'
|
||||||
export { default as UsersAvatarGroup } from './UsersAvatarGroup'
|
export { default as UsersAvatarGroup } from './UsersAvatarGroup'
|
||||||
|
|
|
||||||
|
|
@ -456,13 +456,15 @@ function OrgChartNode({
|
||||||
style={{ cursor: dragging ? 'grabbing' : 'grab' }}
|
style={{ cursor: dragging ? 'grabbing' : 'grab' }}
|
||||||
>
|
>
|
||||||
{/* Header bar */}
|
{/* Header bar */}
|
||||||
<div data-header="" className={`${headerBg} rounded-t-xl px-3 py-2 flex items-center gap-2`}>
|
<div data-header="" className={`${headerBg} rounded-t-xl px-3 py-2 flex items-center gap-2 dark:bg-gray-900 dark:text-gray-100`}>
|
||||||
{mode === 'department' ? (
|
{mode === 'department' ? (
|
||||||
<FaBuilding className="w-3 h-3 text-white opacity-80 flex-shrink-0" />
|
<FaBuilding className="w-3 h-3 text-white opacity-80 flex-shrink-0" />
|
||||||
) : (
|
) : (
|
||||||
<FaBriefcase className="w-3 h-3 text-white opacity-80 flex-shrink-0" />
|
<FaBriefcase className="w-3 h-3 text-white opacity-80 flex-shrink-0" />
|
||||||
)}
|
)}
|
||||||
<span data-node-name="" className="text-white font-semibold text-xs truncate flex-1">{node.name}</span>
|
<span data-node-name="" className="text-white font-semibold text-xs truncate flex-1 dark:bg-gray-900 dark:text-gray-100">
|
||||||
|
{node.name}
|
||||||
|
</span>
|
||||||
{hasChildren && (
|
{hasChildren && (
|
||||||
<button
|
<button
|
||||||
data-stop-drag="true"
|
data-stop-drag="true"
|
||||||
|
|
@ -514,7 +516,7 @@ function OrgChartNode({
|
||||||
|
|
||||||
{/* Child count badge */}
|
{/* Child count badge */}
|
||||||
{hasChildren && (
|
{hasChildren && (
|
||||||
<div className="absolute -bottom-2.5 left-1/2 -translate-x-1/2 bg-white border border-slate-200 rounded-full px-2 py-0.5 text-xs text-slate-500 shadow-sm whitespace-nowrap z-10">
|
<div className="absolute -bottom-2.5 left-1/2 -translate-x-1/2 bg-white border border-slate-200 rounded-full px-2 py-0.5 text-xs text-slate-500 shadow-sm whitespace-nowrap z-10 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-100">
|
||||||
{node.children.length}
|
{node.children.length}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,9 @@ const LoginHistoryIcon = ({ type }: { type: string }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
password: Yup.string().required('Password Required'),
|
password: Yup.string().required(),
|
||||||
newPassword: Yup.string()
|
newPassword: Yup.string()
|
||||||
.required('Enter your new password')
|
.required()
|
||||||
.min(6, 'Too Short!')
|
.min(6, 'Too Short!')
|
||||||
.matches(
|
.matches(
|
||||||
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{6,})/,
|
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{6,})/,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import ActionLink from '@/components/shared/ActionLink'
|
import ActionLink from '@/components/shared/ActionLink'
|
||||||
import Captcha from '@/components/shared/Captcha'
|
import Captcha from '@/components/shared/Captcha'
|
||||||
|
import TenantSelector from '@/components/shared/TenantSelector'
|
||||||
import Alert from '@/components/ui/Alert'
|
import Alert from '@/components/ui/Alert'
|
||||||
import Button from '@/components/ui/Button'
|
import Button from '@/components/ui/Button'
|
||||||
import { FormContainer, FormItem } from '@/components/ui/Form'
|
import { FormContainer, FormItem } from '@/components/ui/Form'
|
||||||
|
|
@ -84,6 +85,7 @@ const ExtendLogin = () => {
|
||||||
{message}
|
{message}
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
<TenantSelector />
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
email: userName,
|
email: userName,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { TenantSelector } from '@/components/shared'
|
||||||
import ActionLink from '@/components/shared/ActionLink'
|
import ActionLink from '@/components/shared/ActionLink'
|
||||||
import Captcha from '@/components/shared/Captcha'
|
import Captcha from '@/components/shared/Captcha'
|
||||||
import Alert from '@/components/ui/Alert'
|
import Alert from '@/components/ui/Alert'
|
||||||
|
|
@ -87,6 +88,7 @@ const ForgotPassword = () => {
|
||||||
{message}
|
{message}
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
<TenantSelector />
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
email: userName,
|
email: userName,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { FailedSignInResponse } from '@/proxy/auth/models'
|
||||||
import ActionLink from '@/components/shared/ActionLink'
|
import ActionLink from '@/components/shared/ActionLink'
|
||||||
import Captcha from '@/components/shared/Captcha'
|
import Captcha from '@/components/shared/Captcha'
|
||||||
import PasswordInput from '@/components/shared/PasswordInput'
|
import PasswordInput from '@/components/shared/PasswordInput'
|
||||||
|
import TenantSelector from '@/components/shared/TenantSelector'
|
||||||
import Alert from '@/components/ui/Alert'
|
import Alert from '@/components/ui/Alert'
|
||||||
import Button from '@/components/ui/Button'
|
import Button from '@/components/ui/Button'
|
||||||
import Checkbox from '@/components/ui/Checkbox'
|
import Checkbox from '@/components/ui/Checkbox'
|
||||||
|
|
@ -9,7 +10,6 @@ import { FormContainer, FormItem } from '@/components/ui/Form'
|
||||||
import Input from '@/components/ui/Input'
|
import Input from '@/components/ui/Input'
|
||||||
import PlatformLoginResultType from '@/constants/login.result.enum'
|
import PlatformLoginResultType from '@/constants/login.result.enum'
|
||||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||||
import { getTenantByNameDetail } from '@/services/tenant.service'
|
|
||||||
import { useStoreActions, useStoreState } from '@/store'
|
import { useStoreActions, useStoreState } from '@/store'
|
||||||
import useAuth from '@/utils/hooks/useAuth'
|
import useAuth from '@/utils/hooks/useAuth'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
@ -17,10 +17,9 @@ import useTimeOutMessage from '@/utils/hooks/useTimeOutMessage'
|
||||||
import { TurnstileInstance } from '@marsidev/react-turnstile'
|
import { TurnstileInstance } from '@marsidev/react-turnstile'
|
||||||
import { Field, Form, Formik } from 'formik'
|
import { Field, Form, Formik } from 'formik'
|
||||||
import { motion } from 'framer-motion'
|
import { motion } from 'framer-motion'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useRef, useState } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import { defaultDomain, getSubdomain } from '@/utils/subdomain'
|
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import { APP_NAME } from '@/constants/app.constant'
|
import { APP_NAME } from '@/constants/app.constant'
|
||||||
|
|
||||||
|
|
@ -33,28 +32,23 @@ type SignInFormSchema = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
userName: Yup.string().required('Please enter your user name'),
|
userName: Yup.string().required(),
|
||||||
password: Yup.string().required('Please enter your password'),
|
password: Yup.string().required(),
|
||||||
rememberMe: Yup.bool(),
|
rememberMe: Yup.bool(),
|
||||||
twoFactor: Yup.boolean(),
|
twoFactor: Yup.boolean(),
|
||||||
twoFactorCode: Yup.string().when('twoFactor', {
|
twoFactorCode: Yup.string().when('twoFactor', {
|
||||||
is: true,
|
is: true,
|
||||||
then: (schema) => schema.required('Mail adresinize gönderilen doğrulama kodunu giriniz'),
|
then: (schema) => schema.required(),
|
||||||
otherwise: (schema) => schema.notRequired(),
|
otherwise: (schema) => schema.notRequired(),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const isMultiTenant = useStoreState((a) => a.abpConfig.config?.multiTenancy.isEnabled)
|
|
||||||
const { setTenant } = useStoreActions((a) => a.auth.tenant)
|
|
||||||
|
|
||||||
const UiVersion = useStoreState((state) => state.locale.currentUiVersion)
|
const UiVersion = useStoreState((state) => state.locale.currentUiVersion)
|
||||||
const { setUiVersion } = useStoreActions((a) => a.locale)
|
const { setUiVersion } = useStoreActions((a) => a.locale)
|
||||||
|
|
||||||
const tenantName = useStoreState((state) => state.locale.currentTenantName)
|
|
||||||
const { setTenantName } = useStoreActions((actions) => actions.locale)
|
|
||||||
|
|
||||||
const [message, setMessage] = useState('')
|
const [message, setMessage] = useState('')
|
||||||
const [error, setError] = useTimeOutMessage(300000)
|
const [error, setError] = useTimeOutMessage(300000)
|
||||||
const [twoFactor, setTwoFactor] = useState(false)
|
const [twoFactor, setTwoFactor] = useState(false)
|
||||||
|
|
@ -93,9 +87,6 @@ const Login = () => {
|
||||||
setError(result.message)
|
setError(result.message)
|
||||||
} else {
|
} else {
|
||||||
setError('')
|
setError('')
|
||||||
|
|
||||||
//Tenant belirlenmişse
|
|
||||||
fetchDataByName(tenantName || '')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.status === 'failed') {
|
if (result.status === 'failed') {
|
||||||
|
|
@ -165,57 +156,6 @@ const Login = () => {
|
||||||
setSubmitting(false)
|
setSubmitting(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchDataByName = async (name: string, isSubdomain = false) => {
|
|
||||||
if (name) {
|
|
||||||
try {
|
|
||||||
const response = await getTenantByNameDetail(name)
|
|
||||||
|
|
||||||
if (response.data) {
|
|
||||||
setTenant({ tenantId: response.data.id, tenantName: response.data.name, menuGroup: response.data.menuGroup });
|
|
||||||
} else {
|
|
||||||
setTenant(undefined)
|
|
||||||
if (isSubdomain) redirectToMainDomain(name)
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
setTenant(undefined)
|
|
||||||
if (isSubdomain) redirectToMainDomain(name)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setTenant(undefined)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const redirectToMainDomain = (name: string) => {
|
|
||||||
setTenantName(undefined)
|
|
||||||
const parts = window.location.hostname.split('.')
|
|
||||||
const mainDomain = parts.length >= 3 ? parts.slice(1).join('.') : window.location.hostname
|
|
||||||
setWarningTimeout(`"${name}" kurumuna ait kayıt bulunamadı. Ana sayfaya yönlendiriliyorsunuz...`)
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location.href = `${window.location.protocol}//${mainDomain}`
|
|
||||||
}, 3000)
|
|
||||||
}
|
|
||||||
|
|
||||||
const subDomainName = getSubdomain()
|
|
||||||
useEffect(() => {
|
|
||||||
if (subDomainName) {
|
|
||||||
setTenantName(subDomainName)
|
|
||||||
fetchDataByName(subDomainName, true)
|
|
||||||
}
|
|
||||||
}, [subDomainName])
|
|
||||||
|
|
||||||
const tenantStyle: React.CSSProperties | undefined =
|
|
||||||
subDomainName && subDomainName !== defaultDomain
|
|
||||||
? {
|
|
||||||
opacity: 0,
|
|
||||||
position: 'absolute',
|
|
||||||
pointerEvents: 'none',
|
|
||||||
height: 0,
|
|
||||||
margin: 0,
|
|
||||||
padding: 0,
|
|
||||||
border: 'none',
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
|
|
||||||
const findUiVersion = async () => {
|
const findUiVersion = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/version.json?ts=${Date.now()}`)
|
const res = await fetch(`/version.json?ts=${Date.now()}`)
|
||||||
|
|
@ -246,22 +186,7 @@ const Login = () => {
|
||||||
<p>{translate('::Abp.Account.WelcomeBack.Message')}</p>
|
<p>{translate('::Abp.Account.WelcomeBack.Message')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isMultiTenant && (
|
<TenantSelector />
|
||||||
<>
|
|
||||||
<label className="form-label mb-2" style={tenantStyle}>
|
|
||||||
{translate('::Organization')}
|
|
||||||
</label>
|
|
||||||
<div className="mb-4">
|
|
||||||
<Input
|
|
||||||
placeholder={translate('::Organization')}
|
|
||||||
value={tenantName}
|
|
||||||
onChange={(e) => setTenantName(e.target.value)}
|
|
||||||
style={tenantStyle}
|
|
||||||
aria-hidden={subDomainName && subDomainName !== defaultDomain ? 'true' : 'false'}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<div>
|
<div>
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
|
|
@ -289,7 +214,7 @@ const Login = () => {
|
||||||
name="userName"
|
name="userName"
|
||||||
placeholder={translate('::Abp.Account.EmailAddress')}
|
placeholder={translate('::Abp.Account.EmailAddress')}
|
||||||
component={Input}
|
component={Input}
|
||||||
inputClassName="dark:bg-gray-900 dark:text-gray-100"
|
className="dark:bg-gray-900 dark:text-gray-100"
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import ActionLink from '@/components/shared/ActionLink'
|
import ActionLink from '@/components/shared/ActionLink'
|
||||||
import PasswordInput from '@/components/shared/PasswordInput'
|
import PasswordInput from '@/components/shared/PasswordInput'
|
||||||
|
import TenantSelector from '@/components/shared/TenantSelector'
|
||||||
import Alert from '@/components/ui/Alert'
|
import Alert from '@/components/ui/Alert'
|
||||||
import Button from '@/components/ui/Button'
|
import Button from '@/components/ui/Button'
|
||||||
import { FormContainer, FormItem } from '@/components/ui/Form'
|
import { FormContainer, FormItem } from '@/components/ui/Form'
|
||||||
|
|
@ -83,6 +84,7 @@ const Register = () => {
|
||||||
{error}
|
{error}
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
<TenantSelector />
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
email: '',
|
email: '',
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ type ResetPasswordFormSchema = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
password: Yup.string().required('Please enter your password'),
|
password: Yup.string().required(),
|
||||||
confirmPassword: Yup.string().oneOf([Yup.ref('password')], 'Your passwords do not match'),
|
confirmPassword: Yup.string().oneOf([Yup.ref('password')], 'Your passwords do not match'),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import useAccount from '@/utils/hooks/useAccount'
|
||||||
import { Alert, Button, FormContainer, FormItem, Input } from '@/components/ui'
|
import { Alert, Button, FormContainer, FormItem, Input } from '@/components/ui'
|
||||||
import { Field, Form, Formik } from 'formik'
|
import { Field, Form, Formik } from 'formik'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import { ActionLink } from '@/components/shared'
|
import { ActionLink, TenantSelector } from '@/components/shared'
|
||||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||||
import { store } from '@/store'
|
import { store } from '@/store'
|
||||||
import Captcha from '@/components/shared/Captcha'
|
import Captcha from '@/components/shared/Captcha'
|
||||||
|
|
@ -57,6 +57,7 @@ const SendConfirmationCode = () => {
|
||||||
{error}
|
{error}
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
<TenantSelector />
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
email: userName,
|
email: userName,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue