Skip to content

Prepare original Sheets add-on for OAuth verification - #19

Merged
karlwaldman merged 2 commits into
mainfrom
codex/original-addon-verification
Jul 29, 2026
Merged

Prepare original Sheets add-on for OAuth verification#19
karlwaldman merged 2 commits into
mainfrom
codex/original-addon-verification

Conversation

@karlwaldman

@karlwaldman karlwaldman commented Jul 29, 2026

Copy link
Copy Markdown
Member

Why

Google OAuth review requires accurate in-product disclosure, narrow scope justification, a matching public privacy policy, and a working deletion path before the original add-on can be approved.

What changed

  • add a prominent sidebar disclosure for current-spreadsheet access and OilPriceAPI transfers
  • link privacy, terms, and Google's Limited Use policy from the in-product UI
  • clear the stored request diagnostic when the user deletes the API key
  • bump the runtime package to 1.2.1
  • add red-green regression coverage for disclosure links and deletion

Verification

oilpriceapi-google-sheets-addin@1.2.1 validate
npm run portfolio:build && node test/validate_code.js && node --test test/runtime.test.js test/public-claims.test.js test/portfolio.test.js && node scripts/verify-deploy-package.js && node scripts/verify-marketplace-assets.js && node scripts/verify-portfolio.js && ./scripts/scan-secrets.sh

oilpriceapi-google-sheets-addin@1.2.1 portfolio:build
node scripts/build-portfolio.js

Built 5 distinct Apps Script release packages.
Apps Script structure and bindings: valid
✔ all five builds compile and expose unique product identities (3.237125ms)
✔ crack-spread math covers 3-2-1 and 2-1-1 conventions (0.540667ms)
✔ bunker voyage model calculates tonnes, blend, and total cost (0.410292ms)
✔ fuel surcharge schedule never produces a negative surcharge (0.357125ms)
✔ curve parser rejects incomplete data and labels structure (0.780292ms)
✔ gas spread normalization makes currency and energy conversion explicit (0.34875ms)
✔ API requests carry measurable product identity without sheet contents (0.612667ms)
✔ reviewed market catalogs and first-party URL boundary are enforced (0.416917ms)
✔ public surfaces identify Marketplace status and canonical facts (1.285ms)
✔ Marketplace listing gives Google Sheets trademark attribution (0.150208ms)
✔ sidebar gives an in-product privacy notice and policy links (0.159667ms)
✔ public surfaces contain no unsupported mutable claims (0.713041ms)
✔ credential lifecycle never returns the stored key (1.730584ms)
✔ spreadsheet-scoped key survives the custom-function user identity boundary (1.409375ms)
✔ legacy user-property key remains readable until it is saved per spreadsheet (0.888417ms)
✔ OILPRICE rejects a missing key with a recovery action (0.507875ms)
✔ OILPRICE maps HTTP 401 to actionable recovery (0.399458ms)
✔ OILPRICE maps HTTP 403 to actionable recovery (0.32975ms)
✔ OILPRICE maps HTTP 429 to actionable recovery (0.302875ms)
✔ OILPRICE maps Apps Script fetch failures to timeout recovery (0.423666ms)
✔ OILPRICE rejects malformed JSON and an empty successful response (0.677917ms)
✔ OILPRICE rejects successful records with missing source fields (1.155875ms)
✔ OILPRICE supports the production flat record and caches its source data (0.325125ms)
✔ Excel-equivalent price, status, unit, and info formulas preserve source context (0.411584ms)
✔ OILPRICE_GET and OILPRICE_CODES match the Excel allowlisted table contract (0.885459ms)
✔ OILPRICE_GET rejects unsupported endpoints and credential-shaped query keys before fetch (0.417209ms)
✔ Excel-equivalent formulas return stable worksheet error codes (0.484208ms)
✔ OILPRICE_GET accepts the full reviewed Excel endpoint catalog (6.452917ms)
✔ OILPRICE_GET renders nested futures, diesel, and price-hash responses (0.933958ms)
✔ nested and encoded credential query keys are rejected (0.878708ms)
✔ a stale cache envelope is discarded before formula refresh (0.311459ms)
✔ historical formula retains API timestamps and rejects missing timestamps (1.191166ms)
✔ bunker records preserve the complete source contract (0.340667ms)
✔ bunker records reject empty, malformed, and incomplete successful responses (1.955625ms)
✔ BUNKER_PRICE maps HTTP 401 to actionable recovery (0.260708ms)
✔ BUNKER_PRICE maps HTTP 402 to actionable recovery (0.238667ms)
✔ BUNKER_PRICE maps HTTP 403 to actionable recovery (0.235166ms)
✔ BUNKER_PRICE maps HTTP 429 to actionable recovery (0.231834ms)
✔ BUNKER_PRICE maps Apps Script fetch failures to timeout recovery (0.2385ms)
✔ bunker formulas normalize and encode filters and return source-aware values (0.577959ms)
✔ bunker inputs reject unsupported filter characters before fetch (0.223917ms)
✔ Data Connector sheet writer creates the nine-column source-aware table (0.407583ms)
✔ Data Connector menu flow alerts on success and recovers from empty data (0.512042ms)
✔ batch refresh rejects the documented Apps Script request limit (0.274208ms)
✔ batch refresh writes only validated API metadata (0.286292ms)
✔ reference conversion uses the validated latest record (0.308834ms)
✔ exchange-rate conversion has no fabricated fallback (0.285417ms)
✔ testConnection validates source data instead of accepting any HTTP 200 (0.48425ms)
✔ user info does not invent a tier or request limit (0.263875ms)
ℹ tests 49
ℹ suites 0
ℹ pass 49
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 69.828209
Deployment package verified: Code.gs, Sidebar.html, FetchDialog.html, appsscript.json
Marketplace assets and 1 screenshot(s) have the required formats and dimensions.
Portfolio verified: crack-spread-lab, bunker-voyage-planner, fuel-surcharge-studio, energy-curve-builder, gas-spread-monitor
Secret scan passed (filenames only).

  • 49 tests passed
  • deployment package, Marketplace assets, portfolio packages, and secret scan passed

Release plan

After merge, push this exact runtime to Apps Script, smoke it, create immutable version 10, then update the Marketplace SDK only after the public policy pages are deployed.

Summary by CodeRabbit

  • New Features

    • Added clearer in-product privacy and data-use notices.
    • Added links to the privacy policy, terms, and Google’s Limited Use requirements.
  • Bug Fixes

    • Removing an API key now also clears saved diagnostic information.
    • Updated the confirmation message to reflect the expanded cleanup.
  • Chores

    • Updated the add-on version to 1.2.1.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@karlwaldman, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 56 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4bae35a8-632d-4838-ba00-b56691047a81

📥 Commits

Reviewing files that changed from the base of the PR and between 052ac1f and e0512af.

📒 Files selected for processing (3)
  • DEPLOYMENT_GUIDE.md
  • OAUTH_VERIFICATION.md
  • test/public-claims.test.js
📝 Walkthrough

Walkthrough

The add-on version is updated to 1.2.1. API-key deletion now also removes stored diagnostics, while the sidebar adds expanded data-use disclosures and privacy policy links with corresponding tests.

Changes

Add-on release updates

Layer / File(s) Summary
Credential cleanup and versioning
Code.gs, test/runtime.test.js, package.json
deleteApiKey() clears API keys and last-diagnostic entries from document and user properties; runtime coverage verifies the cleanup, and the package version is updated to 1.2.1.
Privacy notice and policy links
Sidebar.html, test/public-claims.test.js
The sidebar adds scoped data-use disclosures and links to the add-on privacy policy, terms, and Google API Services User Data Policy; tests verify the claims and URLs.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: preparing the Sheets add-on for OAuth verification.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/original-addon-verification

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@karlwaldman
karlwaldman merged commit 799f49f into main Jul 29, 2026
1 of 2 checks passed
@karlwaldman
karlwaldman deleted the codex/original-addon-verification branch July 29, 2026 07:57

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/runtime.test.js (1)

214-224: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover user-property cleanup as well.

This regression test seeds only document properties, while deleteApiKey() also removes the API key and diagnostic from user properties. Add a user-property fixture and assertions so the legacy fallback path is protected.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/runtime.test.js` around lines 214 - 224, Extend the deleteApiKey
regression test around harness.context.deleteApiKey() by seeding OILPRICEAPI_KEY
and OILPRICEAPI_LAST_DIAGNOSTIC in user properties, then assert both
user-property entries are removed. Preserve the existing document-property
fixtures and assertions to cover cleanup in both storage locations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sidebar.html`:
- Around line 169-170: Update the disclosure text near the add-on privacy notice
and its regression test to accurately state that OILPRICE_GET() may send
user-supplied query parameter keys and values to OilPriceAPI, rather than
claiming only reviewed filters are transmitted. Keep the existing API key and
market identifier disclosure intact.

---

Nitpick comments:
In `@test/runtime.test.js`:
- Around line 214-224: Extend the deleteApiKey regression test around
harness.context.deleteApiKey() by seeding OILPRICEAPI_KEY and
OILPRICEAPI_LAST_DIAGNOSTIC in user properties, then assert both user-property
entries are removed. Preserve the existing document-property fixtures and
assertions to cover cleanup in both storage locations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 356d6d98-d70b-442a-917b-08f1e42c27f3

📥 Commits

Reviewing files that changed from the base of the PR and between aac04f7 and 052ac1f.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • Code.gs
  • Sidebar.html
  • package.json
  • test/public-claims.test.js
  • test/runtime.test.js

Comment thread Sidebar.html
Comment on lines +169 to +170
This add-on works only in the spreadsheet where you open it. It sends only your API key and requested market identifiers to OilPriceAPI, plus reviewed filters needed for the selected endpoint. It does not request broad Google Drive access or use your Google email or profile.
Marketplace publication is pending.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Correct the data-sharing disclosure or restrict query parameters.

OILPRICE_GET() forwards arbitrary non-sensitive query keys and values; normalizeApiQuery_() does not allowlist endpoint-specific filters. Therefore users can send additional data beyond “reviewed filters,” contradicting this OAuth disclosure. Either enforce endpoint-specific query allowlists or update the notice and its regression test to describe user-supplied query parameters accurately.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sidebar.html` around lines 169 - 170, Update the disclosure text near the
add-on privacy notice and its regression test to accurately state that
OILPRICE_GET() may send user-supplied query parameter keys and values to
OilPriceAPI, rather than claiming only reviewed filters are transmitted. Keep
the existing API key and market identifier disclosure intact.

karlwaldman added a commit that referenced this pull request Aug 1, 2026
…ck claim (#26)

* docs: record v11/1.2.2 as release candidate and correct the review-lock claim

Two corrections, both verified against the live Google console and the Apps
Script project on 2026-07-31.

1. Version 11 supersedes version 10.

PR #22 (custom-function credential fix) merged 2026-07-29 22:01 UTC -- after
version 10 was cut -- and changed Code.gs and Sidebar.html. Immutable version
11 was cut the same minute (18:01 EDT, the same instant in local time) and
carries runtime 1.2.2; its Code.gs reads ADDON_VERSION = '1.2.2'.

The Marketplace draft is still pinned to version 9, which was cut 2026-07-28
and predates BOTH #19 (OAuth verification prep) and #22. Version 11 is the
release candidate and the docs now say so in every forward-looking place.

2. App Configuration is NOT locked during review.

DEPLOYMENT_GUIDE.md and OAUTH_VERIFICATION.md both asserted the Marketplace
App Configuration locks while Google reviews the draft. DOM inspection of the
Cloud console disproves it: every input reports disabled:false, readOnly:false,
no aria-disabled, and the Version field is a free-text input currently holding
9. Only the Store Listing tab locks ("The draft is in review and can't be
edited").

That wrong assumption nearly drove an unnecessary cancel-and-recut of a
submission that only ever needed a version repin.

Nothing has been published; there is no live listing.

test/public-claims.test.js is updated to pin 1.2.2/v11 and now also guards
both corrections, so neither can silently regress.

Verified: npm run validate passes -- 54 tests, deployment package, marketplace
assets, portfolio, and secret scan all green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: date the packet July 31 and separate re-verified state from July 29 evidence

Addresses CodeRabbit review on #26: the heading claimed 'Status as of July 29'
while the Current Google state block recorded July 31 console verification.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant