Skip to content

Conversation

@fredrikekelund
Copy link
Contributor

@fredrikekelund fredrikekelund commented Nov 5, 2025

Related issues

Proposed Changes

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

  1. Opens a WordPress.com OAuth2 authorization URL in the browser
  2. The OAuth2 authorization page redirects to a developer.wordpress.com page that renders a convenient button for copying the generated access token
  3. Once copied, the access token can be pasted back to the terminal

Testing Instructions

  1. Check out 156890-ghe-Automattic/wpcom-a8c-themes on your sandbox
  2. Sandbox developer.wordpress.com
  3. Open Studio and log out from WordPress.com
  4. Close Studio
  5. Run npm run cli:build
  6. Run node dist/cli/main.js auth login
  7. Finish the authorization process and paste the token back to the terminal
  8. Open Studio again
  9. Ensure you are logged in to WordPress.com

Pre-merge Checklist

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

@fredrikekelund fredrikekelund requested review from a team and bcotrim November 5, 2025 15:16
@fredrikekelund fredrikekelund self-assigned this Nov 5, 2025
Comment on lines +19 to +28
cmd = 'PowerShell';
args = [
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Bypass',
'-Command',
'Start',
`"${ url }"`,
];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have yet to test this. This was taken from Sindre Sorhus's open module.

@github-actions
Copy link

github-actions bot commented Nov 5, 2025

📊 Performance Test Results

Comparing 0f75d13 vs trunk

site-editor

Metric trunk 0f75d13 Diff Change
load 10107.00 ms 8716.00 ms -1391.00 ms 🟢 -13.8%

site-startup

Metric trunk 0f75d13 Diff Change
siteCreation 13017.00 ms 13009.00 ms -8.00 ms 🟢 -0.1%
siteStartup 4200.00 ms 4936.00 ms +736.00 ms 🔴 17.5%

Results are median values from multiple test runs.

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

@fredrikekelund
Copy link
Contributor Author

Working on a test right now.

@fredrikekelund
Copy link
Contributor Author

Looking at how many changes I had to make today, I see that I opened this PR a little early. In any case, it's good for a full review now 👍

@sejas sejas requested a review from Copilot November 6, 2025 12:39
Copy link

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 PR adds a CLI authentication command (studio auth login) to allow users to authenticate with WordPress.com directly from the command line. The implementation opens a browser for OAuth authentication and stores the resulting token with user information.

Key changes:

  • Adds @inquirer/prompts dependency for interactive token input
  • Implements OAuth-based login flow with browser integration
  • Enhances auth token storage to include expiration time and user details

Reviewed Changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
package.json, package-lock.json Added @inquirer/prompts dependency for interactive CLI prompts
common/logger-actions.ts Added AuthCommandLoggerAction enum for login/logout tracking
common/lib/oauth.ts Made redirect URI configurable for CLI authentication flow
cli/lib/i18n.ts Extracted getAppLocale() function for reusability
cli/lib/browser.ts New utility to open default browser across platforms
cli/lib/appdata.ts Enhanced auth token schema with expiration, email, and display name
cli/lib/api.ts Added getUserInfo() function to fetch user details from WordPress.com
cli/index.ts Registered auth command group with login subcommand
cli/commands/auth/login.ts Main login command implementation
cli/commands/auth/tests/login.test.ts Comprehensive test coverage for login command
cli/lib/tests/snapshots.test.ts, appdata.test.ts Updated test mocks to include new auth token fields
Comments suppressed due to low confidence (1)

cli/lib/browser.ts:2

  • Unused import sprintf.
import { __, sprintf } from '@wordpress/i18n';

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

email: user.email,
displayName: user.display_name,
expiresIn: twoWeeksInSeconds,
expirationTime: now.getTime() + twoWeeksInSeconds,
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

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

The expirationTime calculation is incorrect. twoWeeksInSeconds is in seconds (1209600), but getTime() returns milliseconds. This should be now.getTime() + twoWeeksInSeconds * 1000 to convert seconds to milliseconds, or the calculation should use twoWeeksInSeconds * 1000 directly.

Suggested change
expirationTime: now.getTime() + twoWeeksInSeconds,
expirationTime: now.getTime() + twoWeeksInSeconds * 1000,

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +11
let cmd: string;
let args: string[];
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

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

Variables cmd and args are not initialized and will be undefined if process.platform doesn't match 'darwin', 'win32', or 'linux'. This will cause the spawn() call on line 37 to fail. Add a default case to the switch statement that throws an error for unsupported platforms.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,49 @@
import { spawn } from 'child_process';
import { __, sprintf } from '@wordpress/i18n';
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

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

The sprintf function is imported but never used in this file. Remove the unused import.

Suggested change
import { __, sprintf } from '@wordpress/i18n';
import { __ } from '@wordpress/i18n';

Copilot uses AI. Check for mistakes.
Comment on lines 3 to 4
import { LoggerError } from 'cli/logger';

Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

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

Unused import LoggerError.

Suggested change
import { LoggerError } from 'cli/logger';

Copilot uses AI. Check for mistakes.
Copy link
Member

@sejas sejas left a comment

Choose a reason for hiding this comment

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

I confirm that the login works as expected, and I was able to authenticate by copying and pasting the token. Here are a couple of suggestions to improve the experience:

  • We could avoid hiding the token so the user can see they pasted the correct value.
  • We could automatically try three times when the user enters an invalid token, similarly to SSH connections. Currently the feedback is very rough ✖ Failed to fetch user info: The OAuth2 token is invalid., we could at least invite the user to try again.
Image


export enum AuthCommandLoggerAction {
LOGIN = 'login',
LOGOUT = 'logout',
Copy link
Member

Choose a reason for hiding this comment

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

Nit: We don't really need the logout at this point.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll move this to #2027

const userData = await readAppdata();

const now = new Date();
const twoWeeksInSeconds = 2 * 7 * 24 * 60 * 60;
Copy link
Member

Choose a reason for hiding this comment

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

I just saw that the expiresIn in appData is 1209600 seconds or two weeks, but I always thought the token was valid for months. 🤔

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 governed by the back-end. We could look into this further if we think two weeks is too short

@youknowriad
Copy link
Contributor

I like how simple this is. Good work :)

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