feat: Log user ips (#8872)
* 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
This commit is contained in:
@ -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<string, string> | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 128, nullable: true,
|
||||
})
|
||||
public requestIp: string | null;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
24
packages/backend/src/models/entities/user-ip.ts
Normal file
24
packages/backend/src/models/entities/user-ip.ts
Normal file
@ -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;
|
||||
}
|
@ -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);
|
||||
|
Reference in New Issue
Block a user