Files
deceptifeed/internal/threatfeed/templates/webfeed.html
Ryan Smith 444a446b0f webfeed: format dates and numbers via javascript
This change adjusts the webfeed.html template to return timestamps in ISO 8601 format in UTC and instead uses JavaScript to format and display using the user's local time.

JavaScript is also used to add a thousands seprator to values in the 'Observations' column.

When formatting the 'Added' column, the time is dropped and now displays as YYYY-MM-DD.
2025-04-06 14:55:18 -07:00

139 lines
17 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Deceptifeed</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body class="full-width">
<header>
<nav>
<ul>
<li class="logo">
<a class="logo" href="/" aria-label="Deceptifeed homepage">
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 370 63" fill="none">
<path d="M0.312 49V44.998H7.212V4.702H0.312V0.699997H18.666C24.968 0.699997 29.867 2.31 33.363 5.53C36.905 8.704 38.676 13.672 38.676 20.434V29.335C38.676 36.097 36.905 41.065 33.363 44.239C29.867 47.413 24.968 49 18.666 49H0.312ZM11.628 44.998H18.666C23.726 44.998 27.59 43.779 30.258 41.341C32.926 38.903 34.26 34.97 34.26 29.542V20.227C34.26 14.753 32.926 10.82 30.258 8.428C27.59 5.99 23.726 4.771 18.666 4.771H11.628V44.998ZM60.0735 49.966C56.6235 49.966 53.6105 49.253 51.0345 47.827C48.5045 46.355 46.5265 44.308 45.1005 41.686C43.6745 39.064 42.9615 36.051 42.9615 32.647V31.819C42.9615 28.369 43.6745 25.356 45.1005 22.78C46.5265 20.158 48.4815 18.134 50.9655 16.708C53.4955 15.236 56.3705 14.5 59.5905 14.5C62.7185 14.5 65.4785 15.167 67.8705 16.501C70.3085 17.789 72.2175 19.675 73.5975 22.159C74.9776 24.597 75.6676 27.518 75.6676 30.922V33.13H47.1015C47.2395 37.316 48.5045 40.559 50.8965 42.859C53.3345 45.113 56.3935 46.24 60.0735 46.24C63.2015 46.24 65.6165 45.527 67.3185 44.101C69.0665 42.675 70.4005 40.927 71.3205 38.857L75.0466 40.513C74.3565 42.031 73.3905 43.526 72.1485 44.998C70.9525 46.424 69.3885 47.62 67.4565 48.586C65.5245 49.506 63.0635 49.966 60.0735 49.966ZM47.1705 29.542H71.4585C71.2745 25.908 70.1015 23.125 67.9395 21.193C65.7775 19.215 62.9945 18.226 59.5905 18.226C56.2325 18.226 53.4495 19.215 51.2415 21.193C49.0335 23.125 47.6765 25.908 47.1705 29.542ZM97.0338 49.966C93.7678 49.966 90.8468 49.276 88.2708 47.896C85.7408 46.47 83.7398 44.446 82.2678 41.824C80.7958 39.202 80.0598 36.12 80.0598 32.578V31.888C80.0598 28.3 80.7958 25.218 82.2678 22.642C83.7398 20.02 85.7408 18.019 88.2708 16.639C90.8468 15.213 93.7678 14.5 97.0338 14.5C100.254 14.5 102.968 15.121 105.176 16.363C107.43 17.559 109.178 19.146 110.42 21.124C111.708 23.056 112.513 25.103 112.835 27.265L108.764 28.093C108.534 26.299 107.959 24.666 107.039 23.194C106.119 21.676 104.831 20.48 103.175 19.606C101.519 18.686 99.4718 18.226 97.0338 18.226C94.5958 18.226 92.4108 18.801 90.4788 19.951C88.5468 21.055 87.0058 22.642 85.8558 24.712C84.7518 26.736 84.1998 29.151 84.1998 31.957V32.509C84.1998 35.315 84.7518 37.753 85.8558 39.823C87.0058 41.847 88.5468 43.434 90.4788 44.584C92.4108 45.688 94.5958 46.24 97.0338 46.24C100.714 46.24 103.52 45.297 105.452 43.411C107.384 41.479 108.58 39.133 109.04 36.373L113.111 37.201C112.697 39.363 111.823 41.433 110.489 43.411C109.201 45.343 107.43 46.93 105.176 48.172C102.968 49.368 100.254 49.966 97.0338 49.966ZM134.607 49.966C131.157 49.966 128.144 49.253 125.568 47.827C123.038 46.355 121.06 44.308 119.634 41.686C118.208 39.064 117.495 36.051 117.495 32.647V31.819C117.495 28.369 118.208 25.356 119.634 22.78C121.06 20.158 123.015 18.134 125.499 16.708C128.029 15.236 130.904 14.5 134.124 14.5C137.252 14.5 140.012 15.167 142.404 16.501C144.842 17.789 146.751 19.675 148.131 22.159C149.511 24.597 150.201 27.518 150.201 30.922V33.13H121.635C121.773 37.316 123.038 40.559 125.43 42.859C127.868 45.113 130.927 46.24 134.607 46.24C137.735 46.24 140.15 45.527 141.852 44.101C143.6 42.675 144.934 40.927 145.854 38.857L149.58 40.513C148.89 42.031 147.924 43.526 146.682 44.998C145.486 46.424 143.922 47.62 141.99 48.586C140.058 49.506 137.597 49.966 134.607 49.966ZM121.704 29.542H145.992C145.808 25.908 144.635 23.125 142.473 21.193C140.311 19.215 137.528 18.226 134.124 18.226C130.766 18.226 127.983 19.215 125.775 21.193C123.567 23.125 122.21 25.908 121.704 29.542ZM156.249 62.8V15.466H160.251V21.607H161.079C162.045 19.767 163.54 18.134 165.564 16.708C167.634 15.236 170.509 14.5 174.189 14.5C177.179 14.5 179.893 15.213 182.331 16.639C184.769 18.019 186.701 19.997 188.127 22.573C189.599 25.149 190.335 28.231 190.335 31.819V32.647C190.335 36.189 189.622 39.271 188.196 41.893C186.77 44.469 184.838 46.47 182.4 47.896C179.962 49.276 177.225 49.966 174.189 49.966C171.751 49.966 169.658 49.644 167.91 49C166.208 48.31 164.805 47.436 163.701 46.378C162.643 45.32 161.815 44.239 161.217 43.135H160.389V62.8H156.249ZM173.223 46.24C177.041 46.24 180.123 45.021 182.469 42.583C184.861 40.145 186.057 36.787 186.057 32.509V31.957C186.057 27.679 184.861 24.321 182.469 21.883C180.123 19.445 177.041 18.226 173.223 18.226C169.451 18.226 166.369 19.445 163.977 21.883C161.585 24.321 160.389 27.679 160.389 31.957V32.509C160.389 36.787 161.585 40.145 163.977 42.583C166.369 45.021 169.451 46.24 173.223 46.24ZM207.378 49C205.584 49 204.227 48.54 203.307 47.62C202.433 46.7 201.996 45.412 201.996 43.756V19.192H191.232V15.466H201.996V2.908H206.136V15.466H217.866V19.192H206.136V43.204C206.136 44.584 206.826 45.274 208.206 45.274H216.072V49H207.378ZM222.966 49V15.466H227.106V49H222.966ZM225.036 9.67C224.024 9.67 223.173 9.325 222.483 8.635C221.793 7.945 221.448 7.094 221.448 6.082C221.448 5.024 221.793 4.173 222.483 3.529C223.173 2.839 224.024 2.494 225.036 2.494C226.094 2.494 226.945 2.839 227.589 3.529C228.279 4.173 228.624 5.024 228.624 6.082C228.624 7.094 228.279 7.945 227.589 8.635C226.945 9.325 226.094 9.67 225.036 9.67Z" fill="#FE1133"/>
<path d="M240.488 49V21.952H231.794V14.776H240.488V8.428C240.488 6.082 241.178 4.219 242.558 2.839C243.984 1.413 245.824 0.699997 248.078 0.699997H257.048V7.876H251.114C249.826 7.876 249.182 8.566 249.182 9.946V14.776H258.152V21.952H249.182V49H240.488ZM276.571 49.966C273.167 49.966 270.154 49.253 267.532 47.827C264.956 46.355 262.932 44.308 261.46 41.686C260.034 39.018 259.321 35.89 259.321 32.302V31.474C259.321 27.886 260.034 24.781 261.46 22.159C262.886 19.491 264.887 17.444 267.463 16.018C270.039 14.546 273.029 13.81 276.433 13.81C279.791 13.81 282.712 14.569 285.196 16.087C287.68 17.559 289.612 19.629 290.992 22.297C292.372 24.919 293.062 27.978 293.062 31.474V34.441H268.153C268.245 36.787 269.119 38.696 270.775 40.168C272.431 41.64 274.455 42.376 276.847 42.376C279.285 42.376 281.079 41.847 282.229 40.789C283.379 39.731 284.253 38.558 284.851 37.27L291.958 40.996C291.314 42.192 290.371 43.503 289.129 44.929C287.933 46.309 286.323 47.505 284.299 48.517C282.275 49.483 279.699 49.966 276.571 49.966ZM268.222 27.955H284.23C284.046 25.977 283.241 24.39 281.815 23.194C280.435 21.998 278.618 21.4 276.364 21.4C274.018 21.4 272.155 21.998 270.775 23.194C269.395 24.39 268.544 25.977 268.222 27.955ZM313.634 49.966C310.23 49.966 307.217 49.253 304.595 47.827C302.019 46.355 299.995 44.308 298.523 41.686C297.097 39.018 296.384 35.89 296.384 32.302V31.474C296.384 27.886 297.097 24.781 298.523 22.159C299.949 19.491 301.95 17.444 304.526 16.018C307.102 14.546 310.092 13.81 313.496 13.81C316.854 13.81 319.775 14.569 322.259 16.087C324.743 17.559 326.675 19.629 328.055 22.297C329.435 24.919 330.125 27.978 330.125 31.474V34.441H305.216C305.308 36.787 306.182 38.696 307.838 40.168C309.494 41.64 311.518 42.376 313.91 42.376C316.348 42.376 318.142 41.847 319.292 40.789C320.442 39.731 321.316 38.558 321.914 37.27L329.021 40.996C328.377 42.192 327.434 43.503 326.192 44.929C324.996 46.309 323.386 47.505 321.362 48.517C319.338 49.483 316.762 49.966 313.634 49.966ZM305.285 27.955H321.293C321.109 25.977 320.304 24.39 318.878 23.194C317.498 21.998 315.681 21.4 313.427 21.4C311.081 21.4 309.218 21.998 307.838 23.194C306.458 24.39 305.607 25.977 305.285 27.955ZM348.904 49.966C346.19 49.966 343.637 49.299 341.245 47.965C338.899 46.585 337.013 44.584 335.587 41.962C334.161 39.34 333.448 36.166 333.448 32.44V31.336C333.448 27.61 334.161 24.436 335.587 21.814C337.013 19.192 338.899 17.214 341.245 15.88C343.591 14.5 346.144 13.81 348.904 13.81C350.974 13.81 352.699 14.063 354.079 14.569C355.505 15.029 356.655 15.627 357.529 16.363C358.403 17.099 359.07 17.881 359.53 18.709H360.772V0.699997H369.466V49H360.91V44.86H359.668C358.886 46.148 357.667 47.321 356.011 48.379C354.401 49.437 352.032 49.966 348.904 49.966ZM351.526 42.376C354.194 42.376 356.425 41.525 358.219 39.823C360.013 38.075 360.91 35.545 360.91 32.233V31.543C360.91 28.231 360.013 25.724 358.219 24.022C356.471 22.274 354.24 21.4 351.526 21.4C348.858 21.4 346.627 22.274 344.833 24.022C343.039 25.724 342.142 28.231 342.142 31.543V32.233C342.142 35.545 343.039 38.075 344.833 39.823C346.627 41.525 348.858 42.376 351.526 42.376Z" fill="#FFAC11"/>
</svg>
</a>
</li>
<li class="selected">
<a href="/webfeed">
<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
<path d="M12 2C17.5228 2 22 6.47715 22 12V15.7639C22 16.5215 21.572 17.214 20.8944 17.5528L18 19V20C18 21.5977 16.7511 22.9037 15.1763 22.9949L14.9499 23.0004C14.9718 22.8926 14.9868 22.7823 14.9943 22.67L15 22.5V22C15 20.9456 14.1841 20.0818 13.1493 20.0055L13 20H11C9.94564 20 9.08183 20.8159 9.00549 21.8507L9 22V22.5C9 22.6714 9.01725 22.8387 9.0501 23.0004L9 23C7.34315 23 6 21.6569 6 20V19L3.10557 17.5528C2.428 17.214 2 16.5215 2 15.7639V12C2 6.47715 6.47715 2 12 2ZM8 11C6.89543 11 6 11.8954 6 13C6 14.1046 6.89543 15 8 15C9.10457 15 10 14.1046 10 13C10 11.8954 9.10457 11 8 11ZM16 11C14.8954 11 14 11.8954 14 13C14 14.1046 14.8954 15 16 15C17.1046 15 18 14.1046 18 13C18 11.8954 17.1046 11 16 11Z"/>
</svg>Threats
</a>
</li>
<li>
<a href="/logs">
<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
<path d="M21.0082 3C21.556 3 22 3.44495 22 3.9934V20.0066C22 20.5552 21.5447 21 21.0082 21H2.9918C2.44405 21 2 20.5551 2 20.0066V3.9934C2 3.44476 2.45531 3 2.9918 3H21.0082ZM20 5H4V19H20V5ZM18 15V17H6V15H18ZM12 7V13H6V7H12ZM18 11V13H14V11H18ZM10 9H8V11H10V9ZM18 7V9H14V7H18Z"/>
</svg>Logs
</a>
</li>
<li>
<a href="/live">
<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
<path d="M3 3C12.9411 3 21 11.0589 21 21H18C18 12.7157 11.2843 6 3 6V3ZM3 10C9.07513 10 14 14.9249 14 21H11C11 16.5817 7.41828 13 3 13V10ZM3 17C5.20914 17 7 18.7909 7 21H3V17Z"/>
</svg>Live
</a>
</li>
<li>
<a href="/docs">
<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="20" height="20" fill="currentColor">
<path d="M202.24 74C166.11 56.75 115.61 48.3 48 48a31.36 31.36 0 00-17.92 5.33A32 32 0 0016 79.9V366c0 19.34 13.76 33.93 32 33.93 71.07 0 142.36 6.64 185.06 47a4.11 4.11 0 006.94-3V106.82a15.89 15.89 0 00-5.46-12A143 143 0 00202.24 74zM481.92 53.3A31.33 31.33 0 00464 48c-67.61.3-118.11 8.71-154.24 26a143.31 143.31 0 00-32.31 20.78 15.93 15.93 0 00-5.45 12v337.13a3.93 3.93 0 006.68 2.81c25.67-25.5 70.72-46.82 185.36-46.81a32 32 0 0032-32v-288a32 32 0 00-14.12-26.61z"/>
</svg>Docs
</a>
</li>
<li>
<a href="/config">
<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
<path d="M9.95401 2.2106C11.2876 1.93144 12.6807 1.92263 14.0449 2.20785C14.2219 3.3674 14.9048 4.43892 15.9997 5.07103C17.0945 5.70313 18.364 5.75884 19.4566 5.3323C20.3858 6.37118 21.0747 7.58203 21.4997 8.87652C20.5852 9.60958 19.9997 10.736 19.9997 11.9992C19.9997 13.2632 20.5859 14.3902 21.5013 15.1232C21.29 15.7636 21.0104 16.3922 20.6599 16.9992C20.3094 17.6063 19.9049 18.1627 19.4559 18.6659C18.3634 18.2396 17.0943 18.2955 15.9997 18.9274C14.9057 19.559 14.223 20.6294 14.0453 21.7879C12.7118 22.067 11.3187 22.0758 9.95443 21.7906C9.77748 20.6311 9.09451 19.5595 7.99967 18.9274C6.90484 18.2953 5.63539 18.2396 4.54272 18.6662C3.61357 17.6273 2.92466 16.4164 2.49964 15.1219C3.41412 14.3889 3.99968 13.2624 3.99968 11.9992C3.99968 10.7353 3.41344 9.60827 2.49805 8.87524C2.70933 8.23482 2.98894 7.60629 3.33942 6.99923C3.68991 6.39217 4.09443 5.83576 4.54341 5.33257C5.63593 5.75881 6.90507 5.703 7.99967 5.07103C9.09364 4.43942 9.7764 3.3691 9.95401 2.2106ZM11.9997 14.9992C13.6565 14.9992 14.9997 13.6561 14.9997 11.9992C14.9997 10.3424 13.6565 8.99923 11.9997 8.99923C10.3428 8.99923 8.99967 10.3424 8.99967 11.9992C8.99967 13.6561 10.3428 14.9992 11.9997 14.9992Z"/>
</svg><span class="visually-hidden">Config</span>
</a>
</li>
</ul>
</nav>
</header>
<main class="full-width">
{{if .Data}}
<table id="webfeed" class="webfeed">
<thead>
<tr>
<th><a href="?sort=ip&direction={{if and (eq .SortMethod "ip") (eq .SortDirection "asc")}}desc{{else}}asc{{end}}">
IP
</a>{{if eq .SortMethod "ip"}}<span class="sort-arrow {{if eq .SortDirection "asc"}}asc{{else}}desc{{end}}"></span>{{end}}
</th>
<th><a href="?sort=added&direction={{if and (eq .SortMethod "added") (eq .SortDirection "asc")}}desc{{else}}asc{{end}}">
Added
</a>{{if eq .SortMethod "added"}}<span class="sort-arrow {{if eq .SortDirection "asc"}}asc{{else}}desc{{end}}"></span>{{end}}
</th>
<th><a href="?sort=last_seen&direction={{if and (eq .SortMethod "last_seen") (eq .SortDirection "asc")}}desc{{else}}asc{{end}}">
Last Seen
</a>{{if eq .SortMethod "last_seen"}}<span class="sort-arrow {{if eq .SortDirection "asc"}}asc{{else}}desc{{end}}"></span>{{end}}
</th>
<th><a href="?sort=observations&direction={{if and (eq .SortMethod "observations") (eq .SortDirection "asc")}}desc{{else}}asc{{end}}">
Observations
</a>{{if eq .SortMethod "observations"}}<span class="sort-arrow {{if eq .SortDirection "asc"}}asc{{else}}desc{{end}}"></span>{{end}}
</th>
</tr>
</thead>
<tbody>
{{range .Data}}<tr><td>{{.IP}}<td>{{.Added.UTC.Format "2006-01-02T15:04:05.000Z"}}<td>{{.LastSeen.UTC.Format "2006-01-02T15:04:05.000Z"}}<td>{{.Observations}}
{{end}}
</tbody>
</table>
{{else}}
<p class="no-results">The threat feed is currently empty</p>
{{end}}
</main>
<script>
function formatDatesAndNumbers() {
// Format 'Added' as YYYY-MM-DD.
const addedDateFormat = new Intl.DateTimeFormat('en-CA', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
});
// Format 'Last Seen' as YYYY-MM-DD hh:mm.
const lastSeenDateFormat = new Intl.DateTimeFormat('en-CA', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false,
});
// Format 'Observations' with a thousands separator based on user's locale.
const numberFormat = new Intl.NumberFormat();
// Apply formats to table.
document.querySelectorAll("#webfeed tbody tr").forEach(row => {
// Apply format to 'Added' cell (row.cells[1]).
let date = new Date(row.cells[1].textContent);
if (!isNaN(date.valueOf())) {
row.cells[1].textContent = addedDateFormat.format(date);
}
// Apply format to 'Last Seen' cell (row.cells[2]).
date = new Date(row.cells[2].textContent);
if (!isNaN(date.valueOf())) {
row.cells[2].textContent = lastSeenDateFormat.format(date).replace(',', '');
}
// Apply format to 'Observations' cell (row.cells[3]).
const observationCount = parseInt(row.cells[3].textContent, 10);
if (!isNaN(observationCount)) {
row.cells[3].textContent = numberFormat.format(observationCount);
}
});
}
formatDatesAndNumbers();
</script>
</body>
</html>