fix(mobile): fix file sharing deep-link conflicts and add MIME type inference

- Skip known deep-link paths (qr-login, callback) in makeUrlHandler
  to prevent docuelevate://qr-login URLs from being treated as shared
  files and creating phantom upload errors
- Infer MIME type from file extension for files shared via iOS Share
  Sheet / "Open In…" so the server receives correct Content-Type
  instead of application/octet-stream
- Default login screen server URL to https://app.docuelevate.org

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-19 11:55:45 +00:00
parent 136631762b
commit 1559686f90
4 changed files with 104 additions and 21 deletions
+39 -1
View File
@@ -31,6 +31,44 @@ import { useShare } from "../src/context/ShareContext";
// Helpers
// ---------------------------------------------------------------------------
/**
* Common MIME type mappings for file extensions.
* Used to infer the MIME type of files shared via iOS "Open In…" so the
* server receives a correct Content-Type instead of application/octet-stream.
*/
const EXT_TO_MIME: Record<string, string> = {
pdf: "application/pdf",
jpg: "image/jpeg",
jpeg: "image/jpeg",
png: "image/png",
gif: "image/gif",
bmp: "image/bmp",
tiff: "image/tiff",
tif: "image/tiff",
webp: "image/webp",
heic: "image/heic",
heif: "image/heif",
txt: "text/plain",
csv: "text/csv",
doc: "application/msword",
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
xls: "application/vnd.ms-excel",
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
ppt: "application/vnd.ms-powerpoint",
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
rtf: "application/rtf",
html: "text/html",
xml: "application/xml",
json: "application/json",
zip: "application/zip",
};
/** Infer MIME type from a filename's extension, or undefined if unknown. */
function mimeTypeFromFilename(filename: string): string | undefined {
const ext = filename.split(".").pop()?.toLowerCase();
return ext ? EXT_TO_MIME[ext] : undefined;
}
/**
* First path-segment names that identify iOS/Android sandbox filesystem paths.
* These can never be expo-router route-group names, so their presence is a
@@ -120,7 +158,7 @@ export default function NotFoundScreen() {
// file:// URI so the upload logic can read the file.
const fileUri = `file://${pathname}`;
const filename = filenameFromPath(pathname);
addPendingFile({ uri: fileUri, filename });
addPendingFile({ uri: fileUri, filename, mimeType: mimeTypeFromFilename(filename) });
router.replace("/(tabs)/");
} else {
// Truly unknown in-app route fall back to the root redirect.