-
Notifications
You must be signed in to change notification settings - Fork 153
Feat: Authentication to Tauri and Web simulator #554
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
""" WalkthroughThe changes refactor the authentication flow in the user interface by replacing direct navigation to sign-in and registration pages with a modal dialog for authentication. The modal supports both login and registration, handling form submissions with asynchronous API calls and providing inline user feedback via a snackbar component. The authentication state management in the store is extended with new actions to set the token and sign out, updating user information and resetting state as needed. The sign-out process is also changed to use the store's method instead of redirecting. UI elements and logic are updated to accommodate these new behaviors. Changes
Assessment against linked issues
Assessment against linked issues: Out-of-scope changesNo out-of-scope changes detected. All code modifications relate directly to the authentication feature requirements described in the linked issue #557. 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
npm error Exit handler never called! 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. 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
CodeRabbit Configuration File (
|
✅ Deploy Preview for circuitverse ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (3)
src/store/authStore.ts (1)
83-84
: Open TODO warrants tracking ticketThe
// TODO: extract store verify and check better ways to impliment
comment is vague and easy to forget. Consider opening an issue that precisely describes what must be improved (token verification, persistence strategy, typings, etc.) so it can be prioritised.src/components/Navbar/User/UserMenu.vue (2)
233-242
: Hard-coded localhost URLs hinder production builds & Tauri packagesEndpoints are currently fixed to
http://localhost:4000/...
.
This will fail in production, in the web simulator behind a different origin, and in a Tauri-packaged desktop app.-const url = isLoginMode.value - ? 'http://localhost:4000/api/v1/auth/login' - : 'http://localhost:4000/api/v1/auth/signup' +const base = import.meta.env.VITE_API_BASE_URL ?? 'https://api.circuitverse.org/' +const url = isLoginMode.value + ? `${base}/api/v1/auth/login` + : `${base}/api/v1/auth/signup`Also add
credentials:'include'
if you later switch to cookie-based sessions.
314-315
: Logging out leaves stale token in storageYou’ve wired
authStore.signOut()
, but if the JWT was persisted (e.g.,localStorage
to survive refreshes) it should be removed here as well—otherwise the next page load will automatically set the user back to logged-in.function signout() { authStore.signOut() + localStorage.removeItem('jwt') }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/components/Navbar/User/UserMenu.vue
(2 hunks)src/store/authStore.ts
(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Analyze (javascript)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/components/Navbar/User/UserMenu.vue (2)
270-275
: Consider more detailed error loggingWhile the catch block handles errors, the console.error could provide more context to help with debugging.
- console.error('Authentication error:', error) + console.error('Authentication error:', { error, email: email.value ? '[REDACTED]' : 'empty', formMode: isLoginMode.value ? 'login' : 'register' })
297-303
: Simplify snackbar type handlingThe snackbar type logic could be more flexible to support additional notification types.
function showSnackbar(message: string, type: string) { snackbar.value = { visible: true, message, - color: type === 'error' ? 'error' : 'success' + color: type } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/components/Navbar/User/UserMenu.vue
(2 hunks)src/store/authStore.ts
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/store/authStore.ts
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (10)
src/components/Navbar/User/UserMenu.vue (10)
44-59
: Good implementation of authentication modal triggersThe refactoring from direct navigation to a modal-based approach is a good improvement that keeps users in context. The implementation properly sets the authentication mode and manages the drawer state.
115-171
: Modal implementation follows good practicesThe authentication modal is well-structured with appropriate form validation, conditional rendering based on mode, and proper button states for loading feedback. This enhances user experience by providing immediate visual feedback.
173-188
: Good implementation of feedback mechanismThe snackbar component provides clear user feedback for both successful operations and errors, which is essential for a good UX. The timeout and close button give users control over notifications.
200-213
: Well-structured reactive stateThe reactive state variables are clearly defined and organized logically. The snackbar state object is well-designed with all necessary properties grouped together.
251-256
: Error handling implementation looks goodThe error handling has been properly implemented according to previous review comments. The code now safely parses JSON responses and falls back gracefully when receiving non-JSON responses.
258-269
: Token management and success handlingThe authentication success flow is well implemented. It properly:
- Sets the authentication token in the store
- Displays success feedback
- Clears form fields
- Closes the modal
This creates a smooth user experience.
278-295
: Good error handling with specific messagesThe error handling function properly categorizes different error scenarios and displays appropriate messages to guide the user. This is a good practice for improving user experience.
314-316
: Sign out implementation improvedThe sign out implementation has been improved to use the store's method instead of a redirect. This is a better approach for maintaining consistent state management.
359-403
: Well-organized stylesThe modal styles are well-organized and use proper specificity. The dark theme styling looks good and maintains consistency with the rest of the UI.
225-276
:❌ Incorrect review comment
Consider adding CSRF protection for authentication requests
For improved security, consider adding CSRF token protection to your authentication requests.
You could implement CSRF protection like this:
const response = await fetch(url, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', + 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '', }, body: JSON.stringify(body), })
🌐 Web query:
Is CSRF protection necessary for authentication endpoints?
💡 Result:
Yes, CSRF protection is necessary for authentication endpoints, despite some common misconceptions about this topic. While it might seem that CSRF protection is only needed after a user is authenticated, there are important security considerations for login forms as well.
Why Login Forms Need CSRF Protection
Protection Against Login CSRF Attacks
A login CSRF attack occurs when an attacker tricks a victim into logging into a website using the attacker's credentials without their knowledge[6][7]. This type of attack can have serious consequences:
- The attacker can track the victim's activities within the application
- The attacker may gain access to the victim's personal information or stored financial data
- The attacker could potentially perform actions on behalf of the victim, such as making purchases using stored payment methods[3]
Framework Recommendations
Many security-focused frameworks explicitly include CSRF protection for login endpoints:
- Spring Security protects against CSRF attacks by default for login requests[5]
- Django documentation emphasizes protection against "login CSRF" attacks where users might be tricked into logging in with someone else's credentials[8]
Implementation Approaches
For authentication endpoints, CSRF protection can be implemented using several methods:
Synchronizer Token Pattern (STP) is the most common approach for protecting against CSRF attacks. This involves generating a unique token that must be included with form submissions[10].
Double Submit Cookie Pattern uses a cryptographically strong random value both as a cookie and as a request parameter. The server verifies that these values match before processing the request[1].
For login forms specifically:
- Generate a CSRF token before the user authenticates
- Include the token in the login form
- Verify the token server-side before processing login credentials
Special Considerations for APIs
For REST APIs, CSRF protection requirements depend on the authentication method:
- APIs using token authentication typically don't need CSRF protection unless the token is stored in a cookie[7]
- If using cookie-based authentication for APIs, CSRF protection becomes necessary
Conclusion
CSRF protection for authentication endpoints is an important security measure that prevents attackers from forcing users to log in with malicious credentials. While the specific implementation may vary based on your application architecture, including CSRF protection for login forms is considered a security best practice by major frameworks and security organizations.
Citations:
- 1: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
- 2: https://www.posh.ai/blog/are-csrf-tokens-necessary
- 3: https://www.invicti.com/blog/web-security/protecting-website-using-anti-csrf-token/
- 4: https://www.brightsec.com/blog/csrf-token/
- 5: https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html
- 6: https://community.auth0.com/t/csrf-protection-when-is-it-needed/25353
- 7: https://forum.djangoproject.com/t/csrf-protection-for-rest-apis/10731
- 8: https://docs.djangoproject.com/en/5.2/ref/csrf/
- 9: https://brightsec.com/blog/cross-site-request-forgery-csrf/
- 10: https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-9.0
Ignore CSRF token for this JSON-based login request
This endpoint accepts only JSON and returns a token that’s stored client-side (not in cookies), so it isn’t vulnerable to CSRF. You can safely omit the
X-CSRF-Token
header and keep your current implementation.Likely an incorrect or invalid review comment.
I ll perform some more tests on this, while @aryanndwi123 @Arnabdaz let me know the update on the api changes i need to do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/components/Navbar/User/UserMenu.vue (1)
293-301
: Hard-coded API base URL resurfacedThe login / signup endpoints are still pinned to
http://localhost:4000/*
. This breaks in prod/staging and was already called out previously. Please read the earlier suggestion and move the base URL to a central config or env variable.
🧹 Nitpick comments (1)
src/components/Navbar/User/UserMenu.vue (1)
230-237
:v-btn
icon prop misuse – icon may not render
<v-btn ... :icon="mdiClose">
expects a boolean or string whenicon
style is required.
Here you only need a close icon inside the button:-<v-btn - variant="text" - @click="snackbar.visible = false" - :icon="mdiClose" - color="white" -></v-btn> +<v-btn variant="text" @click="snackbar.visible = false" icon color="white"> + <v-icon :icon="mdiClose" /> +</v-btn>Prevents Vuetify prop warning and guarantees the icon shows up.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/components/Navbar/User/User.scss
(1 hunks)src/components/Navbar/User/UserMenu.vue
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/components/Navbar/User/User.scss
🔇 Additional comments (1)
src/components/Navbar/User/UserMenu.vue (1)
350-356
:❌ Incorrect review comment
JWT storage strategy unclear ‑ verify XSS exposure
authStore.setToken(data.token)
blindly hands the raw JWT to the store. If the store persists it inlocalStorage
, any XSS compromise grants full account takeover. Evaluate:
- Prefer
HttpOnly
secure cookies issued by the backend.- If you must keep the token client-side, at least place it in
sessionStorage
, add XSS mitigation (CSP, strict sanitisation) and rotate tokens frequently.
🏁 Script executed:
#!/bin/bash # Locate occurrences of setToken and inspect related store implementation rg -n "setToken" -C2 srcLength of output: 714
🏁 Script executed:
#!/bin/bash # Display the authStore implementation to see how the token is stored sed -n '1,100p' src/store/authStore.tsLength of output: 2654
authStore.setToken does not persist the JWT
The
setToken
action merely decodes the JWT payload and updates in-memory state—it does not write the token tolocalStorage
(orsessionStorage
). As a result, the XSS risk outlined around client-side storage does not apply here.If you later introduce persistent storage for the token (e.g. to survive page reloads), consider switching to HttpOnly secure cookies issued by the backend or, at minimum, using
sessionStorage
with strong CSP and token rotation.Likely an incorrect or invalid review comment.
function dashboard() { | ||
window.location.href = `/users/${authStore.getUserId}` | ||
} | ||
|
||
function my_groups() { | ||
window.location.href = `/users/${authStore.getUserId}/groups` | ||
} | ||
|
||
function notifications() { | ||
window.location.href = `/users/${authStore.getUserId}/notifications` | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use the router instead of window.location.href
Direct page reloads defeat SPA benefits (state loss, slower navigation). Replace with Vue-Router:
-import router from '@/router' // wherever your router lives
-
-function dashboard() {
- window.location.href = `/users/${authStore.getUserId}`
-}
+function dashboard() {
+ router.push({ name: 'user-dashboard', params: { id: authStore.getUserId } })
+}
Apply the same change to my_groups()
and notifications()
.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/components/Navbar/User/UserMenu.vue lines 358 to 368, replace all
instances of direct URL assignment using window.location.href in the
dashboard(), my_groups(), and notifications() functions with Vue-Router
navigation methods. Use the router's push method to navigate programmatically to
the respective routes, ensuring SPA benefits like state preservation and faster
navigation without full page reloads.
|
||
function handleLoginError(status: number, errorData: any) { | ||
switch (status) { | ||
case 401: | ||
showSnackbar('Invalid credentials', 'error') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function should be in some common folder like utils, and may be instead of login make it generic
UI for the sign in model looks weird, use the same UI/UX pattern, do not introduce new colours or other UI elements |
okay |
@senbo1 Could you help me out with a better UI here if you have time? |
Implemented the Authentication model for the Desktop and the Vue simulator
Fixes #557
Describe the changes you have made in this PR -
Summary by CodeRabbit
Summary by CodeRabbit
New Features
Improvements
Style