merge: Log IP addresses used during registration (!1163)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1163 Closes #836 Approved-by: Hazelnoot <acomputerdog@gmail.com> Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
commit
1f26659995
3 changed files with 60 additions and 1 deletions
14
packages/backend/migration/1752377661219-UserPending-ip.js
Normal file
14
packages/backend/migration/1752377661219-UserPending-ip.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: наб and other Sharkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class UserPendingIp1752377661219 {
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "user_pending" ADD "requestOriginIp" varchar(128)`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "user_pending" DROP COLUMN "requestOriginIp"`);
|
||||
}
|
||||
}
|
||||
|
|
@ -37,4 +37,10 @@ export class MiUserPending {
|
|||
nullable: true,
|
||||
})
|
||||
public reason: string;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 128,
|
||||
nullable: true,
|
||||
})
|
||||
public requestOriginIp: string | null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import * as argon2 from 'argon2';
|
||||
import { IsNull } from 'typeorm';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { RegistrationTicketsRepository, UsedUsernamesRepository, UserPendingsRepository, UserProfilesRepository, UsersRepository, MiRegistrationTicket, MiMeta } from '@/models/_.js';
|
||||
import type { RegistrationTicketsRepository, UsedUsernamesRepository, UserPendingsRepository, UserProfilesRepository, UsersRepository, MiRegistrationTicket, MiMeta, UserIpsRepository } from '@/models/_.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { CaptchaService } from '@/core/CaptchaService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
|
|
@ -19,11 +19,14 @@ import { FastifyReplyError } from '@/misc/fastify-reply-error.js';
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import Logger from '@/logger.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { SigninService } from './SigninService.js';
|
||||
import type { FastifyRequest, FastifyReply } from 'fastify';
|
||||
|
||||
@Injectable()
|
||||
export class SignupApiService {
|
||||
private logger: Logger;
|
||||
constructor(
|
||||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
|
@ -46,6 +49,9 @@ export class SignupApiService {
|
|||
@Inject(DI.registrationTicketsRepository)
|
||||
private registrationTicketsRepository: RegistrationTicketsRepository,
|
||||
|
||||
@Inject(DI.userIpsRepository)
|
||||
private userIpsRepository: UserIpsRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
private captchaService: CaptchaService,
|
||||
|
|
@ -53,7 +59,9 @@ export class SignupApiService {
|
|||
private signinService: SigninService,
|
||||
private emailService: EmailService,
|
||||
private roleService: RoleService,
|
||||
private loggerService: LoggerService,
|
||||
) {
|
||||
this.logger = this.loggerService.getLogger('Signup');
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
@ -213,6 +221,7 @@ export class SignupApiService {
|
|||
username: username,
|
||||
password: hash,
|
||||
reason: reason,
|
||||
requestOriginIp: this.meta.enableIpLogging ? request.ip : null,
|
||||
});
|
||||
|
||||
const link = `${this.config.url}/signup-complete/${code}`;
|
||||
|
|
@ -249,6 +258,10 @@ export class SignupApiService {
|
|||
});
|
||||
}
|
||||
|
||||
if (this.meta.enableIpLogging) {
|
||||
this.logIp(request.ip, null, account.id);
|
||||
}
|
||||
|
||||
const moderators = await this.roleService.getModerators();
|
||||
|
||||
for (const moderator of moderators) {
|
||||
|
|
@ -282,6 +295,10 @@ export class SignupApiService {
|
|||
});
|
||||
}
|
||||
|
||||
if (this.meta.enableIpLogging) {
|
||||
this.logIp(request.ip, null, account.id);
|
||||
}
|
||||
|
||||
return {
|
||||
...res,
|
||||
token: secret,
|
||||
|
|
@ -332,6 +349,15 @@ export class SignupApiService {
|
|||
});
|
||||
}
|
||||
|
||||
if (pendingUser.requestOriginIp) {
|
||||
this.logIp(pendingUser.requestOriginIp, this.idService.parse(pendingUser.id).date, account.id);
|
||||
}
|
||||
|
||||
// The sign-up request and the confirmation may've come from different addresses: log both
|
||||
if (this.meta.enableIpLogging) {
|
||||
this.logIp(request.ip, null, account.id);
|
||||
}
|
||||
|
||||
if (this.meta.approvalRequiredForSignup) {
|
||||
if (pendingUser.email) {
|
||||
this.emailService.sendEmail(pendingUser.email, 'Approval pending',
|
||||
|
|
@ -359,4 +385,17 @@ export class SignupApiService {
|
|||
throw new FastifyReplyError(400, String(err), err);
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private logIp(ip: string, ipDate: Date | null, userId: MiLocalUser['id']) {
|
||||
try {
|
||||
this.userIpsRepository.createQueryBuilder().insert().values({
|
||||
createdAt: ipDate ?? new Date(),
|
||||
userId,
|
||||
ip,
|
||||
}).orIgnore(true).execute();
|
||||
} catch (err) {
|
||||
this.logger.error(err as Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue