Browse Source

fix(formatHost): support basic auth in host URL (#219)

Somprasong Damyos 4 weeks ago
parent
commit
6a4bfe3ab0
2 changed files with 44 additions and 5 deletions
  1. 13 3
      src/utils.ts
  2. 31 2
      test/index.test.ts

+ 13 - 3
src/utils.ts

@@ -1,6 +1,6 @@
-import { version } from './version.js'
+import { defaultHost, defaultPort } from './constant.js'
 import type { ErrorResponse, Fetch } from './interfaces.js'
-import { defaultPort, defaultHost } from './constant.js'
+import { version } from './version.js'
 
 /**
  * An error class for response errors.
@@ -331,7 +331,17 @@ export const formatHost = (host: string): string => {
     }
   }
 
-  let formattedHost = `${url.protocol}//${url.hostname}:${port}${url.pathname}`
+  // Build basic auth part if present
+  let auth = '';
+  if (url.username) {
+    auth = url.username;
+    if (url.password) {
+      auth += `:${url.password}`;
+    }
+    auth += '@';
+  }
+
+  let formattedHost = `${url.protocol}//${auth}${url.hostname}:${port}${url.pathname}`;
   // remove trailing slashes
   if (formattedHost.endsWith('/')) {
     formattedHost = formattedHost.slice(0, -1)

+ 31 - 2
test/index.test.ts

@@ -1,6 +1,6 @@
-import { describe, it, expect } from 'vitest'
-import { formatHost } from '../src/utils'
+import { describe, expect, it } from 'vitest'
 import { defaultHost } from '../src/constant'
+import { formatHost } from '../src/utils'
 
 describe('formatHost Function Tests', () => {
   it('should return default URL for empty string', () => {
@@ -62,4 +62,33 @@ describe('formatHost Function Tests', () => {
   it('should handle trailing slash with only a port', () => {
     expect(formatHost(':56789/')).toBe('http://127.0.0.1:56789')
   })
+
+  // Basic Auth Tests
+  it('should preserve username in URL', () => {
+    expect(formatHost('http://user@localhost:1234')).toBe('http://user@localhost:1234')
+  })
+
+  it('should preserve username and password in URL', () => {
+    expect(formatHost('http://user:pass@localhost:5678')).toBe('http://user:pass@localhost:5678')
+  })
+
+  it('should preserve username with default port', () => {
+    expect(formatHost('http://user@localhost')).toBe('http://user@localhost:80')
+  })
+
+  it('should preserve username and password with default port', () => {
+    expect(formatHost('http://user:pass@localhost')).toBe('http://user:pass@localhost:80')
+  })
+
+  it('should preserve basic auth with https', () => {
+    expect(formatHost('https://user:secret@secure.com')).toBe('https://user:secret@secure.com:443')
+  })
+
+  it('should preserve basic auth with domain and custom port', () => {
+    expect(formatHost('http://admin:1234@example.com:8080')).toBe('http://admin:1234@example.com:8080')
+  })
+
+  it('should preserve basic auth and remove trailing slash', () => {
+    expect(formatHost('http://john:doe@site.com:3000/')).toBe('http://john:doe@site.com:3000')
+  })
 })