[IMP] add server settings for CORS#795
[IMP] add server settings for CORS#795RaoufGhrissi wants to merge 1 commit intoActivityWatch:masterfrom
Conversation
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (allow_aw_chrome_extension and allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-webui#795
|
I will apply the same changes to aw-server once validated on aw-server-rust |
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (cors_allow_aw_chrome_extension and cors_allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-webui#795
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (cors_allow_aw_chrome_extension and cors_allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-webui#795
Greptile SummaryThis PR adds a CORS configuration modal ( Confidence Score: 3/5Safe to merge after addressing the remaining unresolved P1 (stale config on failed reload, flagged in a prior review cycle) and the new The prior P1 issue — src/stores/cors.ts —
|
| Filename | Overview |
|---|---|
| src/components/CorsConfigModal.vue | New modal for editing CORS config. Previous concerns about missing error state and incomplete editable type have been addressed; residual risk is the underlying stale-config issue in the store (previous thread). |
| src/stores/cors.ts | New Pinia store for CORS state. needs_restart is not set to true after save; load() still does not clear this.config before refetch (previous thread), so stale config is shown on failed reload. |
| src/views/settings/Settings.vue | Minimal change: adds "Configure CORS" button and CorsConfigModal component after DeveloperSettings. Correctly registered in components. No issues. |
Sequence Diagram
sequenceDiagram
participant User
participant CorsConfigModal
participant CorsStore
participant Server
User->>CorsConfigModal: Click "Configure CORS"
CorsConfigModal->>CorsStore: load()
CorsStore->>Server: GET /0/cors-config
Server-->>CorsStore: CorsConfig (cors, cors_regex, flags, in_file, needs_restart)
CorsStore-->>CorsConfigModal: config (watch fires → editable, corsStr, corsRegexStr updated)
User->>CorsConfigModal: Edit fields, click OK
CorsConfigModal->>CorsStore: save(editable as MutableCorsConfig)
CorsStore->>Server: POST /0/cors-config (mutable fields only)
Server-->>CorsStore: 200 OK
CorsStore->>CorsStore: config = {...config, ...payload} (needs_restart NOT updated)
CorsConfigModal->>User: Modal closes + alert("restart required")
Reviews (7): Last reviewed commit: "[SEC] restrict CORS to authorized extens..." | Re-trigger Greptile
| | Recommended for security. To allow a specific extension safely: | ||
| ol.mt-2.mb-1 | ||
| li Go to <code>about:debugging#/runtime/this-firefox</code> in your browser. | ||
| li Look for your extension and copy the **Manifest URL** (e.g. <code>moz-extension://4b931c07deded...ff152/manifest.json</code>). |
There was a problem hiding this comment.
Markdown bold syntax renders literally in Pug
The **Manifest URL** syntax is Markdown, not Pug/HTML. Pug templates do not process Markdown, so users will see the asterisks rendered literally in the browser (**Manifest URL** instead of Manifest URL). Use an inline <b> tag or Pug's b element instead.
| li Look for your extension and copy the **Manifest URL** (e.g. <code>moz-extension://4b931c07deded...ff152/manifest.json</code>). | |
| li Look for your extension and copy the <b>Manifest URL</b> (e.g. <code>moz-extension://4b931c07deded...ff152/manifest.json</code>). |
| ol.mt-2.mb-1 | ||
| li Go to <code>about:debugging#/runtime/this-firefox</code> in your browser. | ||
| li Look for your extension and copy the **Manifest URL** (e.g. <code>moz-extension://4b931c07deded...ff152/manifest.json</code>). | ||
| li Remove <code>manifest.json</code> from the end (to get <code>moz-extension://4b931c07deded...ff152</code>). | ||
| li Paste it into the <b>Regex CORS origins</b> field above (use a comma to separate if not empty). |
There was a problem hiding this comment.
Regex field instructions advise pasting literal URLs containing unescaped dots
Step 3 tells the user to paste a raw moz-extension://... URL (e.g. moz-extension://4b931c07deded...ff152) into the Regex CORS origins field. However, the dots (.) in that URL are regex metacharacters that match any character, so the pattern will also match origins with different characters in those positions. This could allow an unintended extension to bypass the CORS check.
Consider updating the instructions to advise users to escape literal dots with \., or direct them to paste the origin into the Fixed CORS origins field instead (which uses exact matching), if the backend supports it.
| div.mt-5.text-muted.small | ||
| | Web UI commit hash: {{ COMMIT_HASH }} |
There was a problem hiding this comment.
| return { | ||
| showSettings: false, | ||
| }; | ||
| }, |
There was a problem hiding this comment.
Unused
showSettings data property
The data() function exposes showSettings: false, but this property is never referenced anywhere in the template or the computed/methods sections. It appears to be an accidental copy-paste artefact from another settings component. It can be safely removed.
| return { | |
| showSettings: false, | |
| }; | |
| }, | |
| computed: { |
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (cors_allow_aw_chrome_extension and cors_allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-webui#795
9e1a0fe to
ee21fb6
Compare
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (cors_allow_aw_chrome_extension and cors_allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-webui#795
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (cors_allow_aw_chrome_extension and cors_allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. The TOML configuration file values are now used only as an initial seed for the database during the first run. On subsequent runs, any values changed and persisted via the Web UI will take precedence over the config file defaults. Fixed a bug in the web-ui store where changing one setting would cause all other settings to be re-saved with their initial client-side values, unintentionally overwriting database settings with stale defaults. Dependent on: ActivityWatch/aw-webui#795
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (cors_allow_aw_chrome_extension and cors_allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. The TOML configuration file values are now used only as an initial seed for the database during the first run. On subsequent runs, any values changed and persisted via the Web UI will take precedence over the config file defaults. Fixed a bug in the web-ui store where changing one setting would cause all other settings to be re-saved with their initial client-side values, unintentionally overwriting database settings with stale defaults. Dependent on: ActivityWatch/aw-webui#795
ee21fb6 to
d0af1de
Compare
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (cors_allow_aw_chrome_extension and cors_allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. The TOML configuration file values are now used only as an initial seed for the database during the first run. On subsequent runs, any values changed and persisted via the Web UI will take precedence over the config file defaults. Fixed a bug in the web-ui store where changing one setting would cause all other settings to be re-saved with their initial client-side values, unintentionally overwriting database settings with stale defaults. Dependent on: ActivityWatch/aw-webui#795
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (cors_allow_aw_chrome_extension and cors_allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. The TOML configuration file values are now used only as an initial seed for the database during the first run. On subsequent runs, any values changed and persisted via the Web UI will take precedence over the config file defaults. Fixed a bug in the web-ui store where changing one setting would cause all other settings to be re-saved with their initial client-side values, unintentionally overwriting database settings with stale defaults. Dependent on: ActivityWatch/aw-webui#795
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (cors_allow_aw_chrome_extension and cors_allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. The TOML configuration file values are now used only as an initial seed for the database during the first run. On subsequent runs, any values changed and persisted via the Web UI will take precedence over the config file defaults. Fixed a bug in the web-ui store where changing one setting would cause all other settings to be re-saved with their initial client-side values, unintentionally overwriting database settings with stale defaults. Dependent on: ActivityWatch/aw-webui#795
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (cors_allow_aw_chrome_extension and cors_allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. The TOML configuration file values are now used only as an initial seed for the database during the first run. On subsequent runs, any values changed and persisted via the Web UI will take precedence over the config file defaults. Fixed a bug in the web-ui store where changing one setting would cause all other settings to be re-saved with their initial client-side values, unintentionally overwriting database settings with stale defaults. Dependent on: ActivityWatch/aw-webui#795
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (allow_aw_chrome_extension and allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-webui#795 edited according to the last changes
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (allow_aw_chrome_extension and allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-webui#795 edited according to the last changes
d0af1de to
cd7673f
Compare
|
Tip: Greploop — Automatically fix all review issues by running Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal. |
| div(v-else-if="loading") | ||
| p Loading... |
There was a problem hiding this comment.
Missing error state — OK button stays active on load failure
The store sets this.error when load() fails, but the component only maps config and loading from the store — error is never observed. When the API returns an error, loading becomes false and config stays null, so the modal shows a completely blank body while the OK button remains enabled (:ok-disabled="loading" only guards the in-flight case). A user clicking OK at that point sends the component's initialised-to-empty editable (cors: [], cors_regex: [], ...) to the server, potentially wiping the existing CORS configuration.
Two changes are needed: (1) also map error from the store and display it, and (2) disable OK when the config hasn't loaded:
| div(v-else-if="loading") | |
| p Loading... | |
| div(v-else-if="loading") | |
| p Loading... | |
| div(v-else-if="error") | |
| b-alert(show variant="danger") Failed to load CORS configuration: {{ error }} |
And update the modal's ok-disabled binding:
b-modal(... :ok-disabled="loading || !config" ...)
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (allow_aw_chrome_extension and allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-webui#795 edited according to the last changes
690f553 to
60917fa
Compare
60917fa to
5279a87
Compare
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (allow_aw_chrome_extension and allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-webui#795 edited according to the last changes
| editable: { | ||
| cors: [] as string[], | ||
| cors_regex: [] as string[], | ||
| cors_allow_aw_chrome_extension: false, | ||
| cors_allow_all_mozilla_extension: false, | ||
| }, | ||
| corsStr: '', | ||
| corsRegexStr: '', | ||
| corsStore: useCorsStore(), | ||
| }; |
There was a problem hiding this comment.
editable declared type is missing CorsConfig fields
editable is initialised with only four fields, but corsStore.save() expects a full CorsConfig (which also requires in_file and needs_restart). TypeScript will likely raise a compile error at the corsStore.save(this.editable) call because the declared type of editable does not satisfy CorsConfig. Declare editable as CorsConfig from the start so the types align end-to-end.
| editable: { | |
| cors: [] as string[], | |
| cors_regex: [] as string[], | |
| cors_allow_aw_chrome_extension: false, | |
| cors_allow_all_mozilla_extension: false, | |
| }, | |
| corsStr: '', | |
| corsRegexStr: '', | |
| corsStore: useCorsStore(), | |
| }; | |
| editable: { | |
| cors: [] as string[], | |
| cors_regex: [] as string[], | |
| cors_allow_aw_chrome_extension: false, | |
| cors_allow_all_mozilla_extension: false, | |
| in_file: [] as string[], | |
| needs_restart: false, | |
| } as CorsConfig, |
5279a87 to
23ca24e
Compare
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (allow_aw_chrome_extension and allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-webui#795 edited according to the last changes
Fixes a security issue where any Firefox extension (moz-extension://.*) could access the ActivityWatch server without any restriction. Previously, the CORS configuration included a wildcard for all Mozilla extensions by default. This commit removes that blanket permission and introduces granular control through both static configuration and the Web UI. We've added 2 new fields to the file configuration (allow_aw_chrome_extension and allow_all_mozilla_extension) and 4 new settings to the Web UI (Fixed origins, Regex origins, and extension-specific shortcuts). The server now merges these settings to determine the final set of authorized origins, ensuring a more secure and flexible configuration. Dependent on: ActivityWatch/aw-server-rust#581 edited according to the last changes
23ca24e to
268528b
Compare
| async load() { | ||
| this.loading = true; | ||
| this.error = null; | ||
| try { | ||
| const client = getClient(); | ||
| const response = await client.req.get('/0/cors-config'); | ||
| this.config = response.data; | ||
| } catch (e: any) { | ||
| this.error = e.response?.data?.message || e.message || 'Failed to load CORS config'; | ||
| } finally { | ||
| this.loading = false; | ||
| } |
There was a problem hiding this comment.
Stale config shown on failed reload
load() never clears this.config before issuing the request. When the modal is opened a second time and the fetch fails, this.config still holds the previous session's data. Back in the template, v-if="config" evaluates to true, so the form renders with stale values and the v-else-if="error" branch is never reached — the user sees no indication that the reload failed and edits data they believe to be current.
Add this.config = null; at the top of load() so that a failed refetch exposes the error state:
| async load() { | |
| this.loading = true; | |
| this.error = null; | |
| try { | |
| const client = getClient(); | |
| const response = await client.req.get('/0/cors-config'); | |
| this.config = response.data; | |
| } catch (e: any) { | |
| this.error = e.response?.data?.message || e.message || 'Failed to load CORS config'; | |
| } finally { | |
| this.loading = false; | |
| } | |
| async load() { | |
| this.loading = true; | |
| this.config = null; | |
| this.error = null; | |
| try { | |
| const client = getClient(); | |
| const response = await client.req.get('/0/cors-config'); | |
| this.config = response.data; | |
| } catch (e: any) { | |
| this.error = e.response?.data?.message || e.message || 'Failed to load CORS config'; | |
| } finally { | |
| this.loading = false; | |
| } | |
| }, |
|
Greptile encountered an error while reviewing this PR. Please reach out to support@greptile.com for assistance. |
Dependent on: ActivityWatch/aw-server-rust#581