mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 16:13:15 +00:00
35 lines
1.4 KiB
TypeScript
35 lines
1.4 KiB
TypeScript
import type { NextRequest } from 'next/server';
|
|
import { isTrustedJmapServerUrl } from '@/lib/stalwart/server-fetch';
|
|
import type { WopiJmapContext } from '@/lib/wopi/files';
|
|
import { verifyWopiToken, type WopiTokenPayload } from '@/lib/wopi/token';
|
|
|
|
/**
|
|
* Authenticate an incoming WOPI request (called by the editor
|
|
* server-to-server, no session cookie) from its `access_token` query
|
|
* parameter, scoped to the fileId in the URL.
|
|
*/
|
|
export async function wopiContext(
|
|
request: NextRequest,
|
|
fileId: string,
|
|
): Promise<{ payload: WopiTokenPayload; ctx: WopiJmapContext } | null> {
|
|
const payload = verifyWopiToken(request.nextUrl.searchParams.get('access_token'), fileId);
|
|
if (!payload) return null;
|
|
// Trust is re-derived from the current config, not persisted in the token
|
|
// (mirrors lib/stalwart/server-fetch.ts): removing a server from the config
|
|
// immediately drops its tokens to the rebinding-safe fetch path. A server on
|
|
// the webmail's own origin (the dev mock) is this process itself - the
|
|
// public-URL guard would refuse localhost, so it counts as trusted.
|
|
const sameOrigin = (() => {
|
|
try {
|
|
return new URL(payload.serverUrl).origin === payload.origin;
|
|
} catch {
|
|
return false;
|
|
}
|
|
})();
|
|
const trusted = sameOrigin || await isTrustedJmapServerUrl(payload.serverUrl);
|
|
return {
|
|
payload,
|
|
ctx: { serverUrl: payload.serverUrl, authHeader: payload.authHeader, trusted },
|
|
};
|
|
}
|