fix: rewrite JMAP session URLs to match user-configured server origin
Fixes Docker/reverse proxy deployments where the JMAP server returns its internal hostname in session URLs, causing all requests after login to fail.
This commit is contained in:
@@ -23,6 +23,7 @@ This document tracks the development status and planned features for JMAP Webmai
|
||||
- [x] Session establishment and keep-alive
|
||||
- [x] Connection error handling and retries
|
||||
- [x] CORS error detection with actionable user guidance
|
||||
- [x] Session URL origin rewriting (fixes Docker/reverse proxy deployments where server returns internal hostname)
|
||||
- [x] Storage quota display
|
||||
- [x] Server capability detection
|
||||
- [x] Shared folders support (multi-account access)
|
||||
|
||||
@@ -102,6 +102,8 @@ export class JMAPClient {
|
||||
|
||||
const session = await sessionResponse.json();
|
||||
|
||||
this.rewriteSessionUrls(session);
|
||||
|
||||
// Store the full session for reference
|
||||
this.session = session;
|
||||
|
||||
@@ -208,6 +210,28 @@ export class JMAPClient {
|
||||
this.capabilities = {};
|
||||
}
|
||||
|
||||
private rewriteSessionUrl(url: string): string {
|
||||
try {
|
||||
const urlOrigin = new URL(url).origin;
|
||||
const serverOrigin = new URL(this.serverUrl).origin;
|
||||
if (urlOrigin === serverOrigin) return url;
|
||||
return serverOrigin + url.slice(urlOrigin.length);
|
||||
} catch {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
private rewriteSessionUrls(session: JMAPSession): void {
|
||||
session.apiUrl = this.rewriteSessionUrl(session.apiUrl);
|
||||
session.downloadUrl = this.rewriteSessionUrl(session.downloadUrl);
|
||||
if (session.uploadUrl) {
|
||||
session.uploadUrl = this.rewriteSessionUrl(session.uploadUrl);
|
||||
}
|
||||
if (session.eventSourceUrl) {
|
||||
session.eventSourceUrl = this.rewriteSessionUrl(session.eventSourceUrl);
|
||||
}
|
||||
}
|
||||
|
||||
private async request(methodCalls: JMAPMethodCall[], using?: string[]): Promise<JMAPResponse> {
|
||||
if (!this.apiUrl) {
|
||||
throw new Error('Not connected. Call connect() first.');
|
||||
|
||||
Reference in New Issue
Block a user