package com.openisle.service; import com.openisle.model.InviteToken; import com.openisle.model.User; import com.openisle.repository.InviteTokenRepository; import com.openisle.repository.UserRepository; import lombok.RequiredArgsConstructor; import lombok.Value; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.util.Optional; @Service @RequiredArgsConstructor public class InviteService { private final InviteTokenRepository inviteTokenRepository; private final UserRepository userRepository; private final JwtService jwtService; private final PointService pointService; @Value public class InviteValidateResult { InviteToken inviteToken; boolean validate; } public String generate(String username) { User inviter = userRepository.findByUsername(username).orElseThrow(); LocalDate today = LocalDate.now(); Optional existing = inviteTokenRepository.findByInviterAndCreatedDate(inviter, today); if (existing.isPresent()) { InviteToken inviteToken = existing.get(); return inviteToken.getShortToken() != null ? inviteToken.getShortToken() : inviteToken.getToken(); } String token = jwtService.generateInviteToken(username); String shortToken; do { shortToken = java.util.UUID.randomUUID().toString().replace("-", "").substring(0, 8); } while (inviteTokenRepository.existsByShortToken(shortToken)); InviteToken inviteToken = new InviteToken(); inviteToken.setToken(token); inviteToken.setShortToken(shortToken); inviteToken.setInviter(inviter); inviteToken.setCreatedDate(today); inviteToken.setUsageCount(0); inviteTokenRepository.save(inviteToken); return shortToken; } public InviteValidateResult validate(String token) { if (token == null || token.isEmpty()) { return new InviteValidateResult(null, false); } InviteToken invite = inviteTokenRepository.findById(token).orElse(null); String realToken = token; if (invite == null) { invite = inviteTokenRepository.findByShortToken(token).orElse(null); if (invite == null) { return new InviteValidateResult(null, false); } realToken = invite.getToken(); } try { jwtService.validateAndGetSubjectForInvite(realToken); } catch (Exception e) { return new InviteValidateResult(null, false); } return new InviteValidateResult(invite, invite.getUsageCount() < 3); } public void consume(String token, String newUserName) { InviteToken invite = inviteTokenRepository.findById(token) .orElseGet(() -> inviteTokenRepository.findByShortToken(token).orElseThrow()); invite.setUsageCount(invite.getUsageCount() + 1); inviteTokenRepository.save(invite); pointService.awardForInvite(invite.getInviter().getUsername(), newUserName); } }