Skip to content

Studio: Refactor AuthProvider into Redux slice#2778

Open
katinthehatsite wants to merge 6 commits intotrunkfrom
fix/refactor-auth-provider-in-redux-slice
Open

Studio: Refactor AuthProvider into Redux slice#2778
katinthehatsite wants to merge 6 commits intotrunkfrom
fix/refactor-auth-provider-in-redux-slice

Conversation

@katinthehatsite
Copy link
Contributor

@katinthehatsite katinthehatsite commented Mar 12, 2026

Related issues

Fixes https://linear.app/a8c/issue/STU-1379/studio-refactor-authprovider-into-redux-slice

How AI was used in this PR

I used it in the plan mode to plan the refactor, then gave feedback on the plan and used it for implementation, making further manual corrections.

Proposed Changes

This PR refactors AuthProvider into Redux slice.

Testing Instructions

  • Pull the changes from this branch
  • Start Studio with npm start
  • Log out of Studio and confirm that you are seeing logged out view
  • Log in and confirm it works as expected
  • Confirm you are correctly seeing the features that should be available with WP.com logged in view
  • Confirm tests are passing
  • Close the app while logged in
  • Open ~/Library/Application Support/Studio/appdata-v1.json
  • Delete the authToken
  • Save the changes
  • Start the app with again
  • Confirm that you can see logged out view

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

@katinthehatsite katinthehatsite self-assigned this Mar 12, 2026
@katinthehatsite katinthehatsite marked this pull request as draft March 12, 2026 13:20
@@ -1,4 +1,4 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not related directly to changes in this PR. This is something that my linter flagged that needed to be fixed and was present on trunk

@katinthehatsite katinthehatsite marked this pull request as ready for review March 12, 2026 15:06
@katinthehatsite katinthehatsite requested a review from a team March 12, 2026 15:15
Copy link
Contributor

@fredrikekelund fredrikekelund left a comment

Choose a reason for hiding this comment

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

Thanks for tackling this, @katinthehatsite.

The end goal with this refactor should be to remove AuthProvider altogether. That, and doing something about setWpcomClient from src/stores/wpcom-api are the two big changes needed here, IMO.

Copy link
Contributor

Choose a reason for hiding this comment

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

We should remove this context provider altogether. Components can easily consume Redux state and dispatch actions. There's no point in keeping this provider as a thin wrapper around the Redux slice.

Comment on lines +189 to +190
export const selectIsAuthenticated = ( state: RootState ) => state.auth.isAuthenticated;
export const selectUser = ( state: RootState ) => state.auth.user ?? undefined;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
export const selectIsAuthenticated = ( state: RootState ) => state.auth.isAuthenticated;
export const selectUser = ( state: RootState ) => state.auth.user ?? undefined;
export const authThunks = {
handleInvalidToken,
initializeAuth,
authTokenReceived,
authLogout,
};
export const authSelectors = {
selectIsAuthenticated: ( state: RootState ) => state.auth.isAuthenticated,
selectUser: ( state: RootState ) => state.auth.user ?? undefined,
};

We've followed this pattern in some other Redux slices. I think it's helpful to namespace selectors, actions, and thunks this way.

import { getIpcApi } from 'src/lib/get-ipc-api';
import { isInvalidTokenError } from 'src/lib/is-invalid-oauth-token-error';
import { store, RootState } from 'src/stores';
import { getWpcomClient, setWpcomClient } from 'src/stores/wpcom-api';
Copy link
Contributor

Choose a reason for hiding this comment

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

Now that the auth details live in the Redux state tree, I'd argue that src/stores/wpcom-api should either retrieve the client state prop from this slice or subscribe to state updates from it. We should remove the getWpcomClient and setWpcomClient from src/stores/wpcom-api

Comment on lines +34 to +39
onInvalidToken();
await getIpcApi().showMessageBox( {
type: 'error',
message: 'Session Expired',
detail: 'Your session has expired. Please log in again.',
} );
Copy link
Contributor

Choose a reason for hiding this comment

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

If the idea is to always dispatch handleInvalidToken here, then I think it's better to pass the store as an argument to this function and call store.dispatch( handleInvalidToken() ).

We could also consider moving the getIpcApi().showMessageBox() call to handleInvalidToken

void dispatch( initializeAuth( { locale } ) );
}, [ dispatch, locale ] );

useIpcListener( 'auth-updated', ( _event, payload ) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be moved to apps/studio/src/stores/auth-slice.ts like so:

window.ipcListener.subscribe( 'auth-updated', ( _event, payload ) => {
	if ( 'error' in payload ) {
		let title: string = __( 'Authentication error' );
		let message: string = __( 'Please try again.' );

		if ( payload.error instanceof Error && payload.error.message.includes( 'access_denied' ) ) {
			title = __( 'Authorization denied' );
			message = __(
				'It looks like you denied the authorization request. To proceed, please click "Approve"'
			);
		}

		void getIpcApi().showErrorMessageBox( { title, message } );
		return;
	}

	void store.dispatch( authTokenReceived( { token: payload.token, locale } ) );
} );

Comment on lines +49 to +51
useEffect( () => {
void dispatch( initializeAuth( { locale } ) );
}, [ dispatch, locale ] );
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be dispatched in apps/studio/src/stores/index.ts instead.

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