Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 23x 23x 23x 23x 23x 23x 23x 23x 15x 15x 15x 30x 15x 15x 15x 30x 28x 28x 15x 15x 15x 15x 1x 15x 1x 1x 15x | /**
* Connection check for the settings page: the account, whether GitLab answers, the
* restrictions in effect, and what to do about problems. It reports no token and no
* other user's data.
*/
import { GITLAB_BASE_URL } from '../../config';
import { currentCaller, getConfigurationService, resolveCaller } from '../../configuration';
import { listedToolSchema, scopeLabel } from '../../configuration/policy';
import { getTokenContext } from '../../oauth/token-context';
import { isToolAvailableForScopes } from '../../services/TokenScopeDetector';
import { executeWhoami } from './whoami';
export interface ConnectionCheck {
account: string;
instance: string;
gitlabVersion: string;
tier: string;
/** Whether GitLab identified the account with the current credentials. */
authenticated: boolean;
/**
* Whether GitLab answered the account lookup. When it did not, `authenticated` is false
* without the credentials having been refused.
*/
reachable: boolean;
readOnly: boolean;
preset: string | null;
scope: string | null;
availableTools: number;
warnings: string[];
recommendations: string[];
}
export const CONNECTION_CHECK_OUTPUT_SCHEMA = {
type: 'object' as const,
properties: {
account: { type: 'string' },
instance: { type: 'string' },
gitlabVersion: { type: 'string' },
tier: { type: 'string' },
authenticated: { type: 'boolean' },
reachable: { type: 'boolean' },
readOnly: { type: 'boolean' },
preset: { type: ['string', 'null'] },
scope: { type: ['string', 'null'] },
availableTools: { type: 'number' },
warnings: { type: 'array', items: { type: 'string' } },
recommendations: { type: 'array', items: { type: 'string' } },
},
required: [
'account',
'instance',
'gitlabVersion',
'tier',
'authenticated',
'reachable',
'readOnly',
'preset',
'scope',
'availableTools',
'warnings',
'recommendations',
],
additionalProperties: false,
};
export async function checkConnection(): Promise<ConnectionCheck> {
const caller = currentCaller() ?? resolveCaller(undefined, GITLAB_BASE_URL);
const [whoami, resolved] = await Promise.all([
executeWhoami(),
getConfigurationService().resolve(caller),
]);
const scope = resolved.policy.scope;
// What this caller can call, as tools/list shows it: the instance's tools narrowed by
// the OAuth token's scopes and by the caller's own settings, including a tool left
// without any action the preset allows.
const { RegistryManager } = await import('../../registry-manager');
const registry = RegistryManager.getInstance();
const tokenScopes = getTokenContext()?.gitlabScopes;
const availableTools = registry.getAvailableToolNames(caller.instanceUrl).filter((name) => {
if (tokenScopes !== undefined && !isToolAvailableForScopes(name, tokenScopes)) return false;
const tool = registry.getTool(name, caller.instanceUrl);
return (
tool !== null &&
listedToolSchema(resolved.policy, registry.getToolFacts(name), tool.inputSchema) !== undefined
);
}).length;
const warnings = [...whoami.warnings];
const recommendations = whoami.recommendations.map((r) => r.message);
// This check runs also while GitLab is marked unreachable: an outage is not a refused sign-in.
const reachable = whoami.userLookup !== 'failed';
if (!reachable)
warnings.push(
'GitLab did not answer the account lookup, so the sign-in could not be checked; try again in a moment.',
);
if (resolved.presetUnavailable) {
warnings.push(
`The saved preset '${resolved.presetUnavailable}' no longer exists on this server; tools that change GitLab are off until another preset is chosen.`,
);
recommendations.push('Choose another preset in the GitLab settings, or with update_settings.');
}
return {
account: whoami.user?.username ?? caller.accountLabel,
instance: whoami.server.apiUrl,
gitlabVersion: whoami.server.version,
tier: whoami.server.tier,
authenticated: whoami.user !== null,
reachable,
readOnly: whoami.server.readOnlyMode || resolved.policy.readOnly,
preset: resolved.policy.presetName ?? null,
scope: scopeLabel(scope) ?? null,
availableTools,
warnings,
recommendations,
};
}
|