diff --git a/.changes/next-release/bugfix-1fa27aca-6711-45ac-ac1d-d5edd392ce7f.json b/.changes/next-release/bugfix-1fa27aca-6711-45ac-ac1d-d5edd392ce7f.json new file mode 100644 index 0000000000..d5dd8f074f --- /dev/null +++ b/.changes/next-release/bugfix-1fa27aca-6711-45ac-ac1d-d5edd392ce7f.json @@ -0,0 +1,4 @@ +{ + "type" : "bugfix", + "description" : "Fix issue displaying SSO code on new UI in Windows" +} \ No newline at end of file diff --git a/.changes/next-release/feature-b4e483d4-59cb-47f4-9a5c-0bb446fce83a.json b/.changes/next-release/feature-b4e483d4-59cb-47f4-9a5c-0bb446fce83a.json new file mode 100644 index 0000000000..e3da3668e3 --- /dev/null +++ b/.changes/next-release/feature-b4e483d4-59cb-47f4-9a5c-0bb446fce83a.json @@ -0,0 +1,4 @@ +{ + "type" : "feature", + "description" : "Authentication: When signing in to AWS Builder Id or IAM Identity Center (SSO), verify the device code matches instead of copy-pasting it" +} \ No newline at end of file diff --git a/jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoLoginCallbackProvider.kt b/jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoLoginCallbackProvider.kt index ed031d142f..bf9c9865f3 100644 --- a/jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoLoginCallbackProvider.kt +++ b/jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoLoginCallbackProvider.kt @@ -6,7 +6,7 @@ package software.aws.toolkits.jetbrains.core.credentials.sso import com.intellij.ide.BrowserUtil import com.intellij.openapi.progress.ProcessCanceledException import software.aws.toolkits.jetbrains.core.credentials.sono.SONO_URL -import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.CopyUserCodeForLoginDialog +import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.ConfirmUserCodeLoginDialog import software.aws.toolkits.jetbrains.utils.computeOnEdt import software.aws.toolkits.jetbrains.utils.notifyError import software.aws.toolkits.resources.message @@ -28,7 +28,7 @@ class DefaultSsoLoginCallbackProvider : SsoLoginCallbackProvider { object SsoPrompt : SsoLoginCallback { override fun tokenPending(authorization: Authorization) { computeOnEdt { - val result = CopyUserCodeForLoginDialog( + val result = ConfirmUserCodeLoginDialog( authorization.userCode, message("credentials.sso.login.title"), CredentialType.SsoProfile @@ -36,7 +36,7 @@ object SsoPrompt : SsoLoginCallback { if (result) { AwsTelemetry.loginWithBrowser(project = null, Result.Succeeded, CredentialType.SsoProfile) - BrowserUtil.browse(authorization.verificationUri) + BrowserUtil.browse(authorization.verificationUriComplete) } else { AwsTelemetry.loginWithBrowser(project = null, Result.Cancelled, CredentialType.SsoProfile) throw ProcessCanceledException(IllegalStateException(message("credentials.sso.login.cancelled"))) @@ -54,7 +54,7 @@ object SsoPrompt : SsoLoginCallback { object BearerTokenPrompt : SsoLoginCallback { override fun tokenPending(authorization: Authorization) { computeOnEdt { - val codeCopied = CopyUserCodeForLoginDialog( + val codeCopied = ConfirmUserCodeLoginDialog( authorization.userCode, message("credentials.sono.login"), CredentialType.BearerToken @@ -62,7 +62,7 @@ object BearerTokenPrompt : SsoLoginCallback { if (codeCopied) { AwsTelemetry.loginWithBrowser(project = null, Result.Succeeded, CredentialType.BearerToken) - BrowserUtil.browse(authorization.verificationUri) + BrowserUtil.browse(authorization.verificationUriComplete) } else { AwsTelemetry.loginWithBrowser(project = null, Result.Cancelled, CredentialType.BearerToken) } diff --git a/jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/CopyUserCodeForLoginDialog.kt b/jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/ConfirmUserCodeLoginDialog.kt similarity index 75% rename from jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/CopyUserCodeForLoginDialog.kt rename to jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/ConfirmUserCodeLoginDialog.kt index 5f9cb97025..a392d6e48c 100644 --- a/jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/CopyUserCodeForLoginDialog.kt +++ b/jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/ConfirmUserCodeLoginDialog.kt @@ -9,12 +9,15 @@ import com.intellij.openapi.actionSystem.ActionToolbar import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.impl.ActionButton +import com.intellij.openapi.editor.colors.EditorColorsUtil import com.intellij.openapi.ide.CopyPasteManager import com.intellij.openapi.ui.DialogWrapper import com.intellij.ui.components.JBLabel import com.intellij.ui.dsl.builder.panel import com.intellij.ui.dsl.gridLayout.HorizontalAlign +import com.intellij.util.ui.JBFont import com.intellij.util.ui.components.BorderLayoutPanel +import software.aws.toolkits.core.utils.tryOrNull import software.aws.toolkits.resources.message import software.aws.toolkits.telemetry.AwsTelemetry import software.aws.toolkits.telemetry.CredentialType @@ -22,7 +25,7 @@ import software.aws.toolkits.telemetry.Result import java.awt.datatransfer.StringSelection import javax.swing.JComponent -class CopyUserCodeForLoginDialog( +class ConfirmUserCodeLoginDialog( private val authCode: String, private val dialogTitle: String, private val credentialType: CredentialType @@ -30,19 +33,29 @@ class CopyUserCodeForLoginDialog( private val pane = panel { row { - text(message("aws.sso.signing.device.code.copy.dialog.text"), maxLineLength = -1) + label(message("aws.sso.signing.device.code.copy.dialog.text")) } row { cell( BorderLayoutPanel(5, 0).apply { val action = CopyUserCodeForLogin(authCode) - addToCenter(JBLabel(authCode).setCopyable(true)) + addToCenter( + JBLabel(authCode).apply { + tryOrNull { + JBFont.create(JBFont.decode(EditorColorsUtil.getGlobalOrDefaultColorScheme().consoleFontName)).biggerOn(9f).asBold() + }?.let { + font = it + } + setCopyable(true) + } + ) addToRight(ActionButton(action, action.templatePresentation.clone(), ActionPlaces.UNKNOWN, ActionToolbar.NAVBAR_MINIMUM_BUTTON_SIZE)) } ).horizontalAlign(HorizontalAlign.CENTER) } } + override fun createCenterPanel(): JComponent? = pane init { @@ -51,11 +64,6 @@ class CopyUserCodeForLoginDialog( super.init() } - override fun doOKAction() { - CopyPasteManager.getInstance().setContents(StringSelection(authCode)) - super.doOKAction() - } - override fun doCancelAction() { super.doCancelAction() AwsTelemetry.loginWithBrowser(project = null, Result.Cancelled, credentialType) diff --git a/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index a9aae1d347..2a4cb5bbf6 100644 --- a/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -136,9 +136,9 @@ aws.settings.telemetry.option=Send usage metrics to AWS aws.settings.telemetry.prompt.message=Usage metrics are collected by default. Click here to adjust this behavior. aws.settings.telemetry.prompt.title=AWS Toolkit telemetry aws.settings.title=AWS -aws.sso.signing.device.code=Open and Copy Code +aws.sso.signing.device.code=Proceed To Browser aws.sso.signing.device.code.copy=Copy Code -aws.sso.signing.device.code.copy.dialog.text=To proceed, open the login page and provide this code to confirm the access request from AWS Toolkit: +aws.sso.signing.device.code.copy.dialog.text=To proceed, open the login page and confirm that the code matches: aws.sso.signing.device.waiting=Waiting for browser authorization for code: {0} aws.terminal.action=Open AWS local terminal aws.terminal.action.tooltip=Start a local terminal with the current AWS connection settings injected as environment variables