From eccc90c843f63b2dc08d8fbf80e4f54a601e477d Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 2 Jul 2022 15:12:11 +0900 Subject: feat: Log user ips (#8872) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wip * store ip and headers * Update admin-file.vue * require admin for view ip/headers * IP (recent) 消した * admin必須 * opt in * clean ips periodically * respect logging setting in drive/files/create --- packages/backend/src/models/entities/drive-file.ts | 13 +++++++++++- packages/backend/src/models/entities/meta.ts | 7 ++++++- packages/backend/src/models/entities/user-ip.ts | 24 ++++++++++++++++++++++ packages/backend/src/models/index.ts | 2 ++ 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 packages/backend/src/models/entities/user-ip.ts (limited to 'packages/backend/src/models') diff --git a/packages/backend/src/models/entities/drive-file.ts b/packages/backend/src/models/entities/drive-file.ts index a636d1d519..32387290dc 100644 --- a/packages/backend/src/models/entities/drive-file.ts +++ b/packages/backend/src/models/entities/drive-file.ts @@ -1,7 +1,7 @@ import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; +import { id } from '../id.js'; import { User } from './user.js'; import { DriveFolder } from './drive-folder.js'; -import { id } from '../id.js'; @Entity() @Index(['userId', 'folderId', 'id']) @@ -165,4 +165,15 @@ export class DriveFile { comment: 'Whether the DriveFile is direct link to remote server.', }) public isLink: boolean; + + @Column('jsonb', { + default: {}, + nullable: true, + }) + public requestHeaders: Record | null; + + @Column('varchar', { + length: 128, nullable: true, + }) + public requestIp: string | null; } diff --git a/packages/backend/src/models/entities/meta.ts b/packages/backend/src/models/entities/meta.ts index 80b5228bcd..2be43bdd4e 100644 --- a/packages/backend/src/models/entities/meta.ts +++ b/packages/backend/src/models/entities/meta.ts @@ -1,6 +1,6 @@ import { Entity, Column, PrimaryColumn, ManyToOne, JoinColumn } from 'typeorm'; -import { User } from './user.js'; import { id } from '../id.js'; +import { User } from './user.js'; import { Clip } from './clip.js'; @Entity() @@ -427,4 +427,9 @@ export class Meta { default: true, }) public objectStorageS3ForcePathStyle: boolean; + + @Column('boolean', { + default: false, + }) + public enableIpLogging: boolean; } diff --git a/packages/backend/src/models/entities/user-ip.ts b/packages/backend/src/models/entities/user-ip.ts new file mode 100644 index 0000000000..543e9e7289 --- /dev/null +++ b/packages/backend/src/models/entities/user-ip.ts @@ -0,0 +1,24 @@ +import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; +import { id } from '../id.js'; +import { Note } from './note.js'; +import { User } from './user.js'; + +@Entity() +@Index(['userId', 'ip'], { unique: true }) +export class UserIp { + @PrimaryGeneratedColumn() + public id: string; + + @Column('timestamp with time zone', { + }) + public createdAt: Date; + + @Index() + @Column(id()) + public userId: User['id']; + + @Column('varchar', { + length: 128, + }) + public ip: string; +} diff --git a/packages/backend/src/models/index.ts b/packages/backend/src/models/index.ts index 814b37d448..3f73269318 100644 --- a/packages/backend/src/models/index.ts +++ b/packages/backend/src/models/index.ts @@ -65,6 +65,7 @@ import { PasswordResetRequest } from './entities/password-reset-request.js'; import { UserPending } from './entities/user-pending.js'; import { InstanceRepository } from './repositories/instance.js'; import { Webhook } from './entities/webhook.js'; +import { UserIp } from './entities/user-ip.js'; export const Announcements = db.getRepository(Announcement); export const AnnouncementReads = db.getRepository(AnnouncementRead); @@ -90,6 +91,7 @@ export const UserGroups = (UserGroupRepository); export const UserGroupJoinings = db.getRepository(UserGroupJoining); export const UserGroupInvitations = (UserGroupInvitationRepository); export const UserNotePinings = db.getRepository(UserNotePining); +export const UserIps = db.getRepository(UserIp); export const UsedUsernames = db.getRepository(UsedUsername); export const Followings = (FollowingRepository); export const FollowRequests = (FollowRequestRepository); -- cgit v1.2.3-freya