Skip to content
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
50 changes: 50 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: CI

on:
push:
branches: ['**']
pull_request:

permissions:
contents: read

jobs:
lint:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
- run: npm run test:unit
- run: npm run build

chrome:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npm run test:chrome

firefox:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- name: Firefox and geckodriver versions
run: |
firefox --version || true
geckodriver --version || true
- run: npm run test:firefox
34 changes: 34 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Release

# Push a tag equal to the manifest version, e.g.: git tag v1.1 && git push origin v1.1
on:
push:
tags: ['v*']

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- name: Check that tag matches manifest version
run: |
VERSION=$(node -p "require('./manifest.json').version")
echo "manifest version: $VERSION, tag: $GITHUB_REF_NAME"
if [ "v$VERSION" != "$GITHUB_REF_NAME" ]; then
echo "::error::Tag $GITHUB_REF_NAME does not match manifest version $VERSION"
exit 1
fi
- run: npm run lint
- run: npm run build
- name: Create GitHub release with the package
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "$GITHUB_REF_NAME" web-ext-artifacts/*.zip --title "$GITHUB_REF_NAME" --generate-notes
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# intellij
.idea/
.vscode/

# packed extendsion
*.zip

# shells
*.sh


# node
node_modules/
web-ext-artifacts/
test-results/
118 changes: 116 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,116 @@
# _NCC (bitrix cookie)
Firefox addon for setting _NCC cookie
# _NCC cookie for Bitrix (BITRIX_SM_NCC)
Browser extension that turns off the 1C-Bitrix composite cache for you: it sets the `_NCC` cookie
(`BITRIX_SM_NCC=Y`) for the current site.

[![Firefox Add-on](https://img.shields.io/amo/v/_ncc-cookie-for-bitrix?logo=firefox&label=Firefox%20Add-on)](https://addons.mozilla.org/firefox/addon/_ncc-cookie-for-bitrix/)
[![Firefox users](https://img.shields.io/amo/users/_ncc-cookie-for-bitrix?logo=firefox&label=users)](https://addons.mozilla.org/firefox/addon/_ncc-cookie-for-bitrix/)

**Install:** [Firefox Add-ons (AMO)](https://addons.mozilla.org/firefox/addon/_ncc-cookie-for-bitrix/) (desktop and Android) · Chrome Web Store — coming soon

Works in **Firefox 140+**, **Firefox for Android 142+** and **Chrome / Chromium 121+** (one Manifest V3 codebase).
On Android there are no keyboard shortcuts (the browser has no commands API); every browser API is
checked before use, so missing APIs only switch off the related feature.

Interface languages: English, Russian, Kazakh (follows the browser language).

## How it works in Bitrix

Composite site settings are stored in `/bitrix/html_pages/.config.php`. The cookie name is
`COOKIE_NCC` there: the cookie prefix of the main module (option "cookie_name", `BITRIX_SM` by default)
plus `_NCC` (`Bitrix\Main\Composite\Helper::getOptions()`).

- A request with the cookie `<prefix>_NCC=Y` (exactly `Y`) is not served from the composite cache and
the page is not saved to it (`Bitrix\Main\Composite\Responder`): you see the page generated by PHP,
other visitors still get the cache.
- A request with the `ncc` parameter (`?ncc=1`) is not served from the cache too.
- Bitrix manages this cookie itself (`Bitrix\Main\Composite\Engine::onEpilog()`): sets it for authorized
users who must not get the cache and **deletes it for anonymous visitors** on every page.
So the extension keeps the cookie you turned on: when the site deletes it, the cookie is set again.
A cookie turned off in the extension is not restored.
- If nginx serves the composite cache directly (without PHP), its config may not check the cookie.
Then use the **"Open without composite (?ncc=1)"** button in the popup.

![Cookie name in .config.php](screens/get_cookie_name.jpg)

## Popup

- switch "Disable composite cache" — sets / removes the cookie for the current site, the toolbar icon
changes its color and gets the `N` badge;
- "Set cookie for" — the current host only or a parent domain with all its subdomains
(e.g. `.example.com` for `www.example.com` and `shop.example.com`), remembered per host;
- click the cookie name — own cookie name for the current site (for a site with another cookie prefix);
an enabled cookie is moved to the new name; other sites keep the name from the settings;
- "Open without composite (?ncc=1)" — reloads the current page with `?ncc=1`.

![Composite is on](screens/composite-on.jpg)
![Composite is off](screens/composite-off.jpg)

## Keyboard shortcuts

- `Alt+Shift+Y` - toggle the cookie
- open popup - no default shortcut

Firefox: `about:addons` → gear → "Manage Extension Shortcuts".
Chrome: `chrome://extensions/shortcuts`.

## Options

- cookie name (`BITRIX_SM_NCC` by default); the value is always `Y`, Bitrix checks it strictly;
- icon colors for "on" and "off" states.

After renaming the cookie in options, cookies with the old name are removed from all sites.
Settings of version 0.1 are kept (the same storage keys); the old placeholder `?????_NCC` means the default name.

## Installation from sources

Firefox: `about:debugging#/runtime/this-firefox` → "Load Temporary Add-on…" → select `manifest.json`.
Firefox may treat host permissions as optional: if the popup shows "Grant access", click it.

Chrome: `chrome://extensions` → enable "Developer mode" → "Load unpacked" → select the repository folder.

Package: `npm install && npm run build` → `web-ext-artifacts/*.zip` (works for both browsers).

## Development

```sh
npm install
npm run lint # web-ext lint
npm run test:unit # no browser: API helpers, Firefox for Android-like environment, cookie restore
npm run test:chrome # Playwright, Chromium (CHROMIUM_PATH can point to a custom binary)
npm run test:firefox # Selenium + geckodriver, needs Firefox
# (FIREFOX_PATH / GECKODRIVER_PATH can point to custom binaries)
```

The test server deletes the cookie the same way as Bitrix (`/epilog` responds with
`Set-Cookie: BITRIX_SM_NCC=deleted; expires=...1970...`).

GitHub Actions run lint and both browser tests on every push and pull request.

## Release

Bump `version` in `manifest.json`, merge to `master`, then push a tag with the same version:

```sh
git tag v1.0 && git push origin v1.0
```

The Release workflow checks the version, builds the zip and creates a GitHub release with it.
Store listing texts, privacy policy and images are in [`store/`](store/README.md).

## Debug

All scripts log with the `[NCC]` prefix (enable "Debug"/"Verbose" level in the console):

- Firefox: `about:debugging#/runtime/this-firefox` → this addon → "Inspect";
- Chrome: `chrome://extensions` → this addon → "service worker".

Popup can be opened in a regular tab for a given tab: `popup.html?tabId=N`.

## Files

- `common.js` - shared code (cookie, settings, keeping the cookie), used by all pages;
- `background.js` - icon, badge, shortcut, sync with cookie/settings changes, restoring the cookie;
- `popup.html/js/css` - toolbar popup;
- `options.html/js/css` - settings page;
- `_locales/` - translations (en, ru, kk);
- `tests/` - browser tests, `store/` - store listing materials, `screens/` - images for this README.
105 changes: 105 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{
"popupUnsupported": {
"message": "Cookies can't be set on this page."
},
"needPermission": {
"message": "The addon needs access to sites to manage cookies."
},
"grantAccess": {
"message": "Grant access"
},
"setCookieFor": {
"message": "Set cookie for"
},
"scopeHostOnly": {
"message": "$1 (this host only)"
},
"scopeWithSubdomains": {
"message": ".$1 (with subdomains)"
},
"failed": {
"message": "Failed: $1"
},
"scopeFailed": {
"message": "Failed to set cookie for this domain: $1"
},
"permissionFailed": {
"message": "Permission request failed: $1"
},
"settings": {
"message": "Settings"
},
"setButton": {
"message": "Set"
},
"forThisSite": {
"message": "for this site"
},
"optOffColor": {
"message": "Off icon color"
},
"optOnColor": {
"message": "On icon color"
},
"optSave": {
"message": "Save"
},
"optSaved": {
"message": "Options saved successfully."
},
"optSaveError": {
"message": "There were some errors during save, please try again."
},
"optInvalidName": {
"message": "Invalid cookie name: \"$1\"."
},
"langCode": {
"message": "en",
"description": "Language code of this translation for the lang attribute"
},
"extName": {
"message": "Bitrix _NCC Cookie: Disable Composite Cache"
},
"extDescription": {
"message": "Toggle the Bitrix _NCC cookie (BITRIX_SM_NCC=Y) to disable the composite cache on the current site while debugging."
},
"trigger_ncc": {
"message": "Disable composite cache"
},
"siteCookieName": {
"message": "Cookie name for this site"
},
"siteCookieNameHint": {
"message": "Empty — the name from the settings. The exact name is \"COOKIE_NCC\" in /bitrix/html_pages/.config.php (cookie prefix + _NCC)."
},
"resetButton": {
"message": "Reset"
},
"changeSiteNameTitle": {
"message": "Change the cookie name for this site"
},
"openWithoutComposite": {
"message": "Open without composite (?ncc=1)"
},
"openWithoutCompositeHint": {
"message": "For servers where nginx serves the composite cache itself and does not check the cookie."
},
"titleOff": {
"message": "_NCC cookie: off"
},
"titleOn": {
"message": "Composite cache disabled ($1)"
},
"titleUnavailable": {
"message": "_NCC cookie (not available on this page)"
},
"titleNoPermission": {
"message": "_NCC cookie: click to grant access to sites"
},
"optCookieName": {
"message": "Cookie name (usually BITRIX_SM_NCC)"
},
"optCookieNameHint": {
"message": "Cookie prefix of the site + _NCC. The exact name is \"COOKIE_NCC\" in /bitrix/html_pages/.config.php. For a site with another prefix set its own name in the popup (click the cookie name)."
}
}
Loading
Loading