#pragma once #include #include #include "debug_auth.h" // The parts of sharing files with a browser (issue #88) that need no network: what a request // asks for, whether it may, and the answers as JSON. The server itself is src/services/web_share.h. namespace roro::files { std::string urlDecode(const std::string& text); // %41 is A; a + stays a + // The value of `key` in a query string ("path=%2Fnotes&replace=1"), decoded. False if it isn't there. bool queryParam(const std::string& query, const std::string& key, std::string& out); // The value of a cookie in a Cookie header ("a=1; s=abc"), or "". std::string cookieValue(const std::string& header, const std::string& name); // A path a browser may name: from the card's root, no "..", nothing a file name can't hold. // "" or why not. std::string checkSharePath(const std::string& path); std::string jsonString(const std::string& text); // with its quotes // A folder's listing as the page wants it: {"path":"/notes","items":[{"n":"a.txt","s":12,"d":0,"t":1791400000}],"more":false} class ShareListing { public: explicit ShareListing(const std::string& path); void add(const std::string& name, uint32_t size, bool folder, int64_t modified); std::string json(bool more); size_t count() const { return count_; } private: std::string out_; size_t count_ = 0; }; // Who may use the page: whoever typed the code the device's screen shows. The code is new each // time sharing starts; five wrong ones in a row close the door for a minute (as the Debug // Console's token does). A browser that got it right is given a token to send back as a cookie. // Nothing here is encrypted on the way: see the issue. class ShareAuth { public: enum class Result { Ok, Wrong, Locked }; void begin(const uint8_t random[4]); // a new code, and nobody is logged in const std::string& code() const { return code_; } // six digits Result login(const std::string& code, uint32_t nowMs, const uint8_t random[16], std::string& token); bool allowed(const std::string& token) const; private: std::string code_, token_; debug::AuthGate gate_; }; } // namespace roro::files