Merge branch 'devel'

This commit is contained in:
Sebastien 2018-09-10 16:21:03 +03:00
commit 2c8a73cdcb
34 changed files with 1491 additions and 913 deletions

2
Jenkinsfile vendored
View File

@ -50,7 +50,7 @@ pipeline {
sh 'docker login -u $USERNAME -p $PASSWORD'
script {
if (env.BRANCH_NAME == 'master') {
app.push()
app.push("master")
} else {
app.push("devel")
}

View File

@ -15,7 +15,7 @@ Docker:<br/>
>
> services:
> botdiscord:
> image: brokenfire/brokendiscordbot:latest
> image: brokenfire/brokendiscordbot:master
> networks:
> - proxy
> - internal

View File

@ -1,11 +1,14 @@
package net.Broken.Commands.Over18;
import net.Broken.Tools.Command.NoDev;
import net.Broken.Tools.Command.NumberedCommande;
import org.apache.logging.log4j.LogManager;
/**
* Ass command, return random picture from les400culs.com
*/
@NoDev()
public class Ass extends NumberedCommande {
public Ass() {

View File

@ -1,11 +1,13 @@
package net.Broken.Commands.Over18;
import net.Broken.Tools.Command.NoDev;
import net.Broken.Tools.Command.NumberedCommande;
import org.apache.logging.log4j.LogManager;
/**
* Boobs command, return random picture from lesaintdesseins.fr
*/
@NoDev()
public class Boobs extends NumberedCommande {
public Boobs() {

View File

@ -1,11 +1,13 @@
package net.Broken.Commands.Over18;
import net.Broken.Tools.Command.NoDev;
import net.Broken.Tools.Command.NumberedCommande;
import org.apache.logging.log4j.LogManager;
/**
* Ass command, return random picture from feelation.com
*/
@NoDev()
public class Pipe extends NumberedCommande {
public Pipe() {
super(LogManager.getLogger(), "http://feelation.com/","featured-img","img");

View File

@ -209,6 +209,23 @@ public class Preference implements Commande {
Message sended = event.getTextChannel().sendMessage(EmbedMessageUtils.buildStandar(eb)).complete();
new MessageTimeOut(MainBot.messageTimeOut, sended, event.getMessage()).start();
break;
case "daily_madame":
value = value.replaceAll(" ", "");
if(value.toLowerCase().equals("true") || value.toLowerCase().equals("false")){
boolean result = Boolean.parseBoolean(value);
pref.setDailyMadame(result);
pref = guildPreferenceRepository.save(pref);
EmbedBuilder ebd = new EmbedBuilder().addField(":ok: Ok :ok:","",false).addField("> Daily Madame", "Activate daily madame message\n```java\n" + String.valueOf(value) + "```", false).setColor(Color.green);
Message sendedm = event.getTextChannel().sendMessage(EmbedMessageUtils.buildStandar(ebd)).complete();
new MessageTimeOut(MainBot.messageTimeOut, sendedm, event.getMessage()).start();
}else{
MessageEmbed msg = EmbedMessageUtils.buildStandar(EmbedMessageUtils.getError("\nWrong value, expect `true` or `false`\n\nMore info with `//help preference`"));
Message sendedm = event.getTextChannel().sendMessage(msg).complete();
new MessageTimeOut(MainBot.messageTimeOut, sendedm, event.getMessage()).start();
}
break;
default:
MessageEmbed msg2 = EmbedMessageUtils.buildStandar(EmbedMessageUtils.getError("\nUnknown id.\n\nUse `//preference` to see list"));
Message sended2 = event.getTextChannel().sendMessage(msg2).complete();

View File

@ -27,8 +27,11 @@ public class GuildPreferenceEntity {
private String defaultRoleId;
private boolean dailyMadame;
public GuildPreferenceEntity(String guildId, boolean antiSpam, boolean welcome, String welcomeMessage, String welcomeChanelID, boolean defaultRole, String defaultRoleId) {
public GuildPreferenceEntity(String guildId, boolean antiSpam, boolean welcome, String welcomeMessage, String welcomeChanelID, boolean defaultRole, String defaultRoleId, boolean dailyMadame) {
this.guildId = guildId;
this.antiSpam = antiSpam;
this.welcome = welcome;
@ -36,13 +39,14 @@ public class GuildPreferenceEntity {
this.welcomeChanelID = welcomeChanelID;
this.defaultRole = defaultRole;
this.defaultRoleId = defaultRoleId;
this.dailyMadame = dailyMadame;
}
public GuildPreferenceEntity(){}
public static GuildPreferenceEntity getDefault(Guild guild){
return new GuildPreferenceEntity(guild.getId(), false, false, "Welcome to this awesome server @name! ", " ", false, " ");
return new GuildPreferenceEntity(guild.getId(), false, false, "Welcome to this awesome server @name! ", " ", false, " ", true);
}
public Integer getId() {
@ -108,4 +112,12 @@ public class GuildPreferenceEntity {
public void setDefaultRole(boolean defaultRole) {
this.defaultRole = defaultRole;
}
public boolean isDailyMadame() {
return dailyMadame;
}
public void setDailyMadame(boolean dailyMadame) {
this.dailyMadame = dailyMadame;
}
}

View File

@ -0,0 +1,56 @@
package net.Broken.DB.Entity;
import javax.persistence.*;
import java.util.Calendar;
import java.util.Date;
@Entity
public class PendingPwdResetEntity {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Integer id;
@OneToOne
private UserEntity userEntity;
private String securityToken;
private Date expirationDate;
public PendingPwdResetEntity(UserEntity userEntity,String token) {
this.userEntity = userEntity;
this.securityToken = token;
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.HOUR, 24);
expirationDate = cal.getTime();
}
public PendingPwdResetEntity() {}
public UserEntity getUserEntity() {
return userEntity;
}
public void setUserEntity(UserEntity userEntity) {
this.userEntity = userEntity;
}
public String getSecurityToken() {
return securityToken;
}
public void setSecurityToken(String securityToken) {
this.securityToken = securityToken;
}
public Date getExpirationDate() {
return expirationDate;
}
public void setExpirationDate(Date expirationDate) {
this.expirationDate = expirationDate;
}
}

View File

@ -1,6 +1,8 @@
package net.Broken.DB.Entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import net.Broken.Tools.UserManager.UserUtils;
import net.dv8tion.jda.core.entities.User;
import javax.persistence.*;
import java.util.ArrayList;
@ -38,6 +40,12 @@ public class UserEntity {
this.apiToken = apiToken;
}
public UserEntity(User user){
this.name = user.getName();
this.jdaId = user.getId();
this.apiToken = UserUtils.getInstance().generateApiToken();
}
public String getPassword() {
return password;
}

View File

@ -0,0 +1,11 @@
package net.Broken.DB.Repository;
import net.Broken.DB.Entity.PendingPwdResetEntity;
import net.Broken.DB.Entity.UserEntity;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
public interface PendingPwdResetRepository extends CrudRepository<PendingPwdResetEntity,Integer>{
List<PendingPwdResetEntity> findByUserEntity(UserEntity userEntity);
}

View File

@ -54,6 +54,7 @@ public class Init {
MainBot.jda = jda;
jda.setAutoReconnect(true);
/*************************************
* Definition des commande *
*************************************/
@ -91,13 +92,6 @@ public class Init {
DayListener dayListener = DayListener.getInstance();
dayListener.addListener(new ResetSpam());
dayListener.addListener(new DailyMadame());
dayListener.start();
logger.debug("-----------------FIN INITIALISATION-----------------");
@ -115,6 +109,10 @@ public class Init {
static void polish(JDA jda){
CommandLoader.load();
ApiCommandLoader.load();
DayListener dayListener = DayListener.getInstance();
dayListener.addListener(new ResetSpam());
dayListener.addListener(new DailyMadame());
dayListener.start();
jda.addEventListener(new BotListener());
jda.getPresence().setPresence(OnlineStatus.ONLINE, Game.playing("bot.seb6596.ovh"));

View File

@ -7,7 +7,9 @@ import net.Broken.Tools.MessageTimeOut;
import net.Broken.Tools.PrivateMessage;
import net.Broken.Tools.UserSpamUtils;
import net.Broken.audio.Youtube.YoutubeTools;
import net.dv8tion.jda.core.AccountType;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.JDABuilder;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.ChannelType;
import net.dv8tion.jda.core.entities.Member;
@ -40,6 +42,7 @@ public class MainBot {
public static HashMap<Member, UserSpamUtils> spamUtils = new HashMap<>();
public static JDA jda;
public static boolean ready = false;
public static boolean dev = false;
@ -56,24 +59,24 @@ public class MainBot {
logger.info("--------------Starting Bot-------------");
logger.info("=======================================");
boolean dev = false;
String token = null;
int i = 0;
for(String aArg: args){
logger.debug(aArg);
if(aArg.startsWith("--") || aArg.startsWith("-")){
aArg = aArg.replaceAll("-","");
if(aArg.equals("token") || aArg.equals("t")){
token = args[i+1];
}
else if(aArg.equals("dev") || aArg.equals("d")){
if(aArg.equals("dev") || aArg.equals("d")){
dev = true;
}
}
i++;
}
token = System.getenv("TOKEN");
jda = Init.initJda(token, dev);
ConfigurableApplicationContext ctx = SpringApplication.run(MainBot.class, args);
if(jda == null) {
System.exit(SpringApplication.exit(ctx, (ExitCodeGenerator) () -> {
@ -91,6 +94,8 @@ public class MainBot {
}
/**

View File

@ -7,6 +7,7 @@ import net.Broken.DB.Repository.UserRepository;
import net.Broken.MainBot;
import net.Broken.RestApi.Data.UserManager.*;
import net.Broken.Tools.UserManager.Exceptions.*;
import net.Broken.Tools.UserManager.Oauth;
import net.Broken.Tools.UserManager.UserUtils;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.User;
@ -29,17 +30,23 @@ import java.util.List;
@RequestMapping("/api/userManagement")
public class UserManagerAPIController {
Logger logger = LogManager.getLogger();
@Autowired
final
PendingUserRepository pendingUserRepository;
@Autowired
final
UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
private final PasswordEncoder passwordEncoder;
UserUtils userUtils = UserUtils.getInstance();
@Autowired
public UserManagerAPIController(PendingUserRepository pendingUserRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.pendingUserRepository = pendingUserRepository;
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
@RequestMapping(value = "/preRegister", method = RequestMethod.POST)
public ResponseEntity<CheckResposeData> command(@RequestBody UserInfoData data){
@ -114,4 +121,20 @@ public class UserManagerAPIController {
}
@RequestMapping(value = "/oauthLogin", method = RequestMethod.POST)
public ResponseEntity<UserConnectionData> oauthLogin(@RequestParam(value = "token") String discordToken){
logger.debug(discordToken);
UserEntity user = Oauth.getInstance().getUserEntity(discordToken, userRepository);
logger.debug(user.getName());
return new ResponseEntity<>(new UserConnectionData(true, user.getName(), user.getApiToken(), ""), HttpStatus.OK);
}
}

View File

@ -20,7 +20,7 @@ public class CommandLoader {
/**
* Search all implemented Command interface class and add it to MainBot.commands HashMap
*/
public static void load(){
public static void load() {
logger.info("Loading Command...");
Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage(
"net.Broken.Commands",
@ -34,13 +34,23 @@ public class CommandLoader {
String reference = command.getName();
String[] splited = reference.split("\\.");
String name = splited[splited.length-1].toLowerCase();
String name = splited[splited.length - 1].toLowerCase();
if (!command.isAnnotationPresent(Ignore.class)) {
logger.info("..." + name);
logger.info("..." + name);
try {
MainBot.commandes.put(name, command.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
logger.error("Failed to load " + name + "!");
if (command.isAnnotationPresent(NoDev.class) && MainBot.dev) {
logger.warn("Command disable in dev mode");
}else{
try {
MainBot.commandes.put(name, command.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
logger.error("Failed to load " + name + "!");
}
}
} else {
logger.trace("Ignored command: " + name);
}
}

View File

@ -0,0 +1,14 @@
package net.Broken.Tools.Command;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to disable command on dev mode
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Ignore {
}

View File

@ -0,0 +1,14 @@
package net.Broken.Tools.Command;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to disable command on dev mode
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface NoDev {
}

View File

@ -13,6 +13,7 @@ import java.net.URL;
/**
* Abstact class used for all command that need to find the max number of page on a web site.
*/
@Ignore
public abstract class NumberedCommande implements Commande{
private Logger logger = LogManager.getLogger();
private int minNumber = 1;
@ -35,9 +36,9 @@ public abstract class NumberedCommande implements Commande{
this.divClass = divClass;
this.htmlType = htmlType;
try {
logger.info("Checking max...");
logger.debug("Checking max...");
maxNumber = LimitChecker.doYourJob(baseURL, minNumber);
logger.info("New limit is "+maxNumber);
logger.info("Limit is "+maxNumber);
} catch (IOException e) {
logger.catching(e);
}

View File

@ -1,13 +1,16 @@
package net.Broken.Tools.DayListener.Listeners;
import net.Broken.Commands.Over18.Madame;
import net.Broken.DB.Repository.GuildPreferenceRepository;
import net.Broken.MainBot;
import net.Broken.SpringContext;
import net.Broken.Tools.DayListener.NewDayListener;
import net.Broken.Tools.Redirection;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.TextChannel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.ApplicationContext;
import java.io.IOException;
import java.util.List;
@ -16,54 +19,68 @@ import java.util.List;
* Daily Listener for DailyMadame
*/
public class DailyMadame implements NewDayListener{
private GuildPreferenceRepository guildPreferenceRepository;
public DailyMadame() {
ApplicationContext context = SpringContext.getAppContext();
guildPreferenceRepository = (GuildPreferenceRepository) context.getBean("guildPreferenceRepository");
}
private Logger logger = LogManager.getLogger();
@Override
public void onNewDay() {
Redirection redirect = new Redirection();
boolean success=false;
boolean error=false;
int errorCp=0;
List<Guild> guilds = MainBot.jda.getGuilds();
for(Guild guild : guilds){
TextChannel chanel = null;
for(TextChannel iterator : guild.getTextChannels())
{
if(iterator.isNSFW()){
chanel = iterator;
break;
}
}
if(chanel != null){
while(!success && !error)
boolean success=false;
boolean error=false;
int errorCp=0;
logger.debug(guild.getName());
if(guildPreferenceRepository.findByGuildId(guild.getId()).get(0).isDailyMadame()){
for(TextChannel iterator : guild.getTextChannels())
{
try {
String url = redirect.get("http://dites.bonjourmadame.fr/random");
logger.debug("URL: "+url);
if(Madame.scanPageForTipeee(url, logger)){
logger.debug("Advertisement detected! Retry! ("+url+")");
}
else{
chanel.sendMessage("Le Daily Madame mes petits cochons :kissing_heart:\n" + url).queue();
success=true;
}
} catch (IOException e) {
errorCp++;
logger.warn("Erreur de redirection. (Essais n°"+errorCp+")");
if(errorCp>5)
{
logger.error("5 Erreur de redirection.");
error=true;
}
if(iterator.isNSFW()){
chanel = iterator;
logger.debug("break: " + chanel.getName());
break;
}
}
if(chanel != null){
while(!success && !error)
{
try {
String url = redirect.get("http://dites.bonjourmadame.fr/random");
logger.debug("URL: "+url);
if(Madame.scanPageForTipeee(url, logger)){
logger.debug("Advertisement detected! Retry! ("+url+")");
}
else{
chanel.sendMessage("Le Daily Madame mes petits cochons :kissing_heart:\n" + url).queue();
success=true;
}
} catch (IOException e) {
errorCp++;
logger.warn("Erreur de redirection. (Essais n°"+errorCp+")");
if(errorCp>5)
{
logger.error("5 Erreur de redirection.");
error=true;
}
}
}
}
else {
logger.info("No NSFW chanel found for " + guild.getName() + ", ignoring it!");
}
}
else {
logger.info("No NSFW chanel found for " + guild.getName() + ", ignoring it!");
}
}

View File

@ -117,7 +117,9 @@ public class EmbedMessageUtils {
.addField("> Default Role ID", "Role id for auto move\n```java\n" + guildPref.getDefaultRoleId() + "```Edit: :unlock:\nKey: default_role_id", false)
.addField("> Welcome", "Activate welcome message\n```java\n" + String.valueOf(guildPref.isWelcome()) + "```Edit: :unlock:\nKey: welcome", false)
.addField("> Welcome chanel ID", "Chane id for welcome message\n```" + guildPref.getWelcomeChanelID() + "```Edit: :unlock:\nKey: welcome_chanel_id", false)
.addField("> Welcome message", "Welcome message (@name for mention)\n```markdown\n" + guildPref.getWelcomeMessage() + "```Edit: :unlock:\nKey: welcome_message", false);
.addField("> Welcome message", "Welcome message (@name for mention)\n```markdown\n" + guildPref.getWelcomeMessage() + "```Edit: :unlock:\nKey: welcome_message", false)
.addField("> Daily Madame", "Activate daily madame message\n```java\n" + String.valueOf(guildPref.isWelcome()) + "```Edit: :unlock:\nKey: daily_madame", false);
return buildStandar(messageB);
}

View File

@ -34,13 +34,13 @@ public class LimitChecker {
huc.setRequestMethod ("GET");
huc.connect ();
result = huc.getResponseCode();
logger.debug("URL: "+u.toString()+" Result: "+result);
logger.trace("URL: "+u.toString()+" Result: "+result);
if(result!=404)
number += 500;
}
number-=400;
result = -1;
logger.debug("First pass: "+number);
logger.trace("First pass: "+number);
while(result != 404 )
{
u = new URL( baseURL+number+"-2/");
@ -48,13 +48,13 @@ public class LimitChecker {
huc.setRequestMethod ("GET");
huc.connect ();
result = huc.getResponseCode();
logger.debug("URL: "+u.toString()+" Result: "+result);
logger.trace("URL: "+u.toString()+" Result: "+result);
if(result!=404)
number += 100;
}
number-=90;
result = -1;
logger.debug("Second pass: "+number);
logger.trace("Second pass: "+number);
while(result != 404 )
{
u = new URL( baseURL+number+"-2/");
@ -62,13 +62,13 @@ public class LimitChecker {
huc.setRequestMethod ("GET");
huc.connect ();
result = huc.getResponseCode();
logger.debug("URL: "+u.toString()+" Result: "+result);
logger.trace("URL: "+u.toString()+" Result: "+result);
if(result!=404)
number += 10;
}
number-=9;
result = -1;
logger.debug("Third pass: "+number);
logger.trace("Third pass: "+number);
while(result != 404 )
{
u = new URL( baseURL+number+"-2/");
@ -76,12 +76,12 @@ public class LimitChecker {
huc.setRequestMethod ("GET");
huc.connect ();
result = huc.getResponseCode();
logger.debug("URL: "+u.toString()+" Result: "+result);
logger.trace("URL: "+u.toString()+" Result: "+result);
if(result!=404)
number += 1;
}
number-=1;
logger.debug("Final pass: "+number);
logger.trace("Final pass: "+number);
return number;

View File

@ -0,0 +1,67 @@
package net.Broken.Tools.UserManager;
import net.Broken.DB.Entity.UserEntity;
import net.Broken.DB.Repository.UserRepository;
import net.Broken.MainBot;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
public class Oauth {
private static Oauth INSTANCE = new Oauth();
public static Oauth getInstance(){ return INSTANCE; }
Logger logger = LogManager.getLogger();
private String baseUrl = "https://discordapp.com/api";
private String mePath = "/users/@me";
private String getUserId(String token){
StringBuffer content = new StringBuffer();
try {
String httpsURL = baseUrl+mePath;
URL myUrl = new URL(httpsURL);
HttpURLConnection con = (HttpURLConnection)myUrl.openConnection();
con.setRequestProperty("Authorization", "Bearer "+token);
con.setRequestProperty("User-Agent", "DiscordBot (bot.seb6596.ovh, 0.1)");
con.setRequestMethod("GET");
logger.debug("Response code: " + con.getResponseCode());
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
JSONObject json = new JSONObject(content.toString());
return json.getString("id");
}
public UserEntity getUserEntity(String token, UserRepository userRepository){
String discorId = getUserId(token);
List<UserEntity> userEntitys = userRepository.findByJdaId(discorId);
if(userEntitys.size() != 0){
return userEntitys.get(0);
}else{
UserEntity user = new UserEntity(MainBot.jda.getUserById(discorId));
user = userRepository.save(user);
return user;
}
}
}

View File

@ -0,0 +1,64 @@
package net.Broken.Tools.UserManager;
import net.Broken.DB.Entity.PendingPwdResetEntity;
import net.Broken.DB.Entity.UserEntity;
import net.Broken.DB.Repository.PendingPwdResetRepository;
import net.Broken.DB.Repository.UserRepository;
import net.Broken.SpringContext;
import net.Broken.Tools.UserManager.Exceptions.TokenNotMatch;
import net.Broken.Tools.UserManager.Exceptions.UserNotFoundException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.List;
public class PasswordResetUtils {
private Logger logger = LogManager.getLogger();
private PasswordEncoder passwordEncoder;
private PendingPwdResetRepository pendingPwdResetRepository;
private UserRepository userRepository;
private static PasswordResetUtils INSTANCE = new PasswordResetUtils();
/**
* Private default constructor
*/
private PasswordResetUtils(){
ApplicationContext context = SpringContext.getAppContext();
passwordEncoder = (PasswordEncoder) context.getBean("passwordEncoder");
pendingPwdResetRepository = (PendingPwdResetRepository) context.getBean("pendingPwdResetRepository");
userRepository = (UserRepository) context.getBean("userRepository");
}
/**
* Singleton
* @return Unique PasswordResetUtils instance
*/
public static PasswordResetUtils getInstance(){
return INSTANCE;
}
public String resetRequest(UserEntity userEntity){
String token = UserUtils.getInstance().generateCheckToken();
String encodedToken = passwordEncoder.encode(token);
PendingPwdResetEntity entity = new PendingPwdResetEntity(userEntity, encodedToken);
pendingPwdResetRepository.save(entity);
return encodedToken;
}
public void changePass(UserEntity userEntity, String token, String newPassword) throws UserNotFoundException, TokenNotMatch {
List<PendingPwdResetEntity> dbResults = pendingPwdResetRepository.findByUserEntity(userEntity);
if(dbResults.size() == 0)
throw new UserNotFoundException();
PendingPwdResetEntity pendingPwdReset = dbResults.get(0);
if(!passwordEncoder.matches(token, pendingPwdReset.getSecurityToken()))
throw new TokenNotMatch();
userEntity.setPassword(passwordEncoder.encode(newPassword));
userRepository.save(userEntity);
}
}

View File

@ -201,7 +201,7 @@ public class UserUtils {
* Generate short check token
* @return check token as string
*/
private String generateCheckToken(){
public String generateCheckToken(){
SecureRandom random = new SecureRandom();
long longToken = Math.abs( random.nextLong() );
String randomStr = Long.toString( longToken, 16 );

View File

@ -31,6 +31,8 @@ public class GeneralWebView {
model.addAttribute("guild_name", guild.getName());
else
model.addAttribute("guild_name", "");
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
return CheckPage.getPageIfReady("index");
}
@ -39,6 +41,16 @@ public class GeneralWebView {
return "loading";
}
@RequestMapping("/forgetPass")
public String forgetPass(Model model){
return CheckPage.getPageIfReady("forgetPass");
}
@RequestMapping("/oauthCallback")
public String oauthCallback(Model model){
return "oauthCallback";
}

View File

@ -19,6 +19,8 @@ public class MusicWebView {
model.addAttribute("guild_name", guild.getName());
else
model.addAttribute("guild_name", "");
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
return CheckPage.getPageIfReady("music");
}

View File

@ -1,8 +1,8 @@
/*!
* Materialize v1.0.0-beta (http://materializecss.com)
* Copyright 2014-2017 Materialize
* MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)
*/
/*!
* Materialize v1.0.0-rc.2 (http://materializecss.com)
* Copyright 2014-2017 Materialize
* MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)
*/
.materialize-red {
background-color: #e51c23 !important;
}
@ -4982,7 +4982,6 @@ small {
height: auto;
min-height: 48px;
line-height: 1.5em;
word-break: break-all;
background-color: #323232;
padding: 10px 25px;
font-size: 1.1rem;
@ -5190,8 +5189,8 @@ small {
.btn-small:disabled,
.btn-flat:disabled,
.btn[disabled],
[disabled].btn-large,
[disabled].btn-small,
.btn-large[disabled],
.btn-small[disabled],
.btn-floating[disabled],
.btn-large[disabled],
.btn-small[disabled],
@ -5217,8 +5216,8 @@ small {
.btn-small:disabled:hover,
.btn-flat:disabled:hover,
.btn[disabled]:hover,
[disabled].btn-large:hover,
[disabled].btn-small:hover,
.btn-large[disabled]:hover,
.btn-small[disabled]:hover,
.btn-floating[disabled]:hover,
.btn-large[disabled]:hover,
.btn-small[disabled]:hover,
@ -5512,7 +5511,7 @@ button.btn-floating {
background-color: rgba(0, 0, 0, 0.1);
}
.btn-flat.disabled {
.btn-flat.disabled, .btn-flat.btn-flat[disabled] {
background-color: transparent !important;
color: #b3b2b2 !important;
cursor: default;
@ -5578,7 +5577,6 @@ button.btn-floating {
.dropdown-content li:focus {
outline: none;
background-color: #dadada;
}
.dropdown-content li.divider {
@ -5608,6 +5606,10 @@ button.btn-floating {
width: 24px;
}
body.keyboard-focused .dropdown-content li:focus {
background-color: #dadada;
}
.input-field.col .dropdown-content [type="checkbox"] + label {
top: 1px;
left: 0;
@ -5616,13 +5618,17 @@ button.btn-floating {
transform: none;
}
/*!
* Waves v0.6.0
* http://fian.my.id/Waves
*
* Copyright 2014 Alfiana E. Sibuea and other contributors
* Released under the MIT license
* https://github.com/fians/Waves/blob/master/LICENSE
.dropdown-trigger {
cursor: pointer;
}
/*!
* Waves v0.6.0
* http://fian.my.id/Waves
*
* Copyright 2014 Alfiana E. Sibuea and other contributors
* Released under the MIT license
* https://github.com/fians/Waves/blob/master/LICENSE
*/
.waves-effect {
position: relative;
@ -5757,6 +5763,10 @@ button.btn-floating {
will-change: top, opacity;
}
.modal:focus {
outline: none;
}
@media only screen and (max-width: 992px) {
.modal {
width: 80%;
@ -5851,6 +5861,10 @@ button.btn-floating {
border-bottom: 1px solid #ddd;
}
.collapsible-header:focus {
outline: 0;
}
.collapsible-header i {
width: 2rem;
font-size: 1.6rem;
@ -5859,6 +5873,10 @@ button.btn-floating {
margin-right: 1rem;
}
.keyboard-focused .collapsible-header:focus {
background-color: #eee;
}
.collapsible-body {
display: none;
border-bottom: 1px solid #ddd;
@ -6095,6 +6113,9 @@ label {
:-ms-input-placeholder {
color: #d1d1d1;
}
::-ms-input-placeholder {
color: #d1d1d1;
}
::placeholder {
color: #d1d1d1;
}
@ -6275,28 +6296,28 @@ textarea.materialize-textarea.validate + label {
/* Validation Sass Placeholders */
input.valid:not([type]), input.valid:not([type]):focus,
input[type=text].valid:not(.browser-default),
input[type=text].valid:not(.browser-default):focus,
input[type=password].valid:not(.browser-default),
input[type=password].valid:not(.browser-default):focus,
input[type=email].valid:not(.browser-default),
input[type=email].valid:not(.browser-default):focus,
input[type=url].valid:not(.browser-default),
input[type=url].valid:not(.browser-default):focus,
input[type=time].valid:not(.browser-default),
input[type=time].valid:not(.browser-default):focus,
input[type=date].valid:not(.browser-default),
input[type=date].valid:not(.browser-default):focus,
input[type=datetime].valid:not(.browser-default),
input[type=datetime].valid:not(.browser-default):focus,
input[type=datetime-local].valid:not(.browser-default),
input[type=datetime-local].valid:not(.browser-default):focus,
input[type=tel].valid:not(.browser-default),
input[type=tel].valid:not(.browser-default):focus,
input[type=number].valid:not(.browser-default),
input[type=number].valid:not(.browser-default):focus,
input[type=search].valid:not(.browser-default),
input[type=search].valid:not(.browser-default):focus,
input.valid[type=text]:not(.browser-default),
input.valid[type=text]:not(.browser-default):focus,
input.valid[type=password]:not(.browser-default),
input.valid[type=password]:not(.browser-default):focus,
input.valid[type=email]:not(.browser-default),
input.valid[type=email]:not(.browser-default):focus,
input.valid[type=url]:not(.browser-default),
input.valid[type=url]:not(.browser-default):focus,
input.valid[type=time]:not(.browser-default),
input.valid[type=time]:not(.browser-default):focus,
input.valid[type=date]:not(.browser-default),
input.valid[type=date]:not(.browser-default):focus,
input.valid[type=datetime]:not(.browser-default),
input.valid[type=datetime]:not(.browser-default):focus,
input.valid[type=datetime-local]:not(.browser-default),
input.valid[type=datetime-local]:not(.browser-default):focus,
input.valid[type=tel]:not(.browser-default),
input.valid[type=tel]:not(.browser-default):focus,
input.valid[type=number]:not(.browser-default),
input.valid[type=number]:not(.browser-default):focus,
input.valid[type=search]:not(.browser-default),
input.valid[type=search]:not(.browser-default):focus,
textarea.materialize-textarea.valid,
textarea.materialize-textarea.valid:focus, .select-wrapper.valid > input.select-dropdown {
border-bottom: 1px solid #4CAF50;
@ -6305,28 +6326,28 @@ textarea.materialize-textarea.valid:focus, .select-wrapper.valid > input.select-
}
input.invalid:not([type]), input.invalid:not([type]):focus,
input[type=text].invalid:not(.browser-default),
input[type=text].invalid:not(.browser-default):focus,
input[type=password].invalid:not(.browser-default),
input[type=password].invalid:not(.browser-default):focus,
input[type=email].invalid:not(.browser-default),
input[type=email].invalid:not(.browser-default):focus,
input[type=url].invalid:not(.browser-default),
input[type=url].invalid:not(.browser-default):focus,
input[type=time].invalid:not(.browser-default),
input[type=time].invalid:not(.browser-default):focus,
input[type=date].invalid:not(.browser-default),
input[type=date].invalid:not(.browser-default):focus,
input[type=datetime].invalid:not(.browser-default),
input[type=datetime].invalid:not(.browser-default):focus,
input[type=datetime-local].invalid:not(.browser-default),
input[type=datetime-local].invalid:not(.browser-default):focus,
input[type=tel].invalid:not(.browser-default),
input[type=tel].invalid:not(.browser-default):focus,
input[type=number].invalid:not(.browser-default),
input[type=number].invalid:not(.browser-default):focus,
input[type=search].invalid:not(.browser-default),
input[type=search].invalid:not(.browser-default):focus,
input.invalid[type=text]:not(.browser-default),
input.invalid[type=text]:not(.browser-default):focus,
input.invalid[type=password]:not(.browser-default),
input.invalid[type=password]:not(.browser-default):focus,
input.invalid[type=email]:not(.browser-default),
input.invalid[type=email]:not(.browser-default):focus,
input.invalid[type=url]:not(.browser-default),
input.invalid[type=url]:not(.browser-default):focus,
input.invalid[type=time]:not(.browser-default),
input.invalid[type=time]:not(.browser-default):focus,
input.invalid[type=date]:not(.browser-default),
input.invalid[type=date]:not(.browser-default):focus,
input.invalid[type=datetime]:not(.browser-default),
input.invalid[type=datetime]:not(.browser-default):focus,
input.invalid[type=datetime-local]:not(.browser-default),
input.invalid[type=datetime-local]:not(.browser-default):focus,
input.invalid[type=tel]:not(.browser-default),
input.invalid[type=tel]:not(.browser-default):focus,
input.invalid[type=number]:not(.browser-default),
input.invalid[type=number]:not(.browser-default):focus,
input.invalid[type=search]:not(.browser-default),
input.invalid[type=search]:not(.browser-default):focus,
textarea.materialize-textarea.invalid,
textarea.materialize-textarea.invalid:focus, .select-wrapper.invalid > input.select-dropdown,
.select-wrapper.invalid > input.select-dropdown:focus {
@ -6530,6 +6551,7 @@ textarea.materialize-textarea + label:after, .select-wrapper + label:after {
transform-origin: 0 0;
}
.input-field > input[type]:-webkit-autofill:not(.browser-default) + label,
.input-field > input[type=date]:not(.browser-default) + label,
.input-field > input[type=time]:not(.browser-default) + label {
-webkit-transform: translateY(-14px) scale(0.8);
@ -7016,7 +7038,7 @@ textarea.materialize-textarea {
border-color: #949494;
}
/* Switch
/* Switch
========================================================================== */
.switch,
.switch * {
@ -7219,6 +7241,10 @@ select:disabled {
background-color: transparent;
}
body.keyboard-focused .select-dropdown.dropdown-content li:focus {
background-color: rgba(0, 0, 0, 0.08);
}
.select-dropdown.dropdown-content li:hover {
background-color: rgba(0, 0, 0, 0.08);
}
@ -7227,10 +7253,6 @@ select:disabled {
background-color: rgba(0, 0, 0, 0.03);
}
.select-dropdown.dropdown-content li:focus {
background-color: rgba(0, 0, 0, 0.08);
}
.prefix ~ .select-wrapper {
margin-left: 3rem;
width: 92%;
@ -7264,7 +7286,7 @@ select:disabled {
padding-left: 1rem;
}
/* File Input
/* File Input
========================================================================== */
.file-field {
position: relative;
@ -7397,7 +7419,7 @@ input[type=range]::-webkit-slider-thumb {
margin: -5px 0 0 0;
}
input[type=range].focused:focus:not(.active)::-webkit-slider-thumb {
.keyboard-focused input[type=range]:focus:not(.active)::-webkit-slider-thumb {
-webkit-box-shadow: 0 0 0 10px rgba(38, 166, 154, 0.26);
box-shadow: 0 0 0 10px rgba(38, 166, 154, 0.26);
}
@ -7436,7 +7458,7 @@ input[type=range]:-moz-focusring {
outline-offset: -1px;
}
input[type=range].focused:focus:not(.active)::-moz-range-thumb {
.keyboard-focused input[type=range]:focus:not(.active)::-moz-range-thumb {
box-shadow: 0 0 0 10px rgba(38, 166, 154, 0.26);
}
@ -7469,7 +7491,7 @@ input[type=range]::-ms-thumb {
transition: box-shadow .3s, -webkit-box-shadow .3s;
}
input[type=range].focused:focus:not(.active)::-ms-thumb {
.keyboard-focused input[type=range]:focus:not(.active)::-ms-thumb {
box-shadow: 0 0 0 10px rgba(38, 166, 154, 0.26);
}
@ -7730,30 +7752,30 @@ input[type=range].focused:focus:not(.active)::-ms-thumb {
display: none;
}
/*
@license
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
/*
@license
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
/**************************/
/* STYLES FOR THE SPINNER */
/**************************/
/*
* Constants:
* STROKEWIDTH = 3px
* ARCSIZE = 270 degrees (amount of circle the arc takes up)
* ARCTIME = 1333ms (time it takes to expand and contract arc)
* ARCSTARTROT = 216 degrees (how much the start location of the arc
* should rotate each time, 216 gives us a
* 5 pointed star shape (it's 360/5 * 3).
* For a 7 pointed star, we might do
* 360/7 * 3 = 154.286)
* CONTAINERWIDTH = 28px
* SHRINK_TIME = 400ms
/*
* Constants:
* STROKEWIDTH = 3px
* ARCSIZE = 270 degrees (amount of circle the arc takes up)
* ARCTIME = 1333ms (time it takes to expand and contract arc)
* ARCSTARTROT = 216 degrees (how much the start location of the arc
* should rotate each time, 216 gives us a
* 5 pointed star shape (it's 360/5 * 3).
* For a 7 pointed star, we might do
* 360/7 * 3 = 154.286)
* CONTAINERWIDTH = 28px
* SHRINK_TIME = 400ms
*/
.preloader-wrapper {
display: inline-block;
@ -7819,18 +7841,18 @@ input[type=range].focused:focus:not(.active)::-ms-thumb {
border-color: #0f9d58;
}
/**
* IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
*
* iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't
* guarantee that the animation will start _exactly_ after that value. So we avoid using
* animation-delay and instead set custom keyframes for each color (as redundant as it
* seems).
*
* We write out each animation in full (instead of separating animation-name,
* animation-duration, etc.) because under the polyfill, Safari does not recognize those
* specific properties properly, treats them as -webkit-animation, and overrides the
* other animation rules. See https://github.com/Polymer/platform/issues/53.
/**
* IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
*
* iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't
* guarantee that the animation will start _exactly_ after that value. So we avoid using
* animation-delay and instead set custom keyframes for each color (as redundant as it
* seems).
*
* We write out each animation in full (instead of separating animation-name,
* animation-duration, etc.) because under the polyfill, Safari does not recognize those
* specific properties properly, treats them as -webkit-animation, and overrides the
* other animation rules. See https://github.com/Polymer/platform/issues/53.
*/
.active .spinner-layer.spinner-blue {
/* durations: 4 * ARCTIME */
@ -8095,9 +8117,9 @@ input[type=range].focused:focus:not(.active)::-ms-thumb {
}
}
/**
* Patch the gap that appear between the two adjacent div.circle-clipper while the
* spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11).
/**
* Patch the gap that appear between the two adjacent div.circle-clipper while the
* spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11).
*/
.gap-patch {
position: absolute;
@ -8464,10 +8486,10 @@ input[type=range].focused:focus:not(.active)::-ms-thumb {
visibility: visible;
-webkit-animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;
animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;
-webkit-transition: opacity .3s, visibility 0s 1s, -webkit-transform .3s;
transition: opacity .3s, visibility 0s 1s, -webkit-transform .3s;
transition: opacity .3s, transform .3s, visibility 0s 1s;
transition: opacity .3s, transform .3s, visibility 0s 1s, -webkit-transform .3s;
-webkit-transition: opacity .3s, visibility 0s 1s, -webkit-transform .3s;
transition: opacity .3s, visibility 0s 1s, -webkit-transform .3s;
transition: opacity .3s, transform .3s, visibility 0s 1s;
transition: opacity .3s, transform .3s, visibility 0s 1s, -webkit-transform .3s;
}
.tap-target {
@ -8520,10 +8542,10 @@ input[type=range].focused:focus:not(.active)::-ms-thumb {
.tap-target-wave::after {
visibility: hidden;
-webkit-transition: opacity .3s, visibility 0s, -webkit-transform .3s;
transition: opacity .3s, visibility 0s, -webkit-transform .3s;
transition: opacity .3s, transform .3s, visibility 0s;
transition: opacity .3s, transform .3s, visibility 0s, -webkit-transform .3s;
-webkit-transition: opacity .3s, visibility 0s, -webkit-transform .3s;
transition: opacity .3s, visibility 0s, -webkit-transform .3s;
transition: opacity .3s, transform .3s, visibility 0s;
transition: opacity .3s, transform .3s, visibility 0s, -webkit-transform .3s;
z-index: -1;
}
@ -8808,6 +8830,12 @@ input[type=range].focused:focus:not(.active)::-ms-thumb {
-ms-flex-direction: row;
flex-direction: row;
}
.datepicker-date-display {
-webkit-box-flex: 0;
-webkit-flex: 0 1 270px;
-ms-flex: 0 1 270px;
flex: 0 1 270px;
}
.datepicker-controls,
.datepicker-table,
.datepicker-footer {

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,33 @@
var hash = window.location.hash.replace("#","").split("&");
var discordToken = "";
hash.forEach(function (value) {
if(value.indexOf("access_token") !== -1){
discordToken = value.split("=")[1];
return 0;
}
});
if(discordToken !== ""){
console.log(discordToken);
$.ajax({
type: "POST",
dataType: 'json',
contentType: 'application/json',
url: "/api/userManagement/oauthLogin?token=" + discordToken,
success: function (data) {
console.log(data);
Cookies.set('token',data.token, { expires: 31 });
Cookies.set('name', data.name, { expires: 31 });
debugger;
window.location = "/";
}
}).fail(function (data) {
console.log(data);
});
}else{
window.location = "/";
debugger;
}

View File

@ -12,7 +12,7 @@
<!-- LOGIN -->
<!--__________________________________________________________-->
<link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<div th:fragment="header (page, guild_name)">
<div th:fragment="header (page, guild_name, redirect_url)">
<nav class="blue-grey darken-4 z-depth-3" role="navigation" >
<div class="nav-wrapper container">
<a id="logo-container" href="/" class="brand-logo">Claptrap Bot</a>
@ -90,11 +90,22 @@
<!--________________________________________-->
<div id="modal_connection" class="modal">
<div class="modal-content">
<div class="row center">
<div class="col s12">
<h3 class="" style="font-weight: bold">Sign in</h3>
</div>
</div>
<div class="row center">
<a class="btn waves-effect waves-light" style="background-color: #7289DA" th:href="${redirect_url}">
Sign in with discord <i class="fab fa-discord fa-lg" style="margin-left: 2px"></i>
</a>
</div>
<div class="row center">
<div class="col s12">
<h3 style="font-weight: bold">Or</h3>
</div>
</div>
<div class="row center" style="margin-bottom: 0px">
<form name="login_form" id="login_form" action="javascript:void(0);" onsubmit="tryConnection()">
<div class="row" style="margin-bottom: 0px">

View File

@ -12,11 +12,13 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
<link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link href="css/style.css" type="text/css" rel="stylesheet" media="screen,projection"/>
</head>
<body class="blue-grey lighten-5" >
<div th:replace="header :: header ('home',${guild_name})">...</div>
<div th:replace="header :: header ('home',${guild_name},${redirect_url})">...</div>
<div class="section no-pad-bot main" id="index-banner">
<div class="center center-align">
@ -34,6 +36,8 @@
<script th:src="@{/js/materialize.js}"></script>
<script th:src="@{/js/navabar.js}"></script>
<script th:src="@{/js/js.cookie.js}"></script>
<script src="https://use.fontawesome.com/releases/v5.3.1/js/all.js" crossorigin="anonymous"></script>
</body>
</html>

View File

@ -16,7 +16,7 @@
<body class="blue-grey lighten-5" >
<div th:replace="header :: header ('music',${guild_name})">...</div>
<div th:replace="header :: header ('music',${guild_name},${redirect_url})">...</div>
<div class="section no-pad-bot main" id="index-banner">
<div class="row">

View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
<title>Claptrap Bot</title>
<link rel="icon"
type="image/x-icon"
href="/favicon.png"/>
<!-- CSS -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
<link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link href="css/style.css" type="text/css" rel="stylesheet" media="screen,projection"/>
</head>
<body class="blue-grey lighten-5" >
<div th:replace="header :: header ('home',${guild_name},${redirect_url})">...</div>
<div class="section no-pad-bot main" id="index-banner">
<div class="row center" >
<div class="preloader-wrapper big active">
<div class="spinner-layer spinner-blue-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
</div>
<div class="row center center-align">
<h3>Please wait</h3>
</div>
</div>
<!-- Scripts-->
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
<script th:src="@{/js/materialize.js}"></script>
<script th:src="@{/js/navabar.js}"></script>
<script th:src="@{/js/js.cookie.js}"></script>
<script th:src="@{/js/oauthCallback.js}"></script>
<script src="https://use.fontawesome.com/releases/v5.3.1/js/all.js" crossorigin="anonymous"></script>
</body>
</html>