Conversation
WalkthroughThis pull request enhances the authentication system by introducing new API methods for email confirmation and token validation. It updates API route constants and user model interfaces accordingly. The AuthService now includes an asynchronous token validation method with improved error logging. Additionally, a new React route and component for confirming emails have been added. The forgot password reset flow is modified to incorporate asynchronous token validation, while the login and registration components have been updated for streamlined error handling and user feedback. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant B as Browser
participant C as ConfirmEmail Component
participant A as AuthApi
participant M as Message Display
U->>B: Navigate to /confirm-email?token=...&username=...
B->>C: Render ConfirmEmail component
C->>C: Extract token & username from URL
alt Missing parameters
C->>B: Redirect to Login Page
else Valid parameters
C->>A: Call confirmEmail({ userName, token })
A-->>C: Return boolean result
C->>M: Display success or error message
C->>B: Redirect to Login Page
end
sequenceDiagram
participant U as User
participant B as Browser
participant F as ForgotPasswordReset Component
participant S as AuthService
U->>B: Open password reset link with token & username
B->>F: Render ForgotPasswordReset component
F->>F: Extract token & username from URL
alt Missing parameters
F->>B: Redirect to Login Page
else Valid parameters
F->>S: Call ValidateTokenAsync(request)
S-->>F: Return validation result
F->>F: Update isOkResult state (enable/disable form submit)
end
Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it’s a critical failure. 🔧 ESLint
src/features/Auth/RegistrationPage/RegistrationPage.component.tsxOops! Something went wrong! :( ESLint: 8.42.0 ESLint couldn't find the plugin "eslint-plugin-react-hooks". (The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following: The plugin "eslint-plugin-react-hooks" was referenced from the config file in ".eslintrc.js". If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team. src/features/Auth/ConfirmEmail/ConfirmEmail.component.tsxOops! Something went wrong! :( ESLint: 8.42.0 ESLint couldn't find the plugin "eslint-plugin-react-hooks". (The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following: The plugin "eslint-plugin-react-hooks" was referenced from the config file in ".eslintrc.js". If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team. 📜 Recent review detailsConfiguration used: .coderabbit.yaml 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (7)
src/app/common/services/auth-service/AuthService.ts (2)
90-97: Follow camelCase naming convention for method namesThe
ValidateTokenAsyncmethod uses PascalCase naming, which is inconsistent with other methods in this class that use camelCase (e.g.,loginAsync,registerAsync).-public static async ValidateTokenAsync(request: ValidateToken) { +public static async validateTokenAsync(request: ValidateToken) { try { await AuthApi.validateToken(request); } catch (error) { console.error(error); return Promise.reject(error); } }
90-97: Clarify return value for the successful caseThe current implementation doesn't explicitly return a value on success. This could confuse developers who expect a consistent return value from the method.
public static async ValidateTokenAsync(request: ValidateToken) { try { await AuthApi.validateToken(request); + return true; // Explicitly return a success indicator } catch (error) { console.error(error); return Promise.reject(error); } }src/features/Auth/ConfirmEmail/ConfirmEmail.component.tsx (1)
15-38: Add more user feedback during the validation processCurrently, the component only shows a loader without any contextual information about what's happening. Consider adding a loading state and more informative feedback.
const ConfirmEmail = () => { const location = useLocation(); const navigate = useNavigate(); const hasRun = useRef(false); + const [status, setStatus] = useState('loading'); // 'loading', 'success', 'error' useAsync(async () => { if (hasRun.current) return; hasRun.current = true; const searchParams = new URLSearchParams(location.search); const token = searchParams.get('token'); const userName = searchParams.get('username'); if (!token || !userName) { navigate(FRONTEND_ROUTES.AUTH.LOGIN); return; } try { await AuthApi.confirmEmail({ userName, token }); + setStatus('success'); message.success('Ваш акаунт успішно створено. Тепер ви можете увійти в систему.'); } catch (error) { + setStatus('error'); message.error('Це посилання недійсне або протерміноване. ' + 'Будь ласка, перейдіть на сторінку входу і спробуйте зареєструватися ще раз.'); } - navigate(FRONTEND_ROUTES.AUTH.LOGIN); + setTimeout(() => navigate(FRONTEND_ROUTES.AUTH.LOGIN), 3000); // Give user time to read the message }, []); - return <Loader />; + return ( + <div className="confirm-email-container"> + {status === 'loading' && <Loader />} + {status === 'loading' && <p>Підтверджуємо вашу електронну адресу...</p>} + </div> + );src/features/Auth/ForgotPassword/ForgotPasswordReset.component.tsx (2)
22-51: Add loading state for token validationThe component doesn't provide any visual feedback during token validation. Users won't know that validation is in progress.
const ForgotPasswordResetComponent: React.FC = () => { const [form] = Form.useForm(); const location = useLocation(); const navigator = useNavigate(); const [isValid, setIsValid] = useState<boolean>(true); const [isOkResult, setIsOkResult] = useState(false); + const [isValidating, setIsValidating] = useState(true); const hasRun = useRef(false); useAsync(async () => { if (hasRun.current) return; hasRun.current = true; const searchParams = new URLSearchParams(location.search); const token = searchParams.get('token'); const userName = searchParams.get('username'); if (!token || !userName) { navigator(FRONTEND_ROUTES.AUTH.LOGIN); return; } const request: ValidateToken = { token, purpose: 'ResetPassword', userName, tokenProvider: 'CustomResetPassword', }; try { await AuthService.ValidateTokenAsync(request); setIsOkResult(true); } catch (error) { message.error('Це посилання недійсне або протерміноване. ' + 'Поверніться на сторінку відновлення паролю і спробуйте ще раз.', 5); setIsOkResult(false); } finally { + setIsValidating(false); } }, []);Then update the button to show loading state:
<Button htmlType="submit" - disabled={!isValid && !isOkResult} + disabled={!isValid || !isOkResult || isValidating} + loading={isValidating} className="streetcode-custom-button forgotPasswordResetButton" >
53-68: Avoid URL parameter duplicationThe token and username are extracted twice from the URL - once in the useAsync hook and again in the handleUpdatePassword function.
Store these values in state variables to avoid duplication:
const ForgotPasswordResetComponent: React.FC = () => { const [form] = Form.useForm(); const location = useLocation(); const navigator = useNavigate(); const [isValid, setIsValid] = useState<boolean>(true); const [isOkResult, setIsOkResult] = useState(false); const [isValidating, setIsValidating] = useState(true); + const [token, setToken] = useState<string | null>(null); + const [username, setUsername] = useState<string | null>(null); const hasRun = useRef(false); useAsync(async () => { if (hasRun.current) return; hasRun.current = true; const searchParams = new URLSearchParams(location.search); const tokenParam = searchParams.get('token'); const userNameParam = searchParams.get('username'); + setToken(tokenParam); + setUsername(userNameParam); if (!tokenParam || !userNameParam) { navigator(FRONTEND_ROUTES.AUTH.LOGIN); return; } // ...rest of the validation code }, []); const handleUpdatePassword = async () => { - const searchParams = new URLSearchParams(location.search); - - const token = searchParams.get('token'); - const username = searchParams.get('username'); const newPassword = form.getFieldValue('password'); const confirmPassword = form.getFieldValue('passwordConfirmation'); await AuthService.sendForgotPasswordUpdate(newPassword, confirmPassword, username, token).then(() => {src/app/api/authentication/auth.api.ts (2)
41-43: Add.then((response) => response.data)for consistency with other methodsYour implementation of
confirmEmailis missing the data extraction that's present in all other methods in this file. This will cause the method to return a full Axios response object instead of just the boolean value.confirmEmail: (confirmEmailRequest: ConfirmEmail) => ( instance.post<boolean>(API_ROUTES.AUTH.CONFIRM_EMAIL, confirmEmailRequest) + .then((response) => response.data) ),
44-46: Add.then((response) => response.data)for consistency with other methodsSimilar to the
confirmEmailmethod, thevalidateTokenmethod should extract the data from the response to maintain consistency with the other methods in this file.validateToken: (validateTokenRequest: ValidateToken) => ( instance.post<boolean>(API_ROUTES.AUTH.VALIDATE_TOKEN, validateTokenRequest) + .then((response) => response.data) ),
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
src/app/api/authentication/auth.api.ts(2 hunks)src/app/common/constants/api-routes.constants.ts(1 hunks)src/app/common/services/auth-service/AuthService.ts(3 hunks)src/app/router/Routes.tsx(2 hunks)src/features/Auth/ConfirmEmail/ConfirmEmail.component.tsx(1 hunks)src/features/Auth/ForgotPassword/ForgotPasswordReset.component.tsx(3 hunks)src/features/Auth/Login/Login.component.tsx(2 hunks)src/features/Auth/RegistrationPage/RegistrationPage.component.tsx(1 hunks)src/models/user/user.model.ts(1 hunks)
🧰 Additional context used
🧬 Code Definitions (4)
src/app/router/Routes.tsx (1)
src/models/user/user.model.ts (1)
ConfirmEmail(64-67)
src/features/Auth/ConfirmEmail/ConfirmEmail.component.tsx (1)
src/models/user/user.model.ts (1)
ConfirmEmail(64-67)
src/app/common/services/auth-service/AuthService.ts (1)
src/models/user/user.model.ts (1)
ValidateToken(69-74)
src/app/api/authentication/auth.api.ts (2)
src/models/user/user.model.ts (2)
ConfirmEmail(64-67)ValidateToken(69-74)src/app/common/constants/api-routes.constants.ts (1)
API_ROUTES(2-272)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Jenkins
🔇 Additional comments (7)
src/app/router/Routes.tsx (2)
4-4: Good addition of the ConfirmEmail component import.The import is properly placed with other authentication-related imports, maintaining organization within the file.
125-125: Route implementation looks good.The new route for email confirmation is correctly added and follows the same pattern as other authentication routes in the application. This provides users with a dedicated path to confirm their email addresses.
src/app/common/constants/api-routes.constants.ts (1)
215-216: API route constants properly defined.The new constants for email confirmation and token validation are correctly placed in the AUTH section and follow the established naming conventions. These endpoints will support the email confirmation functionality as outlined in the PR objectives.
src/models/user/user.model.ts (2)
64-67: Interface for ConfirmEmail is well structured.The interface contains all necessary fields for email confirmation. The naming is clear and follows TypeScript best practices.
69-74: ValidateToken interface is properly defined.This interface includes all required fields for token validation. The inclusion of fields like
purposeandtokenProvidersuggests good flexibility for different token validation scenarios.src/app/api/authentication/auth.api.ts (2)
6-7: Nice work updating the importsThe import changes correctly include the new interfaces needed for email confirmation and token validation functionality. This supports the PR's goal of enhancing the authentication system with email confirmation capabilities.
Also applies to: 12-13
41-46: Great implementation of email confirmation methodsThe addition of these two methods aligns perfectly with the PR objectives of implementing email confirmation functionality. The API routes and request structures match the backend endpoints defined in the constants file.
|


dev
JIRA
Summary of issue
Summary of change
Back-end PR
ita-social-projects/StreetCode#2637
Summary by CodeRabbit
New Features
Refactor