Skip to content

Comments

Feat/signout improvement #1080

Merged
ThinuwanW merged 1 commit intodevelopfrom
feat/signout-improvement
Feb 20, 2026
Merged

Feat/signout improvement #1080
ThinuwanW merged 1 commit intodevelopfrom
feat/signout-improvement

Conversation

@hasalarootcode
Copy link
Contributor

PR checklist

TaskId: (https://github.com/SkappHQ/skapp/issues/[id])

Summary

How to test

Project Checklist

  • Changes build without any errors
  • Have written adequate test cases
  • Done developer testing in
    • Chrome
    • Firefox
    • Safari
  • Code is formatted with npm run format
  • Code is linted with npm run check-lint
  • No unnecessary comments left in code
  • Made corresponding changes to the documentation

Other

  • New atomic components added
  • New molecules added
  • New pages(routes) added
  • New dependencies installed

PR Checklist

  • Pull request is raised from the correct source branch
  • Pull request is raised to the correct destination branch
  • Pull request is raised with correct title
  • Pull request is self reviewed
  • Pull request is self assigned
  • Suitable pull request status labels are added (ready-for-code-review)

Additional Information

@hasalarootcode hasalarootcode self-assigned this Feb 20, 2026
Copilot AI review requested due to automatic review settings February 20, 2026 05:11
@sonarqubecloud
Copy link

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request refactors the authentication flow by moving signOut and refreshAccessToken functions from the React context to standalone utility functions. The changes improve separation of concerns and add a callback feature to preserve user navigation state after sign-out.

Changes:

  • Refactored authentication functions from React context to utility functions for better modularity
  • Added callback parameter support to signOut to redirect users back to their previous location after signing in
  • Simplified error handling in token refresh logic and distributed it across interceptors
  • Added COMMON_ERROR_MISSING_COOKIE_IN_TOKEN error constant and corresponding handler

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/src/community/auth/utils/authUtils.ts Added new signOut function with callback support; simplified error handling in getNewAccessToken and clearCookies
frontend/src/community/auth/providers/AuthProvider.tsx Removed signOut and refreshAccessToken from context; simplified checkAuth function
frontend/src/community/auth/types/auth.ts Removed signOut and refreshAccessToken from AuthContextType interface
frontend/src/community/auth/utils/authInterceptor.ts Added interceptor to handle missing cookie errors and trigger sign-out
frontend/src/community/common/constants/errorMessageKeys.ts Added COMMON_ERROR_MISSING_COOKIE_IN_TOKEN constant
frontend/src/community/common/providers/TanStackProvider.tsx Updated to use imported functions instead of context; moved handleTokenRefresh inside useEffect
frontend/src/community/common/components/templates/ContentLayout/ContentLayout.tsx Updated to import signOut directly from utilities
frontend/src/community/common/components/molecules/ProfileMenu/ProfileMenu.tsx Updated to import signOut directly; removed unused code
frontend/pages/index.tsx Updated to import signOut directly and added missing await

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +34 to +35
await getNewAccessToken();
queryClient.invalidateQueries();
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The handleTokenRefresh function doesn't handle the case where getNewAccessToken returns null (indicating token refresh failure). If token refresh fails, the queries are still invalidated which could lead to failed requests. Consider checking the return value and only invalidating queries if token refresh was successful, or calling signOut if it fails.

Suggested change
await getNewAccessToken();
queryClient.invalidateQueries();
const newAccessToken = await getNewAccessToken();
if (newAccessToken) {
queryClient.invalidateQueries();
} else {
await signOut();
}

Copilot uses AI. Check for mistakes.
Comment on lines +260 to +271
export const signOut = async (redirect: boolean = true): Promise<void> => {
await clearCookies();

if (redirect === false) return;

if (typeof window !== 'undefined') {
const currentPath = window.location.pathname;
const urlParams = new URLSearchParams(window.location.search);
const existingCallback = urlParams.get('callback');

const callbackPath = existingCallback || currentPath;
window.location.href = `${ROUTES.AUTH.SIGNIN}?callback=${callbackPath}`;
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callback path is used without validation. If a malicious actor crafts a URL with a callback parameter pointing to an external site (e.g., ?callback=https://evil.com), users could be redirected to an untrusted site after signing out. Consider validating that the callback path is a relative path (starts with /) or is within the allowed domain before using it in the redirect.

Suggested change
export const signOut = async (redirect: boolean = true): Promise<void> => {
await clearCookies();
if (redirect === false) return;
if (typeof window !== 'undefined') {
const currentPath = window.location.pathname;
const urlParams = new URLSearchParams(window.location.search);
const existingCallback = urlParams.get('callback');
const callbackPath = existingCallback || currentPath;
window.location.href = `${ROUTES.AUTH.SIGNIN}?callback=${callbackPath}`;
const isSafeCallbackPath = (callback: string | null): boolean => {
if (!callback) {
return false;
}
// Allow only relative paths that start with a single "/" and are not protocol-relative.
if (!callback.startsWith("/")) {
return false;
}
if (callback.startsWith("//")) {
return false;
}
return true;
};
export const signOut = async (redirect: boolean = true): Promise<void> => {
await clearCookies();
if (redirect === false) return;
if (typeof window !== "undefined") {
const currentPath = window.location.pathname;
const urlParams = new URLSearchParams(window.location.search);
const existingCallback = urlParams.get("callback");
const callbackPath = isSafeCallbackPath(existingCallback)
? existingCallback!
: currentPath;
const encodedCallback = encodeURIComponent(callbackPath);
window.location.href = `${ROUTES.AUTH.SIGNIN}?callback=${encodedCallback}`;

Copilot uses AI. Check for mistakes.
Comment on lines +265 to +268
if (typeof window !== 'undefined') {
const currentPath = window.location.pathname;
const urlParams = new URLSearchParams(window.location.search);
const existingCallback = urlParams.get('callback');
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code uses single quotes ('undefined') instead of double quotes. The codebase consistently uses double quotes for strings throughout the authentication utilities (see lines 117, 127, 147 in the same file). This should be changed to maintain consistency with the established convention.

Suggested change
if (typeof window !== 'undefined') {
const currentPath = window.location.pathname;
const urlParams = new URLSearchParams(window.location.search);
const existingCallback = urlParams.get('callback');
if (typeof window !== "undefined") {
const currentPath = window.location.pathname;
const urlParams = new URLSearchParams(window.location.search);
const existingCallback = urlParams.get("callback");

Copilot uses AI. Check for mistakes.
Comment on lines +265 to +268
if (typeof window !== 'undefined') {
const currentPath = window.location.pathname;
const urlParams = new URLSearchParams(window.location.search);
const existingCallback = urlParams.get('callback');
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code uses single quotes ('callback') instead of double quotes. The codebase consistently uses double quotes for strings throughout the authentication utilities. This should be changed to maintain consistency with the established convention.

Suggested change
if (typeof window !== 'undefined') {
const currentPath = window.location.pathname;
const urlParams = new URLSearchParams(window.location.search);
const existingCallback = urlParams.get('callback');
if (typeof window !== "undefined") {
const currentPath = window.location.pathname;
const urlParams = new URLSearchParams(window.location.search);
const existingCallback = urlParams.get("callback");

Copilot uses AI. Check for mistakes.
const existingCallback = urlParams.get('callback');

const callbackPath = existingCallback || currentPath;
window.location.href = `${ROUTES.AUTH.SIGNIN}?callback=${callbackPath}`;
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callback path is being directly interpolated into the URL without encoding. If currentPath contains special characters (like query parameters with &, =, etc.), this could break the URL structure or lead to incorrect routing. Consider using encodeURIComponent to properly encode the callback value.

Suggested change
window.location.href = `${ROUTES.AUTH.SIGNIN}?callback=${callbackPath}`;
window.location.href = `${ROUTES.AUTH.SIGNIN}?callback=${encodeURIComponent(callbackPath)}`;

Copilot uses AI. Check for mistakes.
@ThinuwanW ThinuwanW merged commit 3068d08 into develop Feb 20, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants