diff --git a/web/lib/potato_mesh/application/queries.rb b/web/lib/potato_mesh/application/queries.rb index b70cde3..96f0f19 100644 --- a/web/lib/potato_mesh/application/queries.rb +++ b/web/lib/potato_mesh/application/queries.rb @@ -213,7 +213,7 @@ module PotatoMesh db&.close end - def query_messages(limit, node_ref: nil) + def query_messages(limit, node_ref: nil, include_encrypted: false) limit = coerce_query_limit(limit) db = open_database(readonly: true) db.results_as_hash = true @@ -221,11 +221,16 @@ module PotatoMesh where_clauses = [ "(COALESCE(TRIM(m.text), '') != '' OR COALESCE(TRIM(m.encrypted), '') != '' OR m.reply_id IS NOT NULL OR COALESCE(TRIM(m.emoji), '') != '')", ] + include_encrypted = !!include_encrypted now = Time.now.to_i min_rx_time = now - PotatoMesh::Config.week_seconds where_clauses << "m.rx_time >= ?" params << min_rx_time + unless include_encrypted + where_clauses << "COALESCE(TRIM(m.encrypted), '') = ''" + end + if node_ref clause = node_lookup_clause(node_ref, string_columns: ["m.from_id", "m.to_id"]) return [] unless clause diff --git a/web/lib/potato_mesh/application/routes/api.rb b/web/lib/potato_mesh/application/routes/api.rb index de1c0f7..5aeaff5 100644 --- a/web/lib/potato_mesh/application/routes/api.rb +++ b/web/lib/potato_mesh/application/routes/api.rb @@ -75,7 +75,8 @@ module PotatoMesh app.get "/api/messages" do content_type :json limit = [params["limit"]&.to_i || 200, 1000].min - query_messages(limit).to_json + include_encrypted = coerce_boolean(params["encrypted"]) || false + query_messages(limit, include_encrypted: include_encrypted).to_json end app.get "/api/messages/:id" do @@ -83,7 +84,8 @@ module PotatoMesh node_ref = string_or_nil(params["id"]) halt 400, { error: "missing node id" }.to_json unless node_ref limit = [params["limit"]&.to_i || 200, 1000].min - query_messages(limit, node_ref: node_ref).to_json + include_encrypted = coerce_boolean(params["encrypted"]) || false + query_messages(limit, node_ref: node_ref, include_encrypted: include_encrypted).to_json end app.get "/api/positions" do diff --git a/web/spec/app_spec.rb b/web/spec/app_spec.rb index e71af5f..6b59684 100644 --- a/web/spec/app_spec.rb +++ b/web/spec/app_spec.rb @@ -3323,6 +3323,13 @@ RSpec.describe "Potato Mesh Sinatra app" do get "/api/messages" expect(last_response).to be_ok + default_messages = JSON.parse(last_response.body) + expect(default_messages).to be_an(Array) + expect(default_messages.map { |row| row["id"] }).not_to include(payload["packet_id"]) + + get "/api/messages?encrypted=1" + expect(last_response).to be_ok + messages = JSON.parse(last_response.body) expect(messages).to be_an(Array) @@ -3332,6 +3339,23 @@ RSpec.describe "Potato Mesh Sinatra app" do expect(encrypted_entry["text"]).to be_nil expect(encrypted_entry["from_id"]).to eq(sender_id) expect(encrypted_entry["to_id"]).to eq(receiver_id) + + get "/api/messages/#{receiver_id}" + expect(last_response).to be_ok + + node_default = JSON.parse(last_response.body) + expect(node_default.map { |row| row["id"] }).not_to include(payload["packet_id"]) + + get "/api/messages/#{receiver_id}?encrypted=1" + expect(last_response).to be_ok + + node_messages = JSON.parse(last_response.body) + node_entry = node_messages.find { |row| row["id"] == payload["packet_id"] } + expect(node_entry).not_to be_nil + expect(node_entry["encrypted"]).to eq(encrypted_b64) + expect(node_entry["text"]).to be_nil + expect(node_entry["from_id"]).to eq(sender_id) + expect(node_entry["to_id"]).to eq(receiver_id) end it "updates node last_heard for plaintext messages" do @@ -3614,11 +3638,11 @@ RSpec.describe "Potato Mesh Sinatra app" do end describe "GET /api/messages" do - it "returns the stored messages with canonical node references" do + it "returns the stored messages with canonical node references when encrypted messages are included" do import_nodes_fixture import_messages_fixture - get "/api/messages" + get "/api/messages?encrypted=1" expect(last_response).to be_ok actual = JSON.parse(last_response.body)