[REF-822] feat: Add cross-tab authentication state sync with BroadcastChannel API#1973
[REF-822] feat: Add cross-tab authentication state sync with BroadcastChannel API#1973
Conversation
…dcastChannel with localStorage fallback.
📝 Walkthrough📝 WalkthroughPre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
packages/request/src/requests/proxiedRequest.ts (1)
80-96: Consider documenting the reload delay and extracting magic number.The never-resolving promise pattern effectively blocks requests during identity changes, which is intentional. However:
- The 100ms delay should be documented to explain why it's needed (event propagation).
- Consider extracting it as a named constant for clarity.
🔎 Suggested refactor
+// Delay before reload to allow cross-tab event propagation +const IDENTITY_CHANGE_RELOAD_DELAY_MS = 100; + // Flag to indicate if user identity change is being handled let isHandlingUserChange = false; client.interceptors.request.use(async (request: Request) => { // Skip auth-related requests (logout, refreshToken, etc.) const isAuthRequest = request.url.includes('/auth/') || request.url.includes('/logout') || isHandlingUserChange; // Validate user identity before making request (only for non-auth requests) if (!isAuthRequest && !authChannel.validateUserIdentity()) { // User identity mismatch, trigger page refresh isHandlingUserChange = true; // Return a never-resolving promise to block the request return new Promise(() => { - // Delay refresh to allow event propagation setTimeout(() => { window.location.reload(); - }, 100); + }, IDENTITY_CHANGE_RELOAD_DELAY_MS); }); }packages/web-core/src/components/layout/index.tsx (2)
191-195: Handle the return value of validateUserIdentity.The
validateUserIdentity()call in the visibility change handler doesn't handle its return value. If identity validation fails,validateUserIdentityalready broadcasts the appropriate event, but you might want to add logging or additional handling for monitoring purposes.🔎 Optional enhancement
const handleVisibilityChange = () => { if (document.visibilityState === 'visible') { - authChannel.validateUserIdentity(); + const isValid = authChannel.validateUserIdentity(); + if (!isValid) { + console.log('[AuthSync] Identity mismatch detected on tab focus'); + } } };
129-202: Consider using a debounce utility for cleaner code.The inline debouncing logic works correctly, but using a proper debounce utility (e.g., from
lodashor a custom hook) would be more maintainable and testable. This is optional since the current implementation is functional.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
packages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/request/src/requests/proxiedRequest.tspackages/web-core/src/components/layout/index.tsx
🧰 Additional context used
📓 Path-based instructions (20)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{js,ts,jsx,tsx}: Always use optional chaining (?.) when accessing object properties
Always use nullish coalescing (??) or default values for potentially undefined values
Always check array existence before using array methods
Always validate object properties before destructuring
Always use single quotes for string literals in JavaScript/TypeScript code
**/*.{js,ts,jsx,tsx}: Use semicolons at the end of statements
Include spaces around operators (e.g.,a + binstead ofa+b)
Always use curly braces for control statements
Place opening braces on the same line as their statement
**/*.{js,ts,jsx,tsx}: Group import statements in order: React/framework libraries, third-party libraries, internal modules, relative path imports, type imports, style imports
Sort imports alphabetically within each import group
Leave a blank line between import groups
Extract complex logic into custom hooks
Use functional updates for state (e.g.,setCount(prev => prev + 1))
Split complex state into multiple state variables rather than single large objects
Use useReducer for complex state logic instead of multiple useState calls
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}
📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)
**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}: All code comments MUST be written in English
All variable names, function names, class names, and other identifiers MUST use English words
Comments should be concise and explain 'why' rather than 'what'
Use proper grammar and punctuation in comments
Keep comments up-to-date when code changes
Document complex logic, edge cases, and important implementation details
Use clear, descriptive names that indicate purpose
Avoid abbreviations unless they are universally understood
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)
Use JSDoc style comments for functions and classes in JavaScript/TypeScript
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)
**/*.{js,jsx,ts,tsx}: Use single quotes for string literals in TypeScript/JavaScript
Always use optional chaining (?.) when accessing object properties in TypeScript/JavaScript
Always use nullish coalescing (??) or default values for potentially undefined values in TypeScript/JavaScript
Always check array existence before using array methods in TypeScript/JavaScript
Validate object properties before destructuring in TypeScript/JavaScript
Use ES6+ features like arrow functions, destructuring, and spread operators in TypeScript/JavaScript
Avoid magic numbers and strings - use named constants in TypeScript/JavaScript
Use async/await instead of raw promises for asynchronous code in TypeScript/JavaScript
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/03-typescript-guidelines.mdc)
**/*.{ts,tsx}: Avoid usinganytype whenever possible - useunknowntype instead with proper type guards
Always define explicit return types for functions, especially for public APIs
Prefer extending existing types over creating entirely new types
Use TypeScript utility types (Partial<T>,Pick<T, K>,Omit<T, K>,Readonly<T>,Record<K, T>) to derive new types
Use union types and intersection types to combine existing types
Always import types explicitly using theimport typesyntax
Group type imports separately from value imports
Minimize creating local type aliases for imported types
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{js,ts,jsx,tsx,css,json}
📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)
Maximum line length of 100 characters
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{js,ts,jsx,tsx,css,json,yml,yaml}
📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)
Use 2 spaces for indentation, no tabs
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{js,ts,jsx,tsx,css,json,yml,yaml,md}
📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)
No trailing whitespace at the end of lines
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{css,scss,sass,less,js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/09-design-system.mdc)
**/*.{css,scss,sass,less,js,jsx,ts,tsx}: Primary color (#155EEF) should be used for main brand color in buttons, links, and accents
Error color (#F04438) should be used for error states and destructive actions
Success color (#12B76A) should be used for success states and confirmations
Warning color (#F79009) should be used for warnings and important notifications
Info color (#0BA5EC) should be used for informational elements
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{tsx,ts}
📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)
**/*.{tsx,ts}: Use the translation wrapper component and useTranslation hook in components
Ensure all user-facing text is translatable
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{tsx,ts,json}
📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)
Support dynamic content with placeholders in translations
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{tsx,ts,jsx,js,vue,css,scss,less}
📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)
**/*.{tsx,ts,jsx,js,vue,css,scss,less}: Use the primary blue (#155EEF) for main UI elements, CTAs, and active states
Use red (#F04438) only for errors, warnings, and destructive actions
Use green (#12B76A) for success states and confirmations
Use orange (#F79009) for warning states and important notifications
Use blue (#0BA5EC) for informational elements
Primary buttons should be solid with the primary color
Secondary buttons should have a border with transparent or light background
Danger buttons should use the error color
Use consistent padding, border radius, and hover states for all buttons
Follow fixed button sizes based on their importance and context
Use consistent border radius (rounded-lg) for all cards
Apply light shadows (shadow-sm) for card elevation
Maintain consistent padding inside cards (p-4orp-6)
Use subtle borders for card separation
Ensure proper spacing between card elements
Apply consistent styling to all form inputs
Use clear visual indicators for focus, hover, and error states in form elements
Apply proper spacing between elements using 8px, 16px, 24px increments
Ensure proper alignment of elements (left, center, or right)
Use responsive layouts that work across different device sizes
Maintain a minimum contrast ratio of 4.5:1 for text
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{tsx,ts,jsx,js,vue}
📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)
**/*.{tsx,ts,jsx,js,vue}: Include appropriate loading states for async actions in buttons
Group related form elements with appropriate spacing
Provide clear validation feedback for forms
Ensure proper labeling and accessibility for form elements
Ensure all interactive elements are keyboard accessible
Include appropriate ARIA attributes for complex components
Provide alternative text for images and icons
Support screen readers with semantic HTML elements
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)
**/*.{ts,tsx,js,jsx}: Follow the TypeScript/JavaScript style guidelines
Ensure code is well-tested and documented
Files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.tspackages/web-core/src/components/layout/index.tsxpackages/request/src/requests/proxiedRequest.ts
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{jsx,tsx}: Always use tailwind css to style the component
Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation
Always use useCallback for function props to maintain referential equality
Always specify proper dependency arrays in useEffect to prevent infinite loops
Always avoid inline object/array creation in render to prevent unnecessary re-renders
Always use proper key props when rendering lists
Always split nested components with closures into separate components to avoid performance issues and improve code maintainability
**/*.{jsx,tsx}: Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation in React
Always use useCallback for function props to maintain referential equality in React
Always specify proper dependency arrays in useEffect to prevent infinite loops in React
Always avoid inline object/array creation in render to prevent unnecessary re-renders in React
Always use proper key props when rendering lists in React (avoid using index when possible)
Always split nested components with closures into separate components in React
Use lazy loading for components that are not immediately needed in React
Debounce handlers for events that might fire rapidly (resize, scroll, input) in React
Implement fallback UI for components that might fail in React
Use error boundaries to catch and handle runtime errors in React
**/*.{jsx,tsx}: Place each attribute on a new line when a component has multiple attributes in JSX
Use self-closing tags for elements without children in JSX
Keep JSX expressions simple, extract complex logic to variables
Put closing brackets for multi-line JSX on a new line
**/*.{jsx,tsx}: Component file names should match the component name
Organize function components in order: imports, type definitions, constants, component function, hook calls, e...
Files:
packages/web-core/src/components/layout/index.tsx
**/*.{jsx,tsx,css}
📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)
**/*.{jsx,tsx,css}: Use Tailwind CSS for styling components
Follow the utility-first approach with Tailwind CSS
Group related utility classes together in Tailwind CSS
Prefer Tailwind utilities over custom CSS when possible
Files:
packages/web-core/src/components/layout/index.tsx
**/*.{jsx,tsx,js}
📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)
Each component file should contain only one main component
Files:
packages/web-core/src/components/layout/index.tsx
**/index.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)
Use index files to export multiple components from a directory
Files:
packages/web-core/src/components/layout/index.tsx
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)
Explicitly type props with interfaces or types in React components
Files:
packages/web-core/src/components/layout/index.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)
Use React best practices for frontend code
Files:
packages/web-core/src/components/layout/index.tsx
🧠 Learnings (5)
📚 Learning: 2025-12-01T07:29:05.527Z
Learnt from: mrcfps
Repo: refly-ai/refly PR: 1678
File: packages/ai-workspace-common/src/hooks/use-logout.ts:60-65
Timestamp: 2025-12-01T07:29:05.527Z
Learning: In the Refly codebase (packages/ai-workspace-common/src/hooks/use-get-user-settings.ts), user preferences including 'refly-user-profile' and 'refly-local-settings' are stored on the server and fetched via the /user/settings API endpoint on every login. localStorage is used only as a cache for fast initial rendering, not as the source of truth. Therefore, clearing localStorage during logout is safe because preferences will be refetched from the server on next login.
Applied to files:
packages/ai-workspace-common/src/hooks/use-logout.tspackages/ai-workspace-common/src/hooks/use-get-user-settings.tspackages/ai-workspace-common/src/utils/auth-channel.ts
📚 Learning: 2025-11-25T03:04:41.334Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-i18n-guidelines.mdc:0-0
Timestamp: 2025-11-25T03:04:41.334Z
Learning: Applies to **/*.{tsx,ts} : Use the translation wrapper component and useTranslation hook in components
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:04:05.715Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/05-code-organization.mdc:0-0
Timestamp: 2025-11-25T03:04:05.715Z
Learning: Applies to **/*.{jsx,tsx} : Use context for sharing state across multiple components
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:03:19.158Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/00-language-priority.mdc:0-0
Timestamp: 2025-11-25T03:03:19.158Z
Learning: Applies to **/{i18n,locales,translations,lang}/**/*.{json,ts,tsx,js,jsx,properties} : Use Chinese for all user-facing communication
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:04:41.334Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-i18n-guidelines.mdc:0-0
Timestamp: 2025-11-25T03:04:41.334Z
Learning: Applies to **/*.{tsx,ts} : Ensure all user-facing text is translatable
Applied to files:
packages/web-core/src/components/layout/index.tsx
🧬 Code graph analysis (3)
packages/ai-workspace-common/src/hooks/use-logout.ts (1)
packages/ai-workspace-common/src/utils/auth-channel.ts (1)
authChannel(176-176)
packages/ai-workspace-common/src/hooks/use-get-user-settings.ts (1)
packages/ai-workspace-common/src/utils/auth-channel.ts (1)
authChannel(176-176)
packages/web-core/src/components/layout/index.tsx (1)
packages/ai-workspace-common/src/utils/auth-channel.ts (1)
authChannel(176-176)
🪛 ast-grep (0.40.3)
packages/ai-workspace-common/src/utils/auth-channel.ts
[warning] 122-122: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${UID_COOKIE}=([^;]+))
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build / Build
🔇 Additional comments (17)
packages/ai-workspace-common/src/hooks/use-get-user-settings.ts (2)
16-16: LGTM: Clean import of authChannel singleton.The import follows project conventions and correctly imports the singleton instance.
118-123: LGTM: Cross-tab login notification implemented correctly.The login event broadcast correctly updates the authChannel's current UID and notifies other tabs after the login status is set. The optional chaining ensures safety when uid is undefined.
packages/ai-workspace-common/src/hooks/use-logout.ts (2)
7-7: LGTM: Import follows conventions.The authChannel import is correctly structured using named import syntax.
57-59: LGTM: Cross-tab logout notification implemented correctly.Broadcasting the logout event and clearing the current UID before the remote logout call ensures that other tabs are notified immediately and can react appropriately.
packages/request/src/requests/proxiedRequest.ts (2)
18-18: LGTM: Import follows conventions.The authChannel import is correctly placed and follows project import patterns.
77-78: LGTM: Module-scoped flag is appropriate for identity-change handling.The
isHandlingUserChangeflag prevents re-entrancy during identity changes. Since the page reloads immediately after this flag is set, not resetting it is acceptable.packages/web-core/src/components/layout/index.tsx (2)
2-2: LGTM: Imports are clean and follow conventions.Both the Modal import from antd and authChannel import are correctly structured and follow project patterns.
Also applies to: 10-10
90-90: LGTM: Translation hook correctly extractstfunction.Adding
textraction is necessary for the localized modal messages introduced in the cross-tab sync logic.packages/ai-workspace-common/src/utils/auth-channel.ts (9)
1-9: LGTM: Excellent documentation.The file header clearly explains the purpose, compatibility requirements, and fallback strategy. This helps future maintainers understand the design decisions.
11-20: LGTM: Type definitions are clean and type-safe.The
AuthEventunion type provides type safety for the three event variants, and the constants prevent magic strings throughout the code.
22-57: LGTM: Robust initialization with SSR compatibility and fallback.The lazy initialization pattern prevents SSR errors, and the fallback to localStorage ensures compatibility with older browsers. Error handling around BroadcastChannel creation is appropriate.
59-82: LGTM: Solid fallback implementation and error handling.The storage event fallback is correctly implemented, and the error handling in
notifyHandlersensures that a faulty handler doesn't prevent other handlers from executing.
87-115: LGTM: Clean pub-sub pattern with proper fallback.The broadcast and subscribe methods correctly handle both BroadcastChannel and localStorage fallback. The unsubscribe function pattern is idiomatic and prevents memory leaks.
120-125: Acknowledge static analysis warning (false positive).The static analysis tool flags the RegExp construction from a variable. However, since
UID_COOKIEis a constant string ('uid') and not user input, this is a false positive. The regex pattern=([^;]+)is simple and safe.If you want to be extra cautious, you could escape the constant, but it's not necessary here.
Optional: Escape the constant for paranoid security
getUidFromCookie(): string | null { if (typeof document === 'undefined') return null; - const match = document.cookie.match(new RegExp(`${UID_COOKIE}=([^;]+)`)); + const escapedCookie = UID_COOKIE.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const match = document.cookie.match(new RegExp(`${escapedCookie}=([^;]+)`)); return match ? decodeURIComponent(match[1]) : null; }Note: This is overkill since
UID_COOKIEis a known constant, but it would silence the static analysis warning.
154-172: LGTM: Utility methods and cleanup are properly implemented.The
updateCurrentUid,getCurrentUid, anddestroymethods are straightforward and correctly implemented. Thedestroymethod properly cleans up resources.
175-176: LGTM: Singleton pattern is appropriate.Exporting a singleton instance ensures consistent cross-tab synchronization throughout the application. This pattern is correctly implemented and aligns with the usage in other files.
133-149: The separation of validation and state updates invalidateUserIdentityis intentional. The method correctly validates and broadcasts events, while actualcurrentUidupdates happen in their appropriate contexts:use-logout.ts(sets to null) anduse-get-user-settings.ts(sets during login). This design ensures each tab independently detects changes; duplicate broadcasts across tabs are acceptable given this architecture.
…pdate modal usage
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
packages/web-core/src/components/layout/index.tsx (2)
149-156: Hard-coded colors should use theme variables.This issue was previously flagged. The modal button uses hard-coded color values
#0E9F77and#0C8A66instead of theme color tokens. Based on coding guidelines, success color (#12B76A) or corresponding Tailwind utility classes should be used for consistency and maintainability.
167-174: Apply the same theme color fix here.This modal has the same hard-coded color issue as the logout modal above.
🧹 Nitpick comments (1)
packages/web-core/src/components/layout/index.tsx (1)
129-198: Consider extracting cross-tab sync logic into a custom hook.The cross-tab authentication synchronization logic spans nearly 70 lines and handles multiple concerns (event subscription, modal presentation, visibility tracking). Extracting this into a custom hook (e.g.,
useCrossTabAuthSync) would improve:
- Reusability across other components if needed
- Testability in isolation
- Code organization and readability of the main component
Example structure
Create a new hook
packages/ai-workspace-common/src/hooks/use-cross-tab-auth-sync.ts:export const useCrossTabAuthSync = () => { const { t } = useTranslation(); useEffect(() => { // Move the entire debounce + subscription + visibility logic here // ... }, [t]); };Then in this component:
useCrossTabAuthSync();As per coding guidelines on code organization and React best practices.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/i18n/src/en-US/ui.tspackages/i18n/src/zh-Hans/ui.tspackages/web-core/src/components/layout/index.tsx
🧰 Additional context used
📓 Path-based instructions (23)
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{jsx,tsx}: Always use tailwind css to style the component
Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation
Always use useCallback for function props to maintain referential equality
Always specify proper dependency arrays in useEffect to prevent infinite loops
Always avoid inline object/array creation in render to prevent unnecessary re-renders
Always use proper key props when rendering lists
Always split nested components with closures into separate components to avoid performance issues and improve code maintainability
**/*.{jsx,tsx}: Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation in React
Always use useCallback for function props to maintain referential equality in React
Always specify proper dependency arrays in useEffect to prevent infinite loops in React
Always avoid inline object/array creation in render to prevent unnecessary re-renders in React
Always use proper key props when rendering lists in React (avoid using index when possible)
Always split nested components with closures into separate components in React
Use lazy loading for components that are not immediately needed in React
Debounce handlers for events that might fire rapidly (resize, scroll, input) in React
Implement fallback UI for components that might fail in React
Use error boundaries to catch and handle runtime errors in React
**/*.{jsx,tsx}: Place each attribute on a new line when a component has multiple attributes in JSX
Use self-closing tags for elements without children in JSX
Keep JSX expressions simple, extract complex logic to variables
Put closing brackets for multi-line JSX on a new line
**/*.{jsx,tsx}: Component file names should match the component name
Organize function components in order: imports, type definitions, constants, component function, hook calls, e...
Files:
packages/web-core/src/components/layout/index.tsx
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{js,ts,jsx,tsx}: Always use optional chaining (?.) when accessing object properties
Always use nullish coalescing (??) or default values for potentially undefined values
Always check array existence before using array methods
Always validate object properties before destructuring
Always use single quotes for string literals in JavaScript/TypeScript code
**/*.{js,ts,jsx,tsx}: Use semicolons at the end of statements
Include spaces around operators (e.g.,a + binstead ofa+b)
Always use curly braces for control statements
Place opening braces on the same line as their statement
**/*.{js,ts,jsx,tsx}: Group import statements in order: React/framework libraries, third-party libraries, internal modules, relative path imports, type imports, style imports
Sort imports alphabetically within each import group
Leave a blank line between import groups
Extract complex logic into custom hooks
Use functional updates for state (e.g.,setCount(prev => prev + 1))
Split complex state into multiple state variables rather than single large objects
Use useReducer for complex state logic instead of multiple useState calls
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}
📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)
**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}: All code comments MUST be written in English
All variable names, function names, class names, and other identifiers MUST use English words
Comments should be concise and explain 'why' rather than 'what'
Use proper grammar and punctuation in comments
Keep comments up-to-date when code changes
Document complex logic, edge cases, and important implementation details
Use clear, descriptive names that indicate purpose
Avoid abbreviations unless they are universally understood
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)
Use JSDoc style comments for functions and classes in JavaScript/TypeScript
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)
**/*.{js,jsx,ts,tsx}: Use single quotes for string literals in TypeScript/JavaScript
Always use optional chaining (?.) when accessing object properties in TypeScript/JavaScript
Always use nullish coalescing (??) or default values for potentially undefined values in TypeScript/JavaScript
Always check array existence before using array methods in TypeScript/JavaScript
Validate object properties before destructuring in TypeScript/JavaScript
Use ES6+ features like arrow functions, destructuring, and spread operators in TypeScript/JavaScript
Avoid magic numbers and strings - use named constants in TypeScript/JavaScript
Use async/await instead of raw promises for asynchronous code in TypeScript/JavaScript
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{jsx,tsx,css}
📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)
**/*.{jsx,tsx,css}: Use Tailwind CSS for styling components
Follow the utility-first approach with Tailwind CSS
Group related utility classes together in Tailwind CSS
Prefer Tailwind utilities over custom CSS when possible
Files:
packages/web-core/src/components/layout/index.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/03-typescript-guidelines.mdc)
**/*.{ts,tsx}: Avoid usinganytype whenever possible - useunknowntype instead with proper type guards
Always define explicit return types for functions, especially for public APIs
Prefer extending existing types over creating entirely new types
Use TypeScript utility types (Partial<T>,Pick<T, K>,Omit<T, K>,Readonly<T>,Record<K, T>) to derive new types
Use union types and intersection types to combine existing types
Always import types explicitly using theimport typesyntax
Group type imports separately from value imports
Minimize creating local type aliases for imported types
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{js,ts,jsx,tsx,css,json}
📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)
Maximum line length of 100 characters
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{js,ts,jsx,tsx,css,json,yml,yaml}
📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)
Use 2 spaces for indentation, no tabs
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{js,ts,jsx,tsx,css,json,yml,yaml,md}
📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)
No trailing whitespace at the end of lines
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{jsx,tsx,js}
📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)
Each component file should contain only one main component
Files:
packages/web-core/src/components/layout/index.tsx
**/index.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)
Use index files to export multiple components from a directory
Files:
packages/web-core/src/components/layout/index.tsx
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)
Explicitly type props with interfaces or types in React components
Files:
packages/web-core/src/components/layout/index.tsx
**/*.{css,scss,sass,less,js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/09-design-system.mdc)
**/*.{css,scss,sass,less,js,jsx,ts,tsx}: Primary color (#155EEF) should be used for main brand color in buttons, links, and accents
Error color (#F04438) should be used for error states and destructive actions
Success color (#12B76A) should be used for success states and confirmations
Warning color (#F79009) should be used for warnings and important notifications
Info color (#0BA5EC) should be used for informational elements
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{tsx,ts}
📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)
**/*.{tsx,ts}: Use the translation wrapper component and useTranslation hook in components
Ensure all user-facing text is translatable
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{tsx,ts,json}
📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)
Support dynamic content with placeholders in translations
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{tsx,ts,jsx,js,vue,css,scss,less}
📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)
**/*.{tsx,ts,jsx,js,vue,css,scss,less}: Use the primary blue (#155EEF) for main UI elements, CTAs, and active states
Use red (#F04438) only for errors, warnings, and destructive actions
Use green (#12B76A) for success states and confirmations
Use orange (#F79009) for warning states and important notifications
Use blue (#0BA5EC) for informational elements
Primary buttons should be solid with the primary color
Secondary buttons should have a border with transparent or light background
Danger buttons should use the error color
Use consistent padding, border radius, and hover states for all buttons
Follow fixed button sizes based on their importance and context
Use consistent border radius (rounded-lg) for all cards
Apply light shadows (shadow-sm) for card elevation
Maintain consistent padding inside cards (p-4orp-6)
Use subtle borders for card separation
Ensure proper spacing between card elements
Apply consistent styling to all form inputs
Use clear visual indicators for focus, hover, and error states in form elements
Apply proper spacing between elements using 8px, 16px, 24px increments
Ensure proper alignment of elements (left, center, or right)
Use responsive layouts that work across different device sizes
Maintain a minimum contrast ratio of 4.5:1 for text
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{tsx,ts,jsx,js,vue}
📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)
**/*.{tsx,ts,jsx,js,vue}: Include appropriate loading states for async actions in buttons
Group related form elements with appropriate spacing
Provide clear validation feedback for forms
Ensure proper labeling and accessibility for form elements
Ensure all interactive elements are keyboard accessible
Include appropriate ARIA attributes for complex components
Provide alternative text for images and icons
Support screen readers with semantic HTML elements
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)
**/*.{ts,tsx,js,jsx}: Follow the TypeScript/JavaScript style guidelines
Ensure code is well-tested and documented
Files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)
Use React best practices for frontend code
Files:
packages/web-core/src/components/layout/index.tsx
**/{i18n,locales,translations,lang}/**/*.{json,ts,tsx,js,jsx,properties}
📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)
Use Chinese for all user-facing communication
Files:
packages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
packages/i18n/src/{en-US,zh-Hans}/**
📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)
Add new translation keys to both language files (en-US and zh-Hans)
Files:
packages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
packages/i18n/src/**
📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)
packages/i18n/src/**: Maintain consistency in translation key naming conventions
Use descriptive translation keys that reflect the content
Group related translation keys together in the translation file structure
Use namespaces for different sections of the application in translation keys
Follow a hierarchical structure for nested components in translation key organization
Files:
packages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
🧠 Learnings (17)
📚 Learning: 2025-11-25T03:04:41.334Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-i18n-guidelines.mdc:0-0
Timestamp: 2025-11-25T03:04:41.334Z
Learning: Applies to **/*.{tsx,ts} : Use the translation wrapper component and useTranslation hook in components
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:04:41.334Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-i18n-guidelines.mdc:0-0
Timestamp: 2025-11-25T03:04:41.334Z
Learning: Applies to **/*.{tsx,ts} : Ensure all user-facing text is translatable
Applied to files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
📚 Learning: 2025-11-25T03:05:07.580Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/11-ui-design-patterns.mdc:0-0
Timestamp: 2025-11-25T03:05:07.580Z
Learning: Applies to **/*.{tsx,ts,jsx,js,vue,css,scss,less} : Primary buttons should be solid with the primary color
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:04:34.329Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-design-system.mdc:0-0
Timestamp: 2025-11-25T03:04:34.329Z
Learning: Applies to **/*.{css,scss,sass,less,js,jsx,ts,tsx} : Primary color (#155EEF) should be used for main brand color in buttons, links, and accents
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:05:07.580Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/11-ui-design-patterns.mdc:0-0
Timestamp: 2025-11-25T03:05:07.580Z
Learning: Applies to **/*.{tsx,ts,jsx,js,vue,css,scss,less} : Danger buttons should use the error color
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:05:07.580Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/11-ui-design-patterns.mdc:0-0
Timestamp: 2025-11-25T03:05:07.580Z
Learning: Applies to **/*.{tsx,ts,jsx,js,vue,css,scss,less} : Use green (#12B76A) for success states and confirmations
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:05:07.580Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/11-ui-design-patterns.mdc:0-0
Timestamp: 2025-11-25T03:05:07.580Z
Learning: Applies to **/*.{tsx,ts,jsx,js,vue,css,scss,less} : Use the primary blue (#155EEF) for main UI elements, CTAs, and active states
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:04:34.329Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-design-system.mdc:0-0
Timestamp: 2025-11-25T03:04:34.329Z
Learning: Applies to **/*.{css,scss,sass,less,js,jsx,ts,tsx} : Success color (#12B76A) should be used for success states and confirmations
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:05:07.580Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/11-ui-design-patterns.mdc:0-0
Timestamp: 2025-11-25T03:05:07.580Z
Learning: Applies to **/*.{tsx,ts,jsx,js,vue,css,scss,less} : Use consistent padding, border radius, and hover states for all buttons
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:04:34.329Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-design-system.mdc:0-0
Timestamp: 2025-11-25T03:04:34.329Z
Learning: Applies to **/*.{css,scss,sass,less,js,jsx,ts,tsx} : Warning color (#F79009) should be used for warnings and important notifications
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:04:34.329Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-design-system.mdc:0-0
Timestamp: 2025-11-25T03:04:34.329Z
Learning: Applies to **/*.{css,scss,sass,less,js,jsx,ts,tsx} : Error color (#F04438) should be used for error states and destructive actions
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:05:07.580Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/11-ui-design-patterns.mdc:0-0
Timestamp: 2025-11-25T03:05:07.580Z
Learning: Applies to **/*.{tsx,ts,jsx,js,vue,css,scss,less} : Use orange (#F79009) for warning states and important notifications
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:05:07.580Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/11-ui-design-patterns.mdc:0-0
Timestamp: 2025-11-25T03:05:07.580Z
Learning: Applies to **/*.{tsx,ts,jsx,js,vue,css,scss,less} : Use blue (#0BA5EC) for informational elements
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:04:34.329Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-design-system.mdc:0-0
Timestamp: 2025-11-25T03:04:34.329Z
Learning: Applies to **/*.{css,scss,sass,less,js,jsx,ts,tsx} : Info color (#0BA5EC) should be used for informational elements
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:04:05.715Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/05-code-organization.mdc:0-0
Timestamp: 2025-11-25T03:04:05.715Z
Learning: Applies to **/*.{jsx,tsx} : Use context for sharing state across multiple components
Applied to files:
packages/web-core/src/components/layout/index.tsx
📚 Learning: 2025-11-25T03:03:19.158Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/00-language-priority.mdc:0-0
Timestamp: 2025-11-25T03:03:19.158Z
Learning: Applies to **/{i18n,locales,translations,lang}/**/*.{json,ts,tsx,js,jsx,properties} : Use Chinese for all user-facing communication
Applied to files:
packages/web-core/src/components/layout/index.tsxpackages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
📚 Learning: 2025-11-25T03:04:41.334Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-i18n-guidelines.mdc:0-0
Timestamp: 2025-11-25T03:04:41.334Z
Learning: Applies to packages/i18n/src/{en-US,zh-Hans}/** : Add new translation keys to both language files (en-US and zh-Hans)
Applied to files:
packages/i18n/src/zh-Hans/ui.tspackages/i18n/src/en-US/ui.ts
🧬 Code graph analysis (1)
packages/web-core/src/components/layout/index.tsx (1)
packages/ai-workspace-common/src/utils/auth-channel.ts (1)
authChannel(176-176)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build / Build
🔇 Additional comments (2)
packages/i18n/src/zh-Hans/ui.ts (1)
526-533: New auth state messages are clear and correctly scopedThe
loggedOutanduserChangedentries are well-phrased, accurately describe the cross-tab behavior, and follow the existing{ title, content }pattern undercommon. They also align with the corresponding en-US keys.packages/i18n/src/en-US/ui.ts (1)
192-200: Cross-tab auth messages look good and are consistent with zh-HansThe
loggedOutanduserChangedstrings clearly describe the multi-tab logout/account-switch flows, use suitable tone for a modal, and mirror the zh-Hans keys in both naming and structure ({ title, content }), which keeps i18n usage straightforward. Based on learnings, new keys are correctly added to both locales.
…tChannel API (#1973) * feat: Synchronize authentication state across browser tabs using BroadcastChannel with localStorage fallback. * feat: Add i18n messages for logged out and user switched states and update modal usage
Summary
Add cross-tab authentication state synchronization to handle multi-tab logout/user-switch scenarios gracefully.
Auth Channel:
auth-channel.tsutility using BroadcastChannel API with localStorage fallbacklogout,user-changed, andloginevents across tabsLogout Sync:
User Switch Sync:
Request Interceptor:
Visibility Check:
Schedule Popover Fix:
Impact Areas
Checklist
dev/reformat(backend) andcd web && npx lint-staged(frontend) to appease the lint godsSummary by CodeRabbit
New Features
i18n
✏️ Tip: You can customize this high-level summary in your review settings.