external_refs rework

This commit is contained in:
2026-03-16 11:24:37 -05:00
parent 862c70e2c1
commit 91bd3ba31d
4 changed files with 32 additions and 83 deletions
+7 -1
View File
@@ -3,6 +3,9 @@ An alternative view of issues documented by our favorite firewall vendor.
Feel free to host your own version, or use [the one I host](https://firewallissues.axvig.com/).
Inspired by [Pixi888's](https://www.reddit.com/user/Pixi888/) creation [bugidsearch.com](https://bugidsearch.com/).
## Data updates ##
New versions are easily added using the process.html page
- Copy the issue table's HTML from the webpage using devtools.
- Fill out the process.html page's fields and paste in the table HTML.
@@ -12,5 +15,8 @@ New versions are easily added using the process.html page
There is intentionally no automated scaping, to avoid abuse of server resources. Also releases are not that frequent.
## External references ##
Inspired by [Pixi888's](https://www.reddit.com/user/Pixi888/) creation [bugidsearch.com](https://bugidsearch.com/).
The `external_refs.json` file allows for links to be added to other websites that have information or discussion about certain issues.
I have vague ideas of something similar for CVEs.
+7
View File
@@ -0,0 +1,7 @@
[
{
"id": "PAN-290235",
"url": "https://www.reddit.com/r/paloaltonetworks/comments/1qi7zoy/pan290235_dscd_and_low_quality_control/",
"display": "Reddit"
}
]
-23
View File
@@ -1,23 +0,0 @@
{
"reddit": {
"display": "Reddit",
"entries": [
{
"id": "PAN-290235",
"url": "https://www.reddit.com/r/paloaltonetworks/comments/1qi7zoy/pan290235_dscd_and_low_quality_control/"
}
]
},
"facebook": {
"display": "Facebook",
"entries": []
},
"twitter": {
"display": "Twitter",
"entries": []
},
"other_web": {
"display": "Other Web",
"entries": []
}
}
+18 -59
View File
@@ -17,10 +17,10 @@ const issueFileDataCache = new Map();
const issueFilePromiseCache = new Map();
function loadSocialRefs() {
return fetch('data/social_refs.json')
return fetch('data/external_refs.json')
.then(response => {
if (!response.ok) {
throw new Error(`Failed to load data/social_refs.json (${response.status})`);
throw new Error(`Failed to load data/external_refs.json (${response.status})`);
}
return response.json();
})
@@ -28,7 +28,7 @@ function loadSocialRefs() {
socialRefsByIssueId = normalizeSocialRefs(data);
})
.catch(error => {
console.warn('Social refs unavailable:', error);
console.warn('External refs unavailable:', error);
socialRefsByIssueId = new Map();
});
}
@@ -477,73 +477,32 @@ function getSocialRefsForIssue(issueId) {
function normalizeSocialRefs(data) {
const map = new Map();
if (!data || typeof data !== 'object') {
if (!Array.isArray(data)) {
return map;
}
Object.keys(data).forEach(sourceKey => {
const sourceValue = data[sourceKey];
const entries = getSourceEntries(sourceValue);
const label = getSourceDisplayLabel(sourceKey, sourceValue);
data.forEach(entry => {
if (!entry || typeof entry !== 'object') {
return;
}
entries.forEach(entry => {
if (!entry || typeof entry !== 'object') {
return;
}
const id = String(entry.id || '').trim().toUpperCase();
const url = String(entry.url || '').trim();
const label = String(entry.display || '').trim() || 'Link';
if (!id || !url) {
return;
}
const id = String(entry.id || '').trim().toUpperCase();
const url = String(entry.url || '').trim();
if (!id || !url) {
return;
}
if (!map.has(id)) {
map.set(id, []);
}
if (!map.has(id)) {
map.set(id, []);
}
map.get(id).push({ label, url });
});
map.get(id).push({ label, url });
});
return map;
}
function getSourceEntries(sourceValue) {
if (Array.isArray(sourceValue)) {
return sourceValue;
}
if (sourceValue && typeof sourceValue === 'object' && Array.isArray(sourceValue.entries)) {
return sourceValue.entries;
}
return [];
}
function getSourceDisplayLabel(sourceKey, sourceValue) {
if (sourceValue && typeof sourceValue === 'object' && !Array.isArray(sourceValue)) {
const display = String(sourceValue.display || '').trim();
if (display) {
return display;
}
}
return sourceLabelFromKey(sourceKey);
}
function sourceLabelFromKey(sourceKey) {
const key = String(sourceKey || '').trim().toLowerCase();
if (!key) {
return 'Link';
}
return key
.split(/[_\-\s]+/)
.filter(Boolean)
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
.join(' ');
}
function markdownSummaryToHtml(summaryText, caveatText) {
const input = String(summaryText || '').trim();
const caveat = String(caveatText || '').trim();