1
0
Fork 1

Merge branch 'csp-xss' into pr-bundle-001

pull/31/head
gravel 1 year ago
commit 50e87fe966
Signed by: gravel
SSH Key Fingerprint: SHA256:p4HP49CCk4YQMkJpWJ09L8peEPQWjERtdCRAFxPfbOY

@ -3,6 +3,7 @@
// change in the foreseeable future.
export const dom = {
/** @return {HTMLTableElement | null} */
tbl_communities: () => document.getElementById("tbl_communities"),
last_checked: () => document.getElementById("last_checked_value"),
qr_modal: (communityID) => document.getElementById(`modal_${communityID}`),

@ -60,12 +60,26 @@ const transformJoinURL = (join_link) => {
});
}
function onLoad(timestamp) {
setLastChecked(timestamp);
function getTimestamp() {
const timestampRaw =
document.querySelector('meta[name=timestamp]')
?.getAttribute('content');
if (!timestampRaw) return null;
const timestamp = parseInt(timestampRaw);
if (Number.isNaN(timestamp)) return null;
return timestamp;
}
function onLoad() {
const timestamp = getTimestamp();
if (timestamp !== null) {
setLastChecked(timestamp);
}
hideBadCommunities();
sortTable(COLUMN.NAME);
createJoinLinkButtons();
markSortableColumns();
addQRModalHandlers();
}
function displayQRModal(communityID) {
@ -76,6 +90,25 @@ function hideQRModal(communityID) {
dom.qr_modal(communityID).style.display = "none";
}
function addQRModalHandlers() {
const rows = dom.tbl_communities()?.rows;
if (!rows) throw new Error("Rows not found");
for (const row of rows) {
if (row.querySelector('th')) continue;
const communityID = row.getAttribute('--data-identifier');
row.querySelector('.td_qr_code').addEventListener(
'click',
() => displayQRModal(communityID)
);
const closeButton =
dom.qr_modal(communityID).querySelector('.qr-code-modal-close');
closeButton.addEventListener(
'click',
() => hideQRModal(communityID)
);
}
}
function createJoinLinkButtons() {
const join_URLs = dom.join_urls();
Array.from(join_URLs).forEach((td_url) => {
@ -252,9 +285,13 @@ function markSortableColumns() {
const table = dom.tbl_communities();
const header_cells = table.querySelectorAll('th');
for (let colno = 0; colno < header_cells.length; colno++) {
if (!columnIsSortable(colno)) continue;
if (!columnIsSortable(colno)) continue;
header_cells[colno].classList.add('sortable');
}
header_cells[colno].addEventListener(
'click',
() => sortTable(colno)
)
};
}
/**
@ -278,13 +315,7 @@ function sortTable(column) {
setSortState(table, { ascending, column });
}
// html.js for styling purposes
window.document.documentElement.classList.add("js");
// Crude way to export from module script due to inline event handlers.
// Ideally, all handlers would be attached from JS via addEventListener.
Object.assign(window, {
onLoad, sortTable, displayQRModal,
hideQRModal, copyToClipboard
});
// `html.js` selector for styling purposes
document.documentElement.classList.add("js");
document.addEventListener('DOMContentLoaded', () => onLoad());

@ -1,4 +1,11 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/svg+xml" href="favicon.svg" sizes="any">
<meta name="keywords" content="Session, Community, Anonymous, Chat">
<meta name="keywords" content="Session, Community, Anonymous, Chat">
<meta
http-equiv="Content-Security-Policy"
content="
script-src 'self'; img-src 'self' data:; connect-src 'self'; font-src 'none';
object-src 'none'; media-src 'none'; form-action 'none'; base-uri 'self';
"
>

@ -34,7 +34,7 @@
<?php foreach ($rooms as $id => $room): ?>
<div id="modal_<?=$id?>" class="qr-code-modal">
<div class="qr-code-modal-content">
<span class="qr-code-modal-close" onclick='hideQRModal("<?=$id?>")'>
<span class="qr-code-modal-close">
&times;
</span>
<img

@ -12,7 +12,7 @@
$column = $TABLE_COLUMNS[$colno];
if (!column_sortable($column['id'])) return "";
$name = $column['name'];
return " onclick='sortTable($colno)' title='Click to sort by $name'";
return " title='Click to sort by $name'";
}
$TABLE_COLUMNS = [
@ -52,17 +52,29 @@
$hostname = explode("//", $room->join_link)[1];
$hostname = explode("/", $hostname)[0];
// Escape external input.
// Ternaries prevent passing null-equal strings, which produce warnings.
$id = htmlspecialchars($id);
$language = $room->language ? htmlspecialchars($room->language) : "";
$name = htmlspecialchars($room->name);
$desc = $room->description ? htmlspecialchars($room->description) : "";
$users = htmlspecialchars($room->active_users);
$preview_link = htmlspecialchars($room->preview_link);
$join_link = htmlspecialchars($room->join_link);
// TODO: Do not forget to rename this escape when merging!
$token = htmlspecialchars($token);
$hostname = htmlspecialchars($hostname);
?>
<tr id="<?=$id?>" itemscope itemtype="https://schema.org/EntryPoint">
<tr id="<?=$id?>" itemscope itemtype="https://schema.org/EntryPoint" --data-identifier="<?=$id?>">
<td class="td_identifier" itemprop="identifier"><?=$id?></td>
<td class="td_language"><?=$room->language?></td>
<td class="td_name" itemprop="name"><?=$room->name?></td>
<td class="td_description" itemprop="description"
><?=$room->description?></td>
<td class="td_users"><?=$room->active_users?></td>
<td class="td_language"><?=$language?></td>
<td class="td_name" itemprop="name"><?=$name?></td>
<td class="td_description" itemprop="description"><?=$desc?></td>
<td class="td_users"><?=$users?></td>
<td class="td_preview" itemprop="url">
<a href="<?=$room->preview_link?>" target="_blank" rel="noopener noreferrer nofollow">
<a href="<?=$preview_link?>" target="_blank" rel="noopener noreferrer nofollow">
<?php if (str_starts_with($room->preview_link, 'http://')): ?>
<span class="protocol-indicator protocol-http">HTTP</span>
<?php endif; ?>
@ -75,7 +87,6 @@
<img
class="qr-code-icon"
src="qrcode-solid.svg"
onclick='displayQRModal("<?=$id?>")'
alt="Pictogram of a QR code"
>
</td>
@ -89,10 +100,10 @@
</div>
</td>
<td class="td_join_url">
<div class="join_url_container" data-url="<?=$room->join_link?>">
<span class="join_url show-from-w5" title="<?=$room->join_link?>"
><?=truncate($room->join_link, 32)?></span>
<a class="noscript" href="<?=$room->join_link?>" rel="external nofollow"
<div class="join_url_container" data-url="<?=$join_link?>">
<a class="join_url show-from-w5" title="<?=$join_link?>"
><?=truncate($join_link, 32)?></a>
<a class="noscript" href="<?=$join_link?>" rel="external nofollow"
>Copy link</a>
</div>
</td>

@ -15,7 +15,7 @@
<link rel="canonical" href="https://sessioncommunities.online/">
<link rel="stylesheet" href="styles2.css">
<script type="module" src="main.js"></script>
<script type="module" src="./main.js"></script>
<title>Self-updating list of active Session communities</title>
<meta name="description" content="
Directory of Session Open Groups — public chatrooms within Session Messenger.
@ -31,9 +31,9 @@
<meta property="og:url" content="https://sessioncommunities.online/">
<meta property="og:type" content="website">
<meta property="og:locale" content="en_US"/>
<meta name="timestamp" content="<?=$timestamp?>">
</head>
<body onload="onLoad(<?php echo $timestamp ?>)">
<body>
<header>
<div id="header-start"></div>
<div id="header-end">