feat: Landing Page and Login/Register Modal 1.01

This commit is contained in:
OpenVelo Agent
2026-07-21 21:19:36 +00:00
parent ad40b3b820
commit 5f30a125c1
5 changed files with 73 additions and 42 deletions
@@ -18,4 +18,15 @@ export class RegistrationRateLimitService {
arr.push(now);
this.hits.set(ip, arr);
}
}
tryConsume(ip: string, now: number = Date.now()): boolean {
const arr = (this.hits.get(ip) ?? []).filter((t) => now - t < WINDOW_MS);
if (arr.length >= MAX_PER_WINDOW) {
this.hits.set(ip, arr);
return false;
}
arr.push(now);
this.hits.set(ip, arr);
return true;
}
}
+2 -4
View File
@@ -100,7 +100,7 @@ export class AuthService implements OnModuleInit {
async registerFirstAdmin(username: string, password: string, ip: string): Promise<LoginResponse> {
validatePassword(password, this.config);
if (!this.registrationRateLimit.isAllowed(ip)) {
if (!this.registrationRateLimit.tryConsume(ip)) {
throw new ApiError(ERROR_CODES.RATE_LIMITED, 'Too many registrations from this IP; try again later.', 429);
}
@@ -128,7 +128,6 @@ export class AuthService implements OnModuleInit {
});
await manager.save(user);
this.registrationRateLimit.record(ip);
return this.mintSession(manager, user);
});
}
@@ -136,7 +135,7 @@ export class AuthService implements OnModuleInit {
async registerPlayer(dto: RegisterDto, ip: string): Promise<LoginResponse> {
validatePassword(dto.password, this.config);
if (!this.registrationRateLimit.isAllowed(ip)) {
if (!this.registrationRateLimit.tryConsume(ip)) {
throw new ApiError(
ERROR_CODES.RATE_LIMITED,
'Too many registration attempts; please wait a minute before trying again.',
@@ -174,7 +173,6 @@ export class AuthService implements OnModuleInit {
});
await manager.save(user);
this.registrationRateLimit.record(ip);
return this.mintSession(manager, user);
});
}