Failed to obtain OAuth2 Token through Excel script using Fetch API calls

I'm currently working on developing a function in Office Scripts to obtain an OAuth API token. I have a functional example of making a token request in PowerShell and attempted to replicate the same process using fetch in Office Scripts, but unfortunately, I am encountering a failed to fetch error within Office Scripts.

The PowerShell function below effectively retrieves a token:

#requires -Version 3.0
function New-ApiAccessToken
{
    param
    (
        [string]$apiUrl,
        [string]$apiKey,
        [string]$apiSecretKey
    )

    # Specify security protocols
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'

    # Convert password to secure string
    $securePassword = ConvertTo-SecureString -String 'public' -AsPlainText -Force

    # Define parameters for Invoke-WebRequest cmdlet
    $params = @{
        Credential  =   New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ('public-client', $securePassword)
        Uri         =   '{0}/auth/oauth/token' -f $apiUrl
        Method      =   'POST'
        ContentType =   'application/x-www-form-urlencoded'
        Body        =   'grant_type=password&username={0}&password={1}' -f $apiKey, $apiSecretKey
    }
    
    # Request access token
    try {(Invoke-WebRequest @params | ConvertFrom-Json).access_token}
    catch {$_.Exception}
}

# Define parameters
$params = @{
    apiUrl          =   'myurlhere'
    apiKey          =   'thekey'
    apiSecretKey    =   'thesecretkey'
}

# Call New-ApiAccessToken function using defined parameters 
New-ApiAccessToken @params

The script provided below in Excel/Office Scripts returns a failed to fetch error on the fetch line:

async function getToken() {
  let url = 'myurlhere';
  let client_id = 'public-client';
  let client_secret = 'public';
  let username = 'thekey';
  let password = 'thesecretkey';

  let basicAuth: string = base64Encode(client_id + ":" + client_secret).toString();
  let bodyParams: URLSearchParams = new URLSearchParams();
  bodyParams['grant_type'] = 'password';
  bodyParams['username'] = username;
  bodyParams['password'] = password;

  let response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Accept': 'application/json; charset=UTF-8',
      'Authorization': 'Basic ' + basicAuth
    },
    body: bodyParams
    });

  let token: string = await response.json();
  console.log(token)  
}

Upon monitoring the requests with Fiddler (with Decrypt HTTPS traffic enabled):

  • The PowerShell script displays 2 POST calls; The first returns response code 401, while the second successfully obtains the token with response code 200
  • The Office script only shows one OPTIONS call which returns response code 401; There is no second call observed

How can I modify the Office script to effectively retrieve the token?

Answer №1

As outlined in the article about Restrictions when making external calls from Office Scripts

It is highlighted that there is no provision for signing in or utilizing OAuth2 authentication methods. All access keys and credentials must be hardcoded (or fetched from another source).

However ... this may not come as a surprise and you might be exploring ways to reintroduce the OAuth2 flow.

Have you experimented with handling the HTTP OPTIONS request by returning a HTTP_OK status along with the header Access-Control-Allow-Origin: *?

This could help trigger the expected HTTP POST request.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to loop through dynamically generated parameters?

My code is designed to generate dynamic forms with unique names like the following: <div ng-click="wos.wordWordFormRowClicked(wf, $index)" ng-form="wos.wordFormNgForm_{{$index}}" ng-repeat="wf in wos.word.wordForms"> The service responsib ...

Looking for guidance on where to find a functional code sample or comprehensive tutorial on working with ViewMetadata in Angular2

I am currently trying to understand the relationship between viewmetadata and the fundamental use of encapsulation: ViewEncapsulation, including ViewEncapsulation.Emulated and ViewEncapsulation.None. Here is a link for further information: https://angula ...

Identify all the CHECKBOX elements that are visible and not concealed

On my page, I have various checkboxes - some with hidden=true and others with hidden=false attributes. Despite trying to use a selector or jQuery to locate checkboxes with the hidden property, I am still facing some challenges. My goal is to differentiate ...

Error: Unable to assign value to property 12 because the object does not support extensibility

I'm facing an issue with my client application as I cannot figure out the error I am encountering. Despite successfully subscribing to a GraphQL subscription and receiving updates, I am struggling to update the TypeScript array named "models:ModelClas ...

Ways to obtain a data type as an element in an array?

const ratingList = {1: "", 2: "", 3: "", 4: "", 5: ""} type ratingType = keyof typeof ratingList ...... {Object.keys(ratingList).map((value, index) => { if (parseInt(value) <= rating) re ...

What is the reason behind receiving the error message "`Foo` only represents a type, but is being treated as a value here" when using `instanceof` in TypeScript?

As the creator of this code interface Foo { abcdef: number; } let x: Foo | string; if (x instanceof Foo) { // ... } Upon running this code, I encountered an error in TypeScript: 'Foo' is recognized only as a type and cannot be used a ...

Encountered an issue when transitioning from react-native-fcm to react-native-firebase

I find myself in the process of updating my react native app from using deprecated libraries such as react-native-fcm and react-native-firebase-analytics to utilizing react-native-firebase. The build seems successful, but upon launching the app, it remains ...

Error: No provider found for the AlertPanelComponent in the current injector

Error message: ERROR NullInjectorError: R3InjectorError(AppModule)[AlertPanelComponent -> AlertPanelComponent -> AlertPanelComponent]: NullInjectorError: No provider for AlertPanelComponent! Angular I'm having trouble understanding this is ...

Is it planned to include StencilJS as a development choice in Ionic?

I'm curious about the potential adoption of Stencil JS for developing mobile apps within the Ionic framework. When I mention "an option for developing," I'm referring to frameworks like NativeScript where developers can choose between Angular + ...

Is it possible to intercept Angular core methods in order to implement some Aspect-Oriented Programming strategies?

Currently working on a project using Angular 12, I'm wondering if there's a way to intercept calls to core methods like createComponent() from ViewContainerRef in the @angular/core library. This would allow me to implement some aspect-oriented pr ...

Exploring ways to retrieve a function-scoped variable from within an Angular subscribe function

Here's the scenario: I have a simple question regarding an Angular component. Inside this component, there is a function structured like this: somethingCollection: TypeSomething[] ... public deleteSomething(something: TypeSomething): void { // so ...

jQuery AJAX is seamlessly handling cross domain requests in Chrome and other browsers, however, it seems to be struggling in IE10 as it is not properly transmitting data. Additionally, in Internet

My web application requires sending data to an API hosted on a different domain. The API processes the received data and jQuery AJAX handles the response. This process works smoothly on Chrome and Firefox, but encounters issues on Internet Explorer. While ...

Loading data into the Nuxt store upon application launch

Currently, I'm working on an app using Nuxt where I preload some data at nuxtServerInit and store it successfully. However, as I have multiple projects with similar initial-preload requirements, I thought of creating a reusable module for this logic. ...

Utilize Javascript to compare nested objects and store the differences in a separate object

I have a dilemma involving two JavaScript objects var order1 = { sandwich: 'tuna', chips: true, drink: 'soda', order: 1, toppings: [{VendorNumber: 18, PreferredFlag: false, SupportedFlag: true}, {VendorNumber: 19, ...

Exploring ways to test the ng-web-apis/geolocation Observable within an Angular 8 environment

I'm currently working on testing a basic Angular 8 service that utilizes the GeoLocation Service from Web APIs for Angular, which can be found at this link. public enableGPS() { if (!this.locationSubscription) this.locationSubscription = ...

JavaScript: Remove duplicate values from one array by comparing and utilizing a search filter against another array

There are two arrays available: public favoriteTeams: any[] = [ { name: 'Team Batman' }, { name: 'Team Superman' }, { name: 'Team Darkseid' }, { name: 'Team Wonder Woman' } ]; public searchTeams: any[] = [ ...

When npm test is executed, an error is encountered during the execution of Protractor with

Encountered an error while running protractor tests in visual studio code using npm test. The issue seems to be related to node_modules/@types/jasmine/index.d.ts. How can this error be resolved? C:\MyFiles\NewTechonologies\Protractor\T ...

Ways in which this data can be best retrieved

Hey there, I'm currently in the process of building an Ionic2 app with Firebase integration. Within my codebase, there's a provider known as Students-services where I've written a function to navigate through a node, retrieve values, and dis ...

Navigating through elements in Angular

I am working with multiple Angular components housed within a display:flex div container. I am fetching datatable from an API, and it contains the same number of rows as there are components. Each row in the datatable corresponds to data for each compone ...

What is the proper way to import and define typings for node libraries in TypeScript?

I am currently developing a node package in TypeScript that utilizes standard node libraries such as fs, path, stream, and http. Whenever I attempt to import these libraries in a .ts file, VS Code flags the line with an error message: [ts] Cannot find m ...