clearer git permission errors that match the credential type

This commit is contained in:
Jarek Krochmalski committed 2026-09-02 15:52:44 +02:00
1 parent ae754b3140
commit 34ceb74dc1
2 files changed
+62

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
/**
* Pure git error-message helpers, split out of git.ts so they can be unit-tested
* without importing git.ts's heavy deps (db/docker). No I/O here.
*/
/**
* The permission-denied message, tailored to the auth in use (#1509). A token/password
* credential paired with an `git@...` SSH URL is the common trap: git uses the SSH
* transport and never applies the token, so it fails with a public-key error - blaming
* "SSH credentials" then is actively misleading. Point at the real cause instead.
*/
export function permissionDeniedMessage(
authType?: string | null,
url?: string | null
): string {
const isSshUrl = !!url && url.startsWith('git@');
if (authType === 'password') {
if (isSshUrl) {
return 'Permission denied. This credential uses a token, but the repository URL is an SSH URL (git@...). Use an https:// URL for token authentication.';
}
return 'Permission denied. Check your access token and that it has repository access.';
}
if (authType === 'ssh') {
return 'Permission denied. Check your SSH key and that it is authorized for this repository.';
}
return 'Permission denied. Check your credentials.';
}
+35
View File
@@ -0,0 +1,35 @@
import { describe, test, expect } from 'bun:test';
import { permissionDeniedMessage } from '../src/lib/server/git-error';
describe('permissionDeniedMessage (#1509 - auth-aware git error)', () => {
test('token credential on an SSH url points at the URL mismatch, not SSH creds', () => {
const msg = permissionDeniedMessage('password', 'git@github.com:owner/repo.git');
expect(msg).toContain('token');
expect(msg).toContain('https://');
expect(msg).not.toContain('SSH credentials');
});
test('token credential on an https url blames the token, not SSH', () => {
const msg = permissionDeniedMessage('password', 'https://github.com/owner/repo.git');
expect(msg).toContain('token');
expect(msg).not.toContain('SSH');
});
test('ssh credential gets an SSH-key-specific message', () => {
const msg = permissionDeniedMessage('ssh', 'git@github.com:owner/repo.git');
expect(msg).toContain('SSH key');
});
test('unknown/absent auth gets a generic message (no SSH assumption)', () => {
const msg = permissionDeniedMessage(undefined, undefined);
expect(msg).toContain('Permission denied');
expect(msg).not.toContain('SSH');
expect(msg).not.toContain('token');
});
test('token with no url still blames the token (not SSH)', () => {
const msg = permissionDeniedMessage('password', null);
expect(msg).toContain('token');
expect(msg).not.toContain('SSH URL');
});
});