(stateDir: string)
| 183 | } |
| 184 | |
| 185 | async function testProviderRestartRotationAndRevocation(stateDir: string): Promise<void> { |
| 186 | const firstProvider = new SingleUserOAuthProvider(oauthConfig, mcpUrl, stateDir); |
| 187 | const client = await firstProvider.clientsStore.registerClient?.({ |
| 188 | redirect_uris: [redirectUri], |
| 189 | client_name: "ChatGPT", |
| 190 | }); |
| 191 | assert.ok(client); |
| 192 | |
| 193 | const code = "code-test-123"; |
| 194 | firstProvider["codes"].set(code, { |
| 195 | clientId: client.client_id, |
| 196 | params: { |
| 197 | redirectUri, |
| 198 | codeChallenge: "challenge", |
| 199 | scopes: ["devspace"], |
| 200 | resource: mcpUrl, |
| 201 | }, |
| 202 | expiresAtMs: Date.now() + 60_000, |
| 203 | }); |
| 204 | const issued = await firstProvider.exchangeAuthorizationCode( |
| 205 | client, |
| 206 | code, |
| 207 | undefined, |
| 208 | redirectUri, |
| 209 | mcpUrl, |
| 210 | ); |
| 211 | assert.ok(issued.refresh_token); |
| 212 | firstProvider.close(); |
| 213 | |
| 214 | const secondProvider = new SingleUserOAuthProvider(oauthConfig, mcpUrl, stateDir); |
| 215 | try { |
| 216 | const verified = await secondProvider.verifyAccessToken(issued.access_token); |
| 217 | assert.equal(verified.clientId, client.client_id); |
| 218 | |
| 219 | const refreshed = await secondProvider.exchangeRefreshToken( |
| 220 | client, |
| 221 | issued.refresh_token, |
| 222 | ["devspace"], |
| 223 | mcpUrl, |
| 224 | ); |
| 225 | assert.ok(refreshed.refresh_token); |
| 226 | assert.notEqual(refreshed.access_token, issued.access_token); |
| 227 | |
| 228 | await assert.rejects( |
| 229 | secondProvider.exchangeRefreshToken(client, issued.refresh_token, ["devspace"], mcpUrl), |
| 230 | InvalidGrantError, |
| 231 | ); |
| 232 | |
| 233 | await secondProvider.revokeToken(client, { token: refreshed.access_token }); |
| 234 | await assert.rejects(secondProvider.verifyAccessToken(refreshed.access_token), InvalidTokenError); |
| 235 | |
| 236 | await secondProvider.revokeToken(client, { token: refreshed.refresh_token }); |
| 237 | await assert.rejects( |
| 238 | secondProvider.exchangeRefreshToken(client, refreshed.refresh_token, ["devspace"], mcpUrl), |
| 239 | InvalidGrantError, |
| 240 | ); |
| 241 | } finally { |
| 242 | secondProvider.close(); |
no test coverage detected