/*
* Copyright (C) 2008-2024, Juick
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package com.juick.www.api;
import com.github.scribejava.apis.GoogleTokenVerifier;
import com.juick.model.AuthResponse;
import com.juick.service.EmailService;
import com.juick.service.UserService;
import com.juick.util.HttpBadRequestException;
import com.juick.util.HttpForbiddenException;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import jakarta.inject.Inject;
import java.util.Optional;
@Controller
public class ApiSocialLogin {
private static final Logger logger = LoggerFactory.getLogger(ApiSocialLogin.class);
@Value("${google_client_id:}")
private String googleClientId;
@Inject
private UserService userService;
@Inject
private EmailService emailService;
@Inject
private Users users;
@ResponseBody
@PostMapping("/api/signup")
public com.juick.model.User signupWithEmail(String username, String password, String verificationCode) {
if (username.length() < 2 || username.length() > 16 || !username.matches("^[a-zA-Z0-9\\-]+$")
|| password.length() < 6 || password.length() > 32) {
throw new HttpBadRequestException();
}
String verifiedEmail = emailService.getEmailByAuthCode(verificationCode);
if (StringUtils.hasText(verifiedEmail)) {
com.juick.model.User newUser = userService.createUser(username, password).orElseThrow(HttpBadRequestException::new);
emailService.addEmail(newUser.getUid(), verifiedEmail);
emailService.deleteAuthCode(verificationCode);
return newUser;
} else {
throw new HttpForbiddenException();
}
}
@ResponseBody
@PostMapping("/api/_google")
public AuthResponse googleSignIn(@RequestParam(name = "idToken") String idTokenString) {
logger.info("Token: {}", idTokenString);
logger.info("Client: {}", googleClientId);
Optional verifiedEmail = GoogleTokenVerifier.validateToken(googleClientId, idTokenString);
if (verifiedEmail.isPresent()) {
String email = verifiedEmail.get();
com.juick.model.User visitor = userService.getUserByEmail(email);
if (visitor.isAnonymous()) {
String verificationCode = RandomStringUtils.randomAlphanumeric(8).toUpperCase();
emailService.addVerificationCode(null, email, verificationCode);
return new AuthResponse(null, email, verificationCode);
} else {
return new AuthResponse(users.getMe(visitor), null, null);
}
}
throw new HttpForbiddenException();
}
}