Skip to content

Conversation

@fredrikekelund
Copy link
Contributor

Related issues

Proposed Changes

This PR is based on @youknowriad's work in #1958. It implements a studio auth status command that:

  1. Checks for a valid auth token in appdata (and make an API request to confirm its validity)
  2. Prints a message to let the user know if they're authenticated, and, if so, what their username is

Testing Instructions

  1. Run npm run cli:build
  2. Run node dist/cli/main.js auth logout
  3. Run node dist/cli/main.js auth status
  4. Ensure a "Authentication token is invalid or expired" message is printed
  5. Open Studio
  6. Log in to WordPress.com
  7. Run node dist/cli/main.js auth status
  8. Ensure a "Successfully authenticated with WordPress.com as `USERNAME`" message is printed

Pre-merge Checklist

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

@fredrikekelund fredrikekelund requested review from a team and bcotrim November 6, 2025 12:36
@fredrikekelund fredrikekelund self-assigned this Nov 6, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 6, 2025

📊 Performance Test Results

Comparing ddc45d0 vs trunk

site-editor

Metric trunk ddc45d0 Diff Change
load 14992.00 ms 11631.00 ms -3361.00 ms 🟢 -22.4%

site-startup

Metric trunk ddc45d0 Diff Change
siteCreation 22257.00 ms 25323.00 ms +3066.00 ms 🔴 13.8%
siteStartup 6997.00 ms 6985.00 ms -12.00 ms 🟢 -0.2%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change

} catch ( error ) {
throw new LoggerError( __( 'Failed to revoke token' ), error );
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a lot of things in this file that should be "common" between CLI and App.

@claude
Copy link

claude bot commented Nov 17, 2025

Claude finished @fredrikekelund's task —— View job


Documentation updated successfully

Tasks

  • Review the new auth status command implementation
  • Read current docs/ai-instructions.md
  • Update documentation with new command details
  • Commit and push changes

Summary

I've reviewed the PR changes and updated the CLI documentation in docs/ai-instructions.md.

What was done:

  • ✅ Added documentation for studio auth logout command (existed in base branch but wasn't documented)
  • ✅ Added documentation for studio auth status command (new in this PR)
  • ✅ Both commands follow the same documentation format as auth login with Usage, Description, Options, Example, and Notes sections
  • ✅ Committed and pushed changes to the PR branch

Implementation details:
The auth status command works by:

  1. Reading the auth token from app data
  2. Making an API request to /me endpoint to verify the token is valid
  3. Displaying the WordPress.com username if authenticated
  4. Showing an error message if the token is invalid or expired

The documentation now provides clear usage examples and notes for all three authentication commands: login, logout, and status.

--- |

@claude
Copy link

claude bot commented Nov 17, 2025

Claude finished @fredrikekelund's task —— View job


Code Review Complete ✅

I've completed a comprehensive code review of this PR. Overall, this is a well-implemented, clean addition with good test coverage. Here are my findings:


Summary

This PR successfully implements the studio auth status command that checks authentication status and displays the username. The implementation follows existing patterns in the codebase and includes comprehensive unit tests.


Detailed Review

Cross-Platform Compatibility - EXCELLENT

  • No platform-specific issues found. The code uses:
    • Standard Node.js APIs that work across macOS and Windows
    • path.join() is properly used in the appdata module (cli/lib/appdata.ts:75, :78)
    • No hardcoded path separators or platform-specific assumptions
    • OAuth and API calls are platform-agnostic
  • The implementation correctly leverages getAppdataDirectory() which already handles platform differences (APPDATA vs ~/Library)

Code Quality - VERY GOOD

Strengths:

  • Clean, readable code following TypeScript best practices
  • Consistent with existing auth commands (login, logout)
  • Proper error handling with LoggerError
  • Good separation of concerns (command logic vs. API calls)
  • Follows patterns documented in CLAUDE.md

Minor Suggestions:

  • See inline comment on status.ts:12 about variable initialization (style preference)
  • Consider the architectural feedback about moving API functions to common (see inline comment)

Security (OWASP Top 10) - EXCELLENT

  • No security issues found
  • Proper authentication token validation via validateAccessToken()
  • No hardcoded secrets or sensitive data exposure
  • Input from user (username) is safely handled through sprintf with proper escaping
  • Token is read from secure app data storage with file locking
  • No SQL injection, XSS, or other OWASP concerns apply here

Performance - EXCELLENT

  • Minimal performance impact
  • Single API call to /me endpoint (efficient)
  • No memory leaks or resource issues
  • Appropriate async/await usage
  • No blocking operations

Testing - VERY GOOD

Strengths:

  • Comprehensive test coverage with 4 test cases
  • Tests all major code paths: success, token invalid, API error types
  • Proper mocking of dependencies
  • Good use of Jest matchers

Suggestions:

  • See inline comment on status.test.ts:16 about testing explicit token expiration

📝 Documentation - NEEDS UPDATE

Action Required:
The CLAUDE.md file documents auth login but does not yet document auth logout or auth status. Since this PR adds a new command, please add documentation for auth status in the "Authentication Commands" section following the same format as auth login.

Suggested addition to CLAUDE.md after line 82:

#### `studio auth logout`
Log out and clear WordPress.com authentication.

**Usage:**
```bash
node dist/cli/main.js auth logout

Description:
Revokes the current access token and removes authentication data from local storage.

studio auth status

Check current authentication status.

Usage:

node dist/cli/main.js auth status

Description:
Checks if you're currently authenticated with WordPress.com and displays your username if authenticated.

Example Output:

  • When authenticated: Successfully authenticated with WordPress.com as \username``
  • When not authenticated: Authentication token is invalid or expired

---

### Architecture Feedback

I agree with @youknowriad's review comment about api.ts. The `getUserInfo`, `validateAccessToken`, and `revokeAuthToken` functions are generic WordPress.com API operations that would benefit from being in a shared location (see my inline comment for details). This is a good opportunity for future refactoring but **does not block this PR**.

---

### Recommendation

**✅ APPROVE with minor documentation request**

This PR is ready to merge after adding documentation for the new command to CLAUDE.md. The code is solid, well-tested, and follows best practices. The architectural suggestion about moving API functions to common can be addressed in a follow-up PR if desired.

---

Add documentation for `auth logout` and `auth status` commands.

Co-authored-by: Fredrik Rombach Ekelund <[email protected]>
ID: z.number(),
email: z.string().email(),
display_name: z.string(),
username: z.string(),
Copy link

Choose a reason for hiding this comment

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

Code Reusability & Architecture - I agree with @youknowriad's earlier comment. The getUserInfo, validateAccessToken, and revokeAuthToken functions are generic WordPress.com API operations that would benefit from being in a shared location like src/lib/ or common/lib/.

This would:

  1. Allow the main Electron app to reuse these functions for authentication UI
  2. Follow the DRY principle
  3. Make the API operations testable from both CLI and app contexts
  4. Align with the architecture documented in CLAUDE.md where common code goes in /common

Consider creating common/lib/wpcom-user-api.ts or similar for these user-related API functions.

const logger = new Logger< LoggerAction >();

logger.reportStart( LoggerAction.STATUS_CHECK, __( 'Checking authentication status…' ) );
let token: Awaited< ReturnType< typeof getAuthToken > >;
Copy link

Choose a reason for hiding this comment

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

Code Style - The type annotation Awaited< ReturnType< typeof getAuthToken > > is correct but creates an unused variable declaration since token is reassigned in the try block. Consider simplifying:

logger.reportStart( LoggerAction.STATUS_CHECK, __( 'Checking authentication status…' ) );

try {
	const token = await getAuthToken();
	const userData = await getUserInfo( token.accessToken );
	logger.reportSuccess(
		sprintf( __( 'Successfully authenticated with WordPress.com as `%s`' ), userData.username )
	);
} catch ( error ) {
	// Handle getAuthToken errors
	if ( error instanceof LoggerError && error.message.includes( 'Authentication required' ) ) {
		logger.reportError( new LoggerError( __( 'Authentication token is invalid or expired' ) ) );
		return;
	}
	// Handle getUserInfo errors
	// ...
}

This would eliminate the uninitialized variable and flatten the nesting slightly. However, the current approach with two separate try-catch blocks does make the error handling more explicit, so this is a minor style preference.

email: '[email protected]',
displayName: 'Existing User',
expiresIn: 1209600,
expirationTime: Date.now() + 1209600000,
Copy link

Choose a reason for hiding this comment

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

Testing - Edge Case Coverage - Great test coverage overall! Consider adding one more test case for better completeness:

it( 'should report error when token is expired (past expirationTime)', async () => {
	const expiredToken = {
		...mockToken,
		expirationTime: Date.now() - 1000, // Expired 1 second ago
	};
	( getAuthToken as jest.Mock ).mockRejectedValue( new Error( 'Token expired' ) );

	const { runCommand } = await import( '../status' );
	await runCommand();

	expect( mockLogger.reportError ).toHaveBeenCalledWith( expect.any( LoggerError ) );
	expect( getUserInfo ).not.toHaveBeenCalled();
} );

This explicitly tests the expiration time check logic that's in getAuthToken at cli/lib/appdata.ts:152.

Copy link
Contributor

@bcotrim bcotrim left a comment

Choose a reason for hiding this comment

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

LGTM! 👍

Tested and works as described on macOS and Windows

Base automatically changed from f26d/cli-auth-logout-command to trunk November 17, 2025 16:02
@claude
Copy link

claude bot commented Nov 17, 2025

Claude finished @fredrikekelund's task —— View job


Documentation updated successfully

Tasks

  • Review the new auth status command implementation
  • Check current documentation in docs/ai-instructions.md
  • Update documentation with auth status command
  • Commit and push changes

Summary

I've reviewed the PR changes and updated the CLI documentation in docs/ai-instructions.md.

What was done:

  • ✅ Added comprehensive documentation for the new studio auth status command
  • ✅ Documentation follows the same format as other auth commands with Usage, Description, Options, Example, and Notes sections
  • ✅ Committed and pushed changes to the PR branch

Implementation details:
The auth status command (implemented in cli/commands/auth/status.ts) works by:

  1. Reading the auth token from app data using getAuthToken()
  2. Making an API request to the /me endpoint via getUserInfo() to verify the token is valid
  3. Displaying the WordPress.com username if authenticated
  4. Showing an error message if the token is invalid or expired

The documentation now provides clear usage examples and notes for all three authentication commands: login, logout, and status.

Note: The auth logout command was already documented in the base branch (added in a previous PR).


| Branch: f26d/cli-auth-status-command

@fredrikekelund fredrikekelund merged commit 5973494 into trunk Nov 18, 2025
9 of 11 checks passed
@fredrikekelund fredrikekelund deleted the f26d/cli-auth-status-command branch November 18, 2025 09:00
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.

4 participants