* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* fix

* Update SignupApiService.ts

* wip

* wip

* Update ClientServerService.ts

* wip

* wip

* wip

* Update WellKnownServerService.ts

* wip

* wip

* update des

* wip

* Update ApiServerService.ts

* wip

* update deps

* Update WellKnownServerService.ts

* wip

* update deps

* Update ApiCallService.ts

* Update ApiCallService.ts

* Update ApiServerService.ts
This commit is contained in:
syuilo 2022-12-03 19:42:05 +09:00 committed by GitHub
parent 2db9f6efe7
commit 3a7182bfb5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 1651 additions and 1977 deletions

View file

@ -2,10 +2,8 @@ import * as fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import { Inject, Injectable } from '@nestjs/common';
import Koa from 'koa';
import cors from '@koa/cors';
import Router from '@koa/router';
import send from 'koa-send';
import { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify';
import fastifyStatic from '@fastify/static';
import rename from 'rename';
import type { Config } from '@/config.js';
import type { DriveFilesRepository } from '@/models/index.js';
@ -46,45 +44,44 @@ export class FileServerService {
private loggerService: LoggerService,
) {
this.logger = this.loggerService.getLogger('server', 'gray', false);
this.createServer = this.createServer.bind(this);
}
public commonReadableHandlerGenerator(ctx: Koa.Context) {
return (e: Error): void => {
this.logger.error(e);
ctx.status = 500;
ctx.set('Cache-Control', 'max-age=300');
public commonReadableHandlerGenerator(reply: FastifyReply) {
return (err: Error): void => {
this.logger.error(err);
reply.code(500);
reply.header('Cache-Control', 'max-age=300');
};
}
public createServer() {
const app = new Koa();
app.use(cors());
app.use(async (ctx, next) => {
ctx.set('Content-Security-Policy', 'default-src \'none\'; img-src \'self\'; media-src \'self\'; style-src \'unsafe-inline\'');
await next();
public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) {
fastify.addHook('onRequest', (request, reply, done) => {
reply.header('Content-Security-Policy', 'default-src \'none\'; img-src \'self\'; media-src \'self\'; style-src \'unsafe-inline\'');
done();
});
// Init router
const router = new Router();
fastify.register(fastifyStatic, {
root: _dirname,
serve: false,
});
router.get('/app-default.jpg', ctx => {
fastify.get('/app-default.jpg', (request, reply) => {
const file = fs.createReadStream(`${_dirname}/assets/dummy.png`);
ctx.body = file;
ctx.set('Content-Type', 'image/jpeg');
ctx.set('Cache-Control', 'max-age=31536000, immutable');
reply.header('Content-Type', 'image/jpeg');
reply.header('Cache-Control', 'max-age=31536000, immutable');
return reply.send(file);
});
router.get('/:key', ctx => this.sendDriveFile(ctx));
router.get('/:key/(.*)', ctx => this.sendDriveFile(ctx));
fastify.get<{ Params: { key: string; } }>('/:key', async (request, reply) => await this.sendDriveFile(request, reply));
fastify.get<{ Params: { key: string; } }>('/:key/*', async (request, reply) => await this.sendDriveFile(request, reply));
// Register router
app.use(router.routes());
return app;
done();
}
private async sendDriveFile(ctx: Koa.Context) {
const key = ctx.params.key;
private async sendDriveFile(request: FastifyRequest<{ Params: { key: string; } }>, reply: FastifyReply) {
const key = request.params.key;
// Fetch drive file
const file = await this.driveFilesRepository.createQueryBuilder('file')
@ -94,10 +91,9 @@ export class FileServerService {
.getOne();
if (file == null) {
ctx.status = 404;
ctx.set('Cache-Control', 'max-age=86400');
await send(ctx as any, '/dummy.png', { root: assets });
return;
reply.code(404);
reply.header('Cache-Control', 'max-age=86400');
return reply.sendFile('/dummy.png', assets);
}
const isThumbnail = file.thumbnailAccessKey === key;
@ -135,18 +131,18 @@ export class FileServerService {
};
const image = await convertFile();
ctx.body = image.data;
ctx.set('Content-Type', FILE_TYPE_BROWSERSAFE.includes(image.type) ? image.type : 'application/octet-stream');
ctx.set('Cache-Control', 'max-age=31536000, immutable');
reply.header('Content-Type', FILE_TYPE_BROWSERSAFE.includes(image.type) ? image.type : 'application/octet-stream');
reply.header('Cache-Control', 'max-age=31536000, immutable');
return image.data;
} catch (err) {
this.logger.error(`${err}`);
if (err instanceof StatusError && err.isClientError) {
ctx.status = err.statusCode;
ctx.set('Cache-Control', 'max-age=86400');
reply.code(err.statusCode);
reply.header('Cache-Control', 'max-age=86400');
} else {
ctx.status = 500;
ctx.set('Cache-Control', 'max-age=300');
reply.code(500);
reply.header('Cache-Control', 'max-age=300');
}
} finally {
cleanup();
@ -154,8 +150,8 @@ export class FileServerService {
return;
}
ctx.status = 204;
ctx.set('Cache-Control', 'max-age=86400');
reply.code(204);
reply.header('Cache-Control', 'max-age=86400');
return;
}
@ -166,18 +162,17 @@ export class FileServerService {
extname: ext ? `.${ext}` : undefined,
}).toString();
ctx.body = this.internalStorageService.read(key);
ctx.set('Content-Type', FILE_TYPE_BROWSERSAFE.includes(mime) ? mime : 'application/octet-stream');
ctx.set('Cache-Control', 'max-age=31536000, immutable');
ctx.set('Content-Disposition', contentDisposition('inline', filename));
reply.header('Content-Type', FILE_TYPE_BROWSERSAFE.includes(mime) ? mime : 'application/octet-stream');
reply.header('Cache-Control', 'max-age=31536000, immutable');
reply.header('Content-Disposition', contentDisposition('inline', filename));
return this.internalStorageService.read(key);
} else {
const readable = this.internalStorageService.read(file.accessKey!);
readable.on('error', this.commonReadableHandlerGenerator(ctx));
ctx.body = readable;
ctx.set('Content-Type', FILE_TYPE_BROWSERSAFE.includes(file.type) ? file.type : 'application/octet-stream');
ctx.set('Cache-Control', 'max-age=31536000, immutable');
ctx.set('Content-Disposition', contentDisposition('inline', file.name));
readable.on('error', this.commonReadableHandlerGenerator(reply));
reply.header('Content-Type', FILE_TYPE_BROWSERSAFE.includes(file.type) ? file.type : 'application/octet-stream');
reply.header('Cache-Control', 'max-age=31536000, immutable');
reply.header('Content-Disposition', contentDisposition('inline', file.name));
return readable;
}
}
}