filter: Copy is_web_public_compatible from server to frontend.

This will be used to check if the narrow being requested by
spectator requires authentication without requesting the server.
Having this check locally, makes this process look snappy to
the user and doesn't result in 404s in the browser log.
This commit is contained in:
Aman Agrawal
2020-10-05 14:20:51 +05:30
committed by Tim Abbott
parent 3ed833a7e4
commit 3e7538b974
4 changed files with 52 additions and 0 deletions

View File

@@ -1614,3 +1614,39 @@ test("error_cases", ({override}) => {
const predicate = get_predicate([["pm-with", "Joe@example.com"]]);
assert.ok(!predicate({type: "private"}));
});
run_test("is_web_public_compatible", () => {
// tests same as test_is_web_public_compatible from test_message_fetch.py
assert.ok(Filter.is_web_public_compatible([]));
assert.ok(Filter.is_web_public_compatible([{operator: "has", operand: "attachment"}]));
assert.ok(Filter.is_web_public_compatible([{operator: "has", operand: "image"}]));
assert.ok(Filter.is_web_public_compatible([{operator: "search", operand: "magic"}]));
assert.ok(Filter.is_web_public_compatible([{operator: "near", operand: "15"}]));
assert.ok(
Filter.is_web_public_compatible([
{operator: "id", operand: "15"},
{operator: "has", operand: "attachment"},
]),
);
assert.ok(Filter.is_web_public_compatible([{operator: "sender", operand: "hamlet@zulip.com"}]));
assert.ok(
!Filter.is_web_public_compatible([{operator: "pm-with", operand: "hamlet@zulip.com"}]),
);
assert.ok(
!Filter.is_web_public_compatible([
{operator: "group-pm-with", operand: "hamlet@zulip.com"},
]),
);
assert.ok(Filter.is_web_public_compatible([{operator: "stream", operand: "Denmark"}]));
assert.ok(
Filter.is_web_public_compatible([
{operator: "stream", operand: "Denmark"},
{operator: "topic", operand: "logic"},
]),
);
assert.ok(!Filter.is_web_public_compatible([{operator: "is", operand: "starred"}]));
assert.ok(!Filter.is_web_public_compatible([{operator: "is", operand: "private"}]));
assert.ok(Filter.is_web_public_compatible([{operator: "streams", operand: "public"}]));
// Malformed input not allowed
assert.ok(!Filter.is_web_public_compatible([{operator: "has"}]));
});

View File

@@ -1,6 +1,7 @@
import Handlebars from "handlebars/runtime";
import _ from "lodash";
import * as hash_util from "./hash_util";
import {$t} from "./i18n";
import * as message_edit from "./message_edit";
import * as message_parser from "./message_parser";
@@ -1005,4 +1006,16 @@ export class Filter {
static describe(operators) {
return Handlebars.Utils.escapeExpression(Filter.describe_unescaped(operators));
}
static is_web_public_compatible(ops) {
for (const op of ops) {
if (op.operand === undefined) {
return false;
}
if (!hash_util.allowed_web_public_narrows.includes(op.operator)) {
return false;
}
}
return true;
}
}

View File

@@ -283,6 +283,8 @@ export const allowed_web_public_narrows = [
];
export function is_web_public_compatible(hash) {
// Defines which views are supported for spectators.
// This implementation should agree with the similar function in zerver/lib/narrow.py.
const web_public_allowed_hashes = [
"",
"narrow", // full #narrow hash handled in narrow.is_web_public_compatible

View File

@@ -30,6 +30,7 @@ def check_supported_events_narrow_filter(narrow: Iterable[Sequence[str]]) -> Non
def is_web_public_compatible(narrow: Iterable[Dict[str, Any]]) -> bool:
# This implementation should agree with the similar function in static/js/hash_utl.js.
for element in narrow:
operator = element["operator"]
if "operand" not in element: