Skip to content

Commit b0e0e7c

Browse files
committed
Return to a more standard credentials check.
1 parent bdc6cde commit b0e0e7c

2 files changed

Lines changed: 12 additions & 45 deletions

File tree

src/services/ramp.ts

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import { randomUUID } from 'node:crypto';
1616
import type { Browser, BrowserContext, Response } from 'playwright';
17-
import { ApiCredentials, ApiCredentialStatus, OAuthCredentials } from '../apiCredentials/base.js';
17+
import { ApiCredentials, OAuthCredentials } from '../apiCredentials/base.js';
1818
import {
1919
exchangeCodeForTokens,
2020
generateCodeChallenge,
@@ -193,10 +193,18 @@ export class Ramp extends Service {
193193
'Ramp agent-tools API; the REST API is not supported. ' +
194194
'Docs: https://api.ramp.com/v1/public/agent-tools/spec/.';
195195

196-
// Unused: browser-login credentials are validated by holding/refreshing a live
197-
// token (see checkApiCredentials), not by hitting a resource endpoint. Only present
198-
// because the base class declares it abstract.
196+
// Validate credentials against `search-help-center-snippets`: the one agent-tools
197+
// endpoint that requires only a valid token and no specific scope (`security:
198+
// [{oauth2: []}]` in the spec), so the check works regardless of which scopes the
199+
// signed-in user's agent key was granted. It's a POST taking a required
200+
// {query, rationale} body; a bad token returns a non-200 (404 DEVELOPER_7002).
199201
readonly credentialCheckCurlArguments = [
202+
'-X',
203+
'POST',
204+
'-H',
205+
'Content-Type: application/json',
206+
'-d',
207+
'{"query":"ping","rationale":"latchkey credential check"}',
200208
'https://api.ramp.com/developer/v1/agent-tools/search-help-center-snippets',
201209
] as const;
202210

@@ -243,28 +251,6 @@ export class Ramp extends Service {
243251
)
244252
);
245253
}
246-
247-
/**
248-
* Validate credentials by confirming a live token is held (refreshing first if
249-
* expired) rather than by hitting a resource endpoint -- Ramp has no scope-free
250-
* endpoint, so a resource check would force the user to grant a particular scope.
251-
*/
252-
override async checkApiCredentials(apiCredentials: ApiCredentials): Promise<ApiCredentialStatus> {
253-
if (!(apiCredentials instanceof OAuthCredentials)) {
254-
return ApiCredentialStatus.Missing;
255-
}
256-
let credentials: OAuthCredentials | null = apiCredentials;
257-
if (credentials.isExpired() === true) {
258-
const refreshed = await this.refreshCredentials(apiCredentials);
259-
credentials = refreshed instanceof OAuthCredentials ? refreshed : null;
260-
}
261-
if (credentials?.accessToken === undefined) {
262-
return ApiCredentialStatus.Invalid;
263-
}
264-
return credentials.isExpired() === true
265-
? ApiCredentialStatus.Invalid
266-
: ApiCredentialStatus.Valid;
267-
}
268254
}
269255

270256
export const RAMP = new Ramp();

tests/ramp-session.test.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import { describe, it, expect } from 'vitest';
1111
import { RAMP } from '../src/services/ramp.js';
1212
import { AuthorizationBearer, OAuthCredentials } from '../src/apiCredentials/base.js';
13-
import { ApiCredentialStatus } from '../src/apiCredentials/base.js';
1413
import { ServiceSession } from '../src/services/core/base.js';
1514

1615
const FUTURE = new Date(Date.now() + 60 * 60 * 1000).toISOString();
@@ -48,21 +47,3 @@ describe('Ramp.refreshCredentials with OAuth (browser-login) credentials', () =>
4847
expect(await RAMP.refreshCredentials(new AuthorizationBearer('tok'))).toBeNull();
4948
});
5049
});
51-
52-
describe('Ramp.checkApiCredentials with OAuth (browser-login) credentials', () => {
53-
it('reports Valid when a live (unexpired) access token is held', async () => {
54-
const creds = new OAuthCredentials('ramp_id_test', '', 'access-token', 'refresh-token', FUTURE);
55-
expect(await RAMP.checkApiCredentials(creds)).toBe(ApiCredentialStatus.Valid);
56-
});
57-
58-
it('reports Invalid when there is no access token and no way to obtain one', async () => {
59-
const creds = new OAuthCredentials('ramp_id_test', '', undefined, undefined, undefined);
60-
expect(await RAMP.checkApiCredentials(creds)).toBe(ApiCredentialStatus.Invalid);
61-
});
62-
63-
it('reports Missing for unrelated credential types', async () => {
64-
expect(await RAMP.checkApiCredentials(new AuthorizationBearer('tok'))).toBe(
65-
ApiCredentialStatus.Missing
66-
);
67-
});
68-
});

0 commit comments

Comments
 (0)