Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cyberpunkunicorn-os/apps/frequency/BACKEND.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ the link, and frequency-web credits the signed-in member (ledger credit,

| Tag | URL written | Where the URL comes from |
|---|---|---|
| Space check-in node | `${SITE_URL}/n/<node uuid>?s=v1.<iat base36>.<tag>` | Space settings → Check-in (copy link). `tag` = base64url(first 16 bytes of HMAC-SHA256(server secret, `node-code:v1:<nodeId>:<iat>`)), so **only the server can mint it** |
| Event door | `${SITE_URL}/q/<7-char slug>?m=nfc` | the event's door code. The device adds `?m=nfc` if missing. **Never** on `/n/` links |
| Space check-in node | `${SITE_URL}/n/<node uuid>?s=v1.<iat base36>.<tag>&m=nfc` | Space settings → Check-in (copy link). `tag` = base64url(first 16 bytes of HMAC-SHA256(server secret, `node-code:v1:<nodeId>:<iat>`)), so **only the server can mint it** |
| Event door | `${SITE_URL}/q/<7-char slug>?m=nfc` | the event's door code. The device adds `?m=nfc` if missing |

- One NDEF URI record per tag, NTAG213/215/216 only. A signed node URL is ~100
characters, which fits NTAG213's 144 bytes.
- Checks before writing (warn, never block): http(s), `/n/` + UUID + `s=v1.<base36>.<22 base64url chars>`
with no `m=`, or `/q/` + 7-char slug.
with no `m=` other than `m=nfc` (added if missing; `/n` reads only `s`), or `/q/` + 7-char slug.
- Optional **permanent** write-lock (NTAG static + dynamic lock bits), behind
two confirmations.
- Log of tags written: `/frequency/written.csv` on LittleFS
Expand Down
2 changes: 1 addition & 1 deletion cyberpunkunicorn-os/apps/frequency/FrequencyMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ void showTag(const CardInfo &c, const String &title, const String &headline, boo
cyberLine(14, y += 12, "Points to", u.host, cyberHue(180));
cyberLine(14, y += 12, "Path", u.path, kindColor(u.kind));
if (u.kind == URL_VENUE) cyberLine(14, y += 12, "Signed", "yes (?s=v1...)", cyberHue(120));
if (u.kind == URL_EVENT)
if (u.kind == URL_EVENT || u.kind == URL_VENUE)
cyberLine(14, y += 12, "NFC mark", u.fixed == c.uri ? "?m=nfc ok" : "missing ?m=nfc",
u.fixed == c.uri ? cyberHue(120) : cyberHue(30));
if (!u.ok) cyberLine(14, y += 12, "Problem", u.problem, cyberHue(30));
Expand Down
8 changes: 6 additions & 2 deletions cyberpunkunicorn-os/apps/frequency/store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,12 @@ UrlCheck checkUrl(const String &raw) {
String node = u.path.substring(3);
if (!isUuid(node)) u.problem = "node id is not a UUID";
else if (!isNodeSig(queryParam(query, "s"))) u.problem = "missing or bad ?s=v1... signature";
else if (queryParam(query, "m").length()) u.problem = "?m= is for /q/ links only";
else u.ok = true;
else if (queryParam(query, "m").length() && queryParam(query, "m") != "nfc") u.problem = "?m= on a /n/ link must be nfc";
else {
u.ok = true;
// Placards carry ?m=nfc too, so the site's Scan stats count them as taps.
if (queryParam(query, "m") != "nfc") u.fixed = url + "&m=nfc";
}
} else if (u.path.startsWith("/q/")) {
u.kind = URL_EVENT;
String slug = u.path.substring(3);
Expand Down
4 changes: 2 additions & 2 deletions cyberpunkunicorn-os/apps/frequency/store.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Settings &settings(); // loaded on first use
// ---- URLs -------------------------------------------------------------------
enum UrlKind {
URL_EMPTY,
URL_VENUE, // /n/<node uuid>?s=v1.<iat>.<tag> Space check-in node
URL_VENUE, // /n/<node uuid>?s=v1.<iat>.<tag>[&m=nfc] Space check-in node
URL_EVENT, // /q/<7-char slug>[?m=nfc] event door code
URL_MEMBER, // /c/<token> member card (proposed)
URL_OTHER,
Expand All @@ -37,7 +37,7 @@ struct UrlCheck {
UrlKind kind = URL_EMPTY;
bool ok = false; // well formed for its kind
String problem; // why not, for the warning screen
String fixed; // url to actually write (e.g. /q/ gets ?m=nfc)
String fixed; // url to actually write (/n/ and /q/ get m=nfc)
String host; // "frequencylocal.com"
String path; // "/n/<uuid>" (no query: the signature stays off logs)
String token; // member token for URL_MEMBER
Expand Down
2 changes: 1 addition & 1 deletion cyberpunkunicorn-os/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ PIO_ENV=CYD-2432S028
PLATFORMIO_VERSION=6.2.0
ESPTOOL_VERSION=5.4.0
OS_NAME="CyberUnicorn 5000"
OS_VERSION=0.1.0
OS_VERSION=0.1.1

source ./boot.conf
for var in BOOT_TITLE BOOT_TAGLINE; do
Expand Down
Loading