feat: admin page proxy
This commit is contained in:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -15,5 +15,8 @@
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": true
|
||||
},
|
||||
"material-icon-theme.activeIconPack": "nest"
|
||||
"material-icon-theme.activeIconPack": "nest",
|
||||
"cSpell.words": [
|
||||
"qaqdmin"
|
||||
]
|
||||
}
|
||||
@@ -27,7 +27,7 @@ type myError = {
|
||||
|
||||
@Catch()
|
||||
export class AllExceptionsFilter implements ExceptionFilter {
|
||||
private readonly logger = new Logger('捕获异常')
|
||||
private readonly logger = new Logger(AllExceptionsFilter.name)
|
||||
private readonly errorLogPipe: WriteStream
|
||||
constructor(@Inject(REFLECTOR) private reflector: Reflector) {
|
||||
this.errorLogPipe = fs.createWriteStream(resolve(LOGGER_DIR, 'error.log'), {
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { Injectable, NestMiddleware } from '@nestjs/common'
|
||||
import { Injectable, Logger, NestMiddleware } from '@nestjs/common'
|
||||
import { IncomingMessage, ServerResponse } from 'http'
|
||||
import { parseRelativeUrl } from '~/utils/ip.util'
|
||||
// 用于屏蔽 PHP 的请求
|
||||
|
||||
@Injectable()
|
||||
export class SecurityMiddleware implements NestMiddleware {
|
||||
private logger: Logger
|
||||
constructor() {
|
||||
this.logger = new Logger(SecurityMiddleware.name)
|
||||
}
|
||||
async use(req: IncomingMessage, res: ServerResponse, next: () => void) {
|
||||
// @ts-ignore
|
||||
const url = parseRelativeUrl(req.originalUrl).pathname
|
||||
|
||||
@@ -155,4 +155,15 @@ export class AdminExtraDto {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
gaodemapKey?: string
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
title?: string
|
||||
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
/**
|
||||
* 是否开启后台反代访问
|
||||
*/
|
||||
enableAdminProxy?: boolean
|
||||
}
|
||||
|
||||
@@ -51,12 +51,13 @@ export class ConfigsService {
|
||||
this.logger = new Logger(ConfigsService.name)
|
||||
}
|
||||
private configInitd = false
|
||||
|
||||
public waitForConfigReady() {
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise<IConfig>(async (r, j) => {
|
||||
return new Promise<Readonly<IConfig>>(async (r, j) => {
|
||||
// 开始等待, 后续调用直接返回
|
||||
if (this.configInitd) {
|
||||
r(this.config)
|
||||
r(this.getConfig())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -64,7 +65,7 @@ export class ConfigsService {
|
||||
let curCount = 0
|
||||
do {
|
||||
if (this.configInitd) {
|
||||
r({ ...this.config })
|
||||
r(this.getConfig())
|
||||
return
|
||||
}
|
||||
await sleep(100)
|
||||
|
||||
@@ -1,14 +1,46 @@
|
||||
import { Controller, Get, Header } from '@nestjs/common'
|
||||
import { HttpCache } from '~/common/decorator/cache.decorator'
|
||||
import { HTTPDecorators } from '~/common/decorator/http.decorator'
|
||||
import { ApiName } from '~/common/decorator/openapi.decorator'
|
||||
import { ConfigsService } from '../configs/configs.service'
|
||||
|
||||
@Controller()
|
||||
interface IInjectableData {
|
||||
BASE_API: null | string
|
||||
WEB_URL: null | string
|
||||
GATEWAY: null | string
|
||||
LOGIN_BG: null | string
|
||||
TITLE: null | string
|
||||
}
|
||||
|
||||
@Controller('/')
|
||||
@ApiName
|
||||
export class PageProxyController {
|
||||
@Get('/admin')
|
||||
constructor(private readonly configs: ConfigsService) {}
|
||||
|
||||
@Get('/qaqdmin')
|
||||
@Header('Content-Type', 'text/html')
|
||||
@HTTPDecorators.Bypass
|
||||
proxyAdmin() {
|
||||
return ''
|
||||
@HttpCache({ disable: true })
|
||||
async proxyAdmin() {
|
||||
const {
|
||||
adminExtra,
|
||||
url: { wsUrl, serverUrl, webUrl },
|
||||
} = await this.configs.waitForConfigReady()
|
||||
if (!adminExtra.enableAdminProxy) {
|
||||
return '<h1>Admin Proxy is disabled</h1>'
|
||||
}
|
||||
const indexEntryUrl = `https://cdn.jsdelivr.net/gh/mx-space/admin-next@gh-pages/index.html`
|
||||
let entry = await (await fetch(indexEntryUrl)).text()
|
||||
entry = entry.replace(
|
||||
`<!-- injectable script -->`,
|
||||
`<script>${`window.injectData = ${JSON.stringify({
|
||||
BASE_API: serverUrl,
|
||||
GATEWAY: wsUrl,
|
||||
LOGIN_BG: adminExtra.background,
|
||||
TITLE: adminExtra.title,
|
||||
WEB_URL: webUrl,
|
||||
} as IInjectableData)}`}</script>`,
|
||||
)
|
||||
return entry
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user