@@ -33,6 +33,12 @@ import { DevSettings } from '../../shared/settings'
3333import { SdkError } from '@aws-sdk/types'
3434import { HttpRequest , HttpResponse } from '@aws-sdk/protocol-http'
3535import { StandardRetryStrategy , defaultRetryDecider } from '@aws-sdk/middleware-retry'
36+ import OidcClientPKCE from './oidcclientpkce'
37+ import { toSnakeCase } from '../../shared/utilities/textUtilities'
38+ import { Credentials , Service } from 'aws-sdk'
39+ import apiConfig = require( './service-2.json' )
40+ import { ServiceOptions } from '../../shared/awsClientBuilder'
41+ import { ClientRegistration } from './model'
3642
3743export class OidcClient {
3844 public constructor ( private readonly client : SSOOIDC , private readonly clock : { Date : typeof Date } ) { }
@@ -94,6 +100,79 @@ export class OidcClient {
94100 }
95101}
96102
103+ export class OidcClientV2 {
104+ public constructor ( private readonly region : string , private readonly clock : { Date : typeof Date } ) { }
105+
106+ /**
107+ * TODO remove this when the real client gets created.
108+ *
109+ * Creating a new client is required because the old sdk seems to drop unknown parameters from requests
110+ */
111+ private async createNewClient ( ) {
112+ return ( await globals . sdkClientBuilder . createAwsService (
113+ Service ,
114+ {
115+ apiConfig,
116+ region : this . region ,
117+ credentials : new Credentials ( { accessKeyId : 'xxx' , secretAccessKey : 'xxx' } ) ,
118+ } as ServiceOptions ,
119+ undefined
120+ ) ) as OidcClientPKCE
121+ }
122+
123+ public async registerClient ( request : OidcClientPKCE . RegisterClientRequest ) : Promise < ClientRegistration > {
124+ const client = await this . createNewClient ( )
125+ const response = await client . makeUnauthenticatedRequest ( 'registerClient' , request ) . promise ( )
126+ assertHasProps ( response , 'clientId' , 'clientSecret' , 'clientSecretExpiresAt' )
127+
128+ return {
129+ scopes : request . scopes ,
130+ clientId : response . clientId ,
131+ clientSecret : response . clientSecret ,
132+ expiresAt : new this . clock . Date ( response . clientSecretExpiresAt * 1000 ) ,
133+ flow : 'auth code' ,
134+ }
135+ }
136+
137+ public async authorize ( request : OidcClientPKCE . AuthorizeRequest ) {
138+ // aws sdk doesn't convert to url params until right before you make the request, so we have to do
139+ // it manually ahead of time
140+ const params = toSnakeCase ( request )
141+ const searchParams = new URLSearchParams ( params ) . toString ( )
142+ return `https://oidc.${ this . region } .amazonaws.com/authorize?${ searchParams } `
143+ }
144+
145+ public async startDeviceAuthorization ( request : StartDeviceAuthorizationRequest ) : Promise < {
146+ expiresAt : Date
147+ interval : number | undefined
148+ deviceCode : string
149+ userCode : string
150+ verificationUri : string
151+ } > {
152+ throw new Error ( 'OidcClientV2 does not support device authorization' )
153+ }
154+
155+ public async createToken ( request : OidcClientPKCE . CreateTokenRequest ) : Promise < {
156+ accessToken : string
157+ expiresAt : Date
158+ tokenType ?: string | undefined
159+ refreshToken ?: string | undefined
160+ } > {
161+ const client = await this . createNewClient ( )
162+ const response = await client . makeUnauthenticatedRequest ( 'createToken' , request ) . promise ( )
163+ assertHasProps ( response , 'accessToken' , 'expiresIn' )
164+
165+ return {
166+ ...selectFrom ( response , 'accessToken' , 'refreshToken' , 'tokenType' ) ,
167+ expiresAt : new this . clock . Date ( response . expiresIn * 1000 + this . clock . Date . now ( ) ) ,
168+ }
169+ }
170+
171+ public static create ( region : string ) {
172+ return new this ( region , globals . clock )
173+ }
174+ }
175+
97176type OmittedProps = 'accessToken' | 'nextToken'
98177type ExtractOverload < T , U > = T extends {
99178 ( ...args : infer P1 ) : infer R1
0 commit comments