Files
AFFiNE-Mirror/packages/frontend/apps/android/src/proxy.ts
Aki Chang 00bd05897e feat(android): ai chat scaffold (#11124)
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: eyhn <cneyhn@gmail.com>
2025-04-14 06:05:47 +00:00

66 lines
1.8 KiB
TypeScript

import { openDB } from 'idb';
/**
* the below code includes the custom fetch and xmlhttprequest implementation for ios webview.
* should be included in the entry file of the app or webworker.
*/
const rawFetch = globalThis.fetch;
globalThis.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
const request = new Request(input, init);
const origin = new URL(request.url, globalThis.location.origin).origin;
const token = await readEndpointToken(origin);
if (token) {
request.headers.set('Authorization', `Bearer ${token}`);
}
return rawFetch(request);
};
const rawXMLHttpRequest = globalThis.XMLHttpRequest;
globalThis.XMLHttpRequest = class extends rawXMLHttpRequest {
override send(body?: Document | XMLHttpRequestBodyInit | null): void {
const origin = new URL(this.responseURL, globalThis.location.origin).origin;
readEndpointToken(origin).then(
token => {
if (token) {
this.setRequestHeader('Authorization', `Bearer ${token}`);
}
return super.send(body);
},
() => {
throw new Error('Failed to read token');
}
);
}
};
export async function readEndpointToken(
endpoint: string
): Promise<string | null> {
const idb = await openDB('affine-token', 1, {
upgrade(db) {
if (!db.objectStoreNames.contains('tokens')) {
db.createObjectStore('tokens', { keyPath: 'endpoint' });
}
},
});
const token = await idb.get('tokens', endpoint);
return token ? token.token : null;
}
export async function writeEndpointToken(endpoint: string, token: string) {
const db = await openDB('affine-token', 1, {
upgrade(db) {
if (!db.objectStoreNames.contains('tokens')) {
db.createObjectStore('tokens', { keyPath: 'endpoint' });
}
},
});
await db.put('tokens', { endpoint, token });
}