Skip to content

Commit d523ff3

Browse files
committed
fix: validate repository URL paths
1 parent e8b9af6 commit d523ff3

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

packages/billing/src/__tests__/org-billing.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,15 @@ describe('Organization Billing', () => {
190190
expect(result.error).toBeUndefined()
191191
})
192192

193+
it('should validate and normalize SSH URLs', () => {
194+
const result = validateAndNormalizeRepositoryUrl(
195+
'git@github.com:user/repo.git',
196+
)
197+
expect(result.isValid).toBe(true)
198+
expect(result.normalizedUrl).toBe('https://github.com/user/repo')
199+
expect(result.error).toBeUndefined()
200+
})
201+
193202
it('should reject invalid domains', () => {
194203
const result = validateAndNormalizeRepositoryUrl(
195204
'https://example.com/user/repo',
@@ -204,6 +213,12 @@ describe('Organization Billing', () => {
204213
expect(result.error).toBe('Repository domain not allowed')
205214
})
206215

216+
it('should reject URLs without owner and repo path segments', () => {
217+
const result = validateAndNormalizeRepositoryUrl('https://github.com')
218+
expect(result.isValid).toBe(false)
219+
expect(result.error).toBe('Repository path must include owner and repo')
220+
})
221+
207222
it('should accept allowed domains', () => {
208223
const domains = ['github.com', 'gitlab.com', 'bitbucket.org']
209224

packages/billing/src/org-billing.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -498,17 +498,25 @@ export function validateAndNormalizeRepositoryUrl(url: string): {
498498
error?: string
499499
} {
500500
try {
501-
// Basic URL validation
502-
const urlObj = new URL(url.startsWith('http') ? url : `https://${url}`)
501+
const normalized = normalizeRepositoryUrl(url)
502+
const urlObj = new URL(normalized)
503503

504504
// Whitelist allowed domains
505505
const allowedDomains = ['github.com', 'gitlab.com', 'bitbucket.org']
506506
if (!allowedDomains.includes(urlObj.hostname)) {
507507
return { isValid: false, error: 'Repository domain not allowed' }
508508
}
509509

510-
// Normalize URL format
511-
const normalized = normalizeRepositoryUrl(url)
510+
const pathSegments = urlObj.pathname
511+
.split('/')
512+
.filter((segment) => segment.length > 0)
513+
514+
if (pathSegments.length < 2) {
515+
return {
516+
isValid: false,
517+
error: 'Repository path must include owner and repo',
518+
}
519+
}
512520

513521
return { isValid: true, normalizedUrl: normalized }
514522
} catch (error) {

0 commit comments

Comments
 (0)