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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ One bundle serves both backends. The extension decides when it starts, first mat
| 4 | Install type: an **unpacked** install (`chrome.management.getSelf().installType === 'development'`) is TEST, any other install is PROD | Needs no extra permission; background service worker only |
| 5 | Default: PROD | Same as the SDK |

**Tier stamp.** The stamp is the default tier of a store install, so the TEST store item ("UDA TEST") and the PROD item run the same code and differ only in this default. A stamp `TEST` **locks** the extension to TEST: the options page hides the PROD choice, and a PROD request from the options override or from a host page is ignored (the worker and the page side both check). A stamp `PROD` accepts the overrides as before. Without a stamp nothing changes: an unpacked development build (the `test-current` zip has no stamp) is TEST, anything else is PROD. A stamped zip that is loaded unpacked follows its stamp (a PROD-stamped zip gives PROD), so the file you unpack declares its tier. The stamp holds no secret and no URL; the URLs still come from the build settings. The `source` reported by the options page and by `UDASdkReady` is `stamp` when the stamp decided.
**Tier stamp.** The stamp is the default tier of a store install, so the TEST store item ("UDA TEST") and the PROD item ("Universal Digital Assistant by Nistapp (UDAN)") run the same code and differ only in this default. A stamp `TEST` **locks** the extension to TEST: the options page hides the PROD choice, and a PROD request from the options override or from a host page is ignored (the worker and the page side both check). A stamp `PROD` accepts the overrides as before. Without a stamp nothing changes: an unpacked development build (the `test-current` zip has no stamp) is TEST, anything else is PROD. A stamped zip that is loaded unpacked follows its stamp (a PROD-stamped zip gives PROD), so the file you unpack declares its tier. The stamp holds no secret and no URL; the URLs still come from the build settings. The `source` reported by the options page and by `UDASdkReady` is `stamp` when the stamp decided.

The URLs for the chosen environment come, per key, from the page (`apiBaseUrl`, `tokenUrl`, `llmUrl`, `keycloakUrl`), then from the build settings above, then from the SDK's own defaults. A key the page set is never overwritten. When the environment (or a backend, realm or client setting) changes while the panel is open, the panel drops the stored session of the old backend, asks the worker for the session again and runs the search again; no page reload is needed. This is `AuthContext` listening to `UDAConfigUpdated`. The Client never calls `authManager.init` (sign-in runs in the worker), so there is nothing else to re-run.

Expand Down Expand Up @@ -172,7 +172,7 @@ Branch from `dev` and open a PR into `dev`; the PR title must be a [Conventional

- Zip: `udan-extension-<X.Y.Z.N>.zip`, plus `SHA256SUMS` and `build-info.json` (commit, branch, run, attempt, config hash, SDK version and integrity, names of the env keys that were set). Same commit, run number, attempt and build configuration give the same bytes.
- Version: CI stamps the built manifest with `version = X.Y.Z.<run number>` and `version_name = "X.Y.Z (<short commit>) run <run number>.<attempt> cfg <config hash>"`. X.Y.Z comes from `package.json` (Release Please owns it); the run number makes each build higher than the last. `version_name` is the build identity: a re-run of the same CI run (new attempt, e.g. after fixing an Actions variable) or any changed build setting changes it, while `version` stays. The config hash is 8 hex of a sha256 over the build settings the bundle inlines (`node scripts/build-env.js production --hash`); the values are not recoverable from it. The source manifests only hold the base version, for local builds.
- Store zips: the same run also writes the two Chrome Web Store zips, `udan-extension-<X.Y.Z.N>-store-test.zip` (for the unlisted TEST item "UDA TEST") and `udan-extension-<X.Y.Z.N>-store-prod.zip` (for the PROD item), each with its line in `SHA256SUMS`. See "Store zips" below.
- Store zips: the same run also writes the two Chrome Web Store zips, `udan-extension-<X.Y.Z.N>-store-test.zip` (for the unlisted TEST item "UDA TEST") and `udan-extension-<X.Y.Z.N>-store-prod.zip` (for the PROD item, "Universal Digital Assistant by Nistapp (UDAN)"), each with its line in `SHA256SUMS`. See "Store zips" below.
- Retention: artifact `client-zip`, 90 days for pushes to `dev`, 14 days for PRs. The run summary shows the version, SHA256 and SDK version.
- Build settings in CI come from GitHub Actions **variables** (`BASE_PROD_URL`, `TOKEN_TEST_URL`, ..., `KEYCLOAK_PUBLIC_CLIENT_ID`, `KEYCLOAK_IDP_HINT`: `scripts/ci/generate-env.sh --print-names`), never from secrets. They are set once at the organization level and shared with the SDK repo, which uses the same names.

Expand Down Expand Up @@ -204,7 +204,7 @@ Release Please no longer touches the manifests: CI owns the extension version. A
|---|---|---|---|
| Used for | `Deploy to TEST` prereleases, unpacked testing | the unlisted TEST store item | the PROD store item |
| Manifest `key` | kept (pins the dev/TEST id) | **removed** (the store fixes the item id) | **removed** |
| Manifest `name` | unchanged | `UDA TEST` | unchanged |
| Manifest `name` | unchanged | `UDA TEST` | unchanged (`Universal Digital Assistant by Nistapp (UDAN)` from `public/manifest.json`) |
| `tier.json` | none (unpacked = TEST, as before) | `{"tier":"TEST"}` | `{"tier":"PROD"}` |
| Icons | `logos/nist-logo-*.png` | TEST badge from `store/test-icons/` | unchanged |

Expand Down
110 changes: 99 additions & 11 deletions docs/store-listing-draft.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,105 @@
# Store listing draft: privacy (owner submits)
# Store listing: copy-paste text for the Chrome Web Store dashboard

Draft only. The Chrome Web Store text is the owner's to submit; check it against the README section "Privacy: what the extension stores" first.
The owner submits this text. It is checked against the README section "Privacy: what the extension stores"; change the README and this file together. Images and the dashboard field list are in `store/listing/README.md`. The two items (PROD and the unlisted TEST item "UDA TEST") use the same text; the item name comes from the manifest in each store zip, not from this file. The PROD name is `Universal Digital Assistant by Nistapp (UDAN)`, exactly 45 characters, the Chrome Web Store limit; keep any copy consistent with it.

**Single purpose.** Record, save and replay step-by-step guides on a web page (Universal Digital Assistant Network).
## Store listing tab

**Data the extension handles**
- Account: when you sign in, UDAN gets a Keycloak account id, your email and your name from your Google account. The extension keeps sign-in tokens in its own browser storage so you stay signed in; Sign Out deletes them and ends the session.
- Content you create: the guides you record and save (the clicks and labels on a page), and search terms you type, are sent to the UDAN service.
- Local: the extension stores its settings and your sign-in tokens in the browser only.
**Title (PROD item).** Universal Digital Assistant by Nistapp (UDAN)

The title is the manifest `name` of the PROD store zip (45 characters; the documented manifest limit is 75). It is the product name, not a beta label: do not add Beta or Alpha to the listing title or text. The TEST item keeps the name "UDA TEST".

**Summary** (from the package; 112 of 132 characters)

```
Record, save and replay step-by-step guides on any web page. Sign in with Google to keep and search your guides.
```

**Description** (plain text, no headings; paste as is)

```
Universal Digital Assistant by Nistapp (UDAN) lets you record a task on a web page as a step-by-step guide, save it, and replay it later so that you or someone else can follow the same steps.

What you can do
- Record: start a recording on a page and click through the task. The extension notes each step (the clicked element and a label you can edit).
- Save: give the guide a name and save it to your UDAN account.
- Replay: open the panel on the page, search for a guide, and follow it step by step.

How it works
The extension adds a small UDAN button to web pages. Open it to get the panel. Signing in uses Google through UDAN's sign-in page.

Your data, in plain words
- When you sign in, UDAN receives a Keycloak account id, your email and your name from your Google account. Your Google password is never seen by UDAN: you enter it on Google's or UDAN's own sign-in page.
- The guides you record and save (the clicks and labels on a page, and the page's domain) and the search terms you type are sent to the UDAN service.
- Your sign-in tokens and settings are kept in the extension's own browser storage so that you stay signed in. Sign Out ends the session and deletes the tokens.
- The web page where the panel runs receives a short-lived access token (about 5 minutes). A script on that page can ask the extension for a fresh access token while you are signed in. The long-lived refresh token never leaves the extension.
- Your data is not sold and not used for advertising.

Privacy policy: https://udan.nistapp.com/legal/privacy
```

**Category:** Productivity, subcategory "Workflow & Planning". Closest alternatives: Productivity > "Tools" and Productivity > "Education" (from the dashboard list as I know it; I did not open the dashboard, so if a name has changed, pick the nearest).

**Language:** English.

**Privacy policy URL:** `https://udan.nistapp.com/legal/privacy` (renders the policy in a browser, verified 2026-11-01). Do not use `https://udan.nistapp.com/privacy`: the site is a single-page app and that route renders an empty page.

**Images:** see `store/listing/README.md` (three 1280x800 screenshots, small promo tile 440x280).

## Privacy practices tab

**Things to say plainly**
- The web page where the panel runs receives a short-lived access token (about 5 minutes). A script on that page can ask the extension for a new one while you are signed in. The long-lived refresh token never leaves the extension.
**Single purpose** (paste into "Single purpose description")

```
Record, save and replay step-by-step guides on a web page (Universal Digital Assistant Network).
```

**Permission justifications** (one box per permission; unchanged from the earlier submission, `1.0.8.8`)

| Permission | Text for the dashboard |
|---|---|
| `identity` | Opens the sign-in window (launchWebAuthFlow) for the user's Google sign-in through UDAN's sign-in page, and reads the Chrome profile hint so the sign-in page can suggest the signed-in Chrome account. |
| `identity.email` | Suggests the Chrome account that is already signed in on the sign-in page, so the user does not have to type it. |
| `storage` | Keeps the extension's settings and the user's sign-in tokens in the extension's own storage so the user stays signed in. Sign Out deletes the tokens. |
| `tabs` | Finds the page the user is on, to show the panel on it. |
| `activeTab` | Gives the extension access to the page the user is on when they open the panel or start a recording. |
| Host access (`*://*/*`, content scripts) | The panel and the recorder run on the pages where the user records or replays a guide. The guides are for customer sites that can be on any domain, so the extension cannot name them in advance. |

**Remote code:** No. All code is in the package; the page script is loaded from the extension's own files.

**Data usage: what the extension collects** (tick these; leave the others empty)

| Dashboard category | Tick | Why |
|---|---|---|
| Personally identifiable information | yes | Name and email from the user's Google account, and the Keycloak account id. |
| Authentication information | yes | Access, refresh and ID tokens from the UDAN sign-in (kept in the extension's storage). |
| User activity | yes | The clicks the user records as steps in a guide. |
| Website content | yes | The labels and element data of the steps of a recorded guide. |
| Web history | yes | A saved guide stores the page it was recorded on (`fetchDomain()` / the page URL is saved with the recording), so page addresses are collected. Verified. |
| Health, Financial and payment, Personal communications, Location | no | Not collected. |

**Certifications** (the three statements; tick all three)

- I do not sell or transfer user data to third parties, outside of the approved use cases. Data goes to the UDAN service that provides the item's function; the Google sign-in is the approved sign-in use. Not sold.
- I do not use or transfer user data for purposes that are unrelated to my item's single purpose. Not used for advertising or anything else.
- I do not use or transfer user data to determine creditworthiness or for lending purposes.

**Answers to the questions behind them**

| Question | Answer |
|---|---|
| Is data sold? | No. |
| Used for purposes unrelated to the single purpose (for example advertising)? | No. |
| Is the data required for the single purpose? | Yes: the account is needed to save and find guides; the guides and search terms are the function itself. |
| Encrypted in transit? | Yes. Evidence: the PROD store zip `1.1.0.204` was unzipped and the bundle grepped; every backend host is `https://` (`udan.nistapp.com`, `authenticate.nistapp.com`, `iam.nistapp.com`, the `*test` equivalents, third-party docs links). The only `http://` strings are `http://localhost` (dev only) and `http://www.w3.org` (a namespace string, not a request). Checkpoint: no PROD request uses plain HTTP. |
| Can the user delete it? | Sign Out deletes the tokens in the extension. For data saved on the service, point to the privacy policy (the policy page is the place to name a deletion route; see the privacy-policy placeholder issue in the PR output). |

## Facts behind the text (from the README, keep in step)

- Account: when you sign in, UDAN gets a Keycloak account id, your email and your name from your Google account. The extension keeps sign-in tokens in its own browser storage (`chrome.storage.local`, not readable by websites) so you stay signed in; Sign Out ends the session and deletes them.
- Content you create: the guides you record and save (the clicks and labels on a page), and search terms you type, are sent to the UDAN service. The email is sent as a hash.
- Local: the extension stores its settings and your sign-in tokens in the browser only.
- The web page where the panel runs receives a short-lived access token (about 5 minutes). **A script on that page can ask the extension for a new one while you are signed in** (`UDARequestAccessToken`). The long-lived refresh token never leaves the extension.
- Your Google password is never seen by UDAN: you enter it on Google's or Keycloak's own page.
- Data is not sold and not used for advertising.

**Permission reasons** (unchanged by this change): `identity` (sign-in window and the Chrome profile hint), `identity.email` (suggest the signed-in Chrome account on the sign-in page), `storage` (settings and tokens), `tabs` and `activeTab` (find the page to show the panel on), host access (the panel runs on the pages of customer sites).
- The package file `tier.json` (`TEST` or `PROD`) is read from the extension's own package; it stores nothing and sends nothing.
- Not stored or sent: the Google password, browsing history outside the pages where the user records.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "UDAN-Frontend",
"version": "1.1.0",
"private": true,
"license": "AGPL-3.0-only",
"dependencies": {
"@radix-ui/react-accordion": "^1.2.3",
"@radix-ui/react-alert-dialog": "^1.1.6",
Expand Down
2 changes: 1 addition & 1 deletion public/manifest-firefox.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"manifest_version": 3,
"name": "Universal Digital Assistant (UDA) Beta",
"name": "Universal Digital Assistant by Nistapp (UDAN)",
"version": "1.1.0",
"content_scripts": [
{
Expand Down
2 changes: 1 addition & 1 deletion public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"manifest_version": 3,
"name": "Universal Digital Assistant (UDA) Beta",
"name": "Universal Digital Assistant by Nistapp (UDAN)",
"version": "1.1.0",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/HrhD5R5x/MgAVFeM9SJelrhbDUuu52lX2TgP2mdsCgeYZCfNbj7ymCrQrydbxKZpC9Lh/AtyqlFtmXgHGfUvxpXbH/JO/vMqNQImDIIej7gdJq4dBunjbMxpGi9L7qB+3aVBAXI+rlxqToaFoTl6s2Xj6prrIlRBh160mWyARtz0yT20jzrEqITq9cydtyUGskFjquVblFwRHxWgfkiQDcq8G7jU212zyFm9z4knnNNXOIUUVZ99+hU3rlMzmgssImJhgG5xGIUEl7TPa86OVpN3RLE+iXC/pf/EEWwYQoHT7qftoKpq1LC0PJKkfzKxb2iadVxwTBDZyLJqt8WHwIDAQAB",
"content_scripts": [
Expand Down
2 changes: 1 addition & 1 deletion scripts/ci/test-known-issues.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
- The TEST backend currently rejects requests from browsers (CORS). Known issue, being fixed on the backend side.
- None known at the moment.
Binary file added store/listing/01-title-card-1280x800.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added store/listing/02-panel-sign-in-1280x800.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading