test
This commit is contained in:
parent
92c78218bc
commit
a2eac9fff6
82 changed files with 671 additions and 671 deletions
|
@ -58,7 +58,7 @@ export class ActivityPubServerService {
|
|||
) {
|
||||
}
|
||||
|
||||
#setResponseType(ctx: Router.RouterContext) {
|
||||
private setResponseType(ctx: Router.RouterContext) {
|
||||
const accept = ctx.accepts(ACTIVITY_JSON, LD_JSON);
|
||||
if (accept === LD_JSON) {
|
||||
ctx.response.type = LD_JSON;
|
||||
|
@ -71,7 +71,7 @@ export class ActivityPubServerService {
|
|||
* Pack Create<Note> or Announce Activity
|
||||
* @param note Note
|
||||
*/
|
||||
async #packActivity(note: Note): Promise<any> {
|
||||
private async packActivity(note: Note): Promise<any> {
|
||||
if (note.renoteId && note.text == null && !note.hasPoll && (note.fileIds == null || note.fileIds.length === 0)) {
|
||||
const renote = await Notes.findOneByOrFail({ id: note.renoteId });
|
||||
return this.apRendererService.renderAnnounce(renote.uri ? renote.uri : `${this.config.url}/notes/${renote.id}`, note);
|
||||
|
@ -80,7 +80,7 @@ export class ActivityPubServerService {
|
|||
return this.apRendererService.renderCreate(await this.apRendererService.renderNote(note, false), note);
|
||||
}
|
||||
|
||||
#inbox(ctx: Router.RouterContext) {
|
||||
private inbox(ctx: Router.RouterContext) {
|
||||
let signature;
|
||||
|
||||
try {
|
||||
|
@ -95,7 +95,7 @@ export class ActivityPubServerService {
|
|||
ctx.status = 202;
|
||||
}
|
||||
|
||||
async #followers(ctx: Router.RouterContext) {
|
||||
private async followers(ctx: Router.RouterContext) {
|
||||
const userId = ctx.params.user;
|
||||
|
||||
const cursor = ctx.request.query.cursor;
|
||||
|
@ -169,17 +169,17 @@ export class ActivityPubServerService {
|
|||
);
|
||||
|
||||
ctx.body = this.apRendererService.renderActivity(rendered);
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
} else {
|
||||
// index page
|
||||
const rendered = this.apRendererService.renderOrderedCollection(partOf, user.followersCount, `${partOf}?page=true`);
|
||||
ctx.body = this.apRendererService.renderActivity(rendered);
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
async #following(ctx: Router.RouterContext) {
|
||||
private async following(ctx: Router.RouterContext) {
|
||||
const userId = ctx.params.user;
|
||||
|
||||
const cursor = ctx.request.query.cursor;
|
||||
|
@ -253,17 +253,17 @@ export class ActivityPubServerService {
|
|||
);
|
||||
|
||||
ctx.body = this.apRendererService.renderActivity(rendered);
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
} else {
|
||||
// index page
|
||||
const rendered = this.apRendererService.renderOrderedCollection(partOf, user.followingCount, `${partOf}?page=true`);
|
||||
ctx.body = this.apRendererService.renderActivity(rendered);
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
async #featured(ctx: Router.RouterContext) {
|
||||
private async featured(ctx: Router.RouterContext) {
|
||||
const userId = ctx.params.user;
|
||||
|
||||
const user = await this.usersRepository.findOneBy({
|
||||
|
@ -293,10 +293,10 @@ export class ActivityPubServerService {
|
|||
|
||||
ctx.body = this.apRendererService.renderActivity(rendered);
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
}
|
||||
|
||||
async #outbox(ctx: Router.RouterContext) {
|
||||
private async outbox(ctx: Router.RouterContext) {
|
||||
const userId = ctx.params.user;
|
||||
|
||||
const sinceId = ctx.request.query.since_id;
|
||||
|
@ -344,7 +344,7 @@ export class ActivityPubServerService {
|
|||
|
||||
if (sinceId) notes.reverse();
|
||||
|
||||
const activities = await Promise.all(notes.map(note => this.#packActivity(note)));
|
||||
const activities = await Promise.all(notes.map(note => this.packActivity(note)));
|
||||
const rendered = this.apRendererService.renderOrderedCollectionPage(
|
||||
`${partOf}?${url.query({
|
||||
page: 'true',
|
||||
|
@ -363,7 +363,7 @@ export class ActivityPubServerService {
|
|||
);
|
||||
|
||||
ctx.body = this.apRendererService.renderActivity(rendered);
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
} else {
|
||||
// index page
|
||||
const rendered = this.apRendererService.renderOrderedCollection(partOf, user.notesCount,
|
||||
|
@ -372,11 +372,11 @@ export class ActivityPubServerService {
|
|||
);
|
||||
ctx.body = this.apRendererService.renderActivity(rendered);
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
async #userInfo(ctx: Router.RouterContext, user: User | null) {
|
||||
private async userInfo(ctx: Router.RouterContext, user: User | null) {
|
||||
if (user == null) {
|
||||
ctx.status = 404;
|
||||
return;
|
||||
|
@ -384,7 +384,7 @@ export class ActivityPubServerService {
|
|||
|
||||
ctx.body = this.apRendererService.renderActivity(await this.apRendererService.renderPerson(user as ILocalUser));
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
}
|
||||
|
||||
public createRouter() {
|
||||
|
@ -399,8 +399,8 @@ export class ActivityPubServerService {
|
|||
}
|
||||
|
||||
// inbox
|
||||
router.post('/inbox', json(), ctx => this.#inbox(ctx));
|
||||
router.post('/users/:user/inbox', json(), ctx => this.#inbox(ctx));
|
||||
router.post('/inbox', json(), ctx => this.inbox(ctx));
|
||||
router.post('/users/:user/inbox', json(), ctx => this.inbox(ctx));
|
||||
|
||||
// note
|
||||
router.get('/notes/:note', async (ctx, next) => {
|
||||
|
@ -429,7 +429,7 @@ export class ActivityPubServerService {
|
|||
|
||||
ctx.body = this.apRendererService.renderActivity(await this.apRendererService.renderNote(note, false));
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
});
|
||||
|
||||
// note activity
|
||||
|
@ -446,22 +446,22 @@ export class ActivityPubServerService {
|
|||
return;
|
||||
}
|
||||
|
||||
ctx.body = this.apRendererService.renderActivity(await this.#packActivity(note));
|
||||
ctx.body = this.apRendererService.renderActivity(await this.packActivity(note));
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
});
|
||||
|
||||
// outbox
|
||||
router.get('/users/:user/outbox', (ctx) => this.#outbox(ctx));
|
||||
router.get('/users/:user/outbox', (ctx) => this.outbox(ctx));
|
||||
|
||||
// followers
|
||||
router.get('/users/:user/followers', (ctx) => this.#followers(ctx));
|
||||
router.get('/users/:user/followers', (ctx) => this.followers(ctx));
|
||||
|
||||
// following
|
||||
router.get('/users/:user/following', (ctx) => this.#following(ctx));
|
||||
router.get('/users/:user/following', (ctx) => this.following(ctx));
|
||||
|
||||
// featured
|
||||
router.get('/users/:user/collections/featured', (ctx) => this.#featured(ctx));
|
||||
router.get('/users/:user/collections/featured', (ctx) => this.featured(ctx));
|
||||
|
||||
// publickey
|
||||
router.get('/users/:user/publickey', async ctx => {
|
||||
|
@ -482,7 +482,7 @@ export class ActivityPubServerService {
|
|||
if (this.userEntityService.isLocalUser(user)) {
|
||||
ctx.body = this.apRendererService.renderActivity(this.apRendererService.renderKey(user, keypair));
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
} else {
|
||||
ctx.status = 400;
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ export class ActivityPubServerService {
|
|||
isSuspended: false,
|
||||
});
|
||||
|
||||
await this.#userInfo(ctx, user);
|
||||
await this.userInfo(ctx, user);
|
||||
});
|
||||
|
||||
router.get('/@:user', async (ctx, next) => {
|
||||
|
@ -511,7 +511,7 @@ export class ActivityPubServerService {
|
|||
isSuspended: false,
|
||||
});
|
||||
|
||||
await this.#userInfo(ctx, user);
|
||||
await this.userInfo(ctx, user);
|
||||
});
|
||||
//#endregion
|
||||
|
||||
|
@ -529,7 +529,7 @@ export class ActivityPubServerService {
|
|||
|
||||
ctx.body = this.apRendererService.renderActivity(await this.apRendererService.renderEmoji(emoji));
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
});
|
||||
|
||||
// like
|
||||
|
@ -550,7 +550,7 @@ export class ActivityPubServerService {
|
|||
|
||||
ctx.body = this.apRendererService.renderActivity(await this.apRendererService.renderLike(reaction, note));
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
});
|
||||
|
||||
// follow
|
||||
|
@ -576,7 +576,7 @@ export class ActivityPubServerService {
|
|||
|
||||
ctx.body = this.apRendererService.renderActivity(this.apRendererService.renderFollow(follower, followee));
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
this.#setResponseType(ctx);
|
||||
this.setResponseType(ctx);
|
||||
});
|
||||
|
||||
return router;
|
||||
|
|
|
@ -29,7 +29,7 @@ const assets = `${_dirname}/../../server/file/assets/`;
|
|||
|
||||
@Injectable()
|
||||
export class FileServerService {
|
||||
#logger: Logger;
|
||||
private logger: Logger;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.config)
|
||||
|
@ -45,12 +45,12 @@ export class FileServerService {
|
|||
private internalStorageService: InternalStorageService,
|
||||
private loggerService: LoggerService,
|
||||
) {
|
||||
this.#logger = this.loggerService.getLogger('server', 'gray', false);
|
||||
this.logger = this.loggerService.getLogger('server', 'gray', false);
|
||||
}
|
||||
|
||||
public commonReadableHandlerGenerator(ctx: Koa.Context) {
|
||||
return (e: Error): void => {
|
||||
this.#logger.error(e);
|
||||
this.logger.error(e);
|
||||
ctx.status = 500;
|
||||
ctx.set('Cache-Control', 'max-age=300');
|
||||
};
|
||||
|
@ -74,8 +74,8 @@ export class FileServerService {
|
|||
ctx.set('Cache-Control', 'max-age=31536000, immutable');
|
||||
});
|
||||
|
||||
router.get('/:key', ctx => this.#sendDriveFile(ctx));
|
||||
router.get('/:key/(.*)', ctx => this.#sendDriveFile(ctx));
|
||||
router.get('/:key', ctx => this.sendDriveFile(ctx));
|
||||
router.get('/:key/(.*)', ctx => this.sendDriveFile(ctx));
|
||||
|
||||
// Register router
|
||||
app.use(router.routes());
|
||||
|
@ -83,7 +83,7 @@ export class FileServerService {
|
|||
return app;
|
||||
}
|
||||
|
||||
async #sendDriveFile(ctx: Koa.Context) {
|
||||
private async sendDriveFile(ctx: Koa.Context) {
|
||||
const key = ctx.params.key;
|
||||
|
||||
// Fetch drive file
|
||||
|
@ -139,7 +139,7 @@ export class FileServerService {
|
|||
ctx.set('Content-Type', FILE_TYPE_BROWSERSAFE.includes(image.type) ? image.type : 'application/octet-stream');
|
||||
ctx.set('Cache-Control', 'max-age=31536000, immutable');
|
||||
} catch (err) {
|
||||
this.#logger.error(`${err}`);
|
||||
this.logger.error(`${err}`);
|
||||
|
||||
if (err instanceof StatusError && err.isClientError) {
|
||||
ctx.status = err.statusCode;
|
||||
|
|
|
@ -19,7 +19,7 @@ import { LoggerService } from '@/core/LoggerService.js';
|
|||
|
||||
@Injectable()
|
||||
export class MediaProxyServerService {
|
||||
#logger: Logger;
|
||||
private logger: Logger;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.config)
|
||||
|
@ -30,7 +30,7 @@ export class MediaProxyServerService {
|
|||
private imageProcessingService: ImageProcessingService,
|
||||
private loggerService: LoggerService,
|
||||
) {
|
||||
this.#logger = this.loggerService.getLogger('server', 'gray', false);
|
||||
this.logger = this.loggerService.getLogger('server', 'gray', false);
|
||||
}
|
||||
|
||||
public createServer() {
|
||||
|
@ -44,7 +44,7 @@ export class MediaProxyServerService {
|
|||
// Init router
|
||||
const router = new Router();
|
||||
|
||||
router.get('/:url*', ctx => this.#handler(ctx));
|
||||
router.get('/:url*', ctx => this.handler(ctx));
|
||||
|
||||
// Register router
|
||||
app.use(router.routes());
|
||||
|
@ -52,7 +52,7 @@ export class MediaProxyServerService {
|
|||
return app;
|
||||
}
|
||||
|
||||
async #handler(ctx: Koa.Context) {
|
||||
private async handler(ctx: Koa.Context) {
|
||||
const url = 'url' in ctx.query ? ctx.query.url : 'https://' + ctx.params.url;
|
||||
|
||||
if (typeof url !== 'string') {
|
||||
|
@ -126,7 +126,7 @@ export class MediaProxyServerService {
|
|||
ctx.set('Cache-Control', 'max-age=31536000, immutable');
|
||||
ctx.body = image.data;
|
||||
} catch (err) {
|
||||
this.#logger.error(`${err}`);
|
||||
this.logger.error(`${err}`);
|
||||
|
||||
if (err instanceof StatusError && (err.statusCode === 302 || err.isClientError)) {
|
||||
ctx.status = err.statusCode;
|
||||
|
|
|
@ -30,7 +30,7 @@ import { ClientServerService } from './web/ClientServerService.js';
|
|||
|
||||
@Injectable()
|
||||
export class ServerService {
|
||||
#logger: Logger;
|
||||
private logger: Logger;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.config)
|
||||
|
@ -54,7 +54,7 @@ export class ServerService {
|
|||
private globalEventService: GlobalEventService,
|
||||
private loggerService: LoggerService,
|
||||
) {
|
||||
this.#logger = this.loggerService.getLogger('server', 'gray', false);
|
||||
this.logger = this.loggerService.getLogger('server', 'gray', false);
|
||||
}
|
||||
|
||||
public launch() {
|
||||
|
@ -65,7 +65,7 @@ export class ServerService {
|
|||
if (!['production', 'test'].includes(process.env.NODE_ENV ?? '')) {
|
||||
// Logger
|
||||
koa.use(koaLogger(str => {
|
||||
this.#logger.info(str);
|
||||
this.logger.info(str);
|
||||
}));
|
||||
|
||||
// Delay
|
||||
|
@ -157,13 +157,13 @@ export class ServerService {
|
|||
server.on('error', err => {
|
||||
switch ((err as any).code) {
|
||||
case 'EACCES':
|
||||
this.#logger.error(`You do not have permission to listen on port ${this.config.port}.`);
|
||||
this.logger.error(`You do not have permission to listen on port ${this.config.port}.`);
|
||||
break;
|
||||
case 'EADDRINUSE':
|
||||
this.#logger.error(`Port ${this.config.port} is already in use by another process.`);
|
||||
this.logger.error(`Port ${this.config.port} is already in use by another process.`);
|
||||
break;
|
||||
default:
|
||||
this.#logger.error(err);
|
||||
this.logger.error(err);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,9 +23,9 @@ const accessDenied = {
|
|||
|
||||
@Injectable()
|
||||
export class ApiCallService implements OnApplicationShutdown {
|
||||
#logger: Logger;
|
||||
#userIpHistories: Map<User['id'], Set<string>>;
|
||||
#userIpHistoriesClearIntervalId: NodeJS.Timer;
|
||||
private logger: Logger;
|
||||
private userIpHistories: Map<User['id'], Set<string>>;
|
||||
private userIpHistoriesClearIntervalId: NodeJS.Timer;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.userIpsRepository)
|
||||
|
@ -36,11 +36,11 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||
private rateLimiterService: RateLimiterService,
|
||||
private apiLoggerService: ApiLoggerService,
|
||||
) {
|
||||
this.#logger = this.apiLoggerService.logger;
|
||||
this.#userIpHistories = new Map<User['id'], Set<string>>();
|
||||
this.logger = this.apiLoggerService.logger;
|
||||
this.userIpHistories = new Map<User['id'], Set<string>>();
|
||||
|
||||
this.#userIpHistoriesClearIntervalId = setInterval(() => {
|
||||
this.#userIpHistories.clear();
|
||||
this.userIpHistoriesClearIntervalId = setInterval(() => {
|
||||
this.userIpHistories.clear();
|
||||
}, 1000 * 60 * 60);
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||
// Authentication
|
||||
this.authenticateService.authenticate(body['i']).then(([user, app]) => {
|
||||
// API invoking
|
||||
this.#call(endpoint, exec, user, app, body, ctx).then((res: any) => {
|
||||
this.call(endpoint, exec, user, app, body, ctx).then((res: any) => {
|
||||
if (ctx.method === 'GET' && endpoint.meta.cacheSec && !body['i'] && !user) {
|
||||
ctx.set('Cache-Control', `public, max-age=${endpoint.meta.cacheSec}`);
|
||||
}
|
||||
|
@ -90,10 +90,10 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||
this.metaService.fetch().then(meta => {
|
||||
if (!meta.enableIpLogging) return;
|
||||
const ip = ctx.ip;
|
||||
const ips = this.#userIpHistories.get(user.id);
|
||||
const ips = this.userIpHistories.get(user.id);
|
||||
if (ips == null || !ips.has(ip)) {
|
||||
if (ips == null) {
|
||||
this.#userIpHistories.set(user.id, new Set([ip]));
|
||||
this.userIpHistories.set(user.id, new Set([ip]));
|
||||
} else {
|
||||
ips.add(ip);
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||
});
|
||||
}
|
||||
|
||||
async #call(
|
||||
private async call(
|
||||
ep: IEndpoint,
|
||||
exec: any,
|
||||
user: CacheableLocalUser | null | undefined,
|
||||
|
@ -225,7 +225,7 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||
if (err instanceof ApiError) {
|
||||
throw err;
|
||||
} else {
|
||||
this.#logger.error(`Internal error occurred in ${ep.name}: ${err.message}`, {
|
||||
this.logger.error(`Internal error occurred in ${ep.name}: ${err.message}`, {
|
||||
ep: ep.name,
|
||||
ps: data,
|
||||
e: {
|
||||
|
@ -247,12 +247,12 @@ export class ApiCallService implements OnApplicationShutdown {
|
|||
const after = performance.now();
|
||||
const time = after - before;
|
||||
if (time > 1000) {
|
||||
this.#logger.warn(`SLOW API CALL DETECTED: ${ep.name} (${time}ms)`);
|
||||
this.logger.warn(`SLOW API CALL DETECTED: ${ep.name} (${time}ms)`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public onApplicationShutdown(signal?: string | undefined) {
|
||||
clearInterval(this.#userIpHistoriesClearIntervalId);
|
||||
clearInterval(this.userIpHistoriesClearIntervalId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ export class AuthenticationError extends Error {
|
|||
|
||||
@Injectable()
|
||||
export class AuthenticateService {
|
||||
#appCache: Cache<App>;
|
||||
private appCache: Cache<App>;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.usersRepository)
|
||||
|
@ -31,7 +31,7 @@ export class AuthenticateService {
|
|||
|
||||
private userCacheService: UserCacheService,
|
||||
) {
|
||||
this.#appCache = new Cache<App>(Infinity);
|
||||
this.appCache = new Cache<App>(Infinity);
|
||||
}
|
||||
|
||||
public async authenticate(token: string | null): Promise<[CacheableLocalUser | null | undefined, AccessToken | null | undefined]> {
|
||||
|
@ -71,7 +71,7 @@ export class AuthenticateService {
|
|||
}) as Promise<ILocalUser>);
|
||||
|
||||
if (accessToken.appId) {
|
||||
const app = await this.#appCache.fetch(accessToken.appId,
|
||||
const app = await this.appCache.fetch(accessToken.appId,
|
||||
() => this.appsRepository.findOneByOrFail({ id: accessToken.appId! }));
|
||||
|
||||
return [user, {
|
||||
|
|
|
@ -8,7 +8,7 @@ import type { IEndpointMeta } from './endpoints.js';
|
|||
|
||||
@Injectable()
|
||||
export class RateLimiterService {
|
||||
#logger: Logger;
|
||||
private logger: Logger;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.redis)
|
||||
|
@ -16,7 +16,7 @@ export class RateLimiterService {
|
|||
|
||||
private loggerService: LoggerService,
|
||||
) {
|
||||
this.#logger = this.loggerService.getLogger('limiter');
|
||||
this.logger = this.loggerService.getLogger('limiter');
|
||||
}
|
||||
|
||||
public limit(limitation: IEndpointMeta['limit'] & { key: NonNullable<string> }, actor: string) {
|
||||
|
@ -37,7 +37,7 @@ export class RateLimiterService {
|
|||
return reject('ERR');
|
||||
}
|
||||
|
||||
this.#logger.debug(`${actor} ${limitation.key} min remaining: ${info.remaining}`);
|
||||
this.logger.debug(`${actor} ${limitation.key} min remaining: ${info.remaining}`);
|
||||
|
||||
if (info.remaining === 0) {
|
||||
reject('BRIEF_REQUEST_INTERVAL');
|
||||
|
@ -65,7 +65,7 @@ export class RateLimiterService {
|
|||
return reject('ERR');
|
||||
}
|
||||
|
||||
this.#logger.debug(`${actor} ${limitation.key} max remaining: ${info.remaining}`);
|
||||
this.logger.debug(`${actor} ${limitation.key} max remaining: ${info.remaining}`);
|
||||
|
||||
if (info.remaining === 0) {
|
||||
reject('RATE_LIMIT_EXCEEDED');
|
||||
|
|
|
@ -71,13 +71,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
|
||||
(async () => {
|
||||
await this.userSuspendService.doPostSuspend(user).catch(e => {});
|
||||
await this.#unFollowAll(user).catch(e => {});
|
||||
await this.#readAllNotify(user).catch(e => {});
|
||||
await this.unFollowAll(user).catch(e => {});
|
||||
await this.readAllNotify(user).catch(e => {});
|
||||
})();
|
||||
});
|
||||
}
|
||||
|
||||
async #unFollowAll(follower: User) {
|
||||
private async unFollowAll(follower: User) {
|
||||
const followings = await this.followingsRepository.findBy({
|
||||
followerId: follower.id,
|
||||
});
|
||||
|
@ -95,7 +95,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
}
|
||||
}
|
||||
|
||||
async #readAllNotify(notifier: User) {
|
||||
private async readAllNotify(notifier: User) {
|
||||
await this.notificationsRepository.update({
|
||||
notifierId: notifier.id,
|
||||
isRead: false,
|
||||
|
|
|
@ -100,7 +100,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
private apNoteService: ApNoteService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const object = await this.#fetchAny(ps.uri, me);
|
||||
const object = await this.fetchAny(ps.uri, me);
|
||||
if (object) {
|
||||
return object;
|
||||
} else {
|
||||
|
@ -112,12 +112,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
/***
|
||||
* URIからUserかNoteを解決する
|
||||
*/
|
||||
async #fetchAny(uri: string, me: CacheableLocalUser | null | undefined): Promise<SchemaType<typeof meta['res']> | null> {
|
||||
private async fetchAny(uri: string, me: CacheableLocalUser | null | undefined): Promise<SchemaType<typeof meta['res']> | null> {
|
||||
// ブロックしてたら中断
|
||||
const fetchedMeta = await this.metaService.fetch();
|
||||
if (fetchedMeta.blockedHosts.includes(this.utilityService.extractDbHost(uri))) return null;
|
||||
|
||||
let local = await this.#mergePack(me, ...await Promise.all([
|
||||
let local = await this.mergePack(me, ...await Promise.all([
|
||||
this.apDbResolverService.getUserFromApId(uri),
|
||||
this.apDbResolverService.getNoteFromApId(uri),
|
||||
]));
|
||||
|
@ -130,21 +130,21 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
// /@user のような正規id以外で取得できるURIが指定されていた場合、ここで初めて正規URIが確定する
|
||||
// これはDBに存在する可能性があるため再度DB検索
|
||||
if (uri !== object.id) {
|
||||
local = await this.#mergePack(me, ...await Promise.all([
|
||||
local = await this.mergePack(me, ...await Promise.all([
|
||||
this.apDbResolverService.getUserFromApId(object.id),
|
||||
this.apDbResolverService.getNoteFromApId(object.id),
|
||||
]));
|
||||
if (local != null) return local;
|
||||
}
|
||||
|
||||
return await this.#mergePack(
|
||||
return await this.mergePack(
|
||||
me,
|
||||
isActor(object) ? await this.apPersonService.createPerson(getApId(object)) : null,
|
||||
isPost(object) ? await this.apNoteService.createNote(getApId(object), undefined, true) : null,
|
||||
);
|
||||
}
|
||||
|
||||
async #mergePack(me: CacheableLocalUser | null | undefined, user: User | null | undefined, note: Note | null | undefined): Promise<SchemaType<typeof meta.res> | null> {
|
||||
private async mergePack(me: CacheableLocalUser | null | undefined, user: User | null | undefined, note: Note | null | undefined): Promise<SchemaType<typeof meta.res> | null> {
|
||||
if (user != null) {
|
||||
return {
|
||||
type: 'User',
|
||||
|
|
|
@ -42,12 +42,12 @@ export class DiscordServerService {
|
|||
const router = new Router();
|
||||
|
||||
router.get('/disconnect/discord', async ctx => {
|
||||
if (!this.#compareOrigin(ctx)) {
|
||||
if (!this.compareOrigin(ctx)) {
|
||||
ctx.throw(400, 'invalid origin');
|
||||
return;
|
||||
}
|
||||
|
||||
const userToken = this.#getUserToken(ctx);
|
||||
const userToken = this.getUserToken(ctx);
|
||||
if (!userToken) {
|
||||
ctx.throw(400, 'signin required');
|
||||
return;
|
||||
|
@ -91,12 +91,12 @@ export class DiscordServerService {
|
|||
};
|
||||
|
||||
router.get('/connect/discord', async ctx => {
|
||||
if (!this.#compareOrigin(ctx)) {
|
||||
if (!this.compareOrigin(ctx)) {
|
||||
ctx.throw(400, 'invalid origin');
|
||||
return;
|
||||
}
|
||||
|
||||
const userToken = this.#getUserToken(ctx);
|
||||
const userToken = this.getUserToken(ctx);
|
||||
if (!userToken) {
|
||||
ctx.throw(400, 'signin required');
|
||||
return;
|
||||
|
@ -138,7 +138,7 @@ export class DiscordServerService {
|
|||
});
|
||||
|
||||
router.get('/dc/cb', async ctx => {
|
||||
const userToken = this.#getUserToken(ctx);
|
||||
const userToken = this.getUserToken(ctx);
|
||||
|
||||
const oauth2 = await getOAuth2();
|
||||
|
||||
|
@ -299,11 +299,11 @@ export class DiscordServerService {
|
|||
return router;
|
||||
}
|
||||
|
||||
#getUserToken(ctx: Koa.BaseContext): string | null {
|
||||
private getUserToken(ctx: Koa.BaseContext): string | null {
|
||||
return ((ctx.headers['cookie'] ?? '').match(/igi=(\w+)/) ?? [null, null])[1];
|
||||
}
|
||||
|
||||
#compareOrigin(ctx: Koa.BaseContext): boolean {
|
||||
private compareOrigin(ctx: Koa.BaseContext): boolean {
|
||||
function normalizeUrl(url?: string): string {
|
||||
return url ? url.endsWith('/') ? url.substr(0, url.length - 1) : url : '';
|
||||
}
|
||||
|
|
|
@ -42,12 +42,12 @@ export class GithubServerService {
|
|||
const router = new Router();
|
||||
|
||||
router.get('/disconnect/github', async ctx => {
|
||||
if (!this.#compareOrigin(ctx)) {
|
||||
if (!this.compareOrigin(ctx)) {
|
||||
ctx.throw(400, 'invalid origin');
|
||||
return;
|
||||
}
|
||||
|
||||
const userToken = this.#getUserToken(ctx);
|
||||
const userToken = this.getUserToken(ctx);
|
||||
if (!userToken) {
|
||||
ctx.throw(400, 'signin required');
|
||||
return;
|
||||
|
@ -91,12 +91,12 @@ export class GithubServerService {
|
|||
};
|
||||
|
||||
router.get('/connect/github', async ctx => {
|
||||
if (!this.#compareOrigin(ctx)) {
|
||||
if (!this.compareOrigin(ctx)) {
|
||||
ctx.throw(400, 'invalid origin');
|
||||
return;
|
||||
}
|
||||
|
||||
const userToken = this.#getUserToken(ctx);
|
||||
const userToken = this.getUserToken(ctx);
|
||||
if (!userToken) {
|
||||
ctx.throw(400, 'signin required');
|
||||
return;
|
||||
|
@ -136,7 +136,7 @@ export class GithubServerService {
|
|||
});
|
||||
|
||||
router.get('/gh/cb', async ctx => {
|
||||
const userToken = this.#getUserToken(ctx);
|
||||
const userToken = this.getUserToken(ctx);
|
||||
|
||||
const oauth2 = await getOath2();
|
||||
|
||||
|
@ -271,11 +271,11 @@ export class GithubServerService {
|
|||
return router;
|
||||
}
|
||||
|
||||
#getUserToken(ctx: Koa.BaseContext): string | null {
|
||||
private getUserToken(ctx: Koa.BaseContext): string | null {
|
||||
return ((ctx.headers['cookie'] ?? '').match(/igi=(\w+)/) ?? [null, null])[1];
|
||||
}
|
||||
|
||||
#compareOrigin(ctx: Koa.BaseContext): boolean {
|
||||
private compareOrigin(ctx: Koa.BaseContext): boolean {
|
||||
function normalizeUrl(url?: string): string {
|
||||
return url ? url.endsWith('/') ? url.substr(0, url.length - 1) : url : '';
|
||||
}
|
||||
|
|
|
@ -42,12 +42,12 @@ export class TwitterServerService {
|
|||
const router = new Router();
|
||||
|
||||
router.get('/disconnect/twitter', async ctx => {
|
||||
if (!this.#compareOrigin(ctx)) {
|
||||
if (!this.compareOrigin(ctx)) {
|
||||
ctx.throw(400, 'invalid origin');
|
||||
return;
|
||||
}
|
||||
|
||||
const userToken = this.#getUserToken(ctx);
|
||||
const userToken = this.getUserToken(ctx);
|
||||
if (userToken == null) {
|
||||
ctx.throw(400, 'signin required');
|
||||
return;
|
||||
|
@ -90,12 +90,12 @@ export class TwitterServerService {
|
|||
};
|
||||
|
||||
router.get('/connect/twitter', async ctx => {
|
||||
if (!this.#compareOrigin(ctx)) {
|
||||
if (!this.compareOrigin(ctx)) {
|
||||
ctx.throw(400, 'invalid origin');
|
||||
return;
|
||||
}
|
||||
|
||||
const userToken = this.#getUserToken(ctx);
|
||||
const userToken = this.getUserToken(ctx);
|
||||
if (userToken == null) {
|
||||
ctx.throw(400, 'signin required');
|
||||
return;
|
||||
|
@ -125,7 +125,7 @@ export class TwitterServerService {
|
|||
});
|
||||
|
||||
router.get('/tw/cb', async ctx => {
|
||||
const userToken = this.#getUserToken(ctx);
|
||||
const userToken = this.getUserToken(ctx);
|
||||
|
||||
const twAuth = await getTwAuth();
|
||||
|
||||
|
@ -214,11 +214,11 @@ export class TwitterServerService {
|
|||
return router;
|
||||
}
|
||||
|
||||
#getUserToken(ctx: Koa.BaseContext): string | null {
|
||||
private getUserToken(ctx: Koa.BaseContext): string | null {
|
||||
return ((ctx.headers['cookie'] ?? '').match(/igi=(\w+)/) ?? [null, null])[1];
|
||||
}
|
||||
|
||||
#compareOrigin(ctx: Koa.BaseContext): boolean {
|
||||
private compareOrigin(ctx: Koa.BaseContext): boolean {
|
||||
function normalizeUrl(url?: string): string {
|
||||
return url ? url.endsWith('/') ? url.substr(0, url.length - 1) : url : '';
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ export class ClientServerService {
|
|||
) {
|
||||
}
|
||||
|
||||
async #manifestHandler(ctx: Koa.Context) {
|
||||
private async manifestHandler(ctx: Koa.Context) {
|
||||
// TODO
|
||||
//const res = structuredClone(manifest);
|
||||
const res = JSON.parse(JSON.stringify(manifest));
|
||||
|
@ -264,7 +264,7 @@ export class ClientServerService {
|
|||
});
|
||||
|
||||
// Manifest
|
||||
router.get('/manifest.json', ctx => this.#manifestHandler(ctx));
|
||||
router.get('/manifest.json', ctx => this.manifestHandler(ctx));
|
||||
|
||||
router.get('/robots.txt', async ctx => {
|
||||
await send(ctx as any, '/robots.txt', {
|
||||
|
|
|
@ -12,7 +12,7 @@ import type Koa from 'koa';
|
|||
|
||||
@Injectable()
|
||||
export class UrlPreviewService {
|
||||
#logger: Logger;
|
||||
private logger: Logger;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.config)
|
||||
|
@ -25,10 +25,10 @@ export class UrlPreviewService {
|
|||
private httpRequestService: HttpRequestService,
|
||||
private loggerService: LoggerService,
|
||||
) {
|
||||
this.#logger = this.loggerService.getLogger('url-preview');
|
||||
this.logger = this.loggerService.getLogger('url-preview');
|
||||
}
|
||||
|
||||
#wrap(url?: string): string | null {
|
||||
private wrap(url?: string): string | null {
|
||||
return url != null
|
||||
? url.match(/^https?:\/\//)
|
||||
? `${this.config.url}/proxy/preview.webp?${query({
|
||||
|
@ -54,7 +54,7 @@ export class UrlPreviewService {
|
|||
|
||||
const meta = await this.metaService.fetch();
|
||||
|
||||
this.#logger.info(meta.summalyProxy
|
||||
this.logger.info(meta.summalyProxy
|
||||
? `(Proxy) Getting preview of ${url}@${lang} ...`
|
||||
: `Getting preview of ${url}@${lang} ...`);
|
||||
|
||||
|
@ -67,17 +67,17 @@ export class UrlPreviewService {
|
|||
lang: lang ?? 'ja-JP',
|
||||
});
|
||||
|
||||
this.#logger.succ(`Got preview of ${url}: ${summary.title}`);
|
||||
this.logger.succ(`Got preview of ${url}: ${summary.title}`);
|
||||
|
||||
summary.icon = this.#wrap(summary.icon);
|
||||
summary.thumbnail = this.#wrap(summary.thumbnail);
|
||||
summary.icon = this.wrap(summary.icon);
|
||||
summary.thumbnail = this.wrap(summary.thumbnail);
|
||||
|
||||
// Cache 7days
|
||||
ctx.set('Cache-Control', 'max-age=604800, immutable');
|
||||
|
||||
ctx.body = summary;
|
||||
} catch (err) {
|
||||
this.#logger.warn(`Failed to get preview of ${url}: ${err}`);
|
||||
this.logger.warn(`Failed to get preview of ${url}: ${err}`);
|
||||
ctx.status = 200;
|
||||
ctx.set('Cache-Control', 'max-age=86400, immutable');
|
||||
ctx.body = '{}';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue