cli icon indicating copy to clipboard operation
cli copied to clipboard

wire up identity client to current identity callsites

Open alexanderMontague opened this issue 1 month ago β€’ 4 comments

WHY are these changes introduced?

Part of: https://github.com/shop/issues-develop/issues/21594

  • We're swapping the current codepaths that call bespoke identity modules to instead use the client
  • This allows for easy environment configuration

WHAT is this pull request doing?

  • Simply replace the callsites

alexanderMontague avatar Nov 19 '25 22:11 alexanderMontague

[!WARNING] This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite. Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

alexanderMontague avatar Nov 19 '25 22:11 alexanderMontague

Coverage report

St.:grey_question:
Category Percentage Covered / Total
🟑 Statements
78.67% (+0.02% πŸ”Ό)
13621/17313
🟑 Branches
72.71% (+0.02% πŸ”Ό)
6643/9136
🟑 Functions
78.99% (+0.02% πŸ”Ό)
3512/4446
🟑 Lines
79.01% (+0.02% πŸ”Ό)
12866/16285
Show files with reduced coverage πŸ”»
St.:grey_question:
File Statements Branches Functions Lines
🟒
... / session.ts
90.91% (-0.2% πŸ”»)
79% 92.31%
90.32% (-0.23% πŸ”»)
🟑
... / exchange.ts
73.33% (-13.33% πŸ”»)
70.37% (-7.41% πŸ”»)
84.62% (-7.69% πŸ”»)
74.14% (-12.07% πŸ”»)

Test suite run success

3364 tests passing in 1378 suites.

Report generated by πŸ§ͺjest coverage report action from 9caadf8f0c85e89e832b56ca39b1b54406b57115

github-actions[bot] avatar Nov 20 '25 19:11 github-actions[bot]

We detected some changes at packages/*/src and there are no updates in the .changeset. If the changes are user-facing, run pnpm changeset add to track your changes and include them in the next release CHANGELOG.

[!CAUTION] DO NOT create changesets for features which you do not wish to be included in the public changelog of the next CLI release.

github-actions[bot] avatar Nov 20 '25 22:11 github-actions[bot]

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

packages/cli-kit/dist/private/node/clients/identity/identity-client.d.ts
import { IdentityToken } from '../../session/schema.js';
import { TokenRequestResult } from '../../session/exchange.js';
import { API } from '../../api.js';
import { Result } from '../../../../public/node/result.js';
export declare abstract class IdentityClient {
    abstract requestAccessToken(scopes: string[]): Promise<IdentityToken>;
    abstract tokenRequest(params: {
        [key: string]: string;
    }): Promise<Result<TokenRequestResult, {
        error: string;
        store?: string;
    }>>;
    abstract refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken>;
    abstract clientId(): string;
    applicationId(api: API): string;
}

packages/cli-kit/dist/private/node/clients/identity/identity-mock-client.d.ts
import { IdentityClient } from './identity-client.js';
import { ApplicationToken, IdentityToken } from '../../session/schema.js';
import { ExchangeScopes, TokenRequestResult } from '../../session/exchange.js';
import { Result } from '../../../../public/node/result.js';
export declare class IdentityMockClient extends IdentityClient {
    private readonly mockUserId;
    private readonly authTokenPrefix;
    requestAccessToken(_scopes: string[]): Promise<IdentityToken>;
    exchangeAccessForApplicationTokens(_identityToken: IdentityToken, _scopes: ExchangeScopes, _store?: string): Promise<{
        [x: string]: ApplicationToken;
    }>;
    tokenRequest(params: {
        [key: string]: string;
    }): Promise<Result<TokenRequestResult, {
        error: string;
        store?: string;
    }>>;
    refreshAccessToken(_currentToken: IdentityToken): Promise<IdentityToken>;
    clientId(): string;
    private readonly generateTokens;
    private getFutureDate;
    private getCurrentUnixTimestamp;
    private encodeTokenPayload;
}

packages/cli-kit/dist/private/node/clients/identity/identity-service-client.d.ts
import { IdentityClient } from './identity-client.js';
import { IdentityToken } from '../../session/schema.js';
import { TokenRequestResult } from '../../session/exchange.js';
import { Result } from '../../../../public/node/result.js';
export declare class IdentityServiceClient extends IdentityClient {
    requestAccessToken(scopes: string[]): Promise<IdentityToken>;
    tokenRequest(params: {
        [key: string]: string;
    }): Promise<Result<TokenRequestResult, {
        error: string;
        store?: string;
    }>>;
    refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken>;
    clientId(): string;
    /**
     * ========================
     * Private Instance Methods
     * ========================
     */
    /**
     * Initiate a device authorization flow.
     * This will return a DeviceAuthorizationResponse containing the URL where user
     * should go to authorize the device without the need of a callback to the CLI.
     *
     * Also returns a `deviceCode` used for polling the token endpoint in the next step.
     *
     * @param scopes - The scopes to request
     * @returns An object with the device authorization response.
     */
    private requestDeviceAuthorization;
    /**
     * Poll the Oauth token endpoint with the device code obtained from a DeviceAuthorizationResponse.
     * The endpoint will return `authorization_pending` until the user completes the auth flow in the browser.
     * Once the user completes the auth flow, the endpoint will return the identity token.
     *
     * Timeout for the polling is defined by the server and is around 600 seconds.
     *
     * @param code - The device code obtained after starting a device identity flow
     * @param interval - The interval to poll the token endpoint
     * @returns The identity token
     */
    private pollForDeviceAuthorization;
}

packages/cli-kit/dist/private/node/clients/identity/instance.d.ts
import { IdentityClient } from './identity-client.js';
export declare function getIdentityClient(): IdentityClient;

Existing type declarations

packages/cli-kit/dist/private/node/session/device-authorization.d.ts
@@ -1,4 +1,5 @@
 import { IdentityToken } from './schema.js';
+import { Response } from 'node-fetch';
 export interface DeviceAuthorizationResponse {
     deviceCode: string;
     userCode: string;
@@ -29,4 +30,17 @@ export declare function requestDeviceAuthorization(scopes: string[]): Promise<De
  * @param interval - The interval to poll the token endpoint
  * @returns The identity token
  */
-export declare function pollForDeviceAuthorization(code: string, interval?: number): Promise<IdentityToken>;
\ No newline at end of file
+export declare function pollForDeviceAuthorization(code: string, interval?: number): Promise<IdentityToken>;
+export declare function convertRequestToParams(queryParams: {
+    client_id: string;
+    scope: string;
+}): string;
+/**
+ * Build a detailed error message for JSON parsing failures from the authorization service.
+ * Provides context-specific error messages based on response status and content.
+ *
+ * @param response - The HTTP response object
+ * @param responseText - The raw response body text
+ * @returns Detailed error message about the failure
+ */
+export declare function buildAuthorizationParseErrorMessage(response: Response, responseText: string): string;
\ No newline at end of file

packages/cli-kit/dist/private/node/session/exchange.d.ts
@@ -1,7 +1,7 @@
 import { ApplicationToken, IdentityToken } from './schema.js';
 import { API } from '../api.js';
 import { Result } from '../../../public/node/result.js';
-import { ExtendableError } from '../../../public/node/error.js';
+import { AbortError, ExtendableError } from '../../../public/node/error.js';
 export declare class InvalidGrantError extends ExtendableError {
 }
 export declare class InvalidRequestError extends ExtendableError {
@@ -65,4 +65,16 @@ export declare function exchangeDeviceCodeForAccessToken(deviceCode: string): Pr
 export declare function requestAppToken(api: API, token: string, scopes?: string[], store?: string): Promise<{
     [x: string]: ApplicationToken;
 }>;
+export interface TokenRequestResult {
+    access_token: string;
+    expires_in: number;
+    refresh_token: string;
+    scope: string;
+    id_token?: string;
+}
+export declare function tokenRequestErrorHandler({ error, store }: {
+    error: string;
+    store?: string;
+}): AbortError | InvalidGrantError | InvalidRequestError;
+export declare function buildIdentityToken(result: TokenRequestResult, existingUserId?: string, existingAlias?: string): IdentityToken;
 export {};
\ No newline at end of file

packages/cli-kit/dist/private/node/session/identity.d.ts
@@ -1,3 +1,2 @@
 import { API } from '../api.js';
-export declare function clientId(): string;
 export declare function applicationId(api: API): string;
\ No newline at end of file

packages/cli-kit/dist/public/node/vendor/dev_server/dev-server-2024.d.ts
@@ -4,6 +4,7 @@ export declare function createServer(projectName: string): {
     url: (options?: HostOptions) => string;
 };
 declare function assertRunning2024(projectName: string): void;
+export declare function isRunning2024(projectName: string): boolean;
 declare let assertRunningOverride: typeof assertRunning2024 | undefined;
 export declare function setAssertRunning(override: typeof assertRunningOverride): void;
 export {};
\ No newline at end of file

github-actions[bot] avatar Nov 20 '25 22:11 github-actions[bot]