匆忙写了个能跑的东西出来,还很烂

main
lensfrex 3 years ago
parent 0b920d312a
commit fe81cb5e16
Signed by: lensfrex
GPG Key ID: 0F69A0A2FBEE98A0
  1. 3
      .gitignore
  2. 113
      pom.xml
  3. 16
      src/main/java/me/lensfrex/littlebusters/ApiIndex.java
  4. 15
      src/main/java/me/lensfrex/littlebusters/RestTest.java
  5. 86
      src/main/java/me/lensfrex/littlebusters/api/v1/Register.java
  6. 27
      src/main/java/me/lensfrex/littlebusters/api/v1/beans/ProfileItem.java
  7. 10
      src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserInformation.java
  8. 9
      src/main/java/me/lensfrex/littlebusters/api/v1/dao/UserRegister.java
  9. 15
      src/main/java/me/lensfrex/littlebusters/api/v1/inputTest.java
  10. 89
      src/main/java/me/lensfrex/littlebusters/api/v1/login/Login.java
  11. 24
      src/main/java/me/lensfrex/littlebusters/api/v1/login/LoginIdentify.java
  12. 17
      src/main/java/me/lensfrex/littlebusters/api/v1/pojos/UserResult.java
  13. 55
      src/main/java/me/lensfrex/littlebusters/api/v1/responses/LoginResponseData.java
  14. 24
      src/main/java/me/lensfrex/littlebusters/api/v1/responses/ProfileResponseData.java
  15. 52
      src/main/java/me/lensfrex/littlebusters/api/v1/responses/RegisterResponseData.java
  16. 16
      src/main/java/me/lensfrex/littlebusters/api/v1/responses/general/ErrorResponse.java
  17. 53
      src/main/java/me/lensfrex/littlebusters/api/v1/responses/general/ResponseBase.java
  18. 27
      src/main/java/me/lensfrex/littlebusters/api/v1/utils/InputChecker.java
  19. 28
      src/main/java/me/lensfrex/littlebusters/api/v1/utils/MyBatisUtil.java
  20. 13
      src/main/resources/mappers/LoginSqlMapper.xml
  21. 12
      src/main/resources/mappers/RegisterSqlMapper.xml
  22. 93
      src/main/webapp/404.html
  23. 27
      src/main/webapp/WEB-INF/web.xml
  24. 180
      src/main/webapp/css/welcomepage.css
  25. BIN
      src/main/webapp/images/54120216_p0_conpressed.jpg
  26. 52
      src/main/webapp/index.html
  27. 28
      src/main/webapp/js/events.js
  28. 12
      src/main/webapp/js/init.js
  29. 2
      src/main/webapp/js/jquery-3.6.0.min.js
  30. 16
      src/main/webapp/js/sha256-min.js
  31. 28
      src/main/webapp/js/utils.js
  32. 54
      src/main/webapp/js/welcomepage_message.js

3
.gitignore vendored

@ -1,7 +1,7 @@
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
.target
target
# User-specific stuff
.idea/**/workspace.xml
@ -78,3 +78,4 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
/.idea
/src/main/resources/mybatis-config.xml

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>me.lensfrex</groupId>
<artifactId>LittleBusters</artifactId>
<version>0.0.1-dev</version>
<name>LittleBusters</name>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<junit.version>5.8.1</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>3.0.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mindrot/jbcrypt -->
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-gson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.0.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,16 @@
package me.lensfrex.littlebusters;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/")
public class ApiIndex {
@GET
@Produces(MediaType.TEXT_HTML)
public String index() {
return "Here is the API root of LittleBusters.</br>\n" +
"To use the API currently, please see the LittleBusters RESTFul API document.";
}
}

@ -0,0 +1,15 @@
package me.lensfrex.littlebusters;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/lb")
public class RestTest {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getMessage() {
return "ASJKDFHYG";
}
}

@ -0,0 +1,86 @@
package me.lensfrex.littlebusters.api.v1;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import me.lensfrex.littlebusters.api.v1.dao.UserInformation;
import me.lensfrex.littlebusters.api.v1.dao.UserRegister;
import me.lensfrex.littlebusters.api.v1.responses.RegisterResponseData;
import me.lensfrex.littlebusters.api.v1.responses.general.ErrorResponse;
import me.lensfrex.littlebusters.api.v1.responses.general.ResponseBase;
import me.lensfrex.littlebusters.api.v1.utils.InputChecker;
import me.lensfrex.littlebusters.api.v1.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.mindrot.jbcrypt.BCrypt;
import java.util.UUID;
@Path("/register")
public class Register {
private final static Gson gson = new Gson();
@POST
@Produces(MediaType.APPLICATION_JSON)
public String register(String request) {
System.out.println("Start register.");
RegisterRequestBody registerRequestBody;
try {
registerRequestBody = gson.fromJson(request, RegisterRequestBody.class);
if (InputChecker.hasInvalidChar(registerRequestBody.userName) ||
InputChecker.hasInvisibleChar(registerRequestBody.password)) {
ErrorResponse errorResponse = new ErrorResponse(1, "用户名或密码非法");
return gson.toJson(errorResponse);
}
} catch (Exception e) {
System.err.println(request);
ErrorResponse errorResponse = new ErrorResponse(2, "请求的数据格式不对");
return gson.toJson(errorResponse);
}
String userUUID = UUID.randomUUID().toString();
String userBcryptPasswd = BCrypt.hashpw(registerRequestBody.password, BCrypt.gensalt());
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserRegister userRegister = sqlSession.getMapper(UserRegister.class);
userRegister.addRegisterInfoIntoDb(userUUID, registerRequestBody.userName, userBcryptPasswd);
RegisterResponseData registerResponseBody = new RegisterResponseData(10101, userUUID, userBcryptPasswd);
ResponseBase<RegisterResponseData> response = new ResponseBase<>(200, "success", registerResponseBody);
return gson.toJson(response);
}
public static class RegisterRequestBody {
@SerializedName("user_name")
private String userName;
private String password;
public RegisterRequestBody(String userName, String password) {
this.userName = userName;
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
}

@ -0,0 +1,27 @@
package me.lensfrex.littlebusters.api.v1.beans;
public class ProfileItem {
private String itemName;
private String data;
public ProfileItem(String itemName, String data) {
this.itemName = itemName;
this.data = data;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}

@ -0,0 +1,10 @@
package me.lensfrex.littlebusters.api.v1.dao;
import org.apache.ibatis.annotations.Param;
import java.util.Map;
public interface UserInformation {
Map<String, Object> getBasicInfoByUserName(@Param("userName") String userName);
}

@ -0,0 +1,9 @@
package me.lensfrex.littlebusters.api.v1.dao;
import org.apache.ibatis.annotations.Param;
public interface UserRegister {
int addRegisterInfoIntoDb(@Param("uuid") String UUID,
@Param("userName") String userName,
@Param("password") String password);
}

@ -0,0 +1,15 @@
package me.lensfrex.littlebusters.api.v1;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/inputTest")
public class inputTest {
@POST
@Produces(MediaType.APPLICATION_JSON)
public String inputTest(String string) {
return string;
}
}

@ -0,0 +1,89 @@
package me.lensfrex.littlebusters.api.v1.login;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.SerializedName;
import com.sun.org.apache.xalan.internal.xsltc.trax.XSLTCSource;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import me.lensfrex.littlebusters.api.v1.dao.UserInformation;
import me.lensfrex.littlebusters.api.v1.responses.LoginResponseData;
import me.lensfrex.littlebusters.api.v1.responses.general.ErrorResponse;
import me.lensfrex.littlebusters.api.v1.responses.general.ResponseBase;
import me.lensfrex.littlebusters.api.v1.utils.InputChecker;
import me.lensfrex.littlebusters.api.v1.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.mindrot.jbcrypt.BCrypt;
import java.math.BigInteger;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
@Path("/login")
public class Login {
private final static Gson gson = new Gson();
@POST
@Produces(MediaType.APPLICATION_JSON)
public String login(String request) {
LoginRequestBody loginRequestBody;
try {
loginRequestBody = gson.fromJson(request, LoginRequestBody.class);
if (InputChecker.hasInvalidChar(loginRequestBody.userName) ||
InputChecker.hasInvisibleChar(loginRequestBody.password)) {
ErrorResponse errorResponse = new ErrorResponse(100, "请求的用户名或密码非法");
return gson.toJson(errorResponse);
}
if ()
LoginResponseData loginResponseData = new LoginResponseData(((BigInteger) selectResult.get("uid")).intValue(), (String) selectResult.get("password"), LocalDate.now().toString());
ResponseBase<LoginResponseData> response = new ResponseBase<>(200, "success", loginResponseData);
return gson.toJson(response);
} catch (JsonParseException e) {
System.err.println(request);
ErrorResponse errorResponse = new ErrorResponse(300, "请求的数据格式不对");
return gson.toJson(errorResponse);
} catch (Exception e) {
System.err.println(request);
System.err.println(e.getMessage());
ErrorResponse errorResponse = new ErrorResponse(400, "服务器内部错误,请联系那个背锅的家伙。");
return gson.toJson(errorResponse);
}
}
public static class LoginRequestBody {
@SerializedName("user_name")
private String userName;
private String password;
public LoginRequestBody(String userName, String password) {
this.userName = userName;
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
}

@ -0,0 +1,24 @@
package me.lensfrex.littlebusters.api.v1.login;
import me.lensfrex.littlebusters.api.v1.dao.UserInformation;
import me.lensfrex.littlebusters.api.v1.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.mindrot.jbcrypt.BCrypt;
import java.util.Map;
public class LoginIdentify {
public boolean identifyLoginUserName(String userName, String passwordSHA256) {
SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
UserInformation mapper = sqlSession.getMapper(UserInformation.class);
Map<String, Object> selectResult = mapper.getBasicInfoByUserName(userName);
if (selectResult == null) {
return false;
}
return BCrypt.checkpw(passwordSHA256, (String) selectResult.get("password"));
}
}

@ -0,0 +1,17 @@
package me.lensfrex.littlebusters.api.v1.pojos;
public class UserResult {
public final int uid;
public final String UUID;
public final String password;
public final boolean deleted;
public final short accountStatus;
public UserResult(int uid, String UUID, String password, boolean deleted, short accountStatus) {
this.uid = uid;
this.UUID = UUID;
this.password = password;
this.deleted = deleted;
this.accountStatus = accountStatus;
}
}

@ -0,0 +1,55 @@
package me.lensfrex.littlebusters.api.v1.responses;
import com.google.gson.annotations.SerializedName;
/**
* 登录响应中data字段的对象
*/
public class LoginResponseData {
/**
* 登录用户的uid
*/
private int uid;
/**
* 用户本次登录得到的token
*/
@SerializedName("access_token")
private String accessToken;
/**
* 用户此次得到的token的过期时间
*/
@SerializedName("expired_at")
private String expiredAt;
public LoginResponseData(int uid, String accessToken, String expiredAt) {
this.uid = uid;
this.accessToken = accessToken;
this.expiredAt = expiredAt;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getExpiredAt() {
return expiredAt;
}
public void setExpiredAt(String expiredAt) {
this.expiredAt = expiredAt;
}
}

@ -0,0 +1,24 @@
package me.lensfrex.littlebusters.api.v1.responses;
import me.lensfrex.littlebusters.api.v1.beans.ProfileItem;
import java.util.ArrayList;
import java.util.List;
public class ProfileResponseData {
private List<ProfileItem> profileItems;
public ProfileResponseData(List<ProfileItem> profileItems) {
this.profileItems = new ArrayList<>(profileItems);
}
public List<ProfileItem> getProfileItems() {
return profileItems;
}
public void setProfileItems(List<ProfileItem> profileItems) {
this.profileItems = profileItems;
}
}

@ -0,0 +1,52 @@
package me.lensfrex.littlebusters.api.v1.responses;
import com.google.gson.annotations.SerializedName;
public class RegisterResponseData {
/**
* 用户注册分派到的uid
*/
private int uid;
/**
* 用户本次注册时得到的token
*/
@SerializedName("access_token")
private String accessToken;
/**
* 用户此次得到的token的过期时间
*/
@SerializedName("expired_at")
private String expiredAt;
public RegisterResponseData(int uid, String accessToken, String expiredAt) {
this.uid = uid;
this.accessToken = accessToken;
this.expiredAt = expiredAt;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getExpiredAt() {
return expiredAt;
}
public void setExpiredAt(String expiredAt) {
this.expiredAt = expiredAt;
}
}

@ -0,0 +1,16 @@
package me.lensfrex.littlebusters.api.v1.responses.general;
/**
* 错误响应类
*/
public class ErrorResponse extends ResponseBase<ErrorData> {
public ErrorResponse(int code, String message) {
super(code, message, null);
}
}
class ErrorData {}
class ErrorCode {
public static final int REQUEST_PARAM_INVALID = 100;
}

@ -0,0 +1,53 @@
package me.lensfrex.littlebusters.api.v1.responses.general;
import com.google.gson.annotations.SerializedName;
public class ResponseBase<T> {
/**
* 信息码
*/
private int code;
/**
* 处理信息
*/
@SerializedName("msg")
private String message;
private T data;
/**
* 构造一个基本响应
* @param code 信息码
* @param message 处理信息
*/
public ResponseBase(int code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

@ -0,0 +1,27 @@
package me.lensfrex.littlebusters.api.v1.utils;
public class InputChecker {
public static boolean hasInvalidChar(String input) {
char[] source = input.toCharArray();
for (char c : source) {
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9'))) {
return true;
}
}
return false;
}
public static boolean hasInvisibleChar(String input) {
char[] source = input.toCharArray();
for (char c : source) {
if (!(c >= ' ' && c <= '~')) {
return true;
}
}
return false;
}
}

@ -0,0 +1,28 @@
package me.lensfrex.littlebusters.api.v1.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(boolean autoCommit) {
return sqlSessionFactory.openSession(autoCommit);
}
}

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.lensfrex.littlebusters.api.v1.dao.UserInformation">
<select id="getBasicInfoByUserName" resultType="Map" parameterType="java.lang.String">
select uid, uuid, passwd as password, deleted, account_status as accountStstus
from `account_basic`
where user_name = #{userName}
</select>
</mapper>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="me.lensfrex.littlebusters.api.v1.dao.UserRegister">
<insert id="addRegisterInfoIntoDb">
insert into `LittleBusters`.`account_basic` (`uuid`, `user_name`, `passwd`)
values (#{uuid}, #{userName}, #{password})
</insert>
</mapper>

@ -0,0 +1,93 @@
<!DOCTYPE html>
<head>
<title>出问题啦 - 真不愧是lensfrex的破站呢</title>
<meta http-equiv="Content-Type" name="viewport" content="text/html width=device-width initial-scale=1"
charset=utf-8>
<style>
a {
text-decoration: none;
font-size: 15.0pt;
font-family: sans-serif;
margin-top: 10.0pt;
margin-bottom: 10.0pt;
color: rgb(255, 255, 255);
}
/* a:hover {
text-decoration: none;
} */
body {
word-wrap: break-word;
background-image: url(https://res.ciduid.top/blog/backgrounds/95761609_p0_land_processed.jpg);
background-position: 45% 0;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}
#button_box {
background-color: rgba(102, 51, 153, 0.45);
border-radius: 10px;
padding: 7px 10px 7px 10px;
margin: 0 auto;
max-inline-size: fit-content;
text-align: left;
}
.button {
font-size: 15.0pt;
font-family: sans-serif;
margin-top: 10.0pt;
margin-bottom: 10.0pt;
color: rgb(255, 255, 255);
}
.center_box {
text-align: center;
}
.title {
text-align: center;
font-size: 40.0pt;
color: white;
}
.msg {
font-size: 20.0pt;
font-family: -webkit-body;
color: white;
}
</style>
</head>
<body lang="ZH-CN">
<div>
<div id="main_div">
<!-- <p id="title" align="center" style="text-align:center; font-size: 40.0pt; color: white;">50x error page</p> -->
<p class="title">找不到页面...</p>
<hr color="white" size="10">
<div class="center_box">
<p class="msg">找不到你要访问的页面哟</p>
<p class="msg">是不是把地址给搞错了?</p>
</div>
<div class="center_box" style="margin-top: 100px;">
<!-- <br><br> -->
<div id="button_box">
<a href="https://huhu.ciduid.top" class="button">
-> 要不,去博客那里瞧瞧?
</a>
<br><br>
<a href="javascript:history.back(-1)" class="button">
-> 还是说只是想回上一页?
</a>
</div>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>LittleBustersApiV1</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>me.lensfrex.littlebusters</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>LittleBustersApiV1</servlet-name>
<url-pattern>/api/v1/*</url-pattern>
</servlet-mapping>
</web-app>

@ -0,0 +1,180 @@
body {
word-wrap: break-word;
/* background: url(https://res.ciduid.top/static/imgs/compressed/93527505_p0_conpressed.jpg) no-repeat fixed; */
background-position: 45% 0;
background-size: cover;
}
.login-box {
background-color: rgb(256, 256, 256, 0.6);
position: fixed;
top: 10%;
left: 5%;
border-radius: 15px;
padding: 20px 20px 17px 20px;
}
.input-field-group {
transition: height .5s;
}
.login-box-title {
font-size: 45px;
padding-bottom: 40px;
}
.input-field input {
width: 400px;
height: 40px;
font-family: Consolas monospace;
padding-left: 10px;
font-size: 16px;
font-weight: bold;
border-radius: 10px;
border: none;
background: rgba(256, 256, 256, 0.6);
outline: none;
outline: 0;
transition: background-color .5s;
}
.input-field input:focus {
background-color: rgb(214, 234, 248, 0.6);
}
.input-field {
margin-bottom: 15px;
}
/* 仿的是pixiv上登录页的按钮 */
.operator-box .big-button {
display: block;
margin-top: 15px;
margin-bottom: 15px;
width: 190px;
height: 40px;
line-height: 40px;
border-radius: 10px;
border-style: none;
color: #fff;
outline: none;
font-weight: 700;
font-size: 14px;
text-align: center;
transition: background-color .2s;
cursor: pointer;
display: inline-block;
text-decoration: none;
}
#login-botton {
background-color: rgb(0 150 250);
}
#register-botton {
background-color: rgb(34 139 34);
}
.botton-box {
text-align: center;
display: flex;
justify-content: space-between;
}
.operator-box .big-button:hover {
background-color: #0382d6;
}
.operator-box .rl-layout-box .small-link {
cursor: pointer;
}
.rl-layout-box {
text-align: center;
display: flex;
justify-content: space-between;
/* line-height: 25px; */
}
#dialogMask {
width: 100%;
height: 100%;
word-wrap: break-word;
position: fixed;
top: 0;
left: 0;
background: rgb(45 44 44 / 45%);
transition: background 300ms;
z-index: 1001;
display: none;
}
#background {
width: 100%;
height: 100%;
background: url(https://res.ciduid.top/static/imgs/compressed/93527505_p0_conpressed.jpg) no-repeat fixed;
background-position: 45% 0;
background-size: cover;
word-wrap: break-word;
position: fixed;
top: 0;
left: 0;
z-index: -1;
filter: blur(1.5px);
/* 稍微放大除白边 */
transform: scale(1.01);
}
.dialogContentBox {
display: block;
position: fixed;
top: 50%;
left: 50%;
width: 435px;
/* height: 313px; */
margin-left: -227px;
margin-top: -200px;
box-shadow: 2px 2px 11px #a0a0a0, -2px -2px 4px #a0a0a0;
background-color: #fff;
border-radius: 15px;
padding: 30px 20px 15px 20px;
}
.dialogContentBox .titleBox {
}
.dialogContentBox .titleBox #title {
font-size: 30px;
margin: auto auto 15px auto;
}
.dialogContentBox .bodyBox p {
font-size: 20px;
}
.dialogContentBox .bottonBox {
text-align: right;
/* margin: auto auto 15px auto; */
}
.dialogContentBox .bottonBox #okbtn {
border: none;
background: rgb(0 150 250);
cursor: pointer;
color: white;
font-family: sans-serif;
font-size: 16px;
border-radius: 5px;
height: 31px;
width: 80px;
}
#errMsgBox p {
margin: 0 0 0 0;
color: red;
}
@media screen and (max-width: 494px) {
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>欢迎 - LittleBusters</title>
<link rel="stylesheet" type="text/css" href="css\welcomepage.css">
<script src="js/sha256-min.js"></script>
<script src="js/jquery-3.6.0.min.js"></script>
<script src="js/utils.js"></script>
<script src="js/welcomepage_message.js"></script>
<script src="js/events.js"></script>
<script src="js/init.js"></script>
<!--[if IE]><script>alert("别用IE浏览器啦,快换一个吧!");</script><![endif]-->
</head>
<!-- 前端不擅长,逻辑做的很简单,见谅 ( ̄﹏ ̄;)-->
<body lang="ZH-CN">
<div id="content">
<div id="background"></div>
<div id="dialogMask"></div>
<div class="login-box">
<div class="login-box-title">登录/注册</div>
<div class="input-field-group">
<div class="input-field">
<input id="username" type="text" autocomplete="username" placeholder="用户名/UID">
</div>
<div class="input-field">
<input id="passwd" type="password" autocomplete="current-password" placeholder="密码">
</div>
<div id="errMsgBox"></div>
</div>
<div class="operator-box">
<div class="botton-box">
<button class="big-button" type="submit" id="register-botton">注册</button>
<button class="big-button" type="submit" id="login-botton">登录</button>
</div>
<div class="rl-layout-box">
<a class="small-link" id="forgotPasswordLabel">不记得密码了?</a>
</div>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,28 @@
function login() {
console.log("start login");
username = $("#username").val();
password = $("#passwd").val();
if (!checkInputDataCorrect(username, password)) {
return;
}
encPassword = encryptPassword(password);
postData = {
"user_name": username,
"password": encPassword
};
$.ajax({
url: "/api/v1/login",
type: "post",
dataType: "json",
data: JSON.stringify(postData),
success: (result) => {
showDialog("Test", "获取到数据:" + JSON.stringify(result));
},
error: (msg, status) => {
showMessage("登陆时发生错误:",JSON.stringify(msg));
}
})
}

@ -0,0 +1,12 @@
init();
function init() {
addEventListeners();
}
function addEventListeners() {
$(document).on("click", "#register-botton", register);
$(document).on("click", "#login-botton", login);
$(document).on("click", "#forgotPasswordLabel", forgotPasswd);
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,16 @@
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(h,s){var f={},t=f.lib={},g=function(){},j=t.Base={extend:function(a){g.prototype=this;var c=new g;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
q=t.WordArray=j.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=s?c:4*a.length},toString:function(a){return(a||u).stringify(this)},concat:function(a){var c=this.words,d=a.words,b=this.sigBytes;a=a.sigBytes;this.clamp();if(b%4)for(var e=0;e<a;e++)c[b+e>>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535<d.length)for(e=0;e<a;e+=4)c[b+e>>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=j.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d<a;d+=4)c.push(4294967296*h.random()|0);return new q.init(c,a)}}),v=f.enc={},u=v.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++){var e=c[b>>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b+=2)d[b>>>3]|=parseInt(a.substr(b,
2),16)<<24-4*(b%8);return new q.init(d,c/2)}},k=v.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++)d.push(String.fromCharCode(c[b>>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b++)d[b>>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new q.init(d,c)}},l=v.Utf8={stringify:function(a){try{return decodeURIComponent(escape(k.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return k.parse(unescape(encodeURIComponent(a)))}},
x=t.BufferedBlockAlgorithm=j.extend({reset:function(){this._data=new q.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=l.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var m=0;m<a;m+=e)this._doProcessBlock(d,m);m=d.splice(0,a);c.sigBytes-=b}return new q.init(m,b)},clone:function(){var a=j.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});t.Hasher=x.extend({cfg:j.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){x.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(c,d){return(new a.init(d)).finalize(c)}},_createHmacHelper:function(a){return function(c,d){return(new w.HMAC.init(a,
d)).finalize(c)}}});var w=f.algo={};return f}(Math);
(function(h){for(var s=CryptoJS,f=s.lib,t=f.WordArray,g=f.Hasher,f=s.algo,j=[],q=[],v=function(a){return 4294967296*(a-(a|0))|0},u=2,k=0;64>k;){var l;a:{l=u;for(var x=h.sqrt(l),w=2;w<=x;w++)if(!(l%w)){l=!1;break a}l=!0}l&&(8>k&&(j[k]=v(h.pow(u,0.5))),q[k]=v(h.pow(u,1/3)),k++);u++}var a=[],f=f.SHA256=g.extend({_doReset:function(){this._hash=new t.init(j.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],m=b[2],h=b[3],p=b[4],j=b[5],k=b[6],l=b[7],n=0;64>n;n++){if(16>n)a[n]=
c[d+n]|0;else{var r=a[n-15],g=a[n-2];a[n]=((r<<25|r>>>7)^(r<<14|r>>>18)^r>>>3)+a[n-7]+((g<<15|g>>>17)^(g<<13|g>>>19)^g>>>10)+a[n-16]}r=l+((p<<26|p>>>6)^(p<<21|p>>>11)^(p<<7|p>>>25))+(p&j^~p&k)+q[n]+a[n];g=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&m^f&m);l=k;k=j;j=p;p=h+r|0;h=m;m=f;f=e;e=r+g|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+m|0;b[3]=b[3]+h|0;b[4]=b[4]+p|0;b[5]=b[5]+j|0;b[6]=b[6]+k|0;b[7]=b[7]+l|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes;
d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=g.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=g._createHelper(f);s.HmacSHA256=g._createHmacHelper(f)})(Math);

@ -0,0 +1,28 @@
function isLetter(source) {
for (i = 0; i < source.length; i++) {
char = source.charCodeAt(i);
if (!((char >= 65 && char <= 90) ||
(char >= 97 && char <= 122) ||
(char >= 48 && char <= 57))) {
return false;
}
}
return true;
}
function isNormalCharacter(source) {
for (i = 0; i < source.length; i++) {
char = source.charCodeAt(i);
if (!(char >= 32 && char <= 126)) {
return false;
}
}
return true;
}
function encryptPassword(password) {
sha256 = CryptoJS.SHA256;
return sha256(sha256(password).toString()).toString();
}

@ -0,0 +1,54 @@
function forgotPasswd() {
showDialog("( ̄﹏ ̄;)", "欸这个嘛...我还没做完呢...( ̄﹏ ̄;)");
}
function register() {
showDialog("( ̄﹏ ̄;)", "欸这个嘛...我还没做完呢...( ̄﹏ ̄;)");
}
function closeDialog() {
$("#dialogMask").fadeOut(400);
}
function checkInputDataCorrect(username, password) {
if (username == "" || passwd == "") {
showMessage("用户名和密码都不可以是空的哦");
return false;
}
if (!isLetter(username)) {
showMessage("用户名只能是大小写字母和数字哦");
return false;
}
if (!isNormalCharacter(passwd)) {
showMessage("不知道你往密码框都搞了点什么东西...");
return false;
}
return true;
}
function showMessage(message) {
$("#errMsgBox")[0].innerHTML = `<p>${message}</p>`;
}
function showDialog(title, message) {
html = `<div class="dialogContentBox">
<div class="titleBox">
<p id="title">${title}</p>
</div><hr>
<div class="bodyBox">
<p id="bodyText">${message}</p>
</div>
<div class="bottonBox">
<button id="okbtn">知道啦</button>
</div>
</div>`;
dialogMask = $("#dialogMask");
dialogMask[0].innerHTML = html;
$(".dialogContentBox .bottonBox #okbtn").click(closeDialog);
dialogMask.fadeIn(400);
dialogMask.css("display", "block");
}
Loading…
Cancel
Save