Skip to content

Added support for OAuth2 and improved error handling#37

Open
stevenbarash wants to merge 23 commits intomainfrom
feat/oauth-implemented-version-setup-20250917-134909
Open

Added support for OAuth2 and improved error handling#37
stevenbarash wants to merge 23 commits intomainfrom
feat/oauth-implemented-version-setup-20250917-134909

Conversation

@stevenbarash
Copy link

Added

  • OAuth2 (PKCE) login via browser with local HTTP callback.
    • New command: login-oauth (opens browser, handles local callback, exchanges code → tokens).
    • Options:
      • -p, --projectId <projectId> (required)
      • -b, --baseUrl <url> (default https://api.descope.com)
      • -c, --callbackPort <port> (default 8088)
      • -o, --output <session|refresh|json> (default session)
  • New CLI commands (not present on upstream main):
    • validate — validate session token; prints { ok, sub, exp }.
    • validate-and-refresh — validate session; if invalid, refresh with provided refresh token.
  • Test suite (Vitest) covering OAuth flow and CLI commands.
  • Linting and formatting stack (ESLint + @typescript-eslint + Prettier) with scripts to run them.

Changed

  • Existing commands retained and enhanced:
    • login (existed): streamlined to signUpOrIn.email then verify.email; clearer prompts and errors.
    • me (existed upstream or feature-equivalent): standardized to print JSON to stdout and exit with non‑zero on failure.
    • refresh (existed upstream or feature-equivalent): standardized to print the new session JWT to stdout and exit with non‑zero on failure.
  • CLI program refactored for modularity (buildProgram, run) and clearer stdout-focused outputs.
  • README expanded with full command docs (OTP and OAuth), token handling, and examples.
  • Scripts/tooling modernized:
    • test: build then run tests; test:watch.
    • lint: run ESLint (with Prettier integration).
    • start.sh: builds before running the CLI.
  • TypeScript config updated to explicitly include src/**/*.

Removed

  • Legacy helper module replaced by the new modular CLI structure (unifying OTP and OAuth flows).

Security and hardening

  • OAuth flow uses PKCE S256 and state validation to mitigate CSRF/code interception.
  • Scopes limited to openid profile email.
  • Local callback server ensures best-effort cleanup of connections.
  • No token cache on disk; tokens are emitted to stdout only when a command requests them.

Dependency updates

  • Runtime:
    • @descope/node-sdk → 1.7.15
    • commander → 14.0.1
    • node-fetch → 3.3.2
    • rimraf → 6.0.1
    • @types/node → 24.5.1
  • Tooling:
    • typescript → 5.9.2
    • eslint → 9.35.0, @typescript-eslint/* → 8.44.0
    • prettier → 3.6.2, eslint-plugin-prettier → 5.5.4
    • vitest → 1.6.0

Usage (npm)

  • Install: npm install
  • Build: npm run build
  • OTP login: node build/index.js login -p <PROJECT_ID> -e <EMAIL>
  • OAuth login (session): node build/index.js login-oauth -p <PROJECT_ID> -o session
  • OAuth login (refresh): node build/index.js login-oauth -p <PROJECT_ID> -o refresh
  • OAuth login (json): node build/index.js login-oauth -p <PROJECT_ID> -o json
  • Me: node build/index.js me -p <PROJECT_ID> -r <REFRESH_TOKEN>
  • Validate: node build/index.js validate -p <PROJECT_ID> -s <SESSION_JWT>
  • Refresh: node build/index.js refresh -p <PROJECT_ID> -r <REFRESH_TOKEN>
  • Validate and refresh: node build/index.js validate-and-refresh -p <PROJECT_ID> -s <SESSION_JWT> -r <REFRESH_TOKEN>

Notes

  • Upstream main focused on OTP-based CLI and included refresh/me functionality conceptually; this branch adds OAuth PKCE and introduces validate/validate-and-refresh, while standardizing outputs and error handling for existing commands.

rishibhargava and others added 20 commits December 2, 2022 20:59
CLI Authentication sample app
* Add renovate.json

* Update renovate.json

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Omer Cohen <omer@descope.com>
* fixes

* readme
* break into different command parameters

* set specific versions
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…ed clarity on authentication methods, including OTP and OAuth2. Refactor auth logic to remove JWT caching and streamline output options for session and refresh tokens. Improve error handling and user feedback in CLI commands.
…d the CLI structure by consolidating command definitions into a single `buildProgram` function. Added `test:watch` script for improved testing workflow and included new dependencies for coverage support.
…s dependencies in package.json to their latest versions for improved performance and security. Removed obsolete coverage files and scripts to streamline the project structure.
…tion for OAuth2 login command in README. Improved code documentation in `auth.ts` and `index.ts`, including detailed descriptions for functions and parameters. Streamlined the OAuth2 PKCE flow and ensured proper error handling and resource cleanup during authentication.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds OAuth2 authentication with PKCE support and improves error handling for a CLI authentication tool. The changes modernize the codebase with TypeScript, testing infrastructure, and standardized command outputs.

  • OAuth2 PKCE login via browser with local HTTP callback server
  • New CLI commands for token validation, refresh, and user info retrieval
  • Comprehensive test suite and linting/formatting stack

Reviewed Changes

Copilot reviewed 10 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/index.ts Complete rewrite of CLI program with modular structure and new OAuth2/validation commands
src/auth.ts New OAuth2 PKCE implementation with browser integration and local callback server
src/descopeCli.ts Legacy helper module removed
test/cli.test.ts New test suite covering CLI commands with mocked dependencies
test/auth.test.ts New test suite for OAuth2 flow with HTTP server mocking
package.json Updated dependencies and added test/lint scripts
README.md Comprehensive documentation with command examples and usage instructions
.eslintrc.json ESLint configuration for TypeScript
renovate.json Renovate configuration for dependency updates
start.sh Build step added before running CLI

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +67 to +68
if (!res.ok) {
console.log(`Error ${res.error?.errorCode}: ${res.error?.errorDescription}`);
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

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

This error check uses the wrong response object. It should check jwt instead of res since jwt is the response from the verify operation, not res which is from the signUpOrIn operation.

Suggested change
if (!res.ok) {
console.log(`Error ${res.error?.errorCode}: ${res.error?.errorDescription}`);
if (!jwt.ok) {
console.log(`Error ${jwt.error?.errorCode}: ${jwt.error?.errorDescription}`);

Copilot uses AI. Check for mistakes.
import * as os from "os";
import * as path from "path";

const LIVE = false; // remove live-mode test functionality
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

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

This unused constant should be removed since it's not referenced anywhere in the code and the comment suggests it's meant to be removed.

Suggested change
const LIVE = false; // remove live-mode test functionality

Copilot uses AI. Check for mistakes.
Copy link

@gaokevin1 gaokevin1 left a comment

Choose a reason for hiding this comment

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

Overall looks good, just a few minor comments.

exec(`xdg-open "${url}"`);
};

export const descopeOAuthLogin = async (

Choose a reason for hiding this comment

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

Wondering why we don't use a library here, instead of doing all of this manually?

Is there a particular reason we wouldn't use a common OIDC client (based on Node), other than that we should have one ourselves so it's better to show it this way?

Copy link
Author

Choose a reason for hiding this comment

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

Good idea - agreed that a standard library would be better

stevenbarash and others added 2 commits September 25, 2025 12:03
Co-authored-by: Kevin J Gao <32936811+gaokevin1@users.noreply.github.com>
Co-authored-by: Kevin J Gao <32936811+gaokevin1@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.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.

4 participants