Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/update show expired token policy #380

Merged
merged 3 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions addon/inspector.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export let apiVersion = localStorage.getItem("apiVersion") == null ? "60.0" : localStorage.getItem("apiVersion");
export let sessionError = "";
export let sessionError;
export let sfConn = {

async getSession(sfHost) {
Expand Down Expand Up @@ -100,8 +100,11 @@ export let sfConn = {
throw err;
} else if (xhr.status == 401) {
let error = xhr.response.length > 0 ? xhr.response[0].message : "New access token needed";
sessionError = error;
showInvalidTokenBanner();
//set sessionError only if user has already generated a token, which will prevent to display the error when the session is expired and api access control not configured
if (localStorage.getItem(this.instanceHostname + "_access_token")){
sessionError = error;
showInvalidTokenBanner();
}
let err = new Error();
err.name = "Unauthorized";
err.message = error;
Expand Down
1 change: 1 addition & 0 deletions addon/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class OptionsTabSelector extends React.Component {
{option: Option, props: {type: "toggle", title: "Search metadata from Shortcut tab", key: "metadataShortcutSearch"}},
{option: Option, props: {type: "toggle", title: "Disable query input autofocus", key: "disableQueryInputAutoFocus"}},
{option: Option, props: {type: "toggle", title: "Popup Dark theme", key: "popupDarkTheme"}},
{option: Option, props: {type: "toggle", title: "Show 'Generate Access Token' button", key: "popupGenerateTokenButton", default: true}},
{option: Option, props: {type: "text", title: "Custom favicon (org specific)", key: this.sfHost + "_customFavicon", placeholder: "Available values : green, orange, pink, purple, red, yellow"}}
]
},
Expand Down
19 changes: 15 additions & 4 deletions addon/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ class App extends React.PureComponent {
if (sessionError){
text = "Access Token Expired";
title = "Generate New Token";
url = `https://${sfHost}/services/oauth2/authorize?response_type=token&client_id=` + clientId + "&redirect_uri=" + browser + "-extension://" + chrome.i18n.getMessage("@@extension_id") + "/data-export.html";
}
url = `https://${sfHost}/services/oauth2/authorize?response_type=token&client_id=` + clientId + "&redirect_uri=" + browser + "-extension://" + chrome.i18n.getMessage("@@extension_id") + "/data-export.html";
return {title, url, text};
}
render() {
Expand Down Expand Up @@ -297,6 +297,17 @@ class App extends React.PureComponent {
h("div", {className: "slds-m-bottom_xx-small"},
h("a", {ref: "apiExploreBtn", href: "explore-api.html?" + hostArg, target: linkTarget, className: "page-button slds-button slds-button_neutral"}, h("span", {}, "E", h("u", {}, "x"), "plore API"))
),
localStorage.getItem("popupGenerateTokenButton") !== "false" ? h("div", {className: "slds-m-bottom_xx-small"},
h("a",
{
ref: "generateToken",
href: bannerUrlAction.url,
target: linkTarget,
className: !clientId ? "button hide" : "page-button slds-button slds-button_neutral"
},
h("span", {}, h("u", {}, "G"), "enerate Access Token"))
) : null,

// Workaround for in Lightning the link to Setup always opens a new tab, and the link back cannot open a new tab.
inLightning && isInSetup && h("div", {className: "slds-m-bottom_xx-small"},
h("a",
Expand Down Expand Up @@ -1433,10 +1444,10 @@ class UserDetails extends React.PureComponent {
: h("em", {className: "inactive"}, "unknown")
)
),
h("tr", {},
user.UserRole ? h("tr", {},
h("th", {}, "Role:"),
h("td", {className: "oneliner"}, (user.UserRole) ? user.UserRole.Name : "")
),
h("td", {className: "oneliner"}, user.UserRole.Name)
) : null,
h("tr", {},
h("th", {}, "Language:"),
h("td", {},
Expand Down
15 changes: 13 additions & 2 deletions docs/how-to.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,28 @@

---

### For Chrome and Edge users

If you enabled "API client whitelisting" (a.k.a "API Access Control") in your org, SF Inspector may not work anymore.

To secure the extension usage, you can use a OAuth 2.0 flow to get an access token, linked to a connected app installed in your org.
To install the default "SF Inspector reloaded" connected app, open popup and click 'Generate Access Token' button

<img width="275" alt="Generate Token" src="https://github.com/tprouvot/Salesforce-Inspector-reloaded/assets/35368290/931df75d-42ac-4667-ab3f-35f6b6b65a66">

Then navigate to Setup | Connected Apps OAuth Usage, and click "Install" on the Salesforce Inspector reloaded app.

To install the default "SF Inspector reloaded" connected app, navigate to Setup | Connected Apps OAuth Usage, and click "Install" on the Salesforce Inspector reloaded app.
From now when the token will be expired, this banner will show up and provide a link to re-generate the access token

<img width="274" alt="image" src="https://github.com/tprouvot/Salesforce-Inspector-reloaded/assets/35368290/856c3635-008b-4b91-8160-019d1d701ba9">

> **Warning**
> Don't forget to grant access to the users by selecting the related profile(s) or permission set(s).

If you are a Firefox user, or if you want to have full control over the connected app settings, you can also use your own connected app by following these instructions:

### For Firefox users

1. Create a connected app under Setup | App Manager > New Connected App.
2. Set callback url to `chrome-extension://chromeExtensionId/data-export.html` (replace `chromeExtensionId` by the actual ID of the extension in your web browser). Make sure the "Manage user data via APIs (api)" scope is selected. You can leave other settings to their default values.

Expand All @@ -32,7 +43,7 @@ If you are a Firefox user, or if you want to have full control over the connecte

5. Refresh page and generate new token

<img alt="Generate Token" src="https://github.com/tprouvot/Chrome-Salesforce-inspector/blob/master/docs/screenshots/generateAccessToken.png?raw=true" width="300">
<img width="275" alt="Generate Token" src="https://github.com/tprouvot/Salesforce-Inspector-reloaded/assets/35368290/931df75d-42ac-4667-ab3f-35f6b6b65a66">

## Migrate saved queries from legacy extension to Salesforce Inspector Reloaded

Expand Down
14 changes: 14 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ When redirected to the "Data Export" tab at the end of the OAuth flow, check the

![image](screenshots/oauthError.png)

### Generate new token error
If you did not enabled 'API Access Control' and continuously see the banner generate token

You may have seen this message because of an expired token, and since this was the only available option clicked on 'Generate new Token'.

Try to run this code in chrome dev console, after inspecting the extension' popup code:

```js
let tokens = Object.keys(localStorage).filter((localKey) =>
localKey.endsWith("access_token")
);
tokens.forEach((element) => localStorage.removeItem(element));
```

### Managed Application Installation Error

When installing the default connected app when `API Access Control` is enabled, if you face the error `Managed Application Installation Error` you may have an existing connected app named `Salesforce Inspector reloaded`.
Loading