Skip to content

Commit ce1f9ab

Browse files
tsunoyutunetheweb
andauthored
feat: Add custom metric for UCP well-known file parsing (#194)
* feat: Add custom metric for UCP well-known file parsing * chore: trigger CI tests with new test site * Use optional chaining for payment handlers check Co-authored-by: Barry Pollard <barrypollard@google.com> * Change data variable to const Co-authored-by: Barry Pollard <barrypollard@google.com> --------- Co-authored-by: Barry Pollard <barrypollard@google.com>
1 parent 1e9b5f6 commit ce1f9ab

1 file changed

Lines changed: 94 additions & 63 deletions

File tree

dist/well-known.js

Lines changed: 94 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,42 @@
1010

1111
function fetchWithTimeout(url) {
1212
var controller = new AbortController();
13-
setTimeout(() => {controller.abort()}, 5000);
14-
return fetch(url, {signal: controller.signal});
13+
setTimeout(() => { controller.abort() }, 5000);
14+
return fetch(url, { signal: controller.signal });
1515
}
1616

1717
function parseResponse(url, parser) {
1818
return fetchWithTimeout(url)
19-
.then(request => {
20-
let resultObj = {};
21-
if(!request.redirected && request.status === 200) {
22-
resultObj['found'] = true;
23-
if(parser) {
24-
let promise = parser(request);
25-
if (promise) {
26-
return promise
27-
.then(data => {
28-
resultObj['data'] = data;
19+
.then(request => {
20+
let resultObj = {};
21+
if (!request.redirected && request.status === 200) {
22+
resultObj['found'] = true;
23+
if (parser) {
24+
let promise = parser(request);
25+
if (promise) {
26+
return promise
27+
.then(data => {
28+
resultObj['data'] = data;
29+
return [url, resultObj];
30+
})
31+
.catch(error => {
32+
return [url, { 'error': error.message }];
33+
});
34+
} else {
35+
resultObj['error'] = 'parser did not return a promise';
2936
return [url, resultObj];
30-
})
31-
.catch(error => {
32-
return [url, {'error': error.message}];
33-
});
37+
}
3438
} else {
35-
resultObj['error'] = 'parser did not return a promise';
3639
return [url, resultObj];
3740
}
3841
} else {
42+
resultObj['found'] = false;
3943
return [url, resultObj];
4044
}
41-
} else {
42-
resultObj['found'] = false;
43-
return [url, resultObj];
44-
}
45-
})
46-
.catch(error => {
47-
return [url, {'error': error.message}];
48-
});
45+
})
46+
.catch(error => {
47+
return [url, { 'error': error.message }];
48+
});
4949
}
5050

5151
function parseResponseWithRedirects(url, parser) {
@@ -150,58 +150,89 @@ return Promise.all([
150150
// FedCM
151151
parseResponse('/.well-known/web-identity', r => {
152152
return r.text().then(text => {
153-
let result = {
154-
provider_urls: [],
155-
accounts_endpoint: null,
156-
login_url: null
157-
};
158-
try {
159-
let data = JSON.parse(text);
160-
result.provider_urls = Array.isArray(data.provider_urls) && data.provider_urls.length > 0 ? data.provider_urls : [];
161-
result.accounts_endpoint = data.accounts_endpoint || null;
162-
result.login_url = data.login_url || null;
163-
} catch (e) {
164-
// Failed to parse JSON
165-
}
166-
return result;
153+
let result = {
154+
provider_urls: [],
155+
accounts_endpoint: null,
156+
login_url: null
157+
};
158+
try {
159+
let data = JSON.parse(text);
160+
result.provider_urls = Array.isArray(data.provider_urls) && data.provider_urls.length > 0 ? data.provider_urls : [];
161+
result.accounts_endpoint = data.accounts_endpoint || null;
162+
result.login_url = data.login_url || null;
163+
} catch (e) {
164+
// Failed to parse JSON
165+
}
166+
return result;
167167
});
168168
}),
169169
// Passkey
170170
parseResponse('/.well-known/passkey-endpoints', r => {
171171
return r.text().then(text => {
172-
let result = {
173-
enroll: null,
174-
manage: null
175-
};
176-
try {
177-
let data = JSON.parse(text);
178-
result.enroll = data.enroll || null;
179-
result.manage = data.manage || null;
180-
} catch (e) {
181-
// Failed to parse JSON
182-
}
183-
return result;
172+
let result = {
173+
enroll: null,
174+
manage: null
175+
};
176+
try {
177+
let data = JSON.parse(text);
178+
result.enroll = data.enroll || null;
179+
result.manage = data.manage || null;
180+
} catch (e) {
181+
// Failed to parse JSON
182+
}
183+
return result;
184184
});
185185
}),
186186
// Related Origin Requests
187187
parseResponse('/.well-known/webauthn', r => {
188188
return r.text().then(text => {
189-
let result = {
190-
origins: []
191-
};
192-
try {
193-
let data = JSON.parse(text);
194-
result.origins = Array.isArray(data.origins) && data.origins.length > 0 ? data.origins : [];
195-
} catch (e) {
196-
// Failed to parse JSON
189+
let result = {
190+
origins: []
191+
};
192+
try {
193+
let data = JSON.parse(text);
194+
result.origins = Array.isArray(data.origins) && data.origins.length > 0 ? data.origins : [];
195+
} catch (e) {
196+
// Failed to parse JSON
197+
}
198+
return result;
199+
});
200+
}),
201+
// UCP
202+
parseResponse('/.well-known/ucp', r => {
203+
return r.text().then(text => {
204+
let result = {
205+
has_ucp: false,
206+
version: null,
207+
has_payment_handlers: false,
208+
signing_keys_count: 0
209+
};
210+
try {
211+
const data = JSON.parse(text);
212+
if (data.ucp) {
213+
result.has_ucp = true;
214+
result.version = data.ucp.version || null;
215+
216+
if (data.ucp.payment_handlers && Object.keys(data.ucp.payment_handlers).length > 0) {
217+
result.has_payment_handlers = true;
218+
}
197219
}
198-
return result;
220+
if (Array.isArray(data?.payment?.handlers) && data.payment.handlers.length > 0) {
221+
result.has_payment_handlers = true;
222+
}
223+
if (Array.isArray(data.signing_keys)) {
224+
result.signing_keys_count = data.signing_keys.length;
225+
}
226+
} catch (e) {
227+
// Failed to parse JSON
228+
}
229+
return result;
199230
});
200231
}),
201232
// security
202233
parseResponse('/robots.txt', r => {
203234
return r.text().then(text => {
204-
let data = {'matched_disallows': {}};
235+
let data = { 'matched_disallows': {} };
205236
let keywords = [
206237
'login',
207238
'log-in',
@@ -213,7 +244,7 @@ return Promise.all([
213244
'account'
214245
]
215246
let currUserAgent = null;
216-
for(let line of text.split('\n')) {
247+
for (let line of text.split('\n')) {
217248
if (line.toLowerCase().startsWith('user-agent: ')) {
218249
currUserAgent = line.substring(12);
219250
} else if (line.toLowerCase().startsWith('disallow: ')) {
@@ -321,5 +352,5 @@ return Promise.all([
321352
]).then((all_data) => {
322353
return JSON.stringify(Object.fromEntries(all_data));
323354
}).catch(error => {
324-
return JSON.stringify({message: error.message, error: error});
355+
return JSON.stringify({ message: error.message, error: error });
325356
});

0 commit comments

Comments
 (0)