From bb4096ce7eaa3c68afb0db06d626a3e226a9b2d3 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Tue, 3 Mar 2026 18:33:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0N5=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF=E6=8C=81=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=94=A8=E6=88=B7JWKS=E4=BB=A4=E7=89=8C=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E8=BA=AB=E4=BB=BD=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/auth/models/user.ts | 7 +++++-- src/modules/n5/index.ts | 25 ++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/auth/models/user.ts b/src/auth/models/user.ts index 62048bc..f0cb228 100644 --- a/src/auth/models/user.ts +++ b/src/auth/models/user.ts @@ -85,14 +85,17 @@ export class User { /** * 创建JWKS token的通用方法 */ - private static async createJwksTokenResponse(user: { id: string; username: string }, opts: { expire?: number } = {}) { + static async createJwksTokenResponse(user: { id: string; username: string }, opts: { expire?: number, save?: boolean } = {}) { const expiresIn = opts?.expire ?? JWKS_TOKEN_EXPIRY; + const save = opts?.save ?? true; const accessToken = await jwksManager.sign({ sub: 'user:' + user.id, name: user.username, exp: Math.floor(Date.now() / 1000) + expiresIn, }); - await oauth.setJwksToken(accessToken, { id: user.id, expire: expiresIn }); + if (save) { + await oauth.setJwksToken(accessToken, { id: user.id, expire: expiresIn }); + } const token = { accessToken, diff --git a/src/modules/n5/index.ts b/src/modules/n5/index.ts index d9d2cec..b98332e 100644 --- a/src/modules/n5/index.ts +++ b/src/modules/n5/index.ts @@ -1,4 +1,5 @@ import { convex, convexApi } from '@/app.ts'; +import { User } from '@/models/user.ts'; import { IncomingMessage, ServerResponse } from 'http'; type ProxyOptions = { @@ -19,11 +20,33 @@ export const N5Proxy = async (req: IncomingMessage, res: ServerResponse, opts?: opts?.createNotFoundPage?.('应用未找到'); return false; } - const link = convexResult.data.link; + const data = convexResult.data ?? {}; + const link = data.link; if (!link) { opts?.createNotFoundPage?.('应用未找到'); return false; } + if (data?.useOwnerToken) { + const userId = convexResult.userId; + if (!userId) { + opts?.createNotFoundPage?.('未绑定账号'); + return false; + } + try { + const user = await User.findByPk(userId); + const token = await User.createJwksTokenResponse({ id: userId, username: user?.username || '' }, { save: false }); + 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: 'Failed to fetch the link' })); + } + + return true; + } res.writeHead(302, { Location: link, });