feat: auto download admin (#1005
* feat: auto download admin Signed-off-by: Innei <tukon479@gmail.com> * fix: update Signed-off-by: Innei <tukon479@gmail.com> * fix: update Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { isNull } from 'lodash'
|
||||
import { lookup } from 'mime-types'
|
||||
import PKG from 'package.json'
|
||||
import { extname, join } from 'path'
|
||||
import { Observable } from 'rxjs'
|
||||
|
||||
import {
|
||||
Controller,
|
||||
@@ -24,6 +25,7 @@ import { CacheService } from '~/processors/redis/cache.service'
|
||||
import { getRedisKey } from '~/utils/redis.util'
|
||||
|
||||
import { dashboard } from '../../../package.json'
|
||||
import { UpdateService } from '../update/update.service'
|
||||
import { PageProxyDebugDto } from './pageproxy.dto'
|
||||
import { PageProxyService } from './pageproxy.service'
|
||||
|
||||
@@ -33,6 +35,7 @@ export class PageProxyController {
|
||||
constructor(
|
||||
private readonly cacheService: CacheService,
|
||||
private readonly service: PageProxyService,
|
||||
private readonly updateService: UpdateService,
|
||||
) {}
|
||||
|
||||
@Get('/qaqdmin')
|
||||
@@ -150,21 +153,97 @@ export class PageProxyController {
|
||||
return reply.type('text/html').send(entry)
|
||||
}
|
||||
|
||||
private fetchObserver$: Observable<string> | null
|
||||
private fetchLogs: string[] | null
|
||||
private fetchErrorMsg: string | null
|
||||
|
||||
@Get('/proxy/qaqdmin')
|
||||
@HTTPDecorators.Bypass
|
||||
async getLocalBundledAdmin(@Res() reply: FastifyReply) {
|
||||
async getLocalBundledAdmin(@Query() query: any, @Res() reply: FastifyReply) {
|
||||
if ((await this.service.checkCanAccessAdminProxy()) === false) {
|
||||
return reply.type('application/json').status(403).send({
|
||||
message: 'admin proxy not enabled',
|
||||
})
|
||||
}
|
||||
if (this.fetchObserver$ && query.log) {
|
||||
if (this.fetchLogs === null) {
|
||||
return reply.code(204)
|
||||
}
|
||||
const log = this.fetchLogs.pop() || '...'
|
||||
|
||||
reply.code(200).type('text/html').send(`${log}`)
|
||||
return
|
||||
}
|
||||
|
||||
if (query.log) {
|
||||
if (this.fetchErrorMsg) {
|
||||
reply.code(403).type('text/html').send(this.fetchErrorMsg)
|
||||
this.fetchErrorMsg = null
|
||||
} else {
|
||||
reply.code(200).type('text/html').send('...')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const entryPath = path.join(LOCAL_ADMIN_ASSET_PATH, 'index.html')
|
||||
const isAssetPathIsExist = existsSync(entryPath)
|
||||
if (!isAssetPathIsExist) {
|
||||
this.fetchLogs = []
|
||||
reply.code(404).type('text/html')
|
||||
.send(`<p>Local Admin Assets is not found. Navigator to page proxy in 3 second. </p><script>setTimeout(() => {
|
||||
location.href = '/qaqdmin'
|
||||
}, 3000);</script>`)
|
||||
.send(`<script src="https://cdn.jsdelivr.net/npm/ansi_up@4.0.3/ansi_up.js"></script>
|
||||
<p>Local Admin Assets is not found. Downloading start... </p>
|
||||
<p>If finished download but page not reload or logs are not output for a period of time, please reload page manually. </p>
|
||||
<pre id="block"></pre>
|
||||
<script>
|
||||
var txt = '';
|
||||
var lastLine = ''
|
||||
var ansi_up = new AnsiUp();
|
||||
var cdiv = document.getElementById("block");
|
||||
var timer = setInterval(function() {
|
||||
fetch('?log=1')
|
||||
.catch(() => {
|
||||
clearInterval(timer)
|
||||
})
|
||||
.then(res => {
|
||||
if(res.status === 204) {
|
||||
clearInterval(timer)
|
||||
window.location.reload()
|
||||
return
|
||||
}
|
||||
return res
|
||||
})
|
||||
.then(res => res.text()).then(text => {
|
||||
if(!text) window.location.reload()
|
||||
if(lastLine === text) return
|
||||
txt += text + '\\n'
|
||||
lastLine = text
|
||||
var html = ansi_up.ansi_to_html(txt);
|
||||
cdiv.innerHTML = html;
|
||||
})
|
||||
}, 1000)
|
||||
</script>`)
|
||||
|
||||
this.fetchObserver$ = this.updateService.downloadAdminAsset(
|
||||
await this.updateService.getLatestAdminVersion().catch((err) => {
|
||||
this.fetchErrorMsg = err.message
|
||||
|
||||
throw err
|
||||
}),
|
||||
)
|
||||
|
||||
const cleanup = () => {
|
||||
this.fetchObserver$ = null
|
||||
this.fetchLogs = null
|
||||
}
|
||||
|
||||
this.fetchObserver$.subscribe({
|
||||
next: (value) => {
|
||||
this.fetchLogs?.push(value)
|
||||
},
|
||||
error: cleanup,
|
||||
complete: cleanup,
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
|
||||
import { UpdateModule } from '../update/update.module'
|
||||
import { PageProxyController } from './pageproxy.controller'
|
||||
import { PageProxyService } from './pageproxy.service'
|
||||
|
||||
@Module({
|
||||
controllers: [PageProxyController],
|
||||
providers: [PageProxyService],
|
||||
imports: [UpdateModule],
|
||||
})
|
||||
export class PageProxyModule {}
|
||||
|
||||
@@ -6,5 +6,6 @@ import { UpdateService } from './update.service'
|
||||
@Module({
|
||||
controllers: [UpdateController],
|
||||
providers: [UpdateService],
|
||||
exports: [UpdateService],
|
||||
})
|
||||
export class UpdateModule {}
|
||||
|
||||
@@ -31,6 +31,8 @@ export class UpdateService {
|
||||
})
|
||||
|
||||
if (!json) {
|
||||
subscriber.next(chalk.red('Fetching error, json is empty. \n'))
|
||||
subscriber.complete()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -130,7 +132,7 @@ export class UpdateService {
|
||||
return res.data.tag_name.replace(/^v/, '')
|
||||
}
|
||||
|
||||
runShellCommandPipeOutput(
|
||||
private runShellCommandPipeOutput(
|
||||
command: string,
|
||||
args: any[],
|
||||
subscriber: Subscriber<string>,
|
||||
|
||||
Reference in New Issue
Block a user