80 lines
2.6 KiB
TypeScript
80 lines
2.6 KiB
TypeScript
import { User } from '@/models/user.ts';
|
|
import { omit } from 'es-toolkit';
|
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
import { renderServerHtml } from '../html/render-server-html.ts';
|
|
import { baseURL } from '../domain.ts';
|
|
import { app } from '@/app.ts'
|
|
import { N5Service } from '@/routes/n5-link/modules/n5.services.ts';
|
|
type ProxyOptions = {
|
|
createNotFoundPage: (msg?: string) => any;
|
|
};
|
|
// /n5/:slug/
|
|
export const N5Proxy = async (req: IncomingMessage, res: ServerResponse, opts?: ProxyOptions) => {
|
|
const { url } = req;
|
|
const _url = new URL(url || '', baseURL);
|
|
const { pathname, searchParams } = _url;
|
|
let [user, app, userAppKey] = pathname.split('/').slice(1);
|
|
if (!app) {
|
|
opts?.createNotFoundPage?.('应用未找到');
|
|
return false;
|
|
}
|
|
let n5Data = null;
|
|
let data = null;
|
|
let link = '';
|
|
try {
|
|
const convexResult = await N5Service.getBySlug(app);
|
|
if (!convexResult || convexResult.length === 0) {
|
|
opts?.createNotFoundPage?.('应用未找到');
|
|
return false;
|
|
}
|
|
n5Data = convexResult[0];
|
|
data = n5Data.data ?? {};
|
|
link = data.link;
|
|
if (!link) {
|
|
opts?.createNotFoundPage?.('不存在对应的跳转的链接');
|
|
return false;
|
|
}
|
|
} catch (e) {
|
|
console.error('Error fetching N5 data:', e);
|
|
opts?.createNotFoundPage?.('应用数据异常');
|
|
return false;
|
|
}
|
|
|
|
if (data?.useOwnerToken) {
|
|
const userId = n5Data.userId;
|
|
if (!userId) {
|
|
opts?.createNotFoundPage?.('未绑定账号');
|
|
return false;
|
|
}
|
|
try {
|
|
const user = await User.findByPk(userId);
|
|
const token = await User.createJwksTokenResponse({ id: userId, username: user?.username || '' }, { hasRefreshToken: true });
|
|
const urlObj = new URL(link);
|
|
urlObj.searchParams.set('token', token.accessToken);
|
|
const resultLink = await fetch(urlObj.toString(), { method: 'GET' }).then(res => res.json())
|
|
res.end(JSON.stringify(resultLink));
|
|
} catch (e) {
|
|
console.error('Error fetching the link:', e);
|
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ error: '请求服务区失败' }));
|
|
}
|
|
return true;
|
|
}
|
|
const type = data?.type;
|
|
if (type === 'html-render') {
|
|
const createJson = omit(data, ['useOwnerToken', 'permission']);
|
|
const html = await fetch(link, { method: 'GET' }).then(res => res.text());
|
|
const renderedHtml = await renderServerHtml({
|
|
data: createJson,
|
|
pathname: _url.toString(),
|
|
}, html);
|
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
res.end(renderedHtml);
|
|
} else {
|
|
res.writeHead(302, {
|
|
Location: link,
|
|
});
|
|
}
|
|
res.end();
|
|
};
|