diff --git a/src/shared/utils/validation.test.ts b/src/shared/utils/validation.test.ts
index 7fce25e..39fe021 100644
--- a/src/shared/utils/validation.test.ts
+++ b/src/shared/utils/validation.test.ts
@@ -88,10 +88,26 @@ describe('validateUrl', () => {
expect(result).toContain('valid URL')
})
- it('rejects hostname without dot', () => {
- const result = validateUrl('https://localhost')
- // localhost has no dot but is technically valid; our rule catches it
- expect(result).toBe('URL must have a valid hostname')
+ it('accepts localhost (no dot required)', () => {
+ expect(validateUrl('https://localhost')).toBe(true)
+ })
+
+ it('accepts localhost with port', () => {
+ expect(validateUrl('http://localhost:3000')).toBe(true)
+ })
+
+ it('accepts IP address', () => {
+ expect(validateUrl('http://192.168.1.1')).toBe(true)
+ })
+
+ it('rejects javascript: scheme', () => {
+ const result = validateUrl('javascript:alert(1)')
+ expect(result).toContain('http')
+ })
+
+ it('rejects data: scheme', () => {
+ const result = validateUrl('data:text/html,
hi
')
+ expect(result).toContain('http')
})
})
@@ -135,6 +151,18 @@ describe('validateEmail', () => {
it('rejects trailing dot after TLD', () => {
expect(validateEmail('user@example.')).toContain('valid email')
})
+
+ it('rejects double dot in domain', () => {
+ expect(validateEmail('user@example..com')).toContain('valid email')
+ })
+
+ it('accepts subdomain email', () => {
+ expect(validateEmail('user@mail.example.co.uk')).toBe(true)
+ })
+
+ it('rejects missing domain before dot', () => {
+ expect(validateEmail('user@.com')).toContain('valid email')
+ })
})
describe('validateRequired', () => {
diff --git a/src/shared/utils/validation.ts b/src/shared/utils/validation.ts
index 0753f33..0819ab9 100644
--- a/src/shared/utils/validation.ts
+++ b/src/shared/utils/validation.ts
@@ -39,7 +39,7 @@ export function validateUrl(value: string): string | true {
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
return 'URL must start with http:// or https://'
}
- if (!url.hostname.includes('.')) {
+ if (!url.hostname) {
return 'URL must have a valid hostname'
}
return true
@@ -58,7 +58,7 @@ export function validateUrl(value: string): string | true {
export function validateEmail(value: string): string | true {
const trimmed = value.trim()
if (!trimmed) return true
- if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmed)) {
+ if (!/^[^\s@]+@[^\s@.]+(\.[^\s@.]+)+$/.test(trimmed)) {
return 'Please enter a valid email address'
}
return true