Add Step-up rechallenge implementation#2869
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new “step-up / rechallenge” elevated-permissions flow that integrates with the existing Apollo GraphQL client (via a custom ApolloLink), adds an elevated-token cache, and wires the flow into logout. It also adds a new vip defensive-mode CLI command group backed by new defensive-mode GraphQL mutations, along with a broad suite of unit tests around these behaviors.
Changes:
- Add rechallenge (step-up) client, flow orchestration, ApolloLink integration, error types, and elevated-token keychain cache.
- Add defensive-mode GraphQL mutation helpers and new CLI commands (
vip defensive-mode enable|disable|configure). - Add unit tests for rechallenge components, defensive-mode API, logout behavior, and defensive-mode command behavior.
Reviewed changes
Copilot reviewed 22 out of 30 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/token.ts | Switches API host/constants import to avoid pulling full api.ts graph. |
| src/lib/rechallenge/types.ts | Defines rechallenge protocol/types and constants. |
| src/lib/rechallenge/token-cache.ts | Implements keychain-backed elevated-token cache keyed by scope. |
| src/lib/rechallenge/open-browser.ts | Adds wrapper around ESM-only open for browser launching. |
| src/lib/rechallenge/link.ts | Adds ApolloLink that pre-attaches cached elevated token and runs rechallenge on elevated-permission errors. |
| src/lib/rechallenge/index.ts | Exposes rechallenge module exports. |
| src/lib/rechallenge/flow.ts | Implements rechallenge orchestration (session create → poll → exchange → cache). |
| src/lib/rechallenge/errors.ts | Adds typed rechallenge error classes. |
| src/lib/rechallenge/client.ts | Adds HTTP client for rechallenge session/status/exchange endpoints. |
| src/lib/logout.ts | Clears elevated-token cache on logout in addition to primary token purge. |
| src/lib/defensive-mode/api.ts | Adds GraphQL mutations/helpers to update defensive-mode status/config. |
| src/lib/api/http.ts | Switches API_HOST import to new constants module (reduces circular deps). |
| src/lib/api/feature-flags.ts | Lazy-initializes Apollo client to break a circular dependency chain. |
| src/lib/api/constants.ts | Introduces shared API host/URL constants (re-exported by api.ts). |
| src/lib/api.ts | Re-exports constants and injects rechallenge link via lazy require() to avoid Jest mock timing issues. |
| src/bin/vip.js | Registers the new defensive-mode top-level CLI command. |
| src/bin/vip-defensive-mode.js | Adds vip defensive-mode parent command and subcommand wiring. |
| src/bin/vip-defensive-mode-enable.js | Adds vip defensive-mode enable command implementation. |
| src/bin/vip-defensive-mode-disable.js | Adds vip defensive-mode disable command implementation. |
| src/bin/vip-defensive-mode-configure.js | Adds vip defensive-mode configure command implementation with flag validation/prompting. |
| package.json | Adds new vip-defensive-mode* bin entries for distribution. |
| tests/lib/rechallenge/token-cache.test.ts | Unit tests for elevated-token cache behavior and corruption handling. |
| tests/lib/rechallenge/link.test.ts | Unit tests for rechallenge ApolloLink preflight, retry, and error propagation. |
| tests/lib/rechallenge/flow.test.ts | Unit tests for rechallenge flow polling/exchange/caching and interactivity detection. |
| tests/lib/rechallenge/client.test.ts | Unit tests for rechallenge HTTP client request shapes and non-2xx error handling. |
| tests/lib/logout.test.ts | Verifies logout clears both primary token and elevated-token cache + telemetry. |
| tests/lib/defensive-mode/api.test.ts | Verifies defensive-mode mutation input formatting and optional field omission. |
| tests/bin/vip-defensive-mode-enable.js | Tests command registration and enable behavior (including non-interactive production safety). |
| tests/bin/vip-defensive-mode-disable.js | Tests command registration and disable behavior (including non-interactive production safety). |
| tests/bin/vip-defensive-mode-configure.js | Tests configure flag validation, non-interactive behavior, logging, and telemetry. |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
36c8952 to
291ed25
Compare
Also extracts API_HOST/API_URL/PRODUCTION_API_HOST into a leaf constants module and lazy-requires the rechallenge link inside API() to break a circular-dependency cycle that caused Jest mocks to misfire in the rechallenge test suite.
Implements `vip defensive-mode configure` with full flag validation, interactive prompting for missing required flags, and non-interactive hard-error mode.
| super( | ||
| `Step-up verification is required for ${ scope }, but this is a non-interactive session. ` + | ||
| 'Re-run the command interactively, or pass --rechallenge-wait (or set VIP_RECHALLENGE_WAIT=1) ' + | ||
| 'to print the verification URL and wait for you to complete it on another device.', | ||
| scope |
There was a problem hiding this comment.
I am not sure what to do with this one. This is the third reviewer who flags this issue.
I have verified that no other command triggers rechallenge, but I understand why reviews flag this issue.
@rinatkhaziev, what do you think?
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| super( | ||
| `Step-up verification is required for ${ scope }, but this is a non-interactive session. ` + | ||
| 'Re-run the command interactively, or pass --rechallenge-wait (or set VIP_RECHALLENGE_WAIT=1) ' + | ||
| 'to print the verification URL and wait for you to complete it on another device.', | ||
| scope | ||
| ); |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|



Description
This pull request implements step-up rechallenge support end-to-end for elevated-permission operations, and wires it into the shipped CLI experience.
Shipped behavior
vip defensive-modecommand group withenable,disable, andconfiguresubcommands.--rechallenge-wait/VIP_RECHALLENGE_WAIT=1.Test coverage included
Changelog Description
Added
vip defensive-modecommands to enable, disable, and configure defensive mode for an environment.Changed
--rechallenge-waitorVIP_RECHALLENGE_WAIT=1.--skip-confirmation.Fixed
Pull request checklist
New release checklist
Steps to Test
Outline the steps to test and verify the PR here.
Example:
npm run build./dist/bin/vip-cookies.js nom