diff --git a/api/src/Sozsoft.Platform.Application/Identity/PlatformAccountAppService.cs b/api/src/Sozsoft.Platform.Application/Identity/PlatformAccountAppService.cs index e869b21..122d568 100644 --- a/api/src/Sozsoft.Platform.Application/Identity/PlatformAccountAppService.cs +++ b/api/src/Sozsoft.Platform.Application/Identity/PlatformAccountAppService.cs @@ -76,8 +76,7 @@ public class PlatformAccountAppService : AccountAppService, IAccountAppService var SenderName = await settingProvider.GetOrNullAsync(SeedConsts.AbpSettings.Mailing.Default.DefaultFromDisplayName); var SenderEmailAddress = await settingProvider.GetOrNullAsync(SeedConsts.AbpSettings.Mailing.Default.DefaultFromAddress); - var url = await appUrlProvider.GetUrlAsync("MVC", PlatformConsts.Urls.UserDetail); - var userDetailUrl = $"{url}/{user.Id}"; + var userDetailUrl = await GetUserDetailUrlAsync(user.Id); var content = $@"My name is: {user.GetFullName()}. Email Address: {user.Email} @@ -111,17 +110,16 @@ User Detail: {userDetailUrl}"; } [Captcha] - public async Task SendExtendLoginRequestAsync(SendExtendLoginRequestInputDto input) + public async Task SendExtendLoginRequestAsync(SendExtendLoginRequestInputDto input) { var user = await UserManager.FindByEmailAsync(input.EmailAddress); if (user == null) { - return; + return false; } - var userDetailUrl = await appUrlProvider.GetUrlAsync(PlatformConsts.React, PlatformConsts.Urls.UserDetail); var content = $@"My name is: {user.GetFullName()}. -User Detail: {string.Format(userDetailUrl, user.Id)}"; +User Detail: {await GetUserDetailUrlAsync(user.Id)}"; var recipient = await settingProvider.GetOrNullAsync(PlatformConsts.AbpSettings.SiteManagement.General.TimedLoginEmails); if (!recipient.IsNullOrWhiteSpace()) @@ -132,9 +130,11 @@ User Detail: {string.Format(userDetailUrl, user.Id)}"; null, content, subject: PlatformConsts.AppName + " : Extend Login Request"); + + return true; } - return; + return false; } [Captcha] @@ -207,6 +207,15 @@ To validate your account, please complete your profile by clicking (or copy-past return true; } + + private async Task GetUserDetailUrlAsync(Guid userId) + { + var url = await appUrlProvider.GetUrlAsync(PlatformConsts.React, PlatformConsts.Urls.UserDetail); + + return url.Contains("{0}", StringComparison.Ordinal) + ? string.Format(url, userId) + : $"{url.TrimEnd('/')}/{userId}"; + } } diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/HostData.json b/api/src/Sozsoft.Platform.DbMigrator/Seeds/HostData.json index 5d9f4fc..76e10c7 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/HostData.json +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/HostData.json @@ -260,7 +260,7 @@ "descriptionKey": "App.SiteManagement.General.NewMemberNotificationEmails.Description", "defaultValue": "system@sozsoft.com", "isVisibleToClients": false, - "providers": "G|D", + "providers": "T|G|D", "isInherited": false, "isEncrypted": false, "mainGroupKey": "App.SiteManagement", @@ -276,7 +276,7 @@ "descriptionKey": "App.SiteManagement.General.TimedLoginEmails.Description", "defaultValue": "system@sozsoft.com", "isVisibleToClients": false, - "providers": "G|D", + "providers": "T|G|D", "isInherited": false, "isEncrypted": false, "mainGroupKey": "App.SiteManagement", diff --git a/api/src/Sozsoft.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs b/api/src/Sozsoft.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs index 3459fef..73ba4d6 100644 --- a/api/src/Sozsoft.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs +++ b/api/src/Sozsoft.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs @@ -189,7 +189,7 @@ public class PlatformHttpApiHostModule : AbpModule options.Applications[PlatformConsts.React].RootUrl = configuration["App:ClientUrl"]; options.Applications[PlatformConsts.React].Urls[PlatformConsts.Urls.EmailConfirmation] = "confirm"; options.Applications[PlatformConsts.React].Urls[PlatformConsts.Urls.PasswordReset] = "reset-password"; - options.Applications[PlatformConsts.React].Urls[PlatformConsts.Urls.UserDetail] = "account/{0}"; + options.Applications[PlatformConsts.React].Urls[PlatformConsts.Urls.UserDetail] = "admin/users/detail"; //options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; //options.Applications["MVC"].Urls[PlatformConsts.Urls.EmailConfirmation] = "Account/Confirm"; diff --git a/ui/src/services/account.service.ts b/ui/src/services/account.service.ts index 4accd3a..90f539a 100644 --- a/ui/src/services/account.service.ts +++ b/ui/src/services/account.service.ts @@ -73,7 +73,7 @@ export const verifyAccountConfirmationCode = (userId: string, token: string) => }) export const sendExtendLoginRequest = (data: any) => - apiService.fetchData({ + apiService.fetchData({ method: 'POST', url: 'api/app/platform-account/send-extend-login-request', data: { diff --git a/ui/src/views/auth/ExtendLogin.tsx b/ui/src/views/auth/ExtendLogin.tsx index a478cd8..27411f6 100644 --- a/ui/src/views/auth/ExtendLogin.tsx +++ b/ui/src/views/auth/ExtendLogin.tsx @@ -8,12 +8,12 @@ import Input from '@/components/ui/Input' import { APP_NAME } from '@/constants/app.constant' import { ROUTES_ENUM } from '@/routes/route.constant' import { sendExtendLoginRequest } from '@/services/account.service' -import { store } from '@/store' +import { store, useStoreActions } from '@/store' import { useLocalization } from '@/utils/hooks/useLocalization' import useTimeOutMessage from '@/utils/hooks/useTimeOutMessage' import { TurnstileInstance } from '@marsidev/react-turnstile' import { Field, Form, Formik } from 'formik' -import { useRef, useState } from 'react' +import { useEffect, useRef, useState } from 'react' import { Helmet } from 'react-helmet' import * as Yup from 'yup' @@ -36,8 +36,13 @@ const ExtendLogin = () => { const [message, setMessage] = useTimeOutMessage(10000) const { translate } = useLocalization() + const { setWarning } = useStoreActions((actions) => actions.base.messages) const captchaRef = useRef(null) + useEffect(() => { + setWarning('') + }, [setWarning]) + const onSendMail = async ( values: ExtendLoginFormSchema, setSubmitting: (isSubmitting: boolean) => void, @@ -46,10 +51,22 @@ const ExtendLogin = () => { const { email, captchaResponse } = values setSubmitting(true) try { - await sendExtendLoginRequest({ email, captchaResponse }) + const result = await sendExtendLoginRequest({ email, captchaResponse }) + if (result.data !== true) { + throw new Error( + 'Your request could not be sent. Please check the email address and try again.', + ) + } + + setWarning('') setEmailSent(true) } catch (error: any) { - setMessage(error?.response?.data || error.toString()) + setMessage( + error?.response?.data?.error?.message || + error?.response?.data?.message || + error?.message || + error.toString(), + ) } finally { setFieldValue('captchaResponse', '') captchaRef.current?.reset()