Finish sign api. Optimize code.
This commit is contained in:
@@ -75,7 +75,9 @@ class SecurityConfig(
|
|||||||
"/swagger-ui.html",
|
"/swagger-ui.html",
|
||||||
"/favicon.ico",
|
"/favicon.ico",
|
||||||
"/login",
|
"/login",
|
||||||
"/register"
|
"/register",
|
||||||
|
"/forget",
|
||||||
|
"/retrieve"
|
||||||
).anonymous()
|
).anonymous()
|
||||||
// Authentication required
|
// Authentication required
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import org.springframework.web.bind.annotation.RequestBody
|
|||||||
import top.fatweb.api.annotation.BaseController
|
import top.fatweb.api.annotation.BaseController
|
||||||
import top.fatweb.api.entity.common.ResponseCode
|
import top.fatweb.api.entity.common.ResponseCode
|
||||||
import top.fatweb.api.entity.common.ResponseResult
|
import top.fatweb.api.entity.common.ResponseResult
|
||||||
import top.fatweb.api.param.permission.LoginParam
|
import top.fatweb.api.param.permission.*
|
||||||
import top.fatweb.api.param.permission.RegisterParam
|
|
||||||
import top.fatweb.api.param.permission.VerifyParam
|
|
||||||
import top.fatweb.api.service.permission.IAuthenticationService
|
import top.fatweb.api.service.permission.IAuthenticationService
|
||||||
import top.fatweb.api.util.WebUtil
|
import top.fatweb.api.util.WebUtil
|
||||||
import top.fatweb.api.vo.permission.LoginVo
|
import top.fatweb.api.vo.permission.LoginVo
|
||||||
@@ -49,7 +47,7 @@ class AuthenticationController(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "发送验证邮箱")
|
@Operation(summary = "发送验证邮件")
|
||||||
@PostMapping("/resend")
|
@PostMapping("/resend")
|
||||||
fun resend(): ResponseResult<Nothing> {
|
fun resend(): ResponseResult<Nothing> {
|
||||||
authenticationService.resend()
|
authenticationService.resend()
|
||||||
@@ -58,12 +56,12 @@ class AuthenticationController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify
|
* Verify email
|
||||||
*
|
*
|
||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "验证")
|
@Operation(summary = "验证邮箱")
|
||||||
@PostMapping("/verify")
|
@PostMapping("/verify")
|
||||||
fun verify(@Valid @RequestBody verifyParam: VerifyParam): ResponseResult<Nothing> {
|
fun verify(@Valid @RequestBody verifyParam: VerifyParam): ResponseResult<Nothing> {
|
||||||
authenticationService.verify(verifyParam)
|
authenticationService.verify(verifyParam)
|
||||||
@@ -71,6 +69,34 @@ class AuthenticationController(
|
|||||||
return ResponseResult.success(ResponseCode.PERMISSION_VERIFY_SUCCESS)
|
return ResponseResult.success(ResponseCode.PERMISSION_VERIFY_SUCCESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forget password
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Operation(summary = "忘记密码")
|
||||||
|
@PostMapping("/forget")
|
||||||
|
fun forget(request: HttpServletRequest, @Valid @RequestBody forgetParam: ForgetParam): ResponseResult<Nothing> {
|
||||||
|
authenticationService.forget(request, forgetParam)
|
||||||
|
|
||||||
|
return ResponseResult.success(ResponseCode.PERMISSION_FORGET_SUCCESS)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve password
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Operation(summary = "找回密码")
|
||||||
|
@PostMapping("/retrieve")
|
||||||
|
fun retrieve(request: HttpServletRequest, @Valid @RequestBody retrieveParam: RetrieveParam): ResponseResult<Nothing> {
|
||||||
|
authenticationService.retrieve(request, retrieveParam)
|
||||||
|
|
||||||
|
return ResponseResult.success(ResponseCode.PERMISSION_RETRIEVE_SUCCESS)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Login
|
* Login
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ enum class ResponseCode(val code: Int) {
|
|||||||
PERMISSION_REGISTER_SUCCESS(BusinessCode.PERMISSION, 4),
|
PERMISSION_REGISTER_SUCCESS(BusinessCode.PERMISSION, 4),
|
||||||
PERMISSION_RESEND_SUCCESS(BusinessCode.PERMISSION, 5),
|
PERMISSION_RESEND_SUCCESS(BusinessCode.PERMISSION, 5),
|
||||||
PERMISSION_VERIFY_SUCCESS(BusinessCode.PERMISSION, 6),
|
PERMISSION_VERIFY_SUCCESS(BusinessCode.PERMISSION, 6),
|
||||||
|
PERMISSION_FORGET_SUCCESS(BusinessCode.PERMISSION, 7),
|
||||||
|
PERMISSION_RETRIEVE_SUCCESS(BusinessCode.PERMISSION, 8),
|
||||||
|
|
||||||
PERMISSION_UNAUTHORIZED(BusinessCode.PERMISSION, 50),
|
PERMISSION_UNAUTHORIZED(BusinessCode.PERMISSION, 50),
|
||||||
PERMISSION_USERNAME_NOT_FOUND(BusinessCode.PERMISSION, 51),
|
PERMISSION_USERNAME_NOT_FOUND(BusinessCode.PERMISSION, 51),
|
||||||
@@ -37,6 +39,9 @@ enum class ResponseCode(val code: Int) {
|
|||||||
PERMISSION_NO_VERIFICATION_REQUIRED(BusinessCode.PERMISSION, 62),
|
PERMISSION_NO_VERIFICATION_REQUIRED(BusinessCode.PERMISSION, 62),
|
||||||
PERMISSION_VERIFY_CODE_ERROR_OR_EXPIRED(BusinessCode.PERMISSION, 63),
|
PERMISSION_VERIFY_CODE_ERROR_OR_EXPIRED(BusinessCode.PERMISSION, 63),
|
||||||
PERMISSION_ACCOUNT_NEED_INIT(BusinessCode.PERMISSION, 64),
|
PERMISSION_ACCOUNT_NEED_INIT(BusinessCode.PERMISSION, 64),
|
||||||
|
PERMISSION_USER_NOT_FOUND(BusinessCode.PERMISSION, 65),
|
||||||
|
PERMISSION_RETRIEVE_CODE_ERROR_OR_EXPIRED(BusinessCode.PERMISSION, 66),
|
||||||
|
PERMISSION_ACCOUNT_NEED_RESET_PASSWORD(BusinessCode.PERMISSION, 67),
|
||||||
|
|
||||||
DATABASE_SELECT_SUCCESS(BusinessCode.DATABASE, 0),
|
DATABASE_SELECT_SUCCESS(BusinessCode.DATABASE, 0),
|
||||||
DATABASE_SELECT_FAILED(BusinessCode.DATABASE, 5),
|
DATABASE_SELECT_FAILED(BusinessCode.DATABASE, 5),
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class User() : Serializable {
|
|||||||
var password: String? = null
|
var password: String? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify
|
* Verify email
|
||||||
*
|
*
|
||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
@@ -55,6 +55,15 @@ class User() : Serializable {
|
|||||||
@TableField("verify")
|
@TableField("verify")
|
||||||
var verify: String? = null
|
var verify: String? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forget password
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@TableField("forget")
|
||||||
|
var forget: String? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locking
|
* Locking
|
||||||
*
|
*
|
||||||
@@ -242,6 +251,6 @@ class User() : Serializable {
|
|||||||
var operations: List<Operation>? = null
|
var operations: List<Operation>? = null
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "User(id=$id, username=$username, password=$password, locking=$locking, expiration=$expiration, credentialsExpiration=$credentialsExpiration, enable=$enable, currentLoginTime=$currentLoginTime, currentLoginIp=$currentLoginIp, lastLoginTime=$lastLoginTime, lastLoginIp=$lastLoginIp, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, userInfo=$userInfo, roles=$roles, groups=$groups, modules=$modules, menus=$menus, funcs=$funcs, operations=$operations)"
|
return "User(id=$id, username=$username, password=$password, verify=$verify, forget=$forget, locking=$locking, expiration=$expiration, credentialsExpiration=$credentialsExpiration, enable=$enable, currentLoginTime=$currentLoginTime, currentLoginIp=$currentLoginIp, lastLoginTime=$lastLoginTime, lastLoginIp=$lastLoginIp, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, userInfo=$userInfo, roles=$roles, groups=$groups, modules=$modules, menus=$menus, funcs=$funcs, operations=$operations)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package top.fatweb.api.exception
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Account need reset password exception
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
class AccountNeedResetPasswordException : RuntimeException("Account need reset password")
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package top.fatweb.api.exception
|
||||||
|
|
||||||
|
class RetrieveCodeErrorOrExpiredException : RuntimeException("Retrieve code error or expired")
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package top.fatweb.api.exception
|
||||||
|
|
||||||
|
class UserNotFoundException : RuntimeException("User not found")
|
||||||
@@ -121,6 +121,11 @@ class ExceptionHandler {
|
|||||||
ResponseResult.fail(ResponseCode.PERMISSION_ACCESS_DENIED, "Access Denied", null)
|
ResponseResult.fail(ResponseCode.PERMISSION_ACCESS_DENIED, "Access Denied", null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is UserNotFoundException -> {
|
||||||
|
logger.debug(e.localizedMessage, e)
|
||||||
|
ResponseResult.fail(ResponseCode.PERMISSION_USER_NOT_FOUND, e.localizedMessage, null)
|
||||||
|
}
|
||||||
|
|
||||||
is NoVerificationRequiredException -> {
|
is NoVerificationRequiredException -> {
|
||||||
logger.debug(e.localizedMessage, e)
|
logger.debug(e.localizedMessage, e)
|
||||||
ResponseResult.fail(ResponseCode.PERMISSION_NO_VERIFICATION_REQUIRED, e.localizedMessage, null)
|
ResponseResult.fail(ResponseCode.PERMISSION_NO_VERIFICATION_REQUIRED, e.localizedMessage, null)
|
||||||
@@ -136,6 +141,16 @@ class ExceptionHandler {
|
|||||||
ResponseResult.fail(ResponseCode.PERMISSION_ACCOUNT_NEED_INIT, e.localizedMessage, null)
|
ResponseResult.fail(ResponseCode.PERMISSION_ACCOUNT_NEED_INIT, e.localizedMessage, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is RetrieveCodeErrorOrExpiredException -> {
|
||||||
|
logger.debug(e.localizedMessage, e)
|
||||||
|
ResponseResult.fail(ResponseCode.PERMISSION_RETRIEVE_CODE_ERROR_OR_EXPIRED, e.localizedMessage, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
is AccountNeedResetPasswordException -> {
|
||||||
|
logger.debug(e.localizedMessage, e)
|
||||||
|
ResponseResult.fail(ResponseCode.PERMISSION_ACCOUNT_NEED_RESET_PASSWORD, e.localizedMessage, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
is BadSqlGrammarException -> {
|
is BadSqlGrammarException -> {
|
||||||
logger.debug(e.localizedMessage, e)
|
logger.debug(e.localizedMessage, e)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package top.fatweb.api.mapper.permission
|
|||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||||
import org.apache.ibatis.annotations.Mapper
|
import org.apache.ibatis.annotations.Mapper
|
||||||
|
import org.apache.ibatis.annotations.Param
|
||||||
import top.fatweb.api.entity.permission.Group
|
import top.fatweb.api.entity.permission.Group
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +27,11 @@ interface GroupMapper : BaseMapper<Group> {
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see IPage
|
* @see IPage
|
||||||
*/
|
*/
|
||||||
fun selectPage(page: IPage<Long>, searchName: String?, searchRegex: Boolean): IPage<Long>
|
fun selectPage(
|
||||||
|
page: IPage<Long>,
|
||||||
|
@Param("searchName") searchName: String?,
|
||||||
|
@Param("searchRegex") searchRegex: Boolean
|
||||||
|
): IPage<Long>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select group with role list by list of group IDs
|
* Select group with role list by list of group IDs
|
||||||
@@ -37,7 +42,7 @@ interface GroupMapper : BaseMapper<Group> {
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see Group
|
* @see Group
|
||||||
*/
|
*/
|
||||||
fun selectListWithRoleByIds(groupIds: List<Long>): List<Group>?
|
fun selectListWithRoleByIds(@Param("groupIds") groupIds: List<Long>): List<Group>?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select one group by ID
|
* Select one group by ID
|
||||||
@@ -48,5 +53,5 @@ interface GroupMapper : BaseMapper<Group> {
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see Group
|
* @see Group
|
||||||
*/
|
*/
|
||||||
fun selectOneById(id: Long): Group?
|
fun selectOneById(@Param("id") id: Long): Group?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package top.fatweb.api.mapper.permission
|
|||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||||
import org.apache.ibatis.annotations.Mapper
|
import org.apache.ibatis.annotations.Mapper
|
||||||
|
import org.apache.ibatis.annotations.Param
|
||||||
import top.fatweb.api.entity.permission.Role
|
import top.fatweb.api.entity.permission.Role
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +27,11 @@ interface RoleMapper : BaseMapper<Role> {
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see IPage
|
* @see IPage
|
||||||
*/
|
*/
|
||||||
fun selectPage(page: IPage<Long>, searchName: String?, searchRegex: Boolean): IPage<Long>
|
fun selectPage(
|
||||||
|
page: IPage<Long>,
|
||||||
|
@Param("searchName") searchName: String?,
|
||||||
|
@Param("searchRegex") searchRegex: Boolean
|
||||||
|
): IPage<Long>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select role with power list by list of role IDs
|
* Select role with power list by list of role IDs
|
||||||
@@ -37,7 +42,7 @@ interface RoleMapper : BaseMapper<Role> {
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see Role
|
* @see Role
|
||||||
*/
|
*/
|
||||||
fun selectListWithPowerByIds(roleIds: List<Long>): List<Role>?
|
fun selectListWithPowerByIds(@Param("roleIds") roleIds: List<Long>): List<Role>?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select one role by ID
|
* Select one role by ID
|
||||||
@@ -48,5 +53,5 @@ interface RoleMapper : BaseMapper<Role> {
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see Role
|
* @see Role
|
||||||
*/
|
*/
|
||||||
fun selectOneById(id: Long): Role?
|
fun selectOneById(@Param("id") id: Long): Role?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,12 @@ interface UserMapper : BaseMapper<User> {
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see IPage
|
* @see IPage
|
||||||
*/
|
*/
|
||||||
fun selectPage(page: IPage<Long>, searchType: String, searchValue: String?, searchRegex: Boolean): IPage<Long>
|
fun selectPage(
|
||||||
|
page: IPage<Long>,
|
||||||
|
@Param("searchType") searchType: String,
|
||||||
|
@Param("searchValue") searchValue: String?,
|
||||||
|
@Param("searchRegex") searchRegex: Boolean
|
||||||
|
): IPage<Long>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select user with role and information list by list of user IDs
|
* Select user with role and information list by list of user IDs
|
||||||
@@ -50,7 +55,7 @@ interface UserMapper : BaseMapper<User> {
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see User
|
* @see User
|
||||||
*/
|
*/
|
||||||
fun selectListWithRoleInfoByIds(userIds: List<Long>): List<User>
|
fun selectListWithRoleInfoByIds(@Param("userIds") userIds: List<Long>): List<User>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select one user by ID
|
* Select one user by ID
|
||||||
@@ -61,7 +66,7 @@ interface UserMapper : BaseMapper<User> {
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see User
|
* @see User
|
||||||
*/
|
*/
|
||||||
fun selectOneWithRoleInfoById(id: Long): User?
|
fun selectOneWithRoleInfoById(@Param("id") id: Long): User?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select all user with information list
|
* Select all user with information list
|
||||||
@@ -81,7 +86,7 @@ interface UserMapper : BaseMapper<User> {
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
fun selectIdsWithRoleIds(roleIds: List<Long>): List<Long>
|
fun selectIdsWithRoleIds(@Param("roleIds") roleIds: List<Long>): List<Long>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select user IDs list by list of group IDs
|
* Select user IDs list by list of group IDs
|
||||||
@@ -91,5 +96,5 @@ interface UserMapper : BaseMapper<User> {
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
fun selectIdsWithGroupIds(groupIds: List<Long>): List<Long>
|
fun selectIdsWithGroupIds(@Param("groupIds") groupIds: List<Long>): List<Long>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package top.fatweb.api.mapper.system
|
|||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||||
import org.apache.ibatis.annotations.Mapper
|
import org.apache.ibatis.annotations.Mapper
|
||||||
|
import org.apache.ibatis.annotations.Param
|
||||||
import top.fatweb.api.entity.system.SysLog
|
import top.fatweb.api.entity.system.SysLog
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
@@ -34,10 +35,10 @@ interface SysLogMapper : BaseMapper<SysLog> {
|
|||||||
*/
|
*/
|
||||||
fun selectPage(
|
fun selectPage(
|
||||||
page: IPage<SysLog>,
|
page: IPage<SysLog>,
|
||||||
logType: List<String>?,
|
@Param("logType") logType: List<String>?,
|
||||||
requestMethod: List<String>?,
|
@Param("requestMethod") requestMethod: List<String>?,
|
||||||
searchRequestUrl: String?,
|
@Param("searchRequestUrl") searchRequestUrl: String?,
|
||||||
searchStartTime: LocalDateTime?,
|
@Param("searchStartTime") searchStartTime: LocalDateTime?,
|
||||||
searchEndTime: LocalDateTime?
|
@Param("searchEndTime") searchEndTime: LocalDateTime?
|
||||||
): IPage<SysLog>
|
): IPage<SysLog>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ open class PageSortParam {
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "分页页码", example = "1", defaultValue = "1")
|
@Schema(description = "分页页码", defaultValue = "1", example = "1")
|
||||||
@field:Min(1, message = "Pagination page number must be a positive integer")
|
@field:Min(1, message = "Pagination page number must be a positive integer")
|
||||||
var currentPage: Long = 1
|
var currentPage: Long = 1
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ open class PageSortParam {
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "分页大小", example = "20", defaultValue = "20")
|
@Schema(description = "分页大小", defaultValue = "20", example = "20")
|
||||||
@field:Min(1, message = "The number of data per page must be a positive integer")
|
@field:Min(1, message = "The number of data per page must be a positive integer")
|
||||||
var pageSize: Long = 20
|
var pageSize: Long = 20
|
||||||
|
|
||||||
@@ -45,6 +45,6 @@ open class PageSortParam {
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "排序方式", example = "desc", allowableValues = ["desc", "asc"])
|
@Schema(description = "排序方式", allowableValues = ["desc", "asc"], defaultValue = "desc", example = "desc")
|
||||||
var sortOrder: String? = null
|
var sortOrder: String? = null
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package top.fatweb.api.param.permission
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
import jakarta.validation.constraints.NotBlank
|
||||||
|
import jakarta.validation.constraints.Pattern
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forget password parameters
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Schema(description = "忘记密码请求参数")
|
||||||
|
data class ForgetParam(
|
||||||
|
/**
|
||||||
|
* Email
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Schema(description = "邮箱", required = true, example = "user@email.com")
|
||||||
|
@field:NotBlank(message = "Email can not be blank")
|
||||||
|
@field:Pattern(regexp = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$", message = "Illegal email address")
|
||||||
|
val email: String?
|
||||||
|
)
|
||||||
@@ -17,7 +17,7 @@ data class LoginParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "账户", example = "test", required = true)
|
@Schema(description = "账户", required = true, example = "test")
|
||||||
@field:NotBlank(message = "Account can not be blank")
|
@field:NotBlank(message = "Account can not be blank")
|
||||||
val account: String?,
|
val account: String?,
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ data class LoginParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "密码", example = "test123456", required = true)
|
@Schema(description = "密码", required = true)
|
||||||
@field:NotBlank(message = "Password can not be blank")
|
@field:NotBlank(message = "Password can not be blank")
|
||||||
val password: String?
|
val password: String?
|
||||||
)
|
)
|
||||||
@@ -19,7 +19,7 @@ data class RegisterParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户名", example = "abc", required = true)
|
@Schema(description = "用户名", required = true, example = "abc")
|
||||||
@field:NotBlank(message = "Username can not be blank")
|
@field:NotBlank(message = "Username can not be blank")
|
||||||
@field:Pattern(regexp = "[a-zA-Z-_][0-9a-zA-Z-_]{2,38}", message = "Illegal username")
|
@field:Pattern(regexp = "[a-zA-Z-_][0-9a-zA-Z-_]{2,38}", message = "Illegal username")
|
||||||
val username: String?,
|
val username: String?,
|
||||||
@@ -30,7 +30,7 @@ data class RegisterParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "邮箱", example = "guest@fatweb.top", required = true)
|
@Schema(description = "邮箱", required = true, example = "user@email.com")
|
||||||
@field:NotBlank(message = "Email can not be blank")
|
@field:NotBlank(message = "Email can not be blank")
|
||||||
@field:Pattern(regexp = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$", message = "Illegal email address")
|
@field:Pattern(regexp = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$", message = "Illegal email address")
|
||||||
val email: String?,
|
val email: String?,
|
||||||
@@ -41,7 +41,7 @@ data class RegisterParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "密码", example = "test123456", required = true)
|
@Schema(description = "密码", required = true)
|
||||||
@field:NotBlank(message = "Password can not be blank")
|
@field:NotBlank(message = "Password can not be blank")
|
||||||
@field:Size(min = 10, max = 30)
|
@field:Size(min = 10, max = 30)
|
||||||
val password: String?
|
val password: String?
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package top.fatweb.api.param.permission
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
import jakarta.validation.constraints.NotBlank
|
||||||
|
import jakarta.validation.constraints.Size
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve password parameters
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Schema(description = "找回密码请求参数")
|
||||||
|
data class RetrieveParam(
|
||||||
|
/**
|
||||||
|
* Code
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Schema(description = "验证码", required = true)
|
||||||
|
@field:NotBlank(message = "Code can not be blank")
|
||||||
|
val code: String?,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New password
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Schema(description = "新密码")
|
||||||
|
@field:NotBlank(message = "New password can not be blank")
|
||||||
|
@field:Size(min = 10, max = 30)
|
||||||
|
val password: String?
|
||||||
|
)
|
||||||
@@ -4,12 +4,12 @@ import io.swagger.v3.oas.annotations.media.Schema
|
|||||||
import jakarta.validation.constraints.NotBlank
|
import jakarta.validation.constraints.NotBlank
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify parameters
|
* Verify email parameters
|
||||||
*
|
*
|
||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "验证请求参数")
|
@Schema(description = "验证邮箱请求参数")
|
||||||
data class VerifyParam(
|
data class VerifyParam(
|
||||||
/**
|
/**
|
||||||
* Code
|
* Code
|
||||||
@@ -17,7 +17,7 @@ data class VerifyParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "验证码", example = "9c4b8199-1dbe-4f6f-96a5-fe1d75cc6a65", required = true)
|
@Schema(description = "验证码", required = true)
|
||||||
@field:NotBlank(message = "Code can not be blank")
|
@field:NotBlank(message = "Code can not be blank")
|
||||||
val code: String?,
|
val code: String?,
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ data class GroupAddParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户组名称")
|
@Schema(description = "用户组名称", required = true, example = "Group_1")
|
||||||
@field:NotBlank(message = "Name can not be blank")
|
@field:NotBlank(message = "Name can not be blank")
|
||||||
val name: String?,
|
val name: String?,
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ data class GroupAddParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true")
|
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true", example = "true")
|
||||||
val enable: Boolean = true,
|
val enable: Boolean = true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ data class GroupDeleteParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户组 ID 列表")
|
@Schema(description = "用户组 ID 列表", required = true)
|
||||||
val ids: List<Long>
|
val ids: List<Long>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ data class GroupGetParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "查询用户组名称")
|
@Schema(description = "查询用户组名称", example = "Group_1")
|
||||||
val searchName: String?,
|
val searchName: String?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,6 +27,11 @@ data class GroupGetParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "查询使用正则表达式", allowableValues = ["true", "false"], defaultValue = "false")
|
@Schema(
|
||||||
|
description = "查询使用正则表达式",
|
||||||
|
allowableValues = ["true", "false"],
|
||||||
|
defaultValue = "false",
|
||||||
|
example = "false"
|
||||||
|
)
|
||||||
val searchRegex: Boolean = false,
|
val searchRegex: Boolean = false,
|
||||||
) : PageSortParam()
|
) : PageSortParam()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ data class GroupUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户组 ID")
|
@Schema(description = "用户组 ID", required = true)
|
||||||
@field:NotNull(message = "ID can not be null")
|
@field:NotNull(message = "ID can not be null")
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ data class GroupUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户组名称")
|
@Schema(description = "用户组名称", required = true, example = "Group_1")
|
||||||
@field:NotBlank(message = "Name can not be blank")
|
@field:NotBlank(message = "Name can not be blank")
|
||||||
val name: String?,
|
val name: String?,
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ data class GroupUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true")
|
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true", example = "true")
|
||||||
val enable: Boolean = true,
|
val enable: Boolean = true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ data class GroupUpdateStatusParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户组 ID")
|
@Schema(description = "用户组 ID", required = true)
|
||||||
@field:NotNull(message = "ID can not be null")
|
@field:NotNull(message = "ID can not be null")
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
|
|
||||||
@@ -27,6 +27,6 @@ data class GroupUpdateStatusParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true")
|
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true", example = "true")
|
||||||
val enable: Boolean = true
|
val enable: Boolean = true
|
||||||
)
|
)
|
||||||
@@ -17,7 +17,7 @@ data class RoleAddParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "角色名称")
|
@Schema(description = "角色名称", required = true, example = "Role_1")
|
||||||
@field:NotBlank(message = "Name can not be blank")
|
@field:NotBlank(message = "Name can not be blank")
|
||||||
val name: String?,
|
val name: String?,
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ data class RoleAddParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true")
|
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true", example = "true")
|
||||||
val enable: Boolean = true,
|
val enable: Boolean = true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ data class RoleDeleteParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "角色 ID 列表")
|
@Schema(description = "角色 ID 列表", required = true)
|
||||||
val ids: List<Long>
|
val ids: List<Long>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ data class RoleGetParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "查询角色名称")
|
@Schema(description = "查询角色名称", example = "Role_1")
|
||||||
val searchName: String?,
|
val searchName: String?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,6 +27,11 @@ data class RoleGetParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "查询使用正则表达式", allowableValues = ["true", "false"], defaultValue = "false")
|
@Schema(
|
||||||
|
description = "查询使用正则表达式",
|
||||||
|
allowableValues = ["true", "false"],
|
||||||
|
defaultValue = "false",
|
||||||
|
example = "false"
|
||||||
|
)
|
||||||
val searchRegex: Boolean = false,
|
val searchRegex: Boolean = false,
|
||||||
) : PageSortParam()
|
) : PageSortParam()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ data class RoleUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "角色 ID")
|
@Schema(description = "角色 ID", required = true)
|
||||||
@field:NotNull(message = "Role id can not be null")
|
@field:NotNull(message = "Role id can not be null")
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ data class RoleUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "角色名称")
|
@Schema(description = "角色名称", required = true, example = "Role_1")
|
||||||
@field:NotBlank(message = "Name can not be blank")
|
@field:NotBlank(message = "Name can not be blank")
|
||||||
val name: String?,
|
val name: String?,
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ data class RoleUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true")
|
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true", example = "true")
|
||||||
val enable: Boolean = true,
|
val enable: Boolean = true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ data class RoleUpdateStatusParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "角色 ID")
|
@Schema(description = "角色 ID", required = true)
|
||||||
@field:NotNull(message = "Role id can not be null")
|
@field:NotNull(message = "Role id can not be null")
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
|
|
||||||
@@ -27,6 +27,6 @@ data class RoleUpdateStatusParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true")
|
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true", example = "true")
|
||||||
val enable: Boolean = true
|
val enable: Boolean = true
|
||||||
)
|
)
|
||||||
@@ -19,7 +19,7 @@ data class UserAddParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户名")
|
@Schema(description = "用户名", required = true, example = "User_1")
|
||||||
@field:NotBlank(message = "Username can not be blank")
|
@field:NotBlank(message = "Username can not be blank")
|
||||||
val username: String?,
|
val username: String?,
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ data class UserAddParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "是否已验证")
|
@Schema(description = "是否已验证", allowableValues = ["true", "false"], defaultValue = "false", example = "false")
|
||||||
val verified: Boolean = false,
|
val verified: Boolean = false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,7 +47,7 @@ data class UserAddParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "锁定", allowableValues = ["true", "false"], defaultValue = "false")
|
@Schema(description = "锁定", allowableValues = ["true", "false"], defaultValue = "false", example = "false")
|
||||||
val locking: Boolean = false,
|
val locking: Boolean = false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,7 +57,7 @@ data class UserAddParam(
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see LocalDateTime
|
* @see LocalDateTime
|
||||||
*/
|
*/
|
||||||
@Schema(description = "过期时间")
|
@Schema(description = "过期时间", example = "1900-01-01T00:00:00.000Z")
|
||||||
val expiration: LocalDateTime?,
|
val expiration: LocalDateTime?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -67,7 +67,7 @@ data class UserAddParam(
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see LocalDateTime
|
* @see LocalDateTime
|
||||||
*/
|
*/
|
||||||
@Schema(description = "认证过期时间")
|
@Schema(description = "认证过期时间", example = "1900-01-01T00:00:00.000Z")
|
||||||
val credentialsExpiration: LocalDateTime?,
|
val credentialsExpiration: LocalDateTime?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,7 +76,7 @@ data class UserAddParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true")
|
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true", example = "true")
|
||||||
val enable: Boolean = true,
|
val enable: Boolean = true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,7 +85,7 @@ data class UserAddParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "昵称")
|
@Schema(description = "昵称", required = true, example = "Nickname_1")
|
||||||
@field:NotBlank(message = "Nickname can not be blank")
|
@field:NotBlank(message = "Nickname can not be blank")
|
||||||
val nickname: String?,
|
val nickname: String?,
|
||||||
|
|
||||||
@@ -104,7 +104,8 @@ data class UserAddParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "邮箱")
|
@Schema(description = "邮箱", required = true, example = "user@email.com")
|
||||||
|
@NotBlank(message = "Email can not be blank")
|
||||||
@Pattern(regexp = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$", message = "Illegal email address")
|
@Pattern(regexp = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$", message = "Illegal email address")
|
||||||
val email: String?,
|
val email: String?,
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ data class UserDeleteParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户 ID 列表")
|
@Schema(description = "用户 ID 列表", required = true)
|
||||||
val ids: List<Long>
|
val ids: List<Long>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,12 @@ data class UserGetParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "搜索类型", allowableValues = ["ALL", "ID", "USERNAME", "NICKNAME", "EMAIL"], defaultValue = "ALL")
|
@Schema(
|
||||||
|
description = "搜索类型",
|
||||||
|
allowableValues = ["ALL", "ID", "USERNAME", "NICKNAME", "EMAIL"],
|
||||||
|
defaultValue = "ALL",
|
||||||
|
example = "ALL"
|
||||||
|
)
|
||||||
val searchType: String = "ALL",
|
val searchType: String = "ALL",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,7 +32,7 @@ data class UserGetParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "查询内容")
|
@Schema(description = "查询内容", example = "User_1")
|
||||||
val searchValue: String?,
|
val searchValue: String?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,6 +41,11 @@ data class UserGetParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "查询使用正则表达式", allowableValues = ["true", "false"], defaultValue = "false")
|
@Schema(
|
||||||
|
description = "查询使用正则表达式",
|
||||||
|
allowableValues = ["true", "false"],
|
||||||
|
defaultValue = "false",
|
||||||
|
example = "false"
|
||||||
|
)
|
||||||
val searchRegex: Boolean = false,
|
val searchRegex: Boolean = false,
|
||||||
) : PageSortParam()
|
) : PageSortParam()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package top.fatweb.api.param.permission.user
|
package top.fatweb.api.param.permission.user
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
import jakarta.validation.constraints.NotBlank
|
||||||
import jakarta.validation.constraints.NotNull
|
import jakarta.validation.constraints.NotNull
|
||||||
import jakarta.validation.constraints.Pattern
|
import jakarta.validation.constraints.Pattern
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
@@ -19,7 +20,7 @@ data class UserUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户 ID")
|
@Schema(description = "用户 ID", required = true)
|
||||||
@field:NotNull(message = "ID can not be null")
|
@field:NotNull(message = "ID can not be null")
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
|
|
||||||
@@ -29,7 +30,8 @@ data class UserUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户名")
|
@Schema(description = "用户名", required = true, example = "User_1")
|
||||||
|
@field:NotBlank(message = "Username can not be blank")
|
||||||
val username: String?,
|
val username: String?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +40,7 @@ data class UserUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "是否已验证")
|
@Schema(description = "是否已验证", allowableValues = ["true", "false"], defaultValue = "false", example = "false")
|
||||||
val verified: Boolean = false,
|
val verified: Boolean = false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,7 +49,7 @@ data class UserUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "锁定", allowableValues = ["true", "false"], defaultValue = "false")
|
@Schema(description = "锁定", allowableValues = ["true", "false"], defaultValue = "false", example = "false")
|
||||||
val locking: Boolean = false,
|
val locking: Boolean = false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,7 +59,7 @@ data class UserUpdateParam(
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see LocalDateTime
|
* @see LocalDateTime
|
||||||
*/
|
*/
|
||||||
@Schema(description = "过期时间")
|
@Schema(description = "过期时间", example = "1900-01-01T00:00:00.000Z")
|
||||||
val expiration: LocalDateTime?,
|
val expiration: LocalDateTime?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -67,7 +69,7 @@ data class UserUpdateParam(
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see LocalDateTime
|
* @see LocalDateTime
|
||||||
*/
|
*/
|
||||||
@Schema(description = "认证过期时间")
|
@Schema(description = "认证过期时间", example = "1900-01-01T00:00:00.000Z")
|
||||||
val credentialsExpiration: LocalDateTime?,
|
val credentialsExpiration: LocalDateTime?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,7 +78,7 @@ data class UserUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true")
|
@Schema(description = "启用", allowableValues = ["true", "false"], defaultValue = "true", example = "true")
|
||||||
val enable: Boolean = true,
|
val enable: Boolean = true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,7 +87,8 @@ data class UserUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "昵称")
|
@Schema(description = "昵称", required = true, example = "Nickname_1")
|
||||||
|
@field:NotBlank(message = "Nickname can not be blank")
|
||||||
val nickname: String?,
|
val nickname: String?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,7 +106,8 @@ data class UserUpdateParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "邮箱")
|
@Schema(description = "邮箱", required = true, example = "user@email.com")
|
||||||
|
@NotBlank(message = "Email can not be blank")
|
||||||
@Pattern(regexp = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$", message = "Illegal email address")
|
@Pattern(regexp = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$", message = "Illegal email address")
|
||||||
val email: String?,
|
val email: String?,
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ data class UserUpdatePasswordParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用户 ID")
|
@Schema(description = "用户 ID", required = true)
|
||||||
@field:NotNull(message = "ID can not be null")
|
@field:NotNull(message = "ID can not be null")
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ data class UserUpdatePasswordParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "新密码")
|
@Schema(description = "新密码", required = true)
|
||||||
@field:NotBlank(message = "Password can not be blank")
|
@field:NotBlank(message = "Password can not be blank")
|
||||||
val password: String?,
|
val password: String?,
|
||||||
|
|
||||||
@@ -40,6 +40,6 @@ data class UserUpdatePasswordParam(
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see LocalDateTime
|
* @see LocalDateTime
|
||||||
*/
|
*/
|
||||||
@Schema(description = "认证过期时间")
|
@Schema(description = "认证过期时间", example = "1900-01-01T00:00:00.000Z")
|
||||||
val credentialsExpiration: LocalDateTime?
|
val credentialsExpiration: LocalDateTime?
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package top.fatweb.api.param.system
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.EnumValue
|
import com.baomidou.mybatisplus.annotation.EnumValue
|
||||||
import com.fasterxml.jackson.annotation.JsonValue
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get active information parameters
|
* Get active information parameters
|
||||||
@@ -10,6 +11,18 @@ import com.fasterxml.jackson.annotation.JsonValue
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
data class ActiveInfoGetParam(
|
data class ActiveInfoGetParam(
|
||||||
|
/**
|
||||||
|
* Scope
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Schema(
|
||||||
|
description = "范围",
|
||||||
|
allowableValues = ["WEAK", "MONTH", "QUARTER", "YEAR", "TWO_YEARS", "THREE_YEARS", "FIVE_YEARS", "ALL"],
|
||||||
|
defaultValue = "WEAK",
|
||||||
|
example = "WEAK"
|
||||||
|
)
|
||||||
val scope: Scope = Scope.WEAK
|
val scope: Scope = Scope.WEAK
|
||||||
) {
|
) {
|
||||||
enum class Scope(@field:EnumValue @field:JsonValue val code: String) {
|
enum class Scope(@field:EnumValue @field:JsonValue val code: String) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ data class MailSendParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "接收者")
|
@Schema(description = "接收者", required = true, example = "user@email.com")
|
||||||
@field:NotBlank
|
@field:NotBlank
|
||||||
val to: String?
|
val to: String?
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package top.fatweb.api.param.system
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.EnumValue
|
import com.baomidou.mybatisplus.annotation.EnumValue
|
||||||
import com.fasterxml.jackson.annotation.JsonValue
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get online information parameters
|
* Get online information parameters
|
||||||
@@ -10,6 +11,18 @@ import com.fasterxml.jackson.annotation.JsonValue
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
data class OnlineInfoGetParam(
|
data class OnlineInfoGetParam(
|
||||||
|
/**
|
||||||
|
* Scope
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Schema(
|
||||||
|
description = "范围",
|
||||||
|
allowableValues = ["WEAK", "MONTH", "QUARTER", "YEAR", "TWO_YEARS", "THREE_YEARS", "FIVE_YEARS", "ALL"],
|
||||||
|
defaultValue = "WEAK",
|
||||||
|
example = "WEAK"
|
||||||
|
)
|
||||||
val scope: Scope = Scope.WEAK
|
val scope: Scope = Scope.WEAK
|
||||||
) {
|
) {
|
||||||
enum class Scope(@field:EnumValue @field:JsonValue val code: String) {
|
enum class Scope(@field:EnumValue @field:JsonValue val code: String) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ data class SysLogGetParam(
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "类型过滤(多个使用逗号分隔)", example = "INFO", allowableValues = ["INFO", "ERROR"])
|
@Schema(description = "类型过滤(多个使用逗号分隔)", allowableValues = ["INFO", "ERROR"], example = "INFO")
|
||||||
val logType: String?,
|
val logType: String?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,8 +31,8 @@ data class SysLogGetParam(
|
|||||||
*/
|
*/
|
||||||
@Schema(
|
@Schema(
|
||||||
description = "请求方式过滤(多个使用逗号分隔)",
|
description = "请求方式过滤(多个使用逗号分隔)",
|
||||||
example = "GET,POST",
|
allowableValues = ["GET", "POST", "PUT", "PATCH", "DELETE", "DELETE", "OPTIONS"],
|
||||||
allowableValues = ["GET", "POST", "PUT", "PATCH", "DELETE", "DELETE", "OPTIONS"]
|
example = "GET,POST"
|
||||||
)
|
)
|
||||||
val requestMethod: String?,
|
val requestMethod: String?,
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ data class SysLogGetParam(
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see LocalDateTime
|
* @see LocalDateTime
|
||||||
*/
|
*/
|
||||||
@Schema(description = "查询开始时间")
|
@Schema(description = "查询开始时间", example = "1900-01-01T00:00:00.000Z")
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||||
val searchStartTime: LocalDateTime?,
|
val searchStartTime: LocalDateTime?,
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ data class SysLogGetParam(
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see LocalDateTime
|
* @see LocalDateTime
|
||||||
*/
|
*/
|
||||||
@Schema(description = "查询结束时间")
|
@Schema(description = "查询结束时间", example = "1900-01-01T00:00:00.000Z")
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||||
val searchEndTime: LocalDateTime?
|
val searchEndTime: LocalDateTime?
|
||||||
) : PageSortParam()
|
) : PageSortParam()
|
||||||
@@ -2,9 +2,7 @@ package top.fatweb.api.service.permission
|
|||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import top.fatweb.api.entity.permission.User
|
import top.fatweb.api.entity.permission.User
|
||||||
import top.fatweb.api.param.permission.LoginParam
|
import top.fatweb.api.param.permission.*
|
||||||
import top.fatweb.api.param.permission.RegisterParam
|
|
||||||
import top.fatweb.api.param.permission.VerifyParam
|
|
||||||
import top.fatweb.api.vo.permission.LoginVo
|
import top.fatweb.api.vo.permission.LoginVo
|
||||||
import top.fatweb.api.vo.permission.RegisterVo
|
import top.fatweb.api.vo.permission.RegisterVo
|
||||||
import top.fatweb.api.vo.permission.TokenVo
|
import top.fatweb.api.vo.permission.TokenVo
|
||||||
@@ -33,13 +31,29 @@ interface IAuthenticationService {
|
|||||||
fun resend()
|
fun resend()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify
|
* Verify email
|
||||||
*
|
*
|
||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
fun verify(verifyParam: VerifyParam)
|
fun verify(verifyParam: VerifyParam)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forget password
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
fun forget(request: HttpServletRequest, forgetParam: ForgetParam)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve password
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
fun retrieve(request: HttpServletRequest, retrieveParam: RetrieveParam)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Login
|
* Login
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package top.fatweb.api.service.permission.impl
|
package top.fatweb.api.service.permission.impl
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
|
||||||
import com.baomidou.mybatisplus.extension.kotlin.KtUpdateWrapper
|
import com.baomidou.mybatisplus.extension.kotlin.KtUpdateWrapper
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import org.apache.velocity.VelocityContext
|
import org.apache.velocity.VelocityContext
|
||||||
@@ -17,13 +18,8 @@ import top.fatweb.api.entity.permission.LoginUser
|
|||||||
import top.fatweb.api.entity.permission.User
|
import top.fatweb.api.entity.permission.User
|
||||||
import top.fatweb.api.entity.permission.UserInfo
|
import top.fatweb.api.entity.permission.UserInfo
|
||||||
import top.fatweb.api.entity.system.EventLog
|
import top.fatweb.api.entity.system.EventLog
|
||||||
import top.fatweb.api.exception.AccountNeedInitException
|
import top.fatweb.api.exception.*
|
||||||
import top.fatweb.api.exception.NoVerificationRequiredException
|
import top.fatweb.api.param.permission.*
|
||||||
import top.fatweb.api.exception.TokenHasExpiredException
|
|
||||||
import top.fatweb.api.exception.VerificationCodeErrorOrExpiredException
|
|
||||||
import top.fatweb.api.param.permission.LoginParam
|
|
||||||
import top.fatweb.api.param.permission.RegisterParam
|
|
||||||
import top.fatweb.api.param.permission.VerifyParam
|
|
||||||
import top.fatweb.api.properties.SecurityProperties
|
import top.fatweb.api.properties.SecurityProperties
|
||||||
import top.fatweb.api.service.api.v1.IAvatarService
|
import top.fatweb.api.service.api.v1.IAvatarService
|
||||||
import top.fatweb.api.service.permission.IAuthenticationService
|
import top.fatweb.api.service.permission.IAuthenticationService
|
||||||
@@ -71,7 +67,9 @@ class AuthenticationServiceImpl(
|
|||||||
username = registerParam.username
|
username = registerParam.username
|
||||||
password = passwordEncoder.encode(registerParam.password)
|
password = passwordEncoder.encode(registerParam.password)
|
||||||
verify =
|
verify =
|
||||||
"${LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()}-${UUID.randomUUID()}-${UUID.randomUUID()}-${UUID.randomUUID()}"
|
"${
|
||||||
|
LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()
|
||||||
|
}-${UUID.randomUUID()}-${UUID.randomUUID()}-${UUID.randomUUID()}"
|
||||||
locking = 0
|
locking = 0
|
||||||
enable = 1
|
enable = 1
|
||||||
}
|
}
|
||||||
@@ -83,7 +81,7 @@ class AuthenticationServiceImpl(
|
|||||||
email = registerParam.email
|
email = registerParam.email
|
||||||
})
|
})
|
||||||
|
|
||||||
sendVerifyMail(user.username!!, "http://localhost:5173/verify?code=${user.verify!!}", registerParam.email!!)
|
sendVerifyMail(user.username!!, user.verify!!, registerParam.email!!)
|
||||||
|
|
||||||
return RegisterVo(userId = user.id)
|
return RegisterVo(userId = user.id)
|
||||||
}
|
}
|
||||||
@@ -95,21 +93,23 @@ class AuthenticationServiceImpl(
|
|||||||
user.verify ?: throw NoVerificationRequiredException()
|
user.verify ?: throw NoVerificationRequiredException()
|
||||||
|
|
||||||
user.verify =
|
user.verify =
|
||||||
"${LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()}-${UUID.randomUUID()}-${UUID.randomUUID()}-${UUID.randomUUID()}"
|
"${
|
||||||
|
LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()
|
||||||
|
}-${UUID.randomUUID()}-${UUID.randomUUID()}-${UUID.randomUUID()}"
|
||||||
user.updateTime = LocalDateTime.now(ZoneOffset.UTC)
|
user.updateTime = LocalDateTime.now(ZoneOffset.UTC)
|
||||||
userService.updateById(user)
|
userService.updateById(user)
|
||||||
|
|
||||||
WebUtil.getLoginUser()?.user?.userInfo?.email?.let {
|
WebUtil.getLoginUser()?.user?.userInfo?.email?.let {
|
||||||
sendVerifyMail(user.username!!, "http://localhost:5173/verify?code=${user.verify!!}", it)
|
sendVerifyMail(user.username!!, user.verify!!, it)
|
||||||
} ?: throw AccessDeniedException("Access Denied")
|
} ?: throw AccessDeniedException("Access Denied")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendVerifyMail(username: String, verifyUrl: String, email: String) {
|
private fun sendVerifyMail(username: String, code: String, email: String) {
|
||||||
val velocityContext = VelocityContext().apply {
|
val velocityContext = VelocityContext().apply {
|
||||||
put("appName", "氮工具")
|
put("appName", "氮工具")
|
||||||
put("appUrl", "http://localhost:5173/")
|
put("appUrl", "http://localhost:5173/")
|
||||||
put("username", username)
|
put("username", username)
|
||||||
put("verifyUrl", verifyUrl)
|
put("verifyUrl", "http://localhost:5173/verify?code=${code}")
|
||||||
}
|
}
|
||||||
val template = velocityEngine.getTemplate("templates/email-verify-account-cn.vm")
|
val template = velocityEngine.getTemplate("templates/email-verify-account-cn.vm")
|
||||||
|
|
||||||
@@ -147,6 +147,82 @@ class AuthenticationServiceImpl(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
override fun forget(request: HttpServletRequest, forgetParam: ForgetParam) {
|
||||||
|
val user = userService.getUserWithPowerByAccount(forgetParam.email!!)
|
||||||
|
user ?: let { throw UserNotFoundException() }
|
||||||
|
val code = "${
|
||||||
|
LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()
|
||||||
|
}-${UUID.randomUUID()}-${UUID.randomUUID()}-${UUID.randomUUID()}"
|
||||||
|
userService.update(KtUpdateWrapper(User()).eq(User::id, user.id).set(User::forget, code))
|
||||||
|
sendRetrieveMail(user.username!!, request.remoteAddr, code, forgetParam.email)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendRetrieveMail(username: String, ip: String, code: String, email: String) {
|
||||||
|
val velocityContext = VelocityContext().apply {
|
||||||
|
put("appName", "氮工具")
|
||||||
|
put("appUrl", "http://localhost:5173/")
|
||||||
|
put("username", username)
|
||||||
|
put("ipAddress", ip)
|
||||||
|
put("retrieveUrl", "http://localhost:5173/forget?code=${code}")
|
||||||
|
}
|
||||||
|
val template = velocityEngine.getTemplate("templates/email-retrieve-password-cn.vm")
|
||||||
|
|
||||||
|
val stringWriter = StringWriter()
|
||||||
|
template.merge(velocityContext, stringWriter)
|
||||||
|
|
||||||
|
MailUtil.sendSimpleMail(
|
||||||
|
"找回您的密码", stringWriter.toString(), true,
|
||||||
|
email
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
override fun retrieve(request: HttpServletRequest, retrieveParam: RetrieveParam) {
|
||||||
|
val codeStrings = retrieveParam.code!!.split("-")
|
||||||
|
if (codeStrings.size != 16) {
|
||||||
|
throw RetrieveCodeErrorOrExpiredException()
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (LocalDateTime.ofInstant(Instant.ofEpochMilli(codeStrings.first().toLong()), ZoneOffset.UTC)
|
||||||
|
.isBefore(LocalDateTime.now(ZoneOffset.UTC).minusHours(2))
|
||||||
|
) {
|
||||||
|
throw RetrieveCodeErrorOrExpiredException()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw RetrieveCodeErrorOrExpiredException()
|
||||||
|
}
|
||||||
|
|
||||||
|
val user = userService.getOne(KtQueryWrapper(User()).eq(User::forget, retrieveParam.code))
|
||||||
|
?: throw RetrieveCodeErrorOrExpiredException()
|
||||||
|
val userInfo = userInfoService.getOne(KtQueryWrapper(UserInfo()).eq(UserInfo::userId, user.id))
|
||||||
|
|
||||||
|
userService.update(
|
||||||
|
KtUpdateWrapper(User()).eq(User::id, user.id).set(User::forget, null)
|
||||||
|
.set(User::password, passwordEncoder.encode(retrieveParam.password!!))
|
||||||
|
)
|
||||||
|
|
||||||
|
sendPasswordChangedMail(user.username!!, request.remoteAddr, userInfo!!.email!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendPasswordChangedMail(username: String, ip: String, email: String) {
|
||||||
|
val velocityContext = VelocityContext().apply {
|
||||||
|
put("appName", "氮工具")
|
||||||
|
put("appUrl", "http://localhost:5173/")
|
||||||
|
put("username", username)
|
||||||
|
put("ipAddress", ip)
|
||||||
|
}
|
||||||
|
val template = velocityEngine.getTemplate("templates/email-password-changed-cn.vm")
|
||||||
|
|
||||||
|
val stringWriter = StringWriter()
|
||||||
|
template.merge(velocityContext, stringWriter)
|
||||||
|
|
||||||
|
MailUtil.sendSimpleMail(
|
||||||
|
"您的密码已更改", stringWriter.toString(), true,
|
||||||
|
email
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@EventLogRecord(EventLog.Event.LOGIN)
|
@EventLogRecord(EventLog.Event.LOGIN)
|
||||||
override fun login(request: HttpServletRequest, loginParam: LoginParam): LoginVo {
|
override fun login(request: HttpServletRequest, loginParam: LoginParam): LoginVo {
|
||||||
val usernamePasswordAuthenticationToken =
|
val usernamePasswordAuthenticationToken =
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ create table if not exists t_user
|
|||||||
id bigint not null primary key,
|
id bigint not null primary key,
|
||||||
username varchar(20) not null comment '用户名',
|
username varchar(20) not null comment '用户名',
|
||||||
password char(70) not null comment '密码',
|
password char(70) not null comment '密码',
|
||||||
verify varchar(144) null comment '验证信息',
|
verify varchar(144) null comment '验证邮箱',
|
||||||
|
forget varchar(144) null comment '忘记密码',
|
||||||
locking int not null comment '锁定',
|
locking int not null comment '锁定',
|
||||||
expiration datetime comment '过期时间',
|
expiration datetime comment '过期时间',
|
||||||
credentials_expiration datetime comment '认证过期时间',
|
credentials_expiration datetime comment '认证过期时间',
|
||||||
@@ -19,5 +20,6 @@ create table if not exists t_user
|
|||||||
deleted bigint not null default 0,
|
deleted bigint not null default 0,
|
||||||
version int not null default 0,
|
version int not null default 0,
|
||||||
constraint t_user_unique_username unique (username, deleted),
|
constraint t_user_unique_username unique (username, deleted),
|
||||||
constraint t_user_unique_verify unique (verify, deleted)
|
constraint t_user_unique_verify unique (verify, deleted),
|
||||||
|
constraint t_user_unique_forget unique (forget, deleted)
|
||||||
) comment '用户表';
|
) comment '用户表';
|
||||||
78
src/main/resources/templates/email-password-changed-cn.vm
Normal file
78
src/main/resources/templates/email-password-changed-cn.vm
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>您的密码已更改</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
color: #4D4D4D;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #4E47BB;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
background-color: #F1F2F7;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view {
|
||||||
|
display: flex;
|
||||||
|
width: 800px;
|
||||||
|
max-width: 100vw;
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 12px;
|
||||||
|
flex: 1;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bolder;
|
||||||
|
font-size: 1.6em;
|
||||||
|
color: #4E47BB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retrieve-button a {
|
||||||
|
padding: 20px 30px;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 1.2em;
|
||||||
|
background-color: #4E47BB;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-reply {
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="view">
|
||||||
|
<div class="card">
|
||||||
|
<div class="title">密 码 已 更 改</div>
|
||||||
|
<div><strong>${username}</strong>,您好:</div>
|
||||||
|
<div style="text-indent: 2em">您在 <a target="_blank" href=${appUrl}>${appName}(${appUrl})</a> 的密码已更改,操作
|
||||||
|
IP 地址为 [${ipAddress}]。如果不是您自己的操作,请尽快检查您的账号!
|
||||||
|
</div>
|
||||||
|
<div class="not-reply">此邮件由系统自动发送,请勿回复!</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
90
src/main/resources/templates/email-retrieve-password-cn.vm
Normal file
90
src/main/resources/templates/email-retrieve-password-cn.vm
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>找回您的密码</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
color: #4D4D4D;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #4E47BB;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
background-color: #F1F2F7;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view {
|
||||||
|
display: flex;
|
||||||
|
width: 800px;
|
||||||
|
max-width: 100vw;
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 12px;
|
||||||
|
flex: 1;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bolder;
|
||||||
|
font-size: 1.6em;
|
||||||
|
color: #4E47BB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retrieve-button {
|
||||||
|
display: flex;
|
||||||
|
margin: 20px;
|
||||||
|
padding-bottom: 60px;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.retrieve-button a {
|
||||||
|
padding: 20px 30px;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 1.2em;
|
||||||
|
background-color: #4E47BB;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-reply {
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="view">
|
||||||
|
<div class="card">
|
||||||
|
<div class="title">找 回 密 码</div>
|
||||||
|
<div><strong>${username}</strong>,您好:</div>
|
||||||
|
<div style="text-indent: 2em">您正在找回 <a target="_blank" href=${appUrl}>${appName}(${appUrl})</a> 的密码,操作
|
||||||
|
IP 地址为 [${ipAddress}],如果是您自己的操作,请在 <u><i>两小时内</i></u> 点击下面的按钮找回您的密码:
|
||||||
|
</div>
|
||||||
|
<div class="retrieve-button"><a target="_blank" href=${retrieveUrl}>找回密码</a></div>
|
||||||
|
<div>如果以上按钮无法点击,请复制此链接到浏览器地址栏中访问:<a target="_blank"
|
||||||
|
href=${retrieveUrl}>${retrieveUrl}</a></div>
|
||||||
|
<div>如果并非本人操作,请忽略该邮件</div>
|
||||||
|
<div class="not-reply">此邮件由系统自动发送,请勿回复!</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -54,6 +54,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.verify-button a {
|
.verify-button a {
|
||||||
padding: 20px 30px;
|
padding: 20px 30px;
|
||||||
color: white;
|
color: white;
|
||||||
@@ -75,9 +76,12 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="title">账 号 激 活</div>
|
<div class="title">账 号 激 活</div>
|
||||||
<div><strong>${username}</strong>,您好:</div>
|
<div><strong>${username}</strong>,您好:</div>
|
||||||
<div style="text-indent: 2em">感谢注册 <a target="_blank" href=${appUrl}>${appName}(${appUrl})</a>,在继续使用之前,我们需要确定您的电子邮箱地址的有效性,请在 <u><i>两小时内</i></u> 点击下面的按钮帮助我们验证:</div>
|
<div style="text-indent: 2em">感谢注册 <a target="_blank" href=${appUrl}>${appName}(${appUrl})</a>,在继续使用之前,我们需要确定您的电子邮箱地址的有效性,请在
|
||||||
|
<u><i>两小时内</i></u> 点击下面的按钮帮助我们验证:
|
||||||
|
</div>
|
||||||
<div class="verify-button"><a target="_blank" href=${verifyUrl}>验证邮箱</a></div>
|
<div class="verify-button"><a target="_blank" href=${verifyUrl}>验证邮箱</a></div>
|
||||||
<div>如果以上按钮无法点击,请复制此链接到浏览器地址栏中访问:<a target="_blank" href=${verifyUrl}>${verifyUrl}</a></div>
|
<div>如果以上按钮无法点击,请复制此链接到浏览器地址栏中访问:<a target="_blank" href=${verifyUrl}>${verifyUrl}</a>
|
||||||
|
</div>
|
||||||
<div class="not-reply">此邮件由系统自动发送,请勿回复!</div>
|
<div class="not-reply">此邮件由系统自动发送,请勿回复!</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user