@@ -13,9 +13,13 @@ import {
13
13
SsoConnection ,
14
14
codecatalystScopes ,
15
15
hasScopes ,
16
+ createBuilderIdConnection ,
16
17
} from '../credentials/auth'
17
18
import { getSecondaryAuth } from '../credentials/secondaryAuth'
18
19
import { getLogger } from '../shared/logger'
20
+ import * as localizedText from '../shared/localizedText'
21
+ import { ToolkitError } from '../shared/errors'
22
+ import { MetricName , MetricShapes , telemetry } from '../shared/telemetry/telemetry'
19
23
20
24
// Secrets stored on the macOS keychain appear as individual entries for each key
21
25
// This is fine so long as the user has only a few accounts. Otherwise this should
@@ -90,6 +94,58 @@ export class CodeCatalystAuthenticationProvider {
90
94
await this . secondaryAuth . restoreConnection ( )
91
95
}
92
96
97
+ public async promptNotConnected ( ) : Promise < SsoConnection > {
98
+ type ConnectionFlowEvent = Partial < MetricShapes [ MetricName ] > & {
99
+ readonly codecatalyst_connectionFlow : 'Create' | 'Switch' | 'Upgrade'
100
+ }
101
+
102
+ const conn = ( await this . auth . listConnections ( ) ) . find ( isBuilderIdConnection )
103
+ const isNewUser = conn === undefined
104
+ const okItem : vscode . MessageItem = { title : localizedText . ok }
105
+ const cancelItem : vscode . MessageItem = { title : localizedText . cancel , isCloseAffordance : true }
106
+
107
+ if ( isNewUser || ! isValidCodeCatalystConnection ( conn ) ) {
108
+ // TODO: change to `satisfies` on TS 4.9
109
+ telemetry . record ( { codecatalyst_connectionFlow : isNewUser ? 'Create' : 'Upgrade' } as ConnectionFlowEvent )
110
+
111
+ const message = isNewUser
112
+ ? 'CodeCatalyst requires an AWS Builder ID connection. Creating a connection opens your browser to login.\n\n Create one now?'
113
+ : 'Your AWS Builder ID connection does not have access to CodeCatalyst. Upgrading the connection requires another login.\n\n Upgrade now?'
114
+ const resp = await vscode . window . showInformationMessage ( message , { modal : true } , okItem , cancelItem )
115
+ if ( resp !== okItem ) {
116
+ throw new ToolkitError ( 'Not connected to CodeCatalyst' , { code : 'NoConnection' , cancelled : true } )
117
+ }
118
+
119
+ const newConn = await createBuilderIdConnection ( this . auth )
120
+ if ( this . auth . activeConnection ?. id !== newConn . id ) {
121
+ await this . secondaryAuth . useNewConnection ( newConn )
122
+ }
123
+
124
+ return newConn
125
+ }
126
+
127
+ if ( this . auth . activeConnection ?. id !== conn . id ) {
128
+ // TODO: change to `satisfies` on TS 4.9
129
+ telemetry . record ( { codecatalyst_connectionFlow : 'Switch' } as ConnectionFlowEvent )
130
+
131
+ const resp = await vscode . window . showInformationMessage (
132
+ 'CodeCatalyst requires an AWS Builder ID connection.\n\n Switch to it now?' ,
133
+ { modal : true } ,
134
+ okItem ,
135
+ cancelItem
136
+ )
137
+ if ( resp !== okItem ) {
138
+ throw new ToolkitError ( 'Not connected to CodeCatalyst' , { code : 'NoConnection' , cancelled : true } )
139
+ }
140
+
141
+ await this . secondaryAuth . useNewConnection ( conn )
142
+
143
+ return conn
144
+ }
145
+
146
+ throw new ToolkitError ( 'Not connected to CodeCatalyst' , { code : 'NoConnectionBadState' } )
147
+ }
148
+
93
149
private static instance : CodeCatalystAuthenticationProvider
94
150
95
151
public static fromContext ( ctx : Pick < vscode . ExtensionContext , 'secrets' | 'globalState' > ) {
0 commit comments