diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2023-01-16 15:21:43 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2023-01-16 15:21:43 +0900 |
| commit | d56fc4186529bf41fe840cb3497f1a363ac84475 (patch) | |
| tree | e4da77fc7544fb8d5619e9799ee9ce3494ccd80b /packages/backend/src/server/api/ApiServerService.ts | |
| parent | masterブランチをmaster_securityとマージ (#9260) (diff) | |
| parent | 13.0.0 (diff) | |
| download | misskey-d56fc4186529bf41fe840cb3497f1a363ac84475.tar.gz misskey-d56fc4186529bf41fe840cb3497f1a363ac84475.tar.bz2 misskey-d56fc4186529bf41fe840cb3497f1a363ac84475.zip | |
Merge branch 'develop'
Diffstat (limited to 'packages/backend/src/server/api/ApiServerService.ts')
| -rw-r--r-- | packages/backend/src/server/api/ApiServerService.ts | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/packages/backend/src/server/api/ApiServerService.ts b/packages/backend/src/server/api/ApiServerService.ts new file mode 100644 index 0000000000..b29c9616cc --- /dev/null +++ b/packages/backend/src/server/api/ApiServerService.ts @@ -0,0 +1,175 @@ +import { Inject, Injectable } from '@nestjs/common'; +import cors from '@fastify/cors'; +import multipart from '@fastify/multipart'; +import fastifyCookie from '@fastify/cookie'; +import { ModuleRef, repl } from '@nestjs/core'; +import type { Config } from '@/config.js'; +import type { UsersRepository, InstancesRepository, AccessTokensRepository } from '@/models/index.js'; +import { DI } from '@/di-symbols.js'; +import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { bindThis } from '@/decorators.js'; +import endpoints, { IEndpoint } from './endpoints.js'; +import { ApiCallService } from './ApiCallService.js'; +import { SignupApiService } from './SignupApiService.js'; +import { SigninApiService } from './SigninApiService.js'; +import { GithubServerService } from './integration/GithubServerService.js'; +import { DiscordServerService } from './integration/DiscordServerService.js'; +import { TwitterServerService } from './integration/TwitterServerService.js'; +import type { FastifyInstance, FastifyPluginOptions } from 'fastify'; + +@Injectable() +export class ApiServerService { + constructor( + private moduleRef: ModuleRef, + + @Inject(DI.config) + private config: Config, + + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + + @Inject(DI.instancesRepository) + private instancesRepository: InstancesRepository, + + @Inject(DI.accessTokensRepository) + private accessTokensRepository: AccessTokensRepository, + + private userEntityService: UserEntityService, + private apiCallService: ApiCallService, + private signupApiService: SignupApiService, + private signinApiService: SigninApiService, + private githubServerService: GithubServerService, + private discordServerService: DiscordServerService, + private twitterServerService: TwitterServerService, + ) { + //this.createServer = this.createServer.bind(this); + } + + @bindThis + public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) { + fastify.register(cors, { + origin: '*', + }); + + fastify.register(multipart, { + limits: { + fileSize: this.config.maxFileSize ?? 262144000, + files: 1, + }, + }); + + fastify.register(fastifyCookie, {}); + + // Prevent cache + fastify.addHook('onRequest', (request, reply, done) => { + reply.header('Cache-Control', 'private, max-age=0, must-revalidate'); + done(); + }); + + for (const endpoint of endpoints) { + const ep = { + name: endpoint.name, + meta: endpoint.meta, + params: endpoint.params, + exec: this.moduleRef.get('ep:' + endpoint.name, { strict: false }).exec, + }; + + if (endpoint.meta.requireFile) { + fastify.all<{ + Params: { endpoint: string; }, + Body: Record<string, unknown>, + Querystring: Record<string, unknown>, + }>('/' + endpoint.name, (request, reply) => { + if (request.method === 'GET' && !endpoint.meta.allowGet) { + reply.code(405); + reply.send(); + return; + } + + this.apiCallService.handleMultipartRequest(ep, request, reply); + }); + } else { + fastify.all<{ + Params: { endpoint: string; }, + Body: Record<string, unknown>, + Querystring: Record<string, unknown>, + }>('/' + endpoint.name, { bodyLimit: 1024 * 32 }, (request, reply) => { + if (request.method === 'GET' && !endpoint.meta.allowGet) { + reply.code(405); + reply.send(); + return; + } + + this.apiCallService.handleRequest(ep, request, reply); + }); + } + } + + fastify.post<{ + Body: { + username: string; + password: string; + host?: string; + invitationCode?: string; + emailAddress?: string; + 'hcaptcha-response'?: string; + 'g-recaptcha-response'?: string; + 'turnstile-response'?: string; + } + }>('/signup', (request, reply) => this.signupApiService.signup(request, reply)); + + fastify.post<{ + Body: { + username: string; + password: string; + token?: string; + signature?: string; + authenticatorData?: string; + clientDataJSON?: string; + credentialId?: string; + challengeId?: string; + }; + }>('/signin', (request, reply) => this.signinApiService.signin(request, reply)); + + fastify.post<{ Body: { code: string; } }>('/signup-pending', (request, reply) => this.signupApiService.signupPending(request, reply)); + + fastify.register(this.discordServerService.create); + fastify.register(this.githubServerService.create); + fastify.register(this.twitterServerService.create); + + fastify.get('/v1/instance/peers', async (request, reply) => { + const instances = await this.instancesRepository.find({ + select: ['host'], + where: { + isSuspended: false, + }, + }); + + return instances.map(instance => instance.host); + }); + + fastify.post<{ Params: { session: string; } }>('/miauth/:session/check', async (request, reply) => { + const token = await this.accessTokensRepository.findOneBy({ + session: request.params.session, + }); + + if (token && token.session != null && !token.fetched) { + this.accessTokensRepository.update(token.id, { + fetched: true, + }); + + return { + ok: true, + token: token.token, + user: await this.userEntityService.pack(token.userId, null, { detail: true }), + }; + } else { + return { + ok: false, + }; + } + }); + + done(); + } +} |