{t('report.owner_note')} {r.note}
+ )} {published && r.models.length > 0 && (
{t('report.filed_under')}{' '}
diff --git a/frontend/apps/site/src/i18n/boards.en.json b/frontend/apps/site/src/i18n/boards.en.json
index a1083450..eb5ce212 100644
--- a/frontend/apps/site/src/i18n/boards.en.json
+++ b/frontend/apps/site/src/i18n/boards.en.json
@@ -219,7 +219,8 @@
"why_2": "Keep your flash dumps private: only you and OpenIPC's maintainers can download them.",
"why_3": "Collect stars for what you document and for keeping a camera on the Open Wall, and your name next to the boards you documented.",
"why_note": "You don't need an account to browse or download firmware. The site sets no cookie for anyone who doesn't sign in.",
- "why_title": "Why sign in"
+ "why_title": "Why sign in",
+ "your_note": "Your note"
},
"cov_boot_log": "Boot log",
"cov_document": "Docs",
@@ -458,6 +459,7 @@
"lookup_button": "Show its state",
"lookup_label": "Have a receipt?",
"not_found": "No report has this receipt. Check the address ipctool printed.",
+ "owner_note": "The owner's note:",
"received": "Received from {channel}",
"reports_app": "app",
"reports_ask": "Have this board?",
diff --git a/frontend/apps/site/src/i18n/boards.ru.json b/frontend/apps/site/src/i18n/boards.ru.json
index baa3806e..2174fdb0 100644
--- a/frontend/apps/site/src/i18n/boards.ru.json
+++ b/frontend/apps/site/src/i18n/boards.ru.json
@@ -221,7 +221,8 @@
"why_2": "Держать дампы флеш-памяти закрытыми: скачать их можете только вы и мейнтейнеры OpenIPC.",
"why_3": "Получать звёзды за описанные платы и за камеру на Open Wall и видеть своё имя рядом с платами, которые вы описали.",
"why_note": "Чтобы смотреть каталог и скачивать прошивки, учётная запись не нужна. Тем, кто не входит, сайт не ставит ни одной cookie.",
- "why_title": "Зачем входить"
+ "why_title": "Зачем входить",
+ "your_note": "Ваше примечание"
},
"cov_boot_log": "Лог загрузки",
"cov_document": "Документы",
@@ -480,6 +481,7 @@
"lookup_button": "Показать состояние",
"lookup_label": "Есть квитанция?",
"not_found": "Отчёта с такой квитанцией нет. Проверьте адрес, который напечатал ipctool.",
+ "owner_note": "Примечание владельца:",
"received": "Получен от {channel}",
"reports_app": "приложение",
"reports_ask": "Есть такая плата?",
diff --git a/frontend/apps/site/src/i18n/boards.zh.json b/frontend/apps/site/src/i18n/boards.zh.json
index 6f93034f..ee69544f 100644
--- a/frontend/apps/site/src/i18n/boards.zh.json
+++ b/frontend/apps/site/src/i18n/boards.zh.json
@@ -219,7 +219,8 @@
"why_2": "让固件转储保持私密:只有你和 OpenIPC 维护者可以下载。",
"why_3": "为你记录的电路板和保持在线的 Open Wall 摄像头获得星星,并在你记录的电路板旁显示你的名字。",
"why_note": "浏览目录或下载固件无需账户。对不登录的访客,本站不设置任何 cookie。",
- "why_title": "为什么要登录"
+ "why_title": "为什么要登录",
+ "your_note": "你的备注"
},
"cov_boot_log": "启动日志",
"cov_document": "文档",
@@ -458,6 +459,7 @@
"lookup_button": "查看状态",
"lookup_label": "有回执?",
"not_found": "没有与此回执对应的报告。请检查 ipctool 打印的地址。",
+ "owner_note": "所有者的备注:",
"received": "来自 {channel}",
"reports_app": "应用",
"reports_ask": "有这块板?",
diff --git a/service/cmd/openipc/club.go b/service/cmd/openipc/club.go
index 285a9dc8..86391937 100644
--- a/service/cmd/openipc/club.go
+++ b/service/cmd/openipc/club.go
@@ -76,7 +76,9 @@ func refreshReportUnits(ctx context.Context, cfg *config.Config, log *slog.Logge
}
// A report published on several boards is a unit on each, and each
// unit's reference is its own (board_units.source_ref is unique).
- c := boards.Contribution{Unit: t.Model + "-" + t.Report, Model: t.Model, By: by,
+ // The sender's note -- where it was bought, what it is sold as -- is
+ // the unit's, as published (redacted).
+ c := boards.Contribution{Unit: t.Model + "-" + t.Report, Model: t.Model, By: by, Note: t.Note,
Evidence: []string{cfg.ClubSiteURL + boards.ReceiptMark + t.Report + "&board=" + t.Model}}
for _, f := range t.Files {
c.Files = append(c.Files, boards.ContributedFile{Kind: kinds[f.Kind], File: fmt.Sprintf("%d-%s", f.Position, f.Name), Source: f.Path})
diff --git a/service/internal/club/newcamera_test.go b/service/internal/club/newcamera_test.go
index 8684fa1e..c721e4f4 100644
--- a/service/internal/club/newcamera_test.go
+++ b/service/internal/club/newcamera_test.go
@@ -175,3 +175,54 @@ func TestANewCameraComesWithAProgrammersDump(t *testing.T) {
t.Errorf("published texts: %+v (%v)", texts, err)
}
}
+
+// The note under a send -- where it was bought, what it is sold as -- is
+// the sender's to see on /club as written, and once published it goes onto
+// the board's unit redacted: a MAC pasted into it never reaches the page.
+func TestTheSendersNoteIsShownAndPublishedRedacted(t *testing.T) {
+ e := newEnv(t)
+ ctx := context.Background()
+ ivan := e.signedIn(t, 777, "ivan_k", "198.51.100.1")
+ note := "bought on Ozon as Jooan Q9, MAC 00:12:41:ab:cd:ef"
+ _, out := ivan.send(t, map[string]string{"channel": "web", "model": "anjoy-ms-j10", "note": note}, map[string][]byte{"photo": photo})
+ id := out["id"].(string)
+ if _, mine := ivan.json(t, "GET", "/api/v1/club/reports", nil); mine["reports"].([]any)[0].(map[string]any)["note"] != note {
+ t.Errorf("the sender's own note: %v", mine["reports"])
+ }
+ maint := e.maintainer(t)
+ if code, _ := maint.json(t, "POST", "/api/v1/club/review/"+id, map[string]any{"decision": "publish"}); code != 200 {
+ t.Fatal("publish")
+ }
+ texts, err := e.api.Reports.Store().PublishedTexts(ctx)
+ if err != nil || len(texts) != 1 {
+ t.Fatalf("%v %v", texts, err)
+ }
+ if n := texts[0].Note; !strings.HasPrefix(n, "bought on Ozon as Jooan Q9, MAC