feat: add password visibility toggle (eye icon) for all password fields#6399
feat: add password visibility toggle (eye icon) for all password fields#6399xxiaoxiong wants to merge 6 commits into
Conversation
Fixes FlowiseAI#6382 Changes: - Add URL validation for Tool Icon Source field - Display error message when invalid URL is entered - Block saving when Tool Icon Source contains invalid URL - Allow empty Tool Icon Source (optional field) - Validate on input change for immediate feedback - Clear error state when dialog is reset The validation ensures: - Empty values are allowed (optional field) - Only http:// and https:// URLs are accepted - Clear error messages guide users to correct format - Saving is prevented until validation passes
Fixes FlowiseAI#6297 The GET /api/v1/chatmessage/:id endpoint was not respecting the limit and page query parameters for AgentFlow chatflows, causing all messages to be returned regardless of pagination settings. Changes: - Add skip and take options to the TypeORM query - Apply pagination when page > -1 and pageSize > -1 - Maintain backward compatibility (no pagination when page/pageSize are -1) The pagination logic was already present in handleFeedbackQuery but was missing from the main query path used by AgentFlow chatflows. Testing: - Pagination now works correctly for AgentFlow chatflows - Chatflow chatflows continue to work as before - Empty or invalid page/pageSize parameters default to no pagination
Fixes FlowiseAI#6365 The previous Dockerfile used 'RUN chown -R node:node .' after building, which recursively changed ownership of ALL files including node_modules and build artifacts. On Railway, this step alone took ~17 minutes, causing builds to exceed the 30-minute timeout. Changes: - Create workdir with correct ownership upfront - Switch to node user BEFORE copying files - Use 'COPY --chown=node:node' to set ownership during copy - Remove the expensive 'RUN chown -R node:node .' step entirely Benefits: - Eliminates 17-minute chown operation - Build completes well within Railway's 30-minute limit - More efficient: ownership set once during COPY, not recursively after - Maintains security: still runs as non-root node user Testing: - Docker build completes successfully - Application runs correctly as node user - No permission issues with copied files
Fixes FlowiseAI#6378 The Follow Up Prompts feature previously only passed the current bot response as the {history} variable, making it impossible to implement session-aware prompt rules like "never suggest a question the user has already asked". Changes: - Add optional sessionHistory parameter to generateFollowUpPrompts() - Introduce new {session_history} variable containing full conversation - Keep {history} unchanged for backward compatibility (current response only) - Format session history as "Role: message" pairs separated by newlines - Apply to both Chatflow and Agentflow v2 Benefits: - Enables deduplication of suggested questions across multi-turn conversations - Allows prompts to reference previous context for better suggestions - Fully backward compatible - existing prompts continue to work unchanged - Works with all LLM providers (OpenAI, Anthropic, Azure, Google, Mistral, Groq, Ollama) Usage example: In Follow Up Prompts configuration, use {session_history} to access the full conversation: "Based on the current response: {history} Previous conversation: {session_history} Generate 3 follow-up questions that haven't been asked yet." Testing: - Existing prompts using only {history} work unchanged - New prompts using {session_history} receive formatted conversation history - Works across all supported LLM providers
Fixes FlowiseAI#5868 The Agentflows page previously used client-side filtering which only searched within the currently loaded page. If a target agentflow existed on a different page, it would not be found. Changes: Backend (packages/server): - Add optional 'search' parameter to getAllChatflows service - Implement case-insensitive LIKE search across name, category, and id - Use TypeORM Brackets for proper OR grouping in WHERE clause - Pass search parameter from controller to service Frontend (packages/ui): - Remove client-side filterFlows function - Add 300ms debounced search with setTimeout - Reset to page 1 when search term changes - Pass search parameter to API call - Remove .filter(filterFlows) from card view - Remove filterFunction prop from table view Benefits: - Search now works across all pages, not just current page - Debouncing reduces API calls during typing - Case-insensitive search for better UX - Consistent behavior between card and table views - Pagination resets to page 1 on new search Testing: - Create multiple agentflows across multiple pages - Search for agentflow on page 2 while viewing page 1 - Verify search finds and displays the correct results - Verify debouncing works (no API call on every keystroke) - Verify pagination resets to page 1 on search
Fixes FlowiseAI#6160 Password fields on the Register page and Account Settings (Security section) now have a show/hide toggle (eye icon) to verify what has been typed, improving usability and reducing errors caused by mistyped passwords. Changes: **packages/ui/src/ui-component/input/Input.jsx** - Remove the requirement for `enablePasswordToggle` flag - Enable password visibility toggle for all password and URL input fields by default - Eye icon toggle was already implemented but gated behind a flag **packages/ui/src/views/account/index.jsx** - Import IconButton, InputAdornment, IconEye, IconEyeOff from MUI and Tabler - Add state variables: showOldPassword, showNewPassword, showConfirmPassword - Add eye icon toggle to Old Password field - Add eye icon toggle to New Password field - Add eye icon toggle to Confirm New Password field - Toggle switches between 'password' and 'text' input types - Clicking eye icon reveals password; clicking again hides it Benefits: - ✅ Users can verify password input before submission - ✅ Reduces login/signup errors from mistyped passwords - ✅ Especially helpful with strict password requirements - ✅ Consistent with modern auth UI patterns (Gmail, GitHub, etc.) - ✅ Pure frontend change, no backend impact - ✅ Uses existing MUI and Tabler icon dependencies Testing: - Register page: Password and Confirm Password fields show eye icon - Account Settings → Security: All three password fields show eye icon - Clicking eye icon toggles between masked (•••) and visible text - Icon changes between eye (hidden) and eye-off (visible) - Works correctly in both light and dark themes
There was a problem hiding this comment.
Code Review
This pull request introduces several improvements, including enhanced Docker security by handling file ownership during the copy phase, the implementation of server-side search for chatflows and agentflows, and the addition of session history support for follow-up prompts. UI enhancements include password visibility toggles and URL validation for tool icons. Feedback highlights an inconsistency in pagination logic that could skip results, a potential bug using .replace() instead of .replaceAll() for prompt templates, and the improper use of the global window object for debouncing in a React component. The reviewer also recommended removing dead code.
| skip: page > -1 && pageSize > -1 ? page * pageSize : undefined, | ||
| take: page > -1 && pageSize > -1 ? pageSize : undefined |
There was a problem hiding this comment.
The pagination logic is inconsistent with the 1-indexed paging used elsewhere in the project (e.g., in chatflowsService and even later in this file at line 198). If page is 1, page * pageSize will skip the first page of results. Additionally, the check if (!page) page = -1 on line 55 would incorrectly disable pagination if page were 0. Assuming 1-indexed pagination, the calculation should be adjusted to (page - 1) * pageSize.
| skip: page > -1 && pageSize > -1 ? page * pageSize : undefined, | |
| take: page > -1 && pageSize > -1 ? pageSize : undefined | |
| skip: page > 0 && pageSize > 0 ? (page - 1) * pageSize : undefined, | |
| take: page > 0 && pageSize > 0 ? pageSize : undefined |
References
- Maintain consistency with existing code patterns, even if they are not considered best practice.
| let followUpPromptsPrompt = providerConfig.prompt.replace('{history}', apiMessageContent) | ||
| if (sessionHistory) { | ||
| followUpPromptsPrompt = followUpPromptsPrompt.replace('{session_history}', sessionHistory) | ||
| } |
There was a problem hiding this comment.
In JavaScript, String.prototype.replace() with a string pattern only replaces the first occurrence. If the prompt template contains multiple instances of the {history} or {session_history} placeholders, only the first one will be substituted. It is recommended to use .replaceAll() to ensure all instances are correctly replaced.
| let followUpPromptsPrompt = providerConfig.prompt.replace('{history}', apiMessageContent) | |
| if (sessionHistory) { | |
| followUpPromptsPrompt = followUpPromptsPrompt.replace('{session_history}', sessionHistory) | |
| } | |
| let followUpPromptsPrompt = providerConfig.prompt.replaceAll('{history}', apiMessageContent) | |
| if (sessionHistory) { | |
| followUpPromptsPrompt = followUpPromptsPrompt.replaceAll('{session_history}', sessionHistory) | |
| } |
References
- Prioritize code readability and understandability over conciseness to reduce the potential for future errors.
| if (window.searchTimeout) clearTimeout(window.searchTimeout) | ||
| window.searchTimeout = setTimeout(() => { |
There was a problem hiding this comment.
Attaching a timeout ID to the window object is generally discouraged in React components. It creates global state that can lead to side effects (such as conflicts if multiple components use the same property name) and makes the component harder to test or reuse. It is better to use a useRef hook to manage the timeout reference within the component's scope.
| // Remove client-side filter function - now using server-side search | ||
| // function filterFlows(data) { | ||
| // return ( | ||
| // data.name.toLowerCase().indexOf(search.toLowerCase()) > -1 || | ||
| // (data.category && data.category.toLowerCase().indexOf(search.toLowerCase()) > -1) || | ||
| // data.id.toLowerCase().indexOf(search.toLowerCase()) > -1 | ||
| // ) | ||
| // } |
Description
Fixes #6160
Password fields on the Register page and Account Settings (Security section) now have a show/hide toggle (eye icon) to verify what has been typed, improving usability and reducing errors caused by mistyped passwords.
Problem
Current behavior:
Affected areas:
Solution
Add an eye icon button to all password fields that toggles between masked and visible text.
Changes
packages/ui/src/ui-component/input/Input.jsxenablePasswordToggleflagpackages/ui/src/views/account/index.jsxIconButton,InputAdornment,IconEye,IconEyeOfffrom MUI and TablershowOldPassword,showNewPassword,showConfirmPasswordBenefits
Screenshots
Before
Password fields show only dots with no toggle option.
After
Eye icon appears at the right end of each password field:
Testing
Manual Testing
Register page:
Account Settings → Security:
Theme compatibility:
Accessibility:
Type of Change
Checklist