mirror of
https://github.com/davidkaya/aryx.git
synced 2026-07-24 05:28:46 +02:00
Use provider-aware OAuth handling instead of a single hardcoded client ID. GitHub now follows VS Code's GitHub auth setup with the GitHub client ID, GitHub authorize/token endpoints, prompt=select_account, vscode.dev/redirect, and JSON-compatible token exchange. Entra keeps the Copilot client ID via a known provider match, while unknown providers still fall back to metadata and dynamic registration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
import { describe, expect, mock, test } from 'bun:test';
|
|
|
|
mock.module('electron', () => {
|
|
const electronMock = {
|
|
shell: {
|
|
openExternal: async () => undefined,
|
|
},
|
|
};
|
|
|
|
return {
|
|
...electronMock,
|
|
default: electronMock,
|
|
};
|
|
});
|
|
|
|
const {
|
|
buildScopes,
|
|
parseTokenResponseBody,
|
|
resolveKnownProvider,
|
|
} = await import('@main/services/mcpOAuthService');
|
|
|
|
describe('resolveKnownProvider', () => {
|
|
test('matches GitHub OAuth provider', () => {
|
|
const provider = resolveKnownProvider('https://github.com/login/oauth');
|
|
|
|
expect(provider?.id).toBe('github');
|
|
expect(provider?.clientId).toBe('01ab8ac9400c4e429b23');
|
|
expect(provider?.authorizationEndpoint).toBe('https://github.com/login/oauth/authorize');
|
|
expect(provider?.tokenEndpoint).toBe('https://github.com/login/oauth/access_token');
|
|
expect(provider?.authorizationParams).toEqual({ prompt: 'select_account' });
|
|
});
|
|
|
|
test('matches Entra OAuth provider', () => {
|
|
const provider = resolveKnownProvider('https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47/v2.0');
|
|
|
|
expect(provider?.id).toBe('entra');
|
|
expect(provider?.clientId).toBe('aebc6443-996d-45c2-90f0-388ff96faa56');
|
|
expect(provider?.authorizationEndpoint).toBeUndefined();
|
|
expect(provider?.tokenEndpoint).toBeUndefined();
|
|
});
|
|
|
|
test('returns undefined for unknown provider', () => {
|
|
expect(resolveKnownProvider('https://auth.example.com')).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('buildScopes', () => {
|
|
test('uses provider-specific GitHub scopes without offline access', () => {
|
|
const provider = resolveKnownProvider('https://github.com/login/oauth');
|
|
|
|
expect(buildScopes(provider, ['ignored'], ['also-ignored']))
|
|
.toBe('codespace gist notifications project read:org read:packages read:project read:user repo user:email workflow write:packages');
|
|
});
|
|
|
|
test('uses protected resource scopes for Entra and appends offline access', () => {
|
|
const provider = resolveKnownProvider('https://login.microsoftonline.com/common/v2.0');
|
|
|
|
expect(buildScopes(provider, ['api://icmmcpapi-prod/mcp.tools'], ['openid']))
|
|
.toBe('api://icmmcpapi-prod/mcp.tools offline_access');
|
|
});
|
|
|
|
test('falls back to auth server scopes for unknown providers', () => {
|
|
expect(buildScopes(undefined, undefined, ['openid', 'profile']))
|
|
.toBe('openid profile offline_access');
|
|
});
|
|
});
|
|
|
|
describe('parseTokenResponseBody', () => {
|
|
test('parses JSON token responses', () => {
|
|
expect(parseTokenResponseBody('{"access_token":"abc","token_type":"Bearer"}', 'application/json'))
|
|
.toEqual({ access_token: 'abc', token_type: 'Bearer' });
|
|
});
|
|
|
|
test('parses form-encoded token responses', () => {
|
|
expect(parseTokenResponseBody('access_token=abc&scope=repo%20user%3Aemail&token_type=bearer', 'application/x-www-form-urlencoded'))
|
|
.toEqual({ access_token: 'abc', scope: 'repo user:email', token_type: 'bearer' });
|
|
});
|
|
});
|