Skip to content

Jetpack REST connection log into wp.com #22115

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

Merged
merged 32 commits into from
Aug 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9e9bbad
Jetpack connection UI (#22079)
nbradbury Aug 5, 2025
bf08ce1
Added Jetpack Connection feature flag
nbradbury Aug 6, 2025
4de2f1e
Merge branch 'trunk' into feature/jetpack-connection-feature-branch
nbradbury Aug 6, 2025
0c3ea25
Restored feature flag and fixed issue with reused string resources
nbradbury Aug 6, 2025
1e32fbf
Jetpack Connection cleanup (#22104)
nbradbury Aug 7, 2025
13f8dc8
Merge branch 'trunk' into feature/jetpack-rest-connection-feature-branch
nbradbury Aug 7, 2025
2fccbd6
Fixed title casing
nbradbury Aug 7, 2025
fe7e70d
Added start button
nbradbury Aug 7, 2025
26b6fd5
Wired up start button
nbradbury Aug 7, 2025
8f34cc2
Reset uiEvent when starting flow, removed unused init
nbradbury Aug 7, 2025
b36186c
Removed code for steps other than Step 1 (login to wp.com)
nbradbury Aug 7, 2025
adfca30
Removed code for steps other than Step 1 (login to wp.com), p2
nbradbury Aug 7, 2025
fbf016c
First attempt at wp.com login
nbradbury Aug 7, 2025
50de35f
Remove automatic step completion
nbradbury Aug 7, 2025
49b921d
Use correct discovery url
nbradbury Aug 7, 2025
df7fede
Added error type for discovery failure
nbradbury Aug 7, 2025
14dc3e5
First pass at launching and awaiting password flow
nbradbury Aug 7, 2025
379534e
Retain when waiting for password flow
nbradbury Aug 7, 2025
b6902e7
First pass at switching from app password to wp.com login (broken)
nbradbury Aug 7, 2025
15ae52d
Second pass at switching from app password to wp.com login (broken)
nbradbury Aug 8, 2025
562da8b
Merge branch 'trunk' of https://github.com/wordpress-mobile/WordPress…
nbradbury Aug 8, 2025
9066f26
Use showSignInForResultWpComOnly
nbradbury Aug 8, 2025
22e277b
Check for account token
nbradbury Aug 8, 2025
ac9e581
Add sign-in flow for JP rest connect
nbradbury Aug 8, 2025
2e1df7b
Added error type for login wp.com failure, minor code reformatting
nbradbury Aug 8, 2025
62e4fcd
Don't show "Failed" status for errors, only show error message
nbradbury Aug 8, 2025
423b37d
Removed unused account store and deleted commented code
nbradbury Aug 8, 2025
2ca488e
Added comment to LoginActivity
nbradbury Aug 8, 2025
67e9dda
Added comment to loginWpCom
nbradbury Aug 8, 2025
63bcc00
Fixed Detekt warning
nbradbury Aug 8, 2025
225c541
Added comment to ActivityLauncher and shortened function name
nbradbury Aug 8, 2025
efc81fb
Don't expose isWaitingForWPComLogin
nbradbury Aug 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
import static org.wordpress.android.analytics.AnalyticsTracker.Stat.STATS_ACCESS_ERROR;
import static org.wordpress.android.imageeditor.preview.PreviewImageFragment.ARG_EDIT_IMAGE_DATA;
import static org.wordpress.android.login.LoginMode.JETPACK_LOGIN_ONLY;
import static org.wordpress.android.login.LoginMode.JETPACK_REST_CONNECT;
import static org.wordpress.android.login.LoginMode.WPCOM_LOGIN_ONLY;
import static org.wordpress.android.push.NotificationsProcessingService.ARG_NOTIFICATION_TYPE;
import static org.wordpress.android.ui.WPWebViewActivity.ENCODING_UTF8;
Expand Down Expand Up @@ -1415,6 +1416,20 @@ public static void showSignInForResultWpComOnly(Activity activity) {
activity.startActivityForResult(intent, RequestCodes.ADD_ACCOUNT);
}

/**
* Sign in to WordPress.com from the Jetpack REST connection flow.
* This method is specifically for the Jetpack connection process where
* we need to authenticate with WordPress.com to establish the connection
* and return immediately to the connection flow.
*
* @param activity The activity requesting the sign-in
*/
public static void showWpComSignInForRestConnect(@NonNull Activity activity) {
Intent intent = new Intent(activity, LoginActivity.class);
JETPACK_REST_CONNECT.putInto(intent);
activity.startActivityForResult(intent, RequestCodes.ADD_ACCOUNT);
}

public static void showSignInForResultJetpackOnly(Activity activity) {
Intent intent = new Intent(activity, LoginActivity.class);
intent.setFlags(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
loginFromPrologue();
break;
case WPCOM_LOGIN_ONLY:
case JETPACK_REST_CONNECT:
mUnifiedLoginTracker.setSource(Source.ADD_WORDPRESS_COM_ACCOUNT);
mIsSignupFromLoginEnabled = mBuildConfigWrapper.isSignupEnabled();
checkSmartLockPasswordAndStartLogin();
Expand Down Expand Up @@ -357,6 +358,12 @@ private void loggedInAndFinish(ArrayList<Integer> oldSitesIds, boolean doLoginUp
case JETPACK_STATS:
ActivityLauncher.showLoginEpilogueForResult(this, oldSitesIds, true);
break;
case JETPACK_REST_CONNECT:
// for the Jetpack REST connection we want to return to the caller activity instead of
// showing the login epilogue
setResult(Activity.RESULT_OK);
finish();
break;
case WPCOM_LOGIN_DEEPLINK:
case WPCOM_REAUTHENTICATE:
ActivityLauncher.showLoginEpilogueForResult(this, oldSitesIds, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,24 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch
import org.wordpress.android.R
import org.wordpress.android.fluxc.store.AccountStore
import org.wordpress.android.ui.ActivityLauncher
import org.wordpress.android.ui.ActivityNavigator
import org.wordpress.android.ui.RequestCodes
import org.wordpress.android.ui.main.BaseAppCompatActivity
import org.wordpress.android.util.extensions.setContent
import javax.inject.Inject

@AndroidEntryPoint
class JetpackRestConnectionActivity : BaseAppCompatActivity() {
private val viewModel: JetpackRestConnectionViewModel by viewModels()

@Inject
lateinit var activityNavigator: ActivityNavigator

@Inject
lateinit var accountStore: AccountStore

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Expand All @@ -34,13 +45,34 @@ class JetpackRestConnectionActivity : BaseAppCompatActivity() {
lifecycleScope.launch {
viewModel.uiEvent.filterNotNull().collect { event ->
when (event) {
JetpackRestConnectionViewModel.UiEvent.Close -> finish()
JetpackRestConnectionViewModel.UiEvent.ShowCancelConfirmation -> showCancelConfirmationDialog()
JetpackRestConnectionViewModel.UiEvent.StartWPComLogin ->
startWPComLogin()

JetpackRestConnectionViewModel.UiEvent.Close ->
finish()

JetpackRestConnectionViewModel.UiEvent.ShowCancelConfirmation ->
showCancelConfirmationDialog()
}
}
}
}

private fun startWPComLogin() {
ActivityLauncher.showWpComSignInForRestConnect(this)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

// User returned from WordPress.com login - note the resultCode will always be RESULT_OK but
// we check it here in case that ever changes
if (requestCode == RequestCodes.ADD_ACCOUNT) {
val loginSuccessful = resultCode == RESULT_OK && (accountStore.accessToken?.isNotEmpty() == true)
viewModel.onWPComLoginCompleted(success = loginSuccessful)
}
}

private fun showCancelConfirmationDialog() {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.jetpack_rest_connection_cancel_title)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,30 +249,29 @@ private fun ConnectionStepContent(

Spacer(modifier = Modifier.height(4.dp))

Text(
text = getStatusText(status),
style = MaterialTheme.typography.bodyMedium,
color = style.statusColor
)

if (errorType != null && status == ConnectionStatus.Failed) {
Spacer(modifier = Modifier.height(4.dp))
Text(
text = getErrorText(LocalContext.current, errorType),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error
)
} else {
Text(
text = getStatusText(status),
style = MaterialTheme.typography.bodyMedium,
color = style.statusColor
)
}
}
}

private fun getErrorText(context: Context, errorType: ErrorType): String {
@StringRes val messageRes = when (errorType) {
is ErrorType.JetpackAlreadyInstalled -> R.string.jetpack_rest_connection_error_jetpack_already_installed
ErrorType.FailedToLoginWpCom -> R.string.jetpack_rest_connection_error_login_wpcom
ErrorType.FailedToConnectWpCom -> R.string.jetpack_rest_connection_error_connect_wpcom
is ErrorType.Timeout -> R.string.jetpack_rest_connection_error_timeout
is ErrorType.Offline -> R.string.jetpack_rest_connection_error_offline
is ErrorType.Unknown -> R.string.jetpack_rest_connection_error_unknown
is ErrorType.FailedToConnectWpCom -> R.string.jetpack_rest_connection_error_wpcom
}
val baseMessage = context.getString(messageRes)
return errorType.message?.let { "$baseMessage: $it" } ?: baseMessage
Expand Down Expand Up @@ -422,7 +421,7 @@ private fun JetpackRestConnectionScreenPreview() {
ConnectionStep.ConnectSite to StepState(ConnectionStatus.InProgress),
ConnectionStep.ConnectWpCom to StepState(
ConnectionStatus.Failed,
ErrorType.FailedToConnectWpCom()
ErrorType.FailedToConnectWpCom
),
ConnectionStep.Finalize to StepState(ConnectionStatus.NotStarted)
)
Expand All @@ -439,5 +438,7 @@ private fun JetpackRestConnectionScreenPreview() {
)
}

@ColorRes private val IN_PROGRESS_BACKGROUND_COLOR = R.color.yellow_10 // Light yellow
@ColorRes private val IN_PROGRESS_FOREGROUND_COLOR = R.color.yellow_90 // Dark brown for readability on the above
@ColorRes
private val IN_PROGRESS_BACKGROUND_COLOR = R.color.yellow_10 // Light yellow
@ColorRes
private val IN_PROGRESS_FOREGROUND_COLOR = R.color.yellow_90 // Dark brown for readability on the above
Loading