fix(web): upgrade http OSS URLs to https to fix mixed-content block

Aliyun OSS sometimes returns presigned URLs as http:// even though every
page here is served over https:// -- the browser silently blocks these
as mixed content, which is why images (e.g. avatar) failed to display
after upload. Added upgradeToHttps() and wired it into fileDownloadUrl()
(the single chokepoint every image/attachment fetch in the app resolves
through) plus the three chat-attachment send paths, so both freshly
fetched and newly-persisted URLs get the scheme fix.

Also fixed ProfileSettingsPage's avatar upload handler, which extracted
the file id by parsing the upload response's `url` with .split('/').pop()
instead of just reading the `file_id` field the response already
provides -- fragile against exactly this kind of full-URL response and
the most likely actual trigger for the reported bug.

vite.config.ts: dev server port now respects $PORT if set, falls back
to 8094 -- unrelated cleanup, needed it to run a second local dev
server for verification alongside another concurrent session's.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-16 00:18:31 +08:00
co-authored by Claude Sonnet 5
parent 70cc977e16
commit e78437cb2a
4 changed files with 17 additions and 8 deletions
+4 -4
View File
@@ -1,6 +1,6 @@
import { Drafty, type Topic } from 'tinode-sdk';
import { uploadFile } from '@/lib/api/upload';
import { uploadFile, upgradeToHttps } from '@/lib/api/upload';
import { MAX_INBAND_ATTACHMENT_SIZE } from '@/lib/config';
import { newClientMid } from '@/lib/tinode/send';
@@ -43,7 +43,7 @@ export async function sendImage(topic: Topic, file: File): Promise<unknown> {
? Drafty.insertImage(undefined, 0, { mime: file.type, bits: await fileToBase64(file), width, height, filename: file.name, size: file.size })
: Drafty.insertImage(undefined, 0, {
mime: file.type,
refurl: (await uploadFile(file, topic.name)).url,
refurl: upgradeToHttps((await uploadFile(file, topic.name)).url),
width,
height,
filename: file.name,
@@ -58,7 +58,7 @@ export async function sendFile(topic: Topic, file: File): Promise<unknown> {
const content =
file.size <= MAX_INBAND_ATTACHMENT_SIZE
? Drafty.attachFile(undefined, { mime: file.type, data: await fileToBase64(file), filename: file.name, size: file.size })
: Drafty.attachFile(undefined, { mime: file.type, refurl: (await uploadFile(file, topic.name)).url, filename: file.name, size: file.size });
: Drafty.attachFile(undefined, { mime: file.type, refurl: upgradeToHttps((await uploadFile(file, topic.name)).url), filename: file.name, size: file.size });
const msg = topic.createMessage(content, false);
msg.head = Object.assign(msg.head || {}, { 'x-im-type': 'file', 'x-im-client-mid': newClientMid() });
return topic.publishDraft(msg, Promise.resolve());
@@ -79,7 +79,7 @@ export async function sendVoice(topic: Topic, blob: Blob, durationMs: number): P
? Drafty.insertAudio(undefined, 0, { mime: file.type, bits: await fileToBase64(file), duration: durationMs, size: file.size, filename: file.name })
: Drafty.insertAudio(undefined, 0, {
mime: file.type,
refurl: (await uploadFile(file, topic.name)).url,
refurl: upgradeToHttps((await uploadFile(file, topic.name)).url),
duration: durationMs,
size: file.size,
filename: file.name,