Put known passwords in the NZB and show them

release_passwords (from spots: their NZB meta, title or text) was only
read by the judge. The NZB now carries the most trusted one as
<meta type="password">, which SABnzbd and NZBGet use to unpack; a spot's
own NZB gets it added when its meta has none. The release details list
all known passwords with their source, the list marks "Password known",
and the web interface shows them instead of "not in the index".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Daan MeijerandClaude Opus 5.5 committed 2026-10-23 11:56:43 +02:00
1 parent d446bb57df
commit f75097d7ac
5 files changed
+83 -6

No files matched your search

+14 -2
View File
@@ -17,6 +17,12 @@ const SOURCE_LABELS = {
subject: 'Subject',
post: 'Post id',
}
/** Where a known password came from (release_passwords.source). */
const PASSWORD_SOURCES = {
nzb: "from the spot's NZB",
'spot-title': "from the spot's title",
'spot-text': "from the spot's text",
}
/** Newznab categories (lib/newznab/categories.ts). */
const CATEGORIES = [
[2000, 'Movies', [[2030, 'SD'], [2040, 'HD'], [2045, 'UHD']]],
@@ -220,7 +226,8 @@ function releaseRow(release) {
if (release.complete) badges.append(badge(files, 'good', 'Complete'))
else if (release.fileTotal) badges.append(badge(`${release.fileCount}/${release.fileTotal}`, 'warn', 'Files present / announced'))
else badges.append(badge(files))
if (release.passworded) badges.append(badge('Password', 'bad', 'Its archive is encrypted: a password is needed'))
if (release.passworded && release.passwordKnown) badges.append(badge('Password known', 'warn', 'Its archive is encrypted; the password is in the NZB'))
else if (release.passworded) badges.append(badge('Password', 'bad', 'Its archive is encrypted: a password is needed'))
if (!release.settled) badges.append(badge('Collecting', 'accent', 'Recently seen: more files may still arrive'))
if (release.category && release.category !== 8010) badges.append(badge(categoryLabel(release.category), '', 'Category (from the name)'))
if (release.source && release.source !== 'stem' && release.source !== 'subject') {
@@ -347,7 +354,12 @@ function renderDetail(release) {
if (!release.settledAt) {
notices.push(el('div', { class: 'notice notice-warn', text: 'Recently seen: more files of this release may still arrive. The NZB has what is indexed so far.' }))
}
if (release.passworded) {
const passwords = release.passwords ?? []
if (passwords.length) {
notices.push(el('div', { class: 'notice notice-warn' },
el('span', { text: `${passwords.length === 1 ? 'Password' : 'Passwords'} (the first is in the NZB): ` }),
...passwords.map((p, i) => el('span', {}, i ? ', ' : '', el('code', { text: p.password }), ` (${PASSWORD_SOURCES[p.source] ?? p.source})`))))
} else if (release.passworded) {
notices.push(el('div', { class: 'notice notice-bad', text: 'Passworded: its archive has encrypted entries or headers. The password is not in the index.' }))
}
if (!release.readable && !release.innerName) {