async getSsoToken()

in server/aws-lsp-identity/src/language-server/identityService.ts [50:137]


    async getSsoToken(params: GetSsoTokenParams, token: CancellationToken): Promise<GetSsoTokenResult> {
        const emitMetric = this.emitMetric.bind(this, 'flareIdentity_getSsoToken', this.getSsoToken.name, Date.now())

        let clientRegistration: SsoClientRegistration | undefined
        let ssoSession: SsoSession | undefined

        try {
            const options = { ...getSsoTokenOptionsDefaults, ...params.options }

            token.onCancellationRequested(_ => {
                if (options.loginOnInvalidToken) {
                    emitMetric('Cancelled', null, ssoSession, clientRegistration)
                }
            })

            ssoSession = await this.getSsoSession(params.source)
            throwOnInvalidSsoSession(ssoSession)

            let err: unknown
            let ssoToken = await this.ssoCache.getSsoToken(this.clientName, ssoSession).catch(e => {
                err = e
                return undefined
            })

            if (!ssoToken) {
                // If we could not get the cached token and cannot start the login process, give up
                if (!options.loginOnInvalidToken) {
                    if (err) {
                        this.observability.logging.log(
                            'Error when attempting to retrieve SSO token and loginOnInvalidToken = false, returning no token.'
                        )
                        throw err
                    }

                    this.observability.logging.log(
                        'SSO token not found an loginOnInvalidToken = false, returning no token.'
                    )
                    throw new AwsError('SSO token not found.', AwsErrorCodes.E_INVALID_SSO_TOKEN)
                }

                clientRegistration = await this.ssoCache.getSsoClientRegistration(this.clientName, ssoSession)
                throwOnInvalidClientRegistration(clientRegistration)

                const flowOpts: SsoFlowParams = {
                    clientName: this.clientName,
                    clientRegistration,
                    ssoSession,
                    handlers: this.handlers,
                    token,
                    observability: this.observability,
                }

                const flowKind = params.options?.authorizationFlow ?? getSsoTokenOptionsDefaults.authorizationFlow
                if (!Object.keys(this.authFlows).includes(flowKind)) {
                    throw new AwsError(
                        `Unsupported authorization flow requested: ${flowKind}`,
                        AwsErrorCodes.E_CANNOT_CREATE_SSO_TOKEN
                    )
                }

                const flow = this.authFlows[flowKind]
                ssoToken = await flow(flowOpts).catch(reason => {
                    throw AwsError.wrap(reason, AwsErrorCodes.E_CANNOT_CREATE_SSO_TOKEN)
                })

                emitMetric('Succeeded', null, ssoSession, clientRegistration)

                await this.ssoCache.setSsoToken(this.clientName, ssoSession, ssoToken!).catch(reason => {
                    throw AwsError.wrap(reason, AwsErrorCodes.E_CANNOT_WRITE_SSO_CACHE)
                })
            }

            // Auto refresh is best effort
            await this.autoRefresher.watch(this.clientName, ssoSession).catch(reason => {
                this.observability.logging.log(`Unable to auto-refresh token. ${reason}`)
            })

            this.observability.logging.log('Successfully retrieved existing or newly authenticated SSO token.')
            return {
                ssoToken: { accessToken: ssoToken.accessToken, id: ssoSession.name },
                updateCredentialsParams: { data: { token: ssoToken.accessToken }, encrypted: false },
            }
        } catch (e) {
            emitMetric('Failed', e, ssoSession, clientRegistration)

            throw e
        }
    }