Merge pull request #206 from nagisa77/codex/add-whitelist-invitation-registration-mode

Implement whitelist registration mode
This commit is contained in:
Tim
2025-07-14 21:32:23 +08:00
committed by GitHub
21 changed files with 161 additions and 36 deletions

View File

@@ -5,6 +5,8 @@ import com.openisle.model.PublishMode;
import com.openisle.service.PasswordValidator;
import com.openisle.service.PostService;
import com.openisle.service.AiUsageService;
import com.openisle.service.RegisterModeService;
import com.openisle.model.RegisterMode;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@@ -16,6 +18,7 @@ public class AdminConfigController {
private final PostService postService;
private final PasswordValidator passwordValidator;
private final AiUsageService aiUsageService;
private final RegisterModeService registerModeService;
@GetMapping
public ConfigDto getConfig() {
@@ -23,6 +26,7 @@ public class AdminConfigController {
dto.setPublishMode(postService.getPublishMode());
dto.setPasswordStrength(passwordValidator.getStrength());
dto.setAiFormatLimit(aiUsageService.getFormatLimit());
dto.setRegisterMode(registerModeService.getRegisterMode());
return dto;
}
@@ -37,6 +41,9 @@ public class AdminConfigController {
if (dto.getAiFormatLimit() != null) {
aiUsageService.setFormatLimit(dto.getAiFormatLimit());
}
if (dto.getRegisterMode() != null) {
registerModeService.setRegisterMode(dto.getRegisterMode());
}
return getConfig();
}
@@ -45,5 +52,6 @@ public class AdminConfigController {
private PublishMode publishMode;
private PasswordStrength passwordStrength;
private Integer aiFormatLimit;
private RegisterMode registerMode;
}
}

View File

@@ -0,0 +1,36 @@
package com.openisle.controller;
import com.openisle.model.User;
import com.openisle.service.EmailSender;
import com.openisle.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/admin/users")
@RequiredArgsConstructor
public class AdminUserController {
private final UserRepository userRepository;
private final EmailSender emailSender;
@PostMapping("/{id}/approve")
public ResponseEntity<?> approve(@PathVariable Long id) {
User user = userRepository.findById(id).orElseThrow();
user.setApproved(true);
userRepository.save(user);
emailSender.sendEmail(user.getEmail(), "Registration Approved",
"Your account has been approved. Visit: https://www.open-isle.com");
return ResponseEntity.ok().build();
}
@PostMapping("/{id}/reject")
public ResponseEntity<?> reject(@PathVariable Long id) {
User user = userRepository.findById(id).orElseThrow();
user.setApproved(false);
userRepository.save(user);
emailSender.sendEmail(user.getEmail(), "Registration Rejected",
"Your account request was rejected. Visit: https://www.open-isle.com");
return ResponseEntity.ok().build();
}
}

View File

@@ -6,6 +6,8 @@ import com.openisle.service.JwtService;
import com.openisle.service.UserService;
import com.openisle.service.CaptchaService;
import com.openisle.service.GoogleAuthService;
import com.openisle.service.RegisterModeService;
import com.openisle.model.RegisterMode;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
@@ -23,6 +25,7 @@ public class AuthController {
private final EmailSender emailService;
private final CaptchaService captchaService;
private final GoogleAuthService googleAuthService;
private final RegisterModeService registerModeService;
@Value("${app.captcha.enabled:false}")
private boolean captchaEnabled;
@@ -38,7 +41,8 @@ public class AuthController {
if (captchaEnabled && registerCaptchaEnabled && !captchaService.verify(req.getCaptcha())) {
return ResponseEntity.badRequest().body(Map.of("error", "Invalid captcha"));
}
User user = userService.register(req.getUsername(), req.getEmail(), req.getPassword());
User user = userService.register(
req.getUsername(), req.getEmail(), req.getPassword(), req.getReason(), registerModeService.getRegisterMode());
emailService.sendEmail(user.getEmail(), "Verification Code", "Your verification code is " + user.getVerificationCode());
return ResponseEntity.ok(Map.of("message", "Verification code sent"));
}
@@ -67,8 +71,11 @@ public class AuthController {
@PostMapping("/google")
public ResponseEntity<?> loginWithGoogle(@RequestBody GoogleLoginRequest req) {
Optional<User> user = googleAuthService.authenticate(req.getIdToken());
Optional<User> user = googleAuthService.authenticate(req.getIdToken(), req.getReason(), registerModeService.getRegisterMode());
if (user.isPresent()) {
if (!user.get().isApproved()) {
return ResponseEntity.badRequest().body(Map.of("error", "Account awaiting approval"));
}
return ResponseEntity.ok(Map.of("token", jwtService.generateToken(user.get().getUsername())));
}
return ResponseEntity.badRequest().body(Map.of("error", "Invalid google token"));
@@ -85,6 +92,7 @@ public class AuthController {
private String email;
private String password;
private String captcha;
private String reason;
}
@Data
@@ -97,6 +105,7 @@ public class AuthController {
@Data
private static class GoogleLoginRequest {
private String idToken;
private String reason;
}
@Data

View File

@@ -2,12 +2,15 @@ package com.openisle.controller;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import com.openisle.service.RegisterModeService;
import com.openisle.model.RegisterMode;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
@lombok.RequiredArgsConstructor
public class ConfigController {
@Value("${app.captcha.enabled:false}")
@@ -28,6 +31,8 @@ public class ConfigController {
@Value("${app.ai.format-limit:3}")
private int aiFormatLimit;
private final RegisterModeService registerModeService;
@GetMapping("/config")
public ConfigResponse getConfig() {
ConfigResponse resp = new ConfigResponse();
@@ -37,6 +42,7 @@ public class ConfigController {
resp.setPostCaptchaEnabled(postCaptchaEnabled);
resp.setCommentCaptchaEnabled(commentCaptchaEnabled);
resp.setAiFormatLimit(aiFormatLimit);
resp.setRegisterMode(registerModeService.getRegisterMode());
return resp;
}
@@ -48,5 +54,6 @@ public class ConfigController {
private boolean postCaptchaEnabled;
private boolean commentCaptchaEnabled;
private int aiFormatLimit;
private RegisterMode registerMode;
}
}