Skip to content

Conversation

@davixcky
Copy link
Contributor

@davixcky davixcky commented Apr 24, 2025

  • refactor state
  • add debug panel
  • fix tracestate
  • context storage and debug panel under settings

This is break currently, but with this refactor i expect to fix multiple issues related to stata manager including
#44 and one that was reported today Error updating dynamic rules: Error: Rule with id 1 does not have a unique ID.

I think that refactor should improve the speed a little bit cause it will prevent some duplicate calls that are triggered on the service worker

@davixcky davixcky marked this pull request as ready for review April 24, 2025 23:00
@davixcky
Copy link
Contributor Author

davixcky commented Apr 24, 2025

Update:
The refactor is working now, it has been apply to all the page and seems easy to extend now.

  • Sync React state with browser
  • The headers calculation is done on the react side and NOT service worker
  • Service worker still injects the header
  • All actions/updates are being set through storage context

cc: @foxish

@foxish
Copy link
Member

foxish commented Apr 28, 2025

I just loaded this change up locally by building from dist/. And I am not able to turn it on:

image

Also, as soon as I load it, I get an error:

Screenshot 2025-04-28 at 3 20 12 PM
(()=>{"use strict";var e;!function(e){e.routingKey="routingKey",e.signadotUrls="signadotUrls",e.enabled="enabled",e.traceparentHeader="traceparentHeader",e.headers="headers",e.debugMode="debugMode",e.apiUrl="apiUrl",e.previewUrl="previewUrl",e.dashboardUrl="dashboardUrl"}(e||(e={}));const t=chrome.declarativeNetRequest.ResourceType,r=[t.MAIN_FRAME,t.SUB_FRAME,t.STYLESHEET,t.SCRIPT,t.IMAGE,t.FONT,t.OBJECT,t.XMLHTTPREQUEST,t.PING,t.CSP_REPORT,t.MEDIA,t.WEBSOCKET,t.OTHER];function a(){return t=this,a=void 0,o=function*(){const t=yield(i=[e.routingKey,e.enabled,e.headers,e.traceparentHeader],a=void 0,n=void 0,o=void 0,c=function*(){return yield chrome.storage.local.get(i)},new(o||(o=Promise))((function(e,t){function r(e){try{d(c.next(e))}catch(e){t(e)}}function i(e){try{d(c.throw(e))}catch(e){t(e)}}function d(t){var a;t.done?e(t.value):(a=t.value,a instanceof o?a:new o((function(e){e(a)}))).then(r,i)}d((c=c.apply(a,n||[])).next())})));var a,n,o,c,i;const{routingKey:d,enabled:l,headers:s,traceparentHeader:u}=t;if(!(s.length>0&&l&&d)){try{const e=yield chrome.declarativeNetRequest.getDynamicRules();yield chrome.declarativeNetRequest.updateDynamicRules({removeRuleIds:e.map((e=>e.id))}),console.log("Dynamic rules cleared.")}catch(e){console.error("Error clearing dynamic rules: ",e)}return}const h=(e=>{let t=1;return e.map((([e,a])=>({id:t++,priority:1,action:{type:chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS,requestHeaders:[{header:e,operation:chrome.declarativeNetRequest.HeaderOperation.SET,value:a}]},condition:{urlFilter:"*",excludedRequestDomains:["preview.signadot.com","preview.staging.signadot.com","localhost.signadot.com"],resourceTypes:r}})))})(JSON.parse(s)),m=yield chrome.declarativeNetRequest.getDynamicRules();yield chrome.declarativeNetRequest.updateDynamicRules({removeRuleIds:m.map((e=>e.id)),addRules:h}),console.log("Dynamic rules updated successfully.")},new((n=void 0)||(n=Promise))((function(e,r){function c(e){try{d(o.next(e))}catch(e){r(e)}}function i(e){try{d(o.throw(e))}catch(e){r(e)}}function d(t){var r;t.done?e(t.value):(r=t.value,r instanceof n?r:new n((function(e){e(r)}))).then(c,i)}d((o=o.apply(t,a||[])).next())}));var t,a,n,o}chrome.runtime.onInstalled.addListener(a),chrome.runtime.onStartup.addListener(a),chrome.storage.onChanged.addListener(((t,r)=>{console.log({changes:t,areaName:r}),"local"===r&&(t[e.headers]||t[e.routingKey]||t[e.enabled]||t[e.traceparentHeader])&&a()}))})();

Am I missing something / doing something wrong?

Copy link
Member

@foxish foxish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the intent behind the refactor and the separation of the storage this way makes sense, but I had several comments along the way.

useEffect(() => {
refetch();
}, [apiUrl]);
}, [settings.signadotUrls.apiUrl]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a separate follow-up issue, but I'd expect this to be refetched if the org name changes as well (someone logs into different org)


await chrome.storage.local.set({[StorageKey.InjectedHeaders]: headerKeys});
const { routingKey, enabled, headers, traceparentHeader } = values;
const injectHeaders = headers.length > 0 && enabled && routingKey;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the default headers, we don't ever expect headers.length be 0 right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we expect in the case of not being enabled in the react side, we set to empty array.


// Signadot URLs
if (storedValues[StorageBrowserKeys.signadotUrls] !== undefined) {
try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this without the try...catch? If this is our code, can't we check for whether it's present using if..else rather than throwing and catching exceptions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON.parse could trigger an error if it's not a valid JSON or it's malformed. In any case i think it's a good practice to in case of error, set the default. Cause this could be user prune if they updated by hand, or for some reason value is corrupted. Or if between version and version we decide to change the schema

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. fair, but let's catch specific exceptions with JSON parsing using instanceof - that will at least ensure we don't hide errors that are unrelated and behave in surprising ways.

const [previewUrl, setPreviewUrl] = useState<string>(DEFAULT_PREVIEW_URL);
const [dashboardUrl, setDashboardUrl] = useState<string>(DEFAULT_DASHBOARD_URL);
const [traceparentHeader, setTraceparentHeader] = useState<string>(DEFAULT_TRACEPARENT_HEADER);
const [temporaryValues, setTemporaryValues] = useState<{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a temporaryValue is and what purpose does this serve?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe unsavedValues? This is working as temporary values that are yet not saved

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsavedValues sgtm


setTraceparent(temporaryValues.traceparentHeaderEnabled, temporaryValues.traceparentHeader);

// chrome.storage.local.set({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a code comment explaining why this is commented out

davixcky and others added 3 commits April 29, 2025 13:41
I accidentally applyed the prettier to all the files. So there are bunch
of changes, but primarly you should focus on
- Route
- ProtectedRoute
- AuthContext
- Frame
- Layout

This fixes some inconsistences on the unauthenticated state, blocking
the access in some cases, where now it's being fixed thanks to the
RouteView context
@davixcky
Copy link
Contributor Author

@foxish major and minor fixes are been applied, any issue that is not state should be tackled separelty. Things that remains is to test traceparent is being updated correctly and injected when it should. Similar to the others headers to be injected only when

  • feature is enabled
  • selected routing key
  • user is authenticated

Tested on a fresh installation

Copy link
Member

@foxish foxish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, it got messy and too large, in future, please plan ahead so that the complicated changes can be merged separately and the stylistic stuff can happen later.

image

This change is not correct - but can be addressed in follow-up PR - the search should come up on top and also when nothing is selected, it's cutting off the dropdown.

@davixcky
Copy link
Contributor Author

That issue is being addressed in #51

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants