* Validates a domain's brand.json file
(domain: string, options?: { skipCache?: boolean })
| 135 | * Validates a domain's brand.json file |
| 136 | */ |
| 137 | async validateDomain(domain: string, options?: { skipCache?: boolean }): Promise<BrandValidationResult> { |
| 138 | const normalizedDomain = domain.replace(/^https?:\/\//, '').replace(/\/$/, ''); |
| 139 | const cacheKey = normalizedDomain; |
| 140 | |
| 141 | // Check caches unless explicitly skipped |
| 142 | if (!options?.skipCache) { |
| 143 | // Check successful validation cache first |
| 144 | const cachedValid = this.validationCache.get(cacheKey); |
| 145 | if (cachedValid) { |
| 146 | return cachedValid; |
| 147 | } |
| 148 | |
| 149 | // Check failed lookup cache |
| 150 | const cachedFailed = this.failedLookupCache.get(cacheKey); |
| 151 | if (cachedFailed) { |
| 152 | return cachedFailed; |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | const url = `https://${normalizedDomain}/.well-known/brand.json`; |
| 157 | |
| 158 | const result: BrandValidationResult = { |
| 159 | valid: false, |
| 160 | errors: [], |
| 161 | warnings: [], |
| 162 | domain: normalizedDomain, |
| 163 | url, |
| 164 | }; |
| 165 | |
| 166 | try { |
| 167 | // CodeQL: URL is constructed as https://{domain}/.well-known/brand.json |
| 168 | const response = await axios.get(url, { // lgtm[js/request-forgery] |
| 169 | timeout: 10000, |
| 170 | headers: { |
| 171 | Accept: 'application/json', |
| 172 | 'User-Agent': AAO_UA_VALIDATOR, |
| 173 | }, |
| 174 | validateStatus: () => true, |
| 175 | responseType: 'arraybuffer', |
| 176 | }); |
| 177 | |
| 178 | result.status_code = response.status; |
| 179 | |
| 180 | if (response.status !== 200) { |
| 181 | const statusMessage = |
| 182 | response.status === 404 |
| 183 | ? `File not found at ${url}` |
| 184 | : `HTTP ${response.status} error fetching ${url}`; |
| 185 | result.errors.push({ |
| 186 | field: 'http_status', |
| 187 | message: statusMessage, |
| 188 | severity: 'error', |
| 189 | }); |
| 190 | // Cache failed lookups for 1 hour |
| 191 | this.failedLookupCache.set(cacheKey, result); |
| 192 | return result; |
| 193 | } |
| 194 |
no test coverage detected