Not able to access current window url from forge app

Itry to perform oauth from my forge app so it requires redirect url basically that is my current window url where i start my oauth process .
for example my current window url is like
https://peterparker1729.atlassian.net/jira/software/projects/SCRUM/apps/848a27cf-010b-4e41-8979-8fb5c994b73c/2eafa8f9-306e-4ea3-befc-37680e35a86d

so if i access that from app (iframe) it showing this error
SecurityError: Failed to read a named property ‘href’ from ‘Location’: Blocked a frame with origin “http://localhost:8000” from accessing a cross-origin frame.

how to get current window url in forge app . can anyone please help

Thanks in advance :pray:

Hi @PeterParker, you won’t be able to get access to a frame from another frame with a different origin (within the iframe your app is running in).
If you are trying to perform an OAuth dance to an external provider, please have a look at the External authentication we have in Forge.

2 Likes

Thanks @BoZhang ,

In my case I gonna perform Surveysparrow oauth to get access token from surveysparrow .
I guess here we have no docs for to perform external oauth like surveysparrow .

Actually i have client id and client secrets from surveysparrow and i can able to configure redirection url for oauth in surveysparrow .

FYI adding Surveysparrow oauth docs here . Is it possible to perform oauth from external provider like surveysparrow ? .

I tried by manually hitting these surveysparrow oauth url . The problem i am facing here is the redirection url . My forge app in project page location so the url is like

https://peterparker1729.atlassian.net/jira/software/projects/SCRUM/apps/848a27cf-010b-4e41-8979-8fb5c994b73c/2eafa8f9-306e-4ea3-befc-37680e35a86d

so it have some dynamic values like project key in the above url . Form surveysparrow side they are allowing only single redirection url for oauth and it should be static .

can you please help on this case is it possible ?

Thanks in advance :pray:

Hi @PeterParker , this seems to be a pretty standard OAuth integration, you can use Forge’s external auth feature for this, you won’t be able to manage the OAuth dance from the Forge UI. The guide that I linked is a tutorial on how you can setup an integration for Google OAuth, but they should be pretty similar to what you need to do for SurveySparrow. For instance, when using External auth, the redirect URL should be set to https://id.atlassian.com/outboundAuth/finish noted in this step in the guide.

Thanks @BoZhang ,
I have tried External oauth for Surveysparrow . but getting this error .

FYI adding My manifest here ,

permissions:
  scopes:
    - read:jira-work
    - write:jira-work
    - storage:app
  external:
    fetch:
      backend:
        - 'https://app.surveysparrow.com'
        - 'https://api.surveysparrow.com'
        - 'https://www.googleapis.com'
        - 'https://oauth2.googleapis.com'
        - 'https://accounts.google.com'
    images:
      - "https://appnest-app.salesparrow.com/SurveyMigrationTest-4119/version_1.0/icon/Color.png"
      - "https://atlassian.design/static/LockClosed-c651d828718647b03f5d4799d705b7e39d1ead63004aca3617049d3f1c0bb357.png"
      - "https://static.surveysparrow.com/site/assets/integrations/inner/microsoft/v2/create-and-share-chat-surveys-directly-from-teams.png"
      - "https://developer.atlassian.com//console/assets/assets/SearchNoResults.ae017adfe3f389e4be72.svg"

providers:
  auth:
    - key: surveysparrow
      name: SurveySparrow
      scopes:
        - view_contacts
      clientId: ${SURVEYSPARROW_CLIENT_ID}
      type: oauth2
      remotes:
        - surveysparrow-api
      bearerMethod: authorization-header
      actions:
        authorization:
          remote: surveysparrow-api
          path: /o/oauth/auth
          queryParameters:
            response_type: code
        exchange:
          remote: surveysparrow-api
          path: /o/oauth/token
        retrieveProfile:
          remote: surveysparrow-api
          path: /api/v1/users/me
          resolvers:
            id: id
            displayName: name
            avatarUrl: avatar_url

modules:
  jira:projectPage:
    - key: seosparrow-hello-world-project-page
      resource: main
      resolver:
        function: resolver
      render: native
      title: "Surveysparrow"
      layout: basic
  function:
    - key: resolver
      handler: index.handler
    - key: event-handler
      handler: eventHandler.handler
    - key: create-ticket-handler
      handler: createTicket.handler
    - key: main
      handler: oauth.handler
      providers:
        auth:
          - surveysparrow
    - key: oauth-handler
      handler: oauth.handler
  trigger:
    - key: issue-created-trigger
      function: event-handler
      events:
        - avi:jira:created:issue
    - key: issue-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:issue
    - key: issue-deleted-trigger
      function: event-handler
      events:
        - avi:jira:deleted:issue
    - key: task-created-trigger
      function: event-handler
      events:
        - avi:jira:created:task
    - key: task-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:task
    - key: story-created-trigger
      function: event-handler
      events:
        - avi:jira:created:story
    - key: story-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:story
  webtrigger:
    - key: create-ticket-webtrigger
      function: create-ticket-handler
    - key: oauth-callback
      function: main

resources:
  - key: main
    path: src/frontend/index.jsx
  - key: logo
    path: src/assets

app:
  id: ari:cloud:ecosystem::app/848a27cf-010b-4e41-8979-8fb5c994b73c
  runtime:
    name: nodejs20.x

remotes:
  - key: surveysparrow-api
    baseUrl: https://api.surveysparrow.com
  - key: google-apis
    baseUrl: https://www.googleapis.com
  - key: google-account
    baseUrl: https://accounts.google.com
  - key: google-oauth
    baseUrl: https://oauth2.googleapis.com

and Handler

resolver.define('initSurveySparrowAuth', async () => {
  try {
    const surveySparrow = api.asUser().withProvider('surveysparrow');
    if (!await surveySparrow.hasCredentials()) {
      const authUrl = await surveySparrow.requestCredentials();
      return { success: true, authUrl };
    }
    return { success: true, authenticated: true };
  } catch (error) {
    console.error('Auth initialization error:', error);
    throw error;
  }
});
Error: Bad provider or missing config for provider surveysparrow
    at findExternalAuthProviderConfigOrThrow (webpack://jira-project-page-ui-kit-2/node_modules/@forge/api/out/api/fetch.js:70:1)
    at buildExternalAuthAccountsInfo (webpack://jira-project-page-ui-kit-2/node_modules/@forge/api/out/api/fetch.js:110:1)
    at Object.withProvider (webpack://jira-project-page-ui-kit-2/node_modules/@forge/api/out/api/fetch.js:138:1)
    at <anonymous> (webpack://jira-project-page-ui-kit-2/src/resolvers/index.js:7:1)
    at Object.resolve (webpack://jira-project-page-ui-kit-2/node_modules/@forge/resolver/out/index.js:55:1)
    at /private/tmp/forge-tunnel-80291-UGP1SsglA3xI/index.cjs:2:563395
    at Q (/private/tmp/forge-tunnel-80291-UGP1SsglA3xI/index.cjs:2:563401)
    at new Promise (<anonymous>)
    at /private/tmp/forge-tunnel-80291-UGP1SsglA3xI/index.cjs:2:563158
    at AsyncLocalStorage.run (node:async_hooks:338:14)

can you please help me to resolve this :pray:

is there any generic url to navigate to an app inside my account like ?
https://id.atlassian.com/outboundAuth/finish?appId={app_id}&token={toke} . . Even this also fine in this case . please help . Thanks in advance :pray:

Hi @PeterParker , thanks for giving the external auth capability a try.

The particular error that you are running into is thrown when the config for your provider cannot be found, can you please confirm that you have deployed your app and that you have upgraded the installation of your app to the latest version (if applicable, the CLI will give you a prompt to do so) prior to attempting to use the provider?

The stack trace also suggests that you were running your app in a tunnel, please be aware that if you made changes to your manifest, you must first deploy and upgrade your app installation (if applicable) for the changes to be picked up.

1 Like

Hi @BoZhang ,
Yes I have tried . FYI adding here the actual trace

janarthanans@SSLAP0338-2 seosparrow % sudo forge deploy
Warning: Your version of Forge CLI is out of date. We recommend you update to the latest version to get the latest features and bug fixes.
Run npm install -g @forge/cli@latest to update from version 10.7.0 to 10.11.0.

Deploying your app to the development environment.
Press Ctrl+C to cancel.

Running forge lint...
No issues found.

✔ Deploying seosparrow to development...

ℹ Packaging app files
ℹ Uploading app
ℹ Validating manifest
ℹ Snapshotting functions
ℹ Deploying to environment

✔ Deployed

Deployed seosparrow to the development environment.

We've detected new scopes or egress URLs in your app.
Run forge install --upgrade and restart your tunnel to put them into effect.
janarthanans@SSLAP0338-2 seosparrow % sudo forge providers configure surveysparrow    
Warning: Your version of Forge CLI is out of date. We recommend you update to the latest version to get the latest features and bug fixes.
Run npm install -g @forge/cli@latest to update from version 10.7.0 to 10.11.0.

Configuring provider in the development environment.
Press Ctrl+C to cancel.

? Enter the client secret: [hidden]

✔ oauth provider credentials configuration is finished.
janarthanans@SSLAP0338-2 seosparrow % sudo forge install --upgrade                
Warning: Your version of Forge CLI is out of date. We recommend you update to the latest version to get the latest features and bug fixes.
Run npm install -g @forge/cli@latest to update from version 10.7.0 to 10.11.0.

To upgrade your app to use the latest scopes, select it from the list.
Press Ctrl+C to cancel.
? Select the site or workspace to upgrade: peterparker1729.atlassian.net

Upgrading your app on the Atlassian site.

Your app will exchange data with the following urls:
- accounts.google.com
- api.surveysparrow.com
- app.surveysparrow.com
- appnest-app.salesparrow.com
- atlassian.design
- developer.atlassian.com
- oauth2.googleapis.com
- static.surveysparrow.com
- www.googleapis.com

? Do you want to continue? Yes

✔ Upgrade complete!

Your app in the development environment is now the latest in Jira on peterparker1729.atlassian.net.
janarthanans@SSLAP0338-2 seosparrow % sudo forge tunnel
Warning: Your version of Forge CLI is out of date. We recommend you update to the latest version to get the latest features and bug fixes.
Run npm install -g @forge/cli@latest to update from version 10.7.0 to 10.11.0.

Tunnel redirects requests you make to your local machine. This occurs for any Atlassian site where your app is installed in the specific development environment. You will not see requests from other users.
Press Ctrl+C to cancel.


=== Running forge lint...
No issues found.

=== Bundling code...
✔ Functions bundled.
✔ Resources bundled.

Listening for requests...

Serving file index.html for resource main

invocation: 24041ef885494595a5cda7048bf65226 index.handler

invocation: 2cf8c536811f43edb17d567a9a25607b index.handler

invocation: 1602a1c48dc345289758f62f7b9fc0a2 index.handler

invocation: c64b99e06cbc4c3f902fcaa9790d2e23 index.handler

invocation: d2d2da5831034e268f0def848b64eff4 index.handler

invocation: 04ddd8226b4c4ca3bf944c84604e085f index.handler

invocation: b553dbcfaca146f98e286f1d093976fe index.handler
ERROR   15:35:45.701  b3b72294-6718-4410-99f7-782a4ca4ad4b  Auth initialization error: Error: Bad provider or missing config for provider surveysparrow
    at findExternalAuthProviderConfigOrThrow (webpack://jira-project-page-ui-kit-2/node_modules/@forge/api/out/api/fetch.js:70:1)
    at buildExternalAuthAccountsInfo (webpack://jira-project-page-ui-kit-2/node_modules/@forge/api/out/api/fetch.js:110:1)
    at Object.withProvider (webpack://jira-project-page-ui-kit-2/node_modules/@forge/api/out/api/fetch.js:138:1)
    at <anonymous> (webpack://jira-project-page-ui-kit-2/src/resolvers/index.js:7:1)
    at Object.resolve (webpack://jira-project-page-ui-kit-2/node_modules/@forge/resolver/out/index.js:55:1)
    at /private/tmp/forge-tunnel-86677-JttXb9We5KCW/index.cjs:2:563395
    at Q (/private/tmp/forge-tunnel-86677-JttXb9We5KCW/index.cjs:2:563401)
    at new Promise (<anonymous>)
    at /private/tmp/forge-tunnel-86677-JttXb9We5KCW/index.cjs:2:563158
    at AsyncLocalStorage.run (node:async_hooks:338:14)
ERROR   15:35:45.701  b3b72294-6718-4410-99f7-782a4ca4ad4b  Error: Bad provider or missing config for provider surveysparrow
    at findExternalAuthProviderConfigOrThrow (webpack://jira-project-page-ui-kit-2/node_modules/@forge/api/out/api/fetch.js:70:1)
    at buildExternalAuthAccountsInfo (webpack://jira-project-page-ui-kit-2/node_modules/@forge/api/out/api/fetch.js:110:1)
    at Object.withProvider (webpack://jira-project-page-ui-kit-2/node_modules/@forge/api/out/api/fetch.js:138:1)
    at <anonymous> (webpack://jira-project-page-ui-kit-2/src/resolvers/index.js:7:1)
    at Object.resolve (webpack://jira-project-page-ui-kit-2/node_modules/@forge/resolver/out/index.js:55:1)
    at /private/tmp/forge-tunnel-86677-JttXb9We5KCW/index.cjs:2:563395
    at Q (/private/tmp/forge-tunnel-86677-JttXb9We5KCW/index.cjs:2:563401)
    at new Promise (<anonymous>)
    at /private/tmp/forge-tunnel-86677-JttXb9We5KCW/index.cjs:2:563158
    at AsyncLocalStorage.run (node:async_hooks:338:14)

can u please help . Im stuck here :pray:

Hi @PeterParker, I can’t see anything wrong with what you are doing, I think there is a bug somewhere in one of our systems.
Please give me some time to hunt it down and I will get back to you when I have more information.
I apologise for the inconvenience.

Hi @PeterParker , we had a very close look at this today and found that the error was thrown inside your resolver function. You must define the surverysparrow provider for this function as well, like so:

  function:
    - key: resolver
      handler: index.handler
      providers:
        auth:
          - surveysparrow

For any functions where you want to reference a certain provider in the future, you must also include this piece of configuration.

1 Like

Hi @BoZhang ,
yes now the error got resolved after adding providers inside handlers :pray: . Now I am facing another issue like 401

FYI adding my Manifest here

permissions:
  scopes:
    - read:app-user-token
    - read:app-system-token
    - read:jira-work
    - write:jira-work
    - storage:app
  external:
    fetch:
      backend:
        - https://app.surveysparrow.com
        - https://api.surveysparrow.com
        - https://www.googleapis.com
        - https://oauth2.googleapis.com
        - https://accounts.google.com
    images:
      - https://appnest-app.salesparrow.com/SurveyMigrationTest-4119/version_1.0/icon/Color.png
      - https://atlassian.design/static/LockClosed-c651d828718647b03f5d4799d705b7e39d1ead63004aca3617049d3f1c0bb357.png
      - https://static.surveysparrow.com/site/assets/integrations/inner/microsoft/v2/create-and-share-chat-surveys-directly-from-teams.png
      - https://developer.atlassian.com//console/assets/assets/SearchNoResults.ae017adfe3f389e4be72.svg

providers:
  auth:
    - key: surveysparrow
      name: SurveySparrow
      scopes:
        - 'view_contacts'
        - 'view_question'
        - 'manage_share'
        - 'manage_survey_settings'
        - 'manage_invite'
        - 'view_contact_list'
        - 'manage_devices'
        - 'view_survey_integrations'
        - 'manage_workspace'
        - 'view_questions'
        - view_reputation_app_platforms
        - 'view_workspace'
        - 'manage_contacts'
        - 'view_invite'
        - 'manage_contact_list'
        - 'view_user'
        - 'view_employees'
        - 'view_team'
        - 'manage_employees'
        - 'manage_user'
        - 'view_employee_list'
        - 'manage_audit_logs'
        - 'manage_employee_list'
        - 'view_360_report'
        - 'view_survey'
        - 'view_targets'
        - 'manage_survey'
        - 'manage_team'
        - 'view_survey_settings'
        - 'view_ticket_fields'
        - 'manage_question'
        - 'view_audit_logs'
        - 'view_custom_property'
        - 'view_ticket_comments'
        - 'view_expressions'
        - 'view_tickets'
        - 'manage_custom_property'
        - 'manage_tickets'
        - 'view_theme'
        - 'manage_ticket_comments'
        - 'manage_survey_share'
        - 'create_dashboards'
        - 'view_survey_responses'
        - 'view_reputation_reviews'
        - 'view_webhooks'
        - 'view_dashboards'
        - 'manage_responses'
        - 'manage_webhooks'
      clientId: 'cNJMiwtxZkiXLXsywPfStzlLuzPGoHmMBMyLt5rGHC4'
      type: oauth2
      remotes:
        - surveysparrow-api
      bearerMethod: authorization-header
      actions:
        authorization:
          remote: surveysparrow-api
          path: /o/oauth/auth
          queryParameters:
            client_id: 'cNJMiwtxZkiXLXsywPfStzlLuzPGoHmMBMyLt5rGHC4'
            redirect_uri: 'https://id.atlassian.com/outboundAuth/finish'
            scope: 'view_contacts+view_question+manage_share+manage_survey_settings+manage_invite+view_contact_list+manage_devices+view_survey_integrations+manage_workspace+view_questions+view_reputation_app_platforms+view_workspace+manage_contacts+view_invite+manage_contact_list+view_user+view_employees+view_team+manage_employees+manage_user+view_employee_list+manage_audit_logs+manage_employee_list+view_360_report+view_survey+view_targets+manage_survey+manage_team+view_survey_settings+view_ticket_fields+manage_question+view_audit_logs+view_custom_property+view_ticket_comments+view_expressions+view_tickets+manage_custom_property+manage_tickets+view_theme+manage_ticket_comments+manage_survey_share+create_dashboards+view_survey_responses+view_reputation_reviews+view_webhooks+view_dashboards+manage_responses+manage_webhooks'
            # response_type: code
        exchange:
          remote: surveysparrow-api
          path: /o/oauth/token
        retrieveProfile:
          remote: surveysparrow-api
          path: /api/v1/users/me
          resolvers:
            id: id
            displayName: name
            avatarUrl: avatar_url

modules:
  jira:customField:
    - key: surveysparrow-custom-field
      function: custom-field-handler
      name: "SurveySparrow Survey"
      description: "Links SurveySparrow surveys to Jira issues"
      type: "string"
      extraAttributes:
        projectsActivatable: true
      config:
        contexts:
          - addon_env: general
            location: atl.jira.view.issue.right-panel
        type: full
      displayType: string
  jira:issuePanel:
    - key: surveysparrow-panel
      function: macro-handler
      title: "SurveySparrow"
      description: "Display SurveySparrow surveys and responses"
      icon: https://appnest-app.salesparrow.com/SurveyMigrationTest-4119/version_1.0/icon/Color.png
      location: atl.jira.view.issue.right.context
      renderMode: dynamic
      weight: 100
  jira:projectPage:
    - key: seosparrow-hello-world-project-page
      resource: main
      resolver:
        function: resolver
      render: native
      title: "Surveysparrow"
      layout: basic
  function:
    - key: resolver
      handler: index.handler
      providers:
        auth:
          - surveysparrow
    - key: macro-handler
      handler: macro.handler
    - key: custom-field-handler
      handler: customField.handler
    - key: event-handler
      handler: eventHandler.handler
    - key: create-ticket-handler
      handler: createTicket.handler
    - key: main
      handler: oauth.handler
    - key: oauth-handler
      handler: oauth.handler
  trigger:
    - key: issue-created-trigger
      function: event-handler
      events:
        - avi:jira:created:issue
    - key: issue-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:issue
    - key: issue-deleted-trigger
      function: event-handler
      events:
        - avi:jira:deleted:issue
    - key: task-created-trigger
      function: event-handler
      events:
        - avi:jira:created:task
    - key: task-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:task
    - key: story-created-trigger
      function: event-handler
      events:
        - avi:jira:created:story
    - key: story-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:story
  webtrigger:
    - key: create-ticket-webtrigger
      function: create-ticket-handler
    - key: oauth-callback
      function: main

resources:
  - key: main
    path: src/frontend/index.jsx
  - key: logo
    path: src/assets

app:
  id: ari:cloud:ecosystem::app/848a27cf-010b-4e41-8979-8fb5c994b73c
  runtime:
    name: nodejs20.x

remotes:
  - key: surveysparrow-api
    baseUrl: https://api.surveysparrow.com
    auth:
      appUserToken:
        enabled: true
      appSystemToken:
        enabled: true
  - key: google-apis
    baseUrl: https://www.googleapis.com
  - key: google-account
    baseUrl: https://accounts.google.com
  - key: google-oauth
    baseUrl: https://oauth2.googleapis.com

Network call response here

{
    "data": {
        "invokeExtension": {
            "success": false,
            "response": null,
            "contextToken": null,
            "errors": [
                {
                    "message": "Needs authentication error",
                    "extensions": {
                        "errorType": "USER_CONSENT_REQUIRED",
                        "statusCode": 400,
                        "__typename": "InvokeExtensionPayloadErrorExtension",
                        "fields": {
                            "authInfoUrl": "https://id.atlassian.com/login?continue=https%3A%2F%2Fid.atlassian.com%2FoutboundAuth%2Fstart%3FcontainerId%3D848a27cf-010b-4e41-8979-8fb5c994b73c_2eafa8f9-306e-4ea3-befc-37680e35a86d%26serviceKey%3Dsurveysparrow%26isAccountBased%3Dtrue%26cloudId%3Dc07acfa1-7518-47a2-9a28-a760d321ecf9%26contextAri%3Dari%253Acloud%253Ajira%253Ac07acfa1-7518-47a2-9a28-a760d321ecf9%253Aworkspace%252F055210fb-6c16-46fa-a6b2-5d5c16b60be6%26redirectTemplate%3DforgeWarning%26appId%3D848a27cf-010b-4e41-8979-8fb5c994b73c&login_hint=peterparkerj1729%40gmail.com&prompt=none&serviceKey=surveysparrow",
                            "__typename": "InvokeExtensionPayloadErrorExtensionFields"
                        }
                    },
                    "__typename": "MutationError"
                }
            ],
            "__typename": "InvokeExtensionResponse"
        }
    },
    "extensions": {
        "gateway": {
            "request_id": "cc25d22d391a42b3ad2cd10a6b82935a",
            "crossRegion": false,
            "edgeCrossRegion": false
        }
    }
}

Handler here

resolver.define('initSurveySparrowAuth', async () => {
  const surveySparrow = api.asUser().withProvider('surveysparrow', 'surveysparrow-api');
  const isAuthenticated = await surveySparrow.hasCredentials();
  console.log(`surveysparrow: ${isAuthenticated}`);
  if (!isAuthenticated) {
    console.log('before requestCredentials');
    try {
      await surveySparrow.requestCredentials();
    } catch (e) {
      console.error(e);
      console.error('Failed to request credentials');
      throw e;
    }
    console.log('after requestCredentials');
  }
  return {
    code: 401,
    message: 'Failed to get surveysparrow token',
  };
});

And the logs from the console

INFO    15:24:46.923  cbea8001-8a7e-448d-88a0-99e9cfef13b3  surveysparrow: false
INFO    15:24:46.923  cbea8001-8a7e-448d-88a0-99e9cfef13b3  before requestCredentials
ERROR   15:24:46.924  cbea8001-8a7e-448d-88a0-99e9cfef13b3  [NEEDS_AUTHENTICATION_ERR: Authentication Required] {
  status: 401,
  serviceKey: 'surveysparrow',
  options: { scopes: undefined, isExpectedError: true }
}
ERROR   15:24:46.924  cbea8001-8a7e-448d-88a0-99e9cfef13b3  Failed to request credentials

I have gone through the same issue in this forum for slack oauth . but in surveysparrow case its not working . FYI adding Surveysparrow OAuth docs here . Waiting for your help . Thanks in advance :pray:

Hi, don’t catch the error, let it throw, the front end understands this error and will render a configuration prompt allowing the user to go down the OAuth dance.
e.g:

  const surveySparrow = api.asUser().withProvider('surveysparrow', 'surveysparrow-api');
  const isAuthenticated = await surveySparrow.hasCredentials();
  console.log(`surveysparrow: ${isAuthenticated}`);
  if (!isAuthenticated) {
    // let this call throw
    await surveySparrow.requestCredentials();
  }

Hi @BoZhang ,
I tried like you mentioned . so now my handler is

resolver.define('initSurveySparrowAuth', async () => {
  const surveySparrow = api.asUser().withProvider('surveysparrow', 'surveysparrow-api');
  const isAuthenticated = await surveySparrow.hasCredentials();
  console.log(`surveysparrow: ${isAuthenticated}`);
  if (!isAuthenticated) {
    await surveySparrow.requestCredentials();
  }
});

and my front-end function in onclick()

 const handleConnect = async () => {
    await invoke("initSurveySparrowAuth");
   
  };

Logs

invocation: d494c352e22c4726b0df67555260988a index.handler
INFO    17:31:27.350  31f5247d-3b67-45d8-85c3-1fd3d1b28604  surveysparrow: false

nothing happened in front end . even not getting error but still the oauth is not happening can you please help :pray:

FYI I tried with return also @BoZhang .

resolver.define('initSurveySparrowAuth', async () => {
  const surveySparrow = api.asUser().withProvider('surveysparrow', 'surveysparrow-api');
  const isAuthenticated = await surveySparrow.hasCredentials();
  console.log(`surveysparrow: ${isAuthenticated}`);
  if (!isAuthenticated) {
    return await surveySparrow.requestCredentials();
  }
});

What do you see on the front end? you should see something like this:


not able to find like nothing @BoZhang

I tested it myself by creating an app just like yours and it’s working for me, can you try clearing the cache in your browser?

Yes @BoZhang . now i can able to authorize but still im getting this error .

actually still confused how this external oauth working for surveysparrow . basically I will get a exchange code in query param in the redirection url after authorizing app in surveysparrow .

permissions:
  scopes:
    - read:app-user-token
    - read:app-system-token
    - read:jira-work
    - write:jira-work
    - storage:app
  external:
    fetch:
      backend:
        - https://app.surveysparrow.com
        - https://api.surveysparrow.com
        - https://www.googleapis.com
        - https://oauth2.googleapis.com
        - https://accounts.google.com
    images:
      - https://appnest-app.salesparrow.com/SurveyMigrationTest-4119/version_1.0/icon/Color.png
      - https://atlassian.design/static/LockClosed-c651d828718647b03f5d4799d705b7e39d1ead63004aca3617049d3f1c0bb357.png
      - https://static.surveysparrow.com/site/assets/integrations/inner/microsoft/v2/create-and-share-chat-surveys-directly-from-teams.png
      - https://developer.atlassian.com//console/assets/assets/SearchNoResults.ae017adfe3f389e4be72.svg

providers:
  auth:
    - key: surveysparrow
      name: SurveySparrow
      scopes:
        - 'view_contacts'
        - 'view_question'
        - 'manage_share'
        - 'manage_survey_settings'
        - 'manage_invite'
        - 'view_contact_list'
        - 'manage_devices'
        - 'view_survey_integrations'
        - 'manage_workspace'
        - 'view_questions'
        - view_reputation_app_platforms
        - 'view_workspace'
        - 'manage_contacts'
        - 'view_invite'
        - 'manage_contact_list'
        - 'view_user'
        - 'view_employees'
        - 'view_team'
        - 'manage_employees'
        - 'manage_user'
        - 'view_employee_list'
        - 'manage_audit_logs'
        - 'manage_employee_list'
        - 'view_360_report'
        - 'view_survey'
        - 'view_targets'
        - 'manage_survey'
        - 'manage_team'
        - 'view_survey_settings'
        - 'view_ticket_fields'
        - 'manage_question'
        - 'view_audit_logs'
        - 'view_custom_property'
        - 'view_ticket_comments'
        - 'view_expressions'
        - 'view_tickets'
        - 'manage_custom_property'
        - 'manage_tickets'
        - 'view_theme'
        - 'manage_ticket_comments'
        - 'manage_survey_share'
        - 'create_dashboards'
        - 'view_survey_responses'
        - 'view_reputation_reviews'
        - 'view_webhooks'
        - 'view_dashboards'
        - 'manage_responses'
        - 'manage_webhooks'
      clientId: 'cNJMiwtxZkiXLXsywPfStzlLuzPGoHmMBMyLt5rGHC4'
      type: oauth2
      remotes:
        - surveysparrow-api
      bearerMethod: authorization-header
      actions:
        authorization:
          remote: surveysparrow-api
          path: /o/oauth/auth
          queryParameters:
            client_id: 'cNJMiwtxZkiXLXsywPfStzlLuzPGoHmMBMyLt5rGHC4'
            redirect_uri: 'https://id.atlassian.com/outboundAuth/finish'
            scope: 'view_contacts+view_question+manage_share+manage_survey_settings+manage_invite+view_contact_list+manage_devices+view_survey_integrations+manage_workspace+view_questions+view_reputation_app_platforms+view_workspace+manage_contacts+view_invite+manage_contact_list+view_user+view_employees+view_team+manage_employees+manage_user+view_employee_list+manage_audit_logs+manage_employee_list+view_360_report+view_survey+view_targets+manage_survey+manage_team+view_survey_settings+view_ticket_fields+manage_question+view_audit_logs+view_custom_property+view_ticket_comments+view_expressions+view_tickets+manage_custom_property+manage_tickets+view_theme+manage_ticket_comments+manage_survey_share+create_dashboards+view_survey_responses+view_reputation_reviews+view_webhooks+view_dashboards+manage_responses+manage_webhooks'
        exchange:
          remote: surveysparrow-api
          path: /o/oauth/token
          resolvers:
            accessToken: authed_user.access_token
        retrieveProfile:
          remote: surveysparrow-api
          path: /v3/surveys
          resolvers:
            id: id
            displayName: name
            avatarUrl: avatar_url

modules:
  jira:customField:
    - key: surveysparrow-custom-field
      function: custom-field-handler
      name: "SurveySparrow Survey"
      description: "Links SurveySparrow surveys to Jira issues"
      type: "string"
      extraAttributes:
        projectsActivatable: true
      config:
        contexts:
          - addon_env: general
            location: atl.jira.view.issue.right-panel
        type: full
      displayType: string
  jira:issuePanel:
    - key: surveysparrow-panel
      function: macro-handler
      title: "SurveySparrow"
      description: "Display SurveySparrow surveys and responses"
      icon: https://appnest-app.salesparrow.com/SurveyMigrationTest-4119/version_1.0/icon/Color.png
      location: atl.jira.view.issue.right.context
      renderMode: dynamic
      weight: 100
  jira:projectPage:
    - key: seosparrow-hello-world-project-page
      resource: main
      resolver:
        function: resolver
      render: native
      title: "Surveysparrow"
      layout: basic
  function:
    - key: resolver
      handler: index.handler
      providers:
        auth:
          - surveysparrow
    - key: macro-handler
      handler: macro.handler
    - key: custom-field-handler
      handler: customField.handler
    - key: event-handler
      handler: eventHandler.handler
    - key: create-ticket-handler
      handler: createTicket.handler
    - key: main
      handler: oauth.handler
    - key: oauth-handler
      handler: oauth.handler
  trigger:
    - key: issue-created-trigger
      function: event-handler
      events:
        - avi:jira:created:issue
    - key: issue-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:issue
    - key: issue-deleted-trigger
      function: event-handler
      events:
        - avi:jira:deleted:issue
    - key: task-created-trigger
      function: event-handler
      events:
        - avi:jira:created:task
    - key: task-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:task
    - key: story-created-trigger
      function: event-handler
      events:
        - avi:jira:created:story
    - key: story-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:story
  webtrigger:
    - key: create-ticket-webtrigger
      function: create-ticket-handler
    - key: oauth-callback
      function: main

resources:
  - key: main
    path: src/frontend/index.jsx
  - key: logo
    path: src/assets

app:
  id: ari:cloud:ecosystem::app/848a27cf-010b-4e41-8979-8fb5c994b73c
  runtime:
    name: nodejs20.x

remotes:
  - key: surveysparrow-api
    baseUrl: https://api.surveysparrow.com
    auth:
      appUserToken:
        enabled: true
      appSystemToken:
        enabled: true
  - key: google-apis
    baseUrl: https://www.googleapis.com
  - key: google-account
    baseUrl: https://accounts.google.com
  - key: google-oauth
    baseUrl: https://oauth2.googleapis.com

basically here we dont have users api instead of that we can retrive surveys in retrive profile is that fine ?

can you please take a look here and help @BoZhang . Thanks :pray:

FYI tried by moving my app from dev to staging and got this error . can you please help @BoZhang

Have you configured the provider in your staging environment (i.e: Did you run forge providers configure <key> -e staging -s <your-secret>)? Please also make sure that the latest changes have all be deployed into your staging environment.

For the profile retriever issue, it seems like Survey Sparrow doesn’t have a get current user endpoint (from what I could find), what you can do is point the profile retriever to an endpoint that you own that is a proxy for retrieving the account info from Survey Sparrow. If you do this, please make sure that the account info is populated accurately, as it is surfaced to the end user to show them what an app has access, this is important from the trust aspect.

yes @BoZhang .you are right forgot to configure provider in staging :pray: . but that bad_token issue is still there
Actually surveysparrow have an api to fetch current user like /v3/users so i have added that .

FYI adding my manifest here

permissions:
  scopes:
    - read:app-user-token
    - read:app-system-token
    - read:jira-work
    - write:jira-work
    - storage:app
  external:
    fetch:
      backend:
        - https://app.surveysparrow.com
        - https://api.surveysparrow.com
        - https://www.googleapis.com
        - https://oauth2.googleapis.com
        - https://accounts.google.com
    images:
      - https://appnest-app.salesparrow.com/SurveyMigrationTest-4119/version_1.0/icon/Color.png
      - https://atlassian.design/static/LockClosed-c651d828718647b03f5d4799d705b7e39d1ead63004aca3617049d3f1c0bb357.png
      - https://static.surveysparrow.com/site/assets/integrations/inner/microsoft/v2/create-and-share-chat-surveys-directly-from-teams.png
      - https://developer.atlassian.com//console/assets/assets/SearchNoResults.ae017adfe3f389e4be72.svg

providers:
  auth:
    - key: surveysparrow
      name: SurveySparrow
      scopes:
        - 'view_contacts'
        - 'view_question'
        - 'manage_share'
        - 'manage_survey_settings'
        - 'manage_invite'
        - 'view_contact_list'
        - 'manage_devices'
        - 'view_survey_integrations'
        - 'manage_workspace'
        - 'view_questions'
        - view_reputation_app_platforms
        - 'view_workspace'
        - 'manage_contacts'
        - 'view_invite'
        - 'manage_contact_list'
        - 'view_user'
        - 'view_employees'
        - 'view_team'
        - 'manage_employees'
        - 'manage_user'
        - 'view_employee_list'
        - 'manage_audit_logs'
        - 'manage_employee_list'
        - 'view_360_report'
        - 'view_survey'
        - 'view_targets'
        - 'manage_survey'
        - 'manage_team'
        - 'view_survey_settings'
        - 'view_ticket_fields'
        - 'manage_question'
        - 'view_audit_logs'
        - 'view_custom_property'
        - 'view_ticket_comments'
        - 'view_expressions'
        - 'view_tickets'
        - 'manage_custom_property'
        - 'manage_tickets'
        - 'view_theme'
        - 'manage_ticket_comments'
        - 'manage_survey_share'
        - 'create_dashboards'
        - 'view_survey_responses'
        - 'view_reputation_reviews'
        - 'view_webhooks'
        - 'view_dashboards'
        - 'manage_responses'
        - 'manage_webhooks'
      clientId: 'cNJMiwtxZkiXLXsywPfStzlLuzPGoHmMBMyLt5rGHC4'
      type: oauth2
      remotes:
        - surveysparrow-api
      bearerMethod: authorization-header
      actions:
        authorization:
          remote: surveysparrow-api
          path: /o/oauth/auth
          queryParameters:
            client_id: 'cNJMiwtxZkiXLXsywPfStzlLuzPGoHmMBMyLt5rGHC4'
            redirect_uri: 'https://id.atlassian.com/outboundAuth/finish'
            scope: 'view_contacts+view_question+manage_share+manage_survey_settings+manage_invite+view_contact_list+manage_devices+view_survey_integrations+manage_workspace+view_questions+view_reputation_app_platforms+view_workspace+manage_contacts+view_invite+manage_contact_list+view_user+view_employees+view_team+manage_employees+manage_user+view_employee_list+manage_audit_logs+manage_employee_list+view_360_report+view_survey+view_targets+manage_survey+manage_team+view_survey_settings+view_ticket_fields+manage_question+view_audit_logs+view_custom_property+view_ticket_comments+view_expressions+view_tickets+manage_custom_property+manage_tickets+view_theme+manage_ticket_comments+manage_survey_share+create_dashboards+view_survey_responses+view_reputation_reviews+view_webhooks+view_dashboards+manage_responses+manage_webhooks'
        exchange:
          remote: surveysparrow-api
          path: /o/oauth/token
          resolvers:
            accessToken: authed_user.access_token
        retrieveProfile:
          remote: surveysparrow-api
          path: /v3/users
          resolvers:
            id: response.data[0].id
            displayName: response.data[0].name
            avatarUrl: response.data[0].profile_pic

modules:
  jira:customField:
    - key: surveysparrow-custom-field
      function: custom-field-handler
      name: "SurveySparrow Survey"
      description: "Links SurveySparrow surveys to Jira issues"
      type: "string"
      extraAttributes:
        projectsActivatable: true
      config:
        contexts:
          - addon_env: general
            location: atl.jira.view.issue.right-panel
        type: full
      displayType: string
  jira:issuePanel:
    - key: surveysparrow-panel
      function: macro-handler
      title: "SurveySparrow"
      description: "Display SurveySparrow surveys and responses"
      icon: https://appnest-app.salesparrow.com/SurveyMigrationTest-4119/version_1.0/icon/Color.png
      location: atl.jira.view.issue.right.context
      renderMode: dynamic
      weight: 100
  jira:projectPage:
    - key: seosparrow-hello-world-project-page
      resource: main
      resolver:
        function: resolver
      render: native
      title: "Surveysparrow"
      layout: basic
  function:
    - key: resolver
      handler: index.handler
      providers:
        auth:
          - surveysparrow
    - key: macro-handler
      handler: macro.handler
    - key: custom-field-handler
      handler: customField.handler
    - key: event-handler
      handler: eventHandler.handler
    - key: create-ticket-handler
      handler: createTicket.handler
    - key: main
      handler: oauth.handler
    - key: oauth-handler
      handler: oauth.handler
  trigger:
    - key: issue-created-trigger
      function: event-handler
      events:
        - avi:jira:created:issue
    - key: issue-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:issue
    - key: issue-deleted-trigger
      function: event-handler
      events:
        - avi:jira:deleted:issue
    - key: task-created-trigger
      function: event-handler
      events:
        - avi:jira:created:task
    - key: task-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:task
    - key: story-created-trigger
      function: event-handler
      events:
        - avi:jira:created:story
    - key: story-updated-trigger
      function: event-handler
      events:
        - avi:jira:updated:story
  webtrigger:
    - key: create-ticket-webtrigger
      function: create-ticket-handler
    - key: oauth-callback
      function: main

resources:
  - key: main
    path: src/frontend/index.jsx
  - key: logo
    path: src/assets

app:
  id: ari:cloud:ecosystem::app/848a27cf-010b-4e41-8979-8fb5c994b73c
  runtime:
    name: nodejs20.x

remotes:
  - key: surveysparrow-api
    baseUrl: https://api.surveysparrow.com
    auth:
      appUserToken:
        enabled: true
      appSystemToken:
        enabled: true
  - key: google-apis
    baseUrl: https://www.googleapis.com
  - key: google-account
    baseUrl: https://accounts.google.com
  - key: google-oauth
    baseUrl: https://oauth2.googleapis.com

And the response that from /v3/users is like

{
  "data": [
    {
      "id": 1000197018,
      "name": "Jana",
      "email": "jana@gmail.com",
      "phone": "9876543210",
      "admin": false,
      "owner": true,
      "agency_owner": false,
      "profile_pic": null,
      "verified": true,
      "role_id": 1000871866,
      "created_at": "2024-02-08T07:14:07.897Z",
      "current_user": true
    }
  ],
  "has_next_page": false
}

is it possible to destruct these datas in manifest like i used ?

FYI adding the sample api call to surveysparrow apis

 const response = await axios.get(`https://api.surveysparrow.com/v3/questions?survey_id=${req.payload.surveyId}`, {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

can we expect the Bearer infront of token in this flow . @BoZhang can you please help me to correct where I’m missing something :pray: