feat: share resumable mobile search previews (Closes #787)
CI / lint (pull_request) Successful in 1m41s
CI / build-release (pull_request) Successful in 5s
CI / release-candidate (pull_request) Has been skipped

This commit is contained in:
timmy committed 2026-08-14 01:04:20 +00:00
1 parent 66a2b78860
commit 43163ed926
11 files changed
+234 -10

No files matched your search

+1 -1
View File
@@ -28,7 +28,7 @@ FEATURE_SOURCES = {
"device-setup": ("static/install-app.js", "static/mobile-device-setup.js"),
"security-center": ("static/security-center.js",),
"today-timer": (
"static/task-overlay-history.js", "static/my-work.js", "static/protect-today.js", "static/mobile-task-dock.js", "static/mobile-queue-launcher.js", "static/update-triage-session.js", "static/update-review-handoff.js", "static/update-triage-launcher.js", "static/update-triage-gesture.js", "static/notification-undo.js", "static/today-timer.js", "static/today-recap.js",
"static/task-overlay-history.js", "static/search-preview.js", "static/my-work.js", "static/protect-today.js", "static/mobile-task-dock.js", "static/mobile-queue-launcher.js", "static/update-triage-session.js", "static/update-review-handoff.js", "static/update-triage-launcher.js", "static/update-triage-gesture.js", "static/notification-undo.js", "static/today-timer.js", "static/today-recap.js",
"static/today-rollover.js", "static/later-work.js", "static/drafts.js", "static/unfiled-captures.js",
"static/draft-filing-session.js", "static/draft-capacity-dialog.js", "static/work-selection.js",
"static/today-work.js", "static/pick-work.js", "static/batch-find-work.js",
+21
View File
@@ -5,6 +5,7 @@ import hashlib
import hmac
import math
import os
import re
import secrets
import sqlite3
import time
@@ -1002,6 +1003,26 @@ app.include_router(frontend_router)
def _share_target_login_redirect(request: Request) -> str:
search_values = request.query_params.getlist("search")
preview_values = request.query_params.getlist("preview")
if search_values or preview_values:
allowed = {"search", "preview"}
if (
set(request.query_params.keys()) - allowed
or len(search_values) != 1
or len(preview_values) != 1
or len(search_values[0]) > 200
or len(preview_values[0]) > 200
or not re.fullmatch(
r"(?:issue|pull):[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+:[1-9]\d*",
preview_values[0],
)
):
return "login"
continuation = urlencode(
(("search", search_values[0].strip()), ("preview", preview_values[0]))
)
return f"login?{urlencode({'continue': f'./?{continuation}'})}"
limits = {"title": 200, "text": 8000, "url": 2048}
if any(
len(request.query_params.get(name, "")) > limit