rename activity_log and activity_context to ap_inbox_log and ap_context

This commit is contained in:
Hazelnoot 2024-12-09 10:00:25 -05:00
parent 0979392925
commit cc2edae7ab
11 changed files with 113 additions and 65 deletions

View file

@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class RenameActivityLogToApInboxLog1733756280460 {
name = 'RenameActivityLogToApInboxLog1733756280460'
async up(queryRunner) {
await queryRunner.query(`ALTER INDEX "IDX_activity_log_at" RENAME TO "IDX_ap_inbox_log_at"`);
await queryRunner.query(`ALTER INDEX "IDX_activity_log_host" RENAME TO "IDX_ap_inbox_log_host"`);
await queryRunner.query(`ALTER TABLE "activity_log" RENAME CONSTRAINT "PK_activity_log" TO "PK_ap_inbox_log"`);
await queryRunner.query(`ALTER TABLE "activity_log" RENAME CONSTRAINT "FK_activity_log_context_hash" TO "FK_ap_inbox_log_context_hash"`);
await queryRunner.query(`ALTER TABLE "activity_log" RENAME CONSTRAINT "FK_activity_log_auth_user_id" TO "FK_ap_inbox_log_auth_user_id"`);
await queryRunner.query(`ALTER TABLE "activity_log" RENAME TO "ap_inbox_log"`);
await queryRunner.query(`ALTER TABLE "activity_context" RENAME CONSTRAINT "PK_activity_context" TO "PK_ap_context"`);
await queryRunner.query(`ALTER TABLE "activity_context" RENAME TO "ap_context"`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "ap_context" RENAME TO "activity_context"`);
await queryRunner.query(`ALTER TABLE "activity_context" RENAME CONSTRAINT "PK_ap_context" TO "PK_activity_context"`);
await queryRunner.query(`ALTER TABLE "ap_inbox_log" RENAME TO "activity_log"`);
await queryRunner.query(`ALTER TABLE "activity_log" RENAME CONSTRAINT "FK_ap_inbox_log_auth_user_id" TO "FK_activity_log_auth_user_id"`);
await queryRunner.query(`ALTER TABLE "activity_log" RENAME CONSTRAINT "FK_ap_inbox_log_context_hash" TO "FK_activity_log_context_hash"`);
await queryRunner.query(`ALTER TABLE "activity_log" RENAME CONSTRAINT "PK_ap_inbox_log" TO "PK_activity_log"`);
await queryRunner.query(`ALTER INDEX "IDX_ap_inbox_log_host" RENAME TO "IDX_activity_log_host"`);
await queryRunner.query(`ALTER INDEX "IDX_ap_inbox_log_at" RENAME TO "IDX_activity_log_at"`);
}
}

View file

@ -13,7 +13,7 @@ import { ServerStatsService } from '@/daemons/ServerStatsService.js';
import { ServerService } from '@/server/ServerService.js'; import { ServerService } from '@/server/ServerService.js';
import { MainModule } from '@/MainModule.js'; import { MainModule } from '@/MainModule.js';
import { envOption } from '@/env.js'; import { envOption } from '@/env.js';
import { ActivityLogCleanupService } from '@/daemons/ActivityLogCleanupService.js'; import { ApLogCleanupService } from '@/daemons/ApLogCleanupService.js';
export async function server() { export async function server() {
const app = await NestFactory.createApplicationContext(MainModule, { const app = await NestFactory.createApplicationContext(MainModule, {
@ -29,7 +29,7 @@ export async function server() {
if (!envOption.noDaemons) { if (!envOption.noDaemons) {
app.get(QueueStatsService).start(); app.get(QueueStatsService).start();
app.get(ServerStatsService).start(); app.get(ServerStatsService).start();
app.get(ActivityLogCleanupService).start(); app.get(ApLogCleanupService).start();
} }
return app; return app;

View file

@ -8,7 +8,7 @@ import { LessThan } from 'typeorm';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import type { ActivityLogsRepository } from '@/models/_.js'; import type { ApInboxLogsRepository } from '@/models/_.js';
import { LoggerService } from '@/core/LoggerService.js'; import { LoggerService } from '@/core/LoggerService.js';
import Logger from '@/logger.js'; import Logger from '@/logger.js';
@ -16,7 +16,7 @@ import Logger from '@/logger.js';
export const scanInterval = 1000 * 60 * 10; export const scanInterval = 1000 * 60 * 10;
@Injectable() @Injectable()
export class ActivityLogCleanupService implements OnApplicationShutdown { export class ApLogCleanupService implements OnApplicationShutdown {
private readonly logger: Logger; private readonly logger: Logger;
private scanTimer: NodeJS.Timeout | null = null; private scanTimer: NodeJS.Timeout | null = null;
@ -24,8 +24,8 @@ export class ActivityLogCleanupService implements OnApplicationShutdown {
@Inject(DI.config) @Inject(DI.config)
private readonly config: Config, private readonly config: Config,
@Inject(DI.activityLogsRepository) @Inject(DI.apInboxLogsRepository)
private readonly activityLogsRepository: ActivityLogsRepository, private readonly apInboxLogsRepository: ApInboxLogsRepository,
loggerService: LoggerService, loggerService: LoggerService,
) { ) {
@ -51,7 +51,7 @@ export class ActivityLogCleanupService implements OnApplicationShutdown {
const oldestAllowed = new Date(Date.now() - this.config.activityLogging.maxAge); const oldestAllowed = new Date(Date.now() - this.config.activityLogging.maxAge);
// Delete all logs older than the threshold. // Delete all logs older than the threshold.
const { affected } = await this.activityLogsRepository.delete({ const { affected } = await this.apInboxLogsRepository.delete({
at: LessThan(oldestAllowed), at: LessThan(oldestAllowed),
}); });

View file

@ -8,7 +8,7 @@ import { CoreModule } from '@/core/CoreModule.js';
import { GlobalModule } from '@/GlobalModule.js'; import { GlobalModule } from '@/GlobalModule.js';
import { QueueStatsService } from './QueueStatsService.js'; import { QueueStatsService } from './QueueStatsService.js';
import { ServerStatsService } from './ServerStatsService.js'; import { ServerStatsService } from './ServerStatsService.js';
import { ActivityLogCleanupService } from './ActivityLogCleanupService.js'; import { ApLogCleanupService } from './ApLogCleanupService.js';
@Module({ @Module({
imports: [ imports: [
@ -18,12 +18,12 @@ import { ActivityLogCleanupService } from './ActivityLogCleanupService.js';
providers: [ providers: [
QueueStatsService, QueueStatsService,
ServerStatsService, ServerStatsService,
ActivityLogCleanupService, ApLogCleanupService,
], ],
exports: [ exports: [
QueueStatsService, QueueStatsService,
ServerStatsService, ServerStatsService,
ActivityLogCleanupService, ApLogCleanupService,
], ],
}) })
export class DaemonModule {} export class DaemonModule {}

View file

@ -22,9 +22,8 @@ export const DI = {
appsRepository: Symbol('appsRepository'), appsRepository: Symbol('appsRepository'),
avatarDecorationsRepository: Symbol('avatarDecorationsRepository'), avatarDecorationsRepository: Symbol('avatarDecorationsRepository'),
latestNotesRepository: Symbol('latestNotesRepository'), latestNotesRepository: Symbol('latestNotesRepository'),
activityContextRepository: Symbol('activityContextRepository'), apContextsRepository: Symbol('apContextsRepository'),
contextUsagesRepository: Symbol('contextUsagesRepository'), apInboxLogsRepository: Symbol('apInboxLogsRepository'),
activityLogsRepository: Symbol('activityLogsRepository'),
noteFavoritesRepository: Symbol('noteFavoritesRepository'), noteFavoritesRepository: Symbol('noteFavoritesRepository'),
noteThreadMutingsRepository: Symbol('noteThreadMutingsRepository'), noteThreadMutingsRepository: Symbol('noteThreadMutingsRepository'),
noteReactionsRepository: Symbol('noteReactionsRepository'), noteReactionsRepository: Symbol('noteReactionsRepository'),

View file

@ -81,8 +81,8 @@ import {
MiUserSecurityKey, MiUserSecurityKey,
MiWebhook, MiWebhook,
NoteEdit, NoteEdit,
SkActivityContext, SkApContext,
SkActivityLog, SkApInboxLog,
} from './_.js'; } from './_.js';
import type { DataSource } from 'typeorm'; import type { DataSource } from 'typeorm';
@ -128,15 +128,15 @@ const $latestNotesRepository: Provider = {
inject: [DI.db], inject: [DI.db],
}; };
const $activityContextRepository: Provider = { const $apContextRepository: Provider = {
provide: DI.activityContextRepository, provide: DI.apContextsRepository,
useFactory: (db: DataSource) => db.getRepository(SkActivityContext).extend(miRepository as MiRepository<SkActivityContext>), useFactory: (db: DataSource) => db.getRepository(SkApContext).extend(miRepository as MiRepository<SkApContext>),
inject: [DI.db], inject: [DI.db],
}; };
const $activityLogsRepository: Provider = { const $apInboxLogsRepository: Provider = {
provide: DI.activityLogsRepository, provide: DI.apInboxLogsRepository,
useFactory: (db: DataSource) => db.getRepository(SkActivityLog).extend(miRepository as MiRepository<SkActivityLog>), useFactory: (db: DataSource) => db.getRepository(SkApInboxLog).extend(miRepository as MiRepository<SkApInboxLog>),
inject: [DI.db], inject: [DI.db],
}; };
@ -540,8 +540,8 @@ const $noteScheduleRepository: Provider = {
$appsRepository, $appsRepository,
$avatarDecorationsRepository, $avatarDecorationsRepository,
$latestNotesRepository, $latestNotesRepository,
$activityContextRepository, $apContextRepository,
$activityLogsRepository, $apInboxLogsRepository,
$noteFavoritesRepository, $noteFavoritesRepository,
$noteThreadMutingsRepository, $noteThreadMutingsRepository,
$noteReactionsRepository, $noteReactionsRepository,
@ -616,8 +616,8 @@ const $noteScheduleRepository: Provider = {
$appsRepository, $appsRepository,
$avatarDecorationsRepository, $avatarDecorationsRepository,
$latestNotesRepository, $latestNotesRepository,
$activityContextRepository, $apContextRepository,
$activityLogsRepository, $apInboxLogsRepository,
$noteFavoritesRepository, $noteFavoritesRepository,
$noteThreadMutingsRepository, $noteThreadMutingsRepository,
$noteReactionsRepository, $noteReactionsRepository,

View file

@ -5,10 +5,10 @@
import { Column, PrimaryColumn, Entity } from 'typeorm'; import { Column, PrimaryColumn, Entity } from 'typeorm';
@Entity('activity_context') @Entity('ap_context')
export class SkActivityContext { export class SkApContext {
@PrimaryColumn('text', { @PrimaryColumn('text', {
primaryKeyConstraintName: 'PK_activity_context', primaryKeyConstraintName: 'PK_ap_context',
}) })
public md5: string; public md5: string;
@ -17,7 +17,7 @@ export class SkActivityContext {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
public json: any; public json: any;
constructor(data?: Partial<SkActivityContext>) { constructor(data?: Partial<SkApContext>) {
if (data) { if (data) {
Object.assign(this, data); Object.assign(this, data);
} }

View file

@ -4,19 +4,22 @@
*/ */
import { Column, Entity, Index, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm'; import { Column, Entity, Index, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm';
import { SkActivityContext } from '@/models/SkActivityContext.js'; import { SkApContext } from '@/models/SkApContext.js';
import { MiUser } from '@/models/_.js'; import { MiUser } from '@/models/_.js';
import { id } from './util/id.js'; import { id } from './util/id.js';
@Entity('activity_log') /**
export class SkActivityLog { * Records activities received in the inbox
*/
@Entity('ap_inbox_log')
export class SkApInboxLog {
@PrimaryColumn({ @PrimaryColumn({
...id(), ...id(),
primaryKeyConstraintName: 'PK_activity_log', primaryKeyConstraintName: 'PK_ap_inbox_log',
}) })
public id: string; public id: string;
@Index('IDX_activity_log_at') @Index('IDX_ap_inbox_log_at')
@Column('timestamptz') @Column('timestamptz')
public at: Date; public at: Date;
@ -26,13 +29,21 @@ export class SkActivityLog {
@Column('double precision', { nullable: true }) @Column('double precision', { nullable: true })
public duration: number | null = null; public duration: number | null = null;
/**
* Key ID that was used to sign this request.
* Untrusted unless verified is true.
*/
@Column({ @Column({
type: 'text', type: 'text',
name: 'key_id', name: 'key_id',
}) })
public keyId: string; public keyId: string;
@Index('IDX_activity_log_host') /**
* Instance that the activity was sent from.
* Untrusted unless verified is true.
*/
@Index('IDX_ap_inbox_log_host')
@Column('text') @Column('text')
public host: string; public host: string;
@ -57,16 +68,19 @@ export class SkActivityLog {
}) })
public contextHash: string | null; public contextHash: string | null;
@ManyToOne(() => SkActivityContext, { @ManyToOne(() => SkApContext, {
onDelete: 'CASCADE', onDelete: 'CASCADE',
nullable: true, nullable: true,
}) })
@JoinColumn({ @JoinColumn({
name: 'context_hash', name: 'context_hash',
foreignKeyConstraintName: 'FK_activity_log_context_hash', foreignKeyConstraintName: 'FK_ap_inbox_log_context_hash',
}) })
public context: SkActivityContext | null; public context: SkApContext | null;
/**
* ID of the user who signed this request.
*/
@Column({ @Column({
...id(), ...id(),
name: 'auth_user_id', name: 'auth_user_id',
@ -74,17 +88,20 @@ export class SkActivityLog {
}) })
public authUserId: string | null; public authUserId: string | null;
/**
* User who signed this request.
*/
@ManyToOne(() => MiUser, { @ManyToOne(() => MiUser, {
onDelete: 'CASCADE', onDelete: 'CASCADE',
nullable: true, nullable: true,
}) })
@JoinColumn({ @JoinColumn({
name: 'auth_user_id', name: 'auth_user_id',
foreignKeyConstraintName: 'FK_activity_log_auth_user_id', foreignKeyConstraintName: 'FK_ap_inbox_log_auth_user_id',
}) })
public authUser: MiUser | null; public authUser: MiUser | null;
constructor(data?: Partial<SkActivityLog>) { constructor(data?: Partial<SkApInboxLog>) {
if (data) { if (data) {
Object.assign(this, data); Object.assign(this, data);
} }

View file

@ -82,8 +82,8 @@ import { NoteEdit } from '@/models/NoteEdit.js';
import { MiBubbleGameRecord } from '@/models/BubbleGameRecord.js'; import { MiBubbleGameRecord } from '@/models/BubbleGameRecord.js';
import { MiReversiGame } from '@/models/ReversiGame.js'; import { MiReversiGame } from '@/models/ReversiGame.js';
import { MiNoteSchedule } from '@/models/NoteSchedule.js'; import { MiNoteSchedule } from '@/models/NoteSchedule.js';
import { SkActivityLog } from '@/models/SkActivityLog.js'; import { SkApInboxLog } from '@/models/SkApInboxLog.js';
import { SkActivityContext } from './SkActivityContext.js'; import { SkApContext } from '@/models/SkApContext.js';
import type { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity.js'; import type { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity.js';
export interface MiRepository<T extends ObjectLiteral> { export interface MiRepository<T extends ObjectLiteral> {
@ -131,8 +131,8 @@ export const miRepository = {
export { export {
SkLatestNote, SkLatestNote,
SkActivityContext, SkApContext,
SkActivityLog, SkApInboxLog,
MiAbuseUserReport, MiAbuseUserReport,
MiAbuseReportNotificationRecipient, MiAbuseReportNotificationRecipient,
MiAccessToken, MiAccessToken,
@ -233,8 +233,8 @@ export type HashtagsRepository = Repository<MiHashtag> & MiRepository<MiHashtag>
export type InstancesRepository = Repository<MiInstance> & MiRepository<MiInstance>; export type InstancesRepository = Repository<MiInstance> & MiRepository<MiInstance>;
export type MetasRepository = Repository<MiMeta> & MiRepository<MiMeta>; export type MetasRepository = Repository<MiMeta> & MiRepository<MiMeta>;
export type LatestNotesRepository = Repository<SkLatestNote> & MiRepository<SkLatestNote>; export type LatestNotesRepository = Repository<SkLatestNote> & MiRepository<SkLatestNote>;
export type ActivityContextRepository = Repository<SkActivityContext> & MiRepository<SkActivityContext>; export type ApContextsRepository = Repository<SkApContext> & MiRepository<SkApContext>;
export type ActivityLogsRepository = Repository<SkActivityLog> & MiRepository<SkActivityLog>; export type ApInboxLogsRepository = Repository<SkApInboxLog> & MiRepository<SkApInboxLog>;
export type ModerationLogsRepository = Repository<MiModerationLog> & MiRepository<MiModerationLog>; export type ModerationLogsRepository = Repository<MiModerationLog> & MiRepository<MiModerationLog>;
export type MutingsRepository = Repository<MiMuting> & MiRepository<MiMuting>; export type MutingsRepository = Repository<MiMuting> & MiRepository<MiMuting>;
export type RenoteMutingsRepository = Repository<MiRenoteMuting> & MiRepository<MiRenoteMuting>; export type RenoteMutingsRepository = Repository<MiRenoteMuting> & MiRepository<MiRenoteMuting>;

View file

@ -85,8 +85,8 @@ import { Config } from '@/config.js';
import MisskeyLogger from '@/logger.js'; import MisskeyLogger from '@/logger.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { SkLatestNote } from '@/models/LatestNote.js'; import { SkLatestNote } from '@/models/LatestNote.js';
import { SkActivityContext } from '@/models/SkActivityContext.js'; import { SkApContext } from '@/models/SkApContext.js';
import { SkActivityLog } from '@/models/SkActivityLog.js'; import { SkApInboxLog } from '@/models/SkApInboxLog.js';
pg.types.setTypeParser(20, Number); pg.types.setTypeParser(20, Number);
@ -173,8 +173,8 @@ class MyCustomLogger implements Logger {
export const entities = [ export const entities = [
SkLatestNote, SkLatestNote,
SkActivityContext, SkApContext,
SkActivityLog, SkApInboxLog,
MiAnnouncement, MiAnnouncement,
MiAnnouncementRead, MiAnnouncementRead,
MiMeta, MiMeta,

View file

@ -32,8 +32,8 @@ import { MiMeta } from '@/models/Meta.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { IdService } from '@/core/IdService.js'; import { IdService } from '@/core/IdService.js';
import { JsonValue } from '@/misc/json-value.js'; import { JsonValue } from '@/misc/json-value.js';
import { SkActivityLog, SkActivityContext } from '@/models/_.js'; import { SkApInboxLog, SkApContext } from '@/models/_.js';
import type { ActivityLogsRepository, ActivityContextRepository } from '@/models/_.js'; import type { ApInboxLogsRepository, ApContextsRepository } from '@/models/_.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
import { QueueLoggerService } from '../QueueLoggerService.js'; import { QueueLoggerService } from '../QueueLoggerService.js';
import type { InboxJobData } from '../types.js'; import type { InboxJobData } from '../types.js';
@ -68,11 +68,11 @@ export class InboxProcessorService implements OnApplicationShutdown {
private queueLoggerService: QueueLoggerService, private queueLoggerService: QueueLoggerService,
private idService: IdService, private idService: IdService,
@Inject(DI.activityContextRepository) @Inject(DI.apContextsRepository)
private activityContextRepository: ActivityContextRepository, private apContextsRepository: ApContextsRepository,
@Inject(DI.activityLogsRepository) @Inject(DI.apInboxLogsRepository)
private activityLogsRepository: ActivityLogsRepository, private apInboxLogsRepository: ApInboxLogsRepository,
) { ) {
this.logger = this.queueLoggerService.logger.createSubLogger('inbox'); this.logger = this.queueLoggerService.logger.createSubLogger('inbox');
this.updateInstanceQueue = new CollapsedQueue(process.env.NODE_ENV !== 'test' ? 60 * 1000 * 5 : 0, this.collapseUpdateInstanceJobs, this.performUpdateInstance); this.updateInstanceQueue = new CollapsedQueue(process.env.NODE_ENV !== 'test' ? 60 * 1000 * 5 : 0, this.collapseUpdateInstanceJobs, this.performUpdateInstance);
@ -132,7 +132,7 @@ export class InboxProcessorService implements OnApplicationShutdown {
} }
} }
private async _process(job: Bull.Job<InboxJobData>, log?: SkActivityLog): Promise<string> { private async _process(job: Bull.Job<InboxJobData>, log?: SkApInboxLog): Promise<string> {
const signature = job.data.signature; // HTTP-signature const signature = job.data.signature; // HTTP-signature
let activity = job.data.activity; let activity = job.data.activity;
@ -369,11 +369,11 @@ export class InboxProcessorService implements OnApplicationShutdown {
await this.dispose(); await this.dispose();
} }
private createLog(payload: IActivity, keyId: string): SkActivityLog { private createLog(payload: IActivity, keyId: string): SkApInboxLog {
const activity = Object.assign({}, payload, { '@context': undefined }) as unknown as JsonValue; const activity = Object.assign({}, payload, { '@context': undefined }) as unknown as JsonValue;
const host = this.utilityService.extractDbHost(keyId); const host = this.utilityService.extractDbHost(keyId);
const log = new SkActivityLog({ const log = new SkApInboxLog({
id: this.idService.gen(), id: this.idService.gen(),
at: new Date(), at: new Date(),
verified: false, verified: false,
@ -387,7 +387,7 @@ export class InboxProcessorService implements OnApplicationShutdown {
if (context) { if (context) {
const md5 = createHash('md5').update(JSON.stringify(context)).digest('base64'); const md5 = createHash('md5').update(JSON.stringify(context)).digest('base64');
log.contextHash = md5; log.contextHash = md5;
log.context = new SkActivityContext({ log.context = new SkApContext({
md5, md5,
json: context, json: context,
}); });
@ -396,18 +396,18 @@ export class InboxProcessorService implements OnApplicationShutdown {
return log; return log;
} }
private async recordLog(log: SkActivityLog): Promise<void> { private async recordLog(log: SkApInboxLog): Promise<void> {
if (log.context) { if (log.context) {
// https://stackoverflow.com/a/47064558 // https://stackoverflow.com/a/47064558
await this.activityContextRepository await this.apContextsRepository
.createQueryBuilder('context_body') .createQueryBuilder('activity_context')
.insert() .insert()
.into(SkActivityContext) .into(SkApContext)
.values(log.context) .values(log.context)
.orIgnore('md5') .orIgnore('md5')
.execute(); .execute();
} }
await this.activityLogsRepository.upsert(log, ['id']); await this.apInboxLogsRepository.upsert(log, ['id']);
} }
} }