mirror of
https://github.com/immich-app/immich
synced 2026-08-29 13:15:45 +00:00
feat: add SSR to maintenance API
This commit is contained in:
parent
598b1f87a1
commit
998675f48c
5 changed files with 44 additions and 13 deletions
|
|
@ -10,6 +10,7 @@ import { ConfigRepository } from 'src/repositories/config.repository';
|
|||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { bootstrapTelemetry } from 'src/repositories/telemetry.repository';
|
||||
import { ApiService } from 'src/services/api.service';
|
||||
import { MaintenanceWorkerService } from 'src/services/maintenance-worker.service';
|
||||
import { useSwagger } from 'src/utils/misc';
|
||||
|
||||
export function configureTelemetry() {
|
||||
|
|
@ -23,7 +24,7 @@ export async function configureExpress(
|
|||
app: NestExpressApplication,
|
||||
{
|
||||
permitSwaggerWrite = true,
|
||||
ssr = true,
|
||||
ssr,
|
||||
}: {
|
||||
/**
|
||||
* Whether to allow swagger module to write to the specs.json
|
||||
|
|
@ -32,12 +33,10 @@ export async function configureExpress(
|
|||
*/
|
||||
permitSwaggerWrite?: boolean;
|
||||
/**
|
||||
* Whether to enable server-side rendering
|
||||
* @requires ApiService
|
||||
* @default true
|
||||
* Service to use for server-side rendering
|
||||
*/
|
||||
ssr?: boolean;
|
||||
} = {},
|
||||
ssr: typeof ApiService | typeof MaintenanceWorkerService;
|
||||
},
|
||||
) {
|
||||
const configRepository = app.get(ConfigRepository);
|
||||
const { environment, host, port, resourcePaths, network } = configRepository.getEnv();
|
||||
|
|
@ -78,10 +77,7 @@ export async function configureExpress(
|
|||
);
|
||||
}
|
||||
|
||||
if (ssr) {
|
||||
app.use(app.get(ApiService).ssr(excludePaths));
|
||||
}
|
||||
|
||||
app.use(app.get(ssr).ssr(excludePaths));
|
||||
app.use(compression());
|
||||
|
||||
const server = await (host ? app.listen(port, host) : app.listen(port));
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { SharedLinkService } from 'src/services/shared-link.service';
|
|||
import { VersionService } from 'src/services/version.service';
|
||||
import { OpenGraphTags } from 'src/utils/misc';
|
||||
|
||||
const render = (index: string, meta: OpenGraphTags) => {
|
||||
export const render = (index: string, meta: OpenGraphTags) => {
|
||||
const [title, description, imageUrl] = [meta.title, meta.description, meta.imageUrl].map((item) =>
|
||||
item ? sanitizeHtml(item, { allowedTags: [] }) : '',
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { BadRequestException, Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { parse } from 'cookie';
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { jwtVerify } from 'jose';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { IncomingHttpHeaders } from 'node:http';
|
||||
import { MaintenanceAuthDto } from 'src/dtos/maintenance.dto';
|
||||
import { ImmichCookie, SystemMetadataKey } from 'src/enum';
|
||||
|
|
@ -109,4 +111,34 @@ export class MaintenanceWorkerService {
|
|||
await this.systemMetadataRepository.set(SystemMetadataKey.MaintenanceMode, state);
|
||||
this.maintenanceWorkerRepository.restartApp(state);
|
||||
}
|
||||
|
||||
ssr(excludePaths: string[]) {
|
||||
const { resourcePaths } = this.configRepository.getEnv();
|
||||
|
||||
let index = '';
|
||||
try {
|
||||
index = readFileSync(resourcePaths.web.indexHtml).toString();
|
||||
} catch {
|
||||
this.logger.warn(`Unable to open ${resourcePaths.web.indexHtml}, skipping SSR.`);
|
||||
}
|
||||
|
||||
return async (request: Request, res: Response, next: NextFunction) => {
|
||||
if (
|
||||
request.url.startsWith('/api') ||
|
||||
request.method.toLowerCase() !== 'get' ||
|
||||
excludePaths.some((item) => request.url.startsWith(item))
|
||||
) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const shareKey = request.url.match(/^\/share\/(.+)$/);
|
||||
const shareSlug = request.url.match(/^\/s\/(.+)$/);
|
||||
|
||||
res
|
||||
.status(shareKey || shareSlug ? 500 : 200)
|
||||
.type('text/html')
|
||||
.header('Cache-Control', 'no-store')
|
||||
.send(index);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { NestExpressApplication } from '@nestjs/platform-express';
|
|||
import { configureExpress, configureTelemetry } from 'src/app.common';
|
||||
import { ApiModule } from 'src/app.module';
|
||||
import { MaintenanceRepository } from 'src/repositories/maintenance.repository';
|
||||
import { ApiService } from 'src/services/api.service';
|
||||
import { isStartUpError } from 'src/utils/misc';
|
||||
|
||||
async function bootstrap() {
|
||||
|
|
@ -13,7 +14,9 @@ async function bootstrap() {
|
|||
const app = await NestFactory.create<NestExpressApplication>(ApiModule, { bufferLogs: true });
|
||||
app.get(MaintenanceRepository).setCloseFn(() => app.close());
|
||||
|
||||
void configureExpress(app);
|
||||
void configureExpress(app, {
|
||||
ssr: ApiService,
|
||||
});
|
||||
}
|
||||
|
||||
bootstrap().catch((error) => {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ async function bootstrap() {
|
|||
app.get(MaintenanceRepository).setCloseFn(() => app.close());
|
||||
void configureExpress(app, {
|
||||
permitSwaggerWrite: false,
|
||||
ssr: false,
|
||||
ssr: MaintenanceWorkerService,
|
||||
});
|
||||
|
||||
void app.get(MaintenanceWorkerService).logSecret();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue