Compare commits

..

5 Commits

Author SHA1 Message Date
Yang Luo
a4524e9996 fix: fix Swagger @Tag 2024-01-15 23:35:40 +08:00
Yang Luo
b469928780 Fix Swagger @router 2024-01-15 23:27:42 +08:00
Yang Luo
dc6fe13f75 feat: use signupItem.Regex to check signup page 2024-01-15 18:12:38 +08:00
Yang Luo
8227762988 Support more special chars in password validating 2024-01-15 18:12:38 +08:00
hsluoyz
d92b072ed0 feat: revert PR: "feat: more RFC like LDAP server behaviour" (#2611) 2024-01-15 13:58:33 +08:00
14 changed files with 1022 additions and 524 deletions

View File

@@ -453,7 +453,7 @@ func (c *ApiController) GetUserinfo2() {
// GetCaptcha ... // GetCaptcha ...
// @Tag Login API // @Tag Login API
// @Title GetCaptcha // @Title GetCaptcha
// @router /api/get-captcha [get] // @router /get-captcha [get]
// @Success 200 {object} object.Userinfo The Response object // @Success 200 {object} object.Userinfo The Response object
func (c *ApiController) GetCaptcha() { func (c *ApiController) GetCaptcha() {
applicationId := c.Input().Get("applicationId") applicationId := c.Input().Get("applicationId")

View File

@@ -916,9 +916,9 @@ func (c *ApiController) HandleSamlLogin() {
} }
// HandleOfficialAccountEvent ... // HandleOfficialAccountEvent ...
// @Tag HandleOfficialAccountEvent API // @Tag System API
// @Title HandleOfficialAccountEvent // @Title HandleOfficialAccountEvent
// @router /api/webhook [POST] // @router /webhook [POST]
// @Success 200 {object} object.Userinfo The Response object // @Success 200 {object} object.Userinfo The Response object
func (c *ApiController) HandleOfficialAccountEvent() { func (c *ApiController) HandleOfficialAccountEvent() {
respBytes, err := ioutil.ReadAll(c.Ctx.Request.Body) respBytes, err := ioutil.ReadAll(c.Ctx.Request.Body)
@@ -947,9 +947,9 @@ func (c *ApiController) HandleOfficialAccountEvent() {
} }
// GetWebhookEventType ... // GetWebhookEventType ...
// @Tag GetWebhookEventType API // @Tag System API
// @Title GetWebhookEventType // @Title GetWebhookEventType
// @router /api/get-webhook-event [GET] // @router /get-webhook-event [GET]
// @Success 200 {object} object.Userinfo The Response object // @Success 200 {object} object.Userinfo The Response object
func (c *ApiController) GetWebhookEventType() { func (c *ApiController) GetWebhookEventType() {
lock.Lock() lock.Lock()
@@ -970,7 +970,7 @@ func (c *ApiController) GetWebhookEventType() {
// @Description Get Login Error Counts // @Description Get Login Error Counts
// @Param id query string true "The id ( owner/name ) of user" // @Param id query string true "The id ( owner/name ) of user"
// @Success 200 {object} controllers.Response The Response object // @Success 200 {object} controllers.Response The Response object
// @router /api/get-captcha-status [get] // @router /get-captcha-status [get]
func (c *ApiController) GetCaptchaStatus() { func (c *ApiController) GetCaptchaStatus() {
organization := c.Input().Get("organization") organization := c.Input().Get("organization")
userId := c.Input().Get("userId") userId := c.Input().Get("userId")
@@ -1001,7 +1001,7 @@ func (c *ApiController) GetCaptchaStatus() {
// @Title Callback // @Title Callback
// @Tag Callback API // @Tag Callback API
// @Description Get Login Error Counts // @Description Get Login Error Counts
// @router /api/Callback [post] // @router /Callback [post]
// @Success 200 {object} object.Userinfo The Response object // @Success 200 {object} object.Userinfo The Response object
func (c *ApiController) Callback() { func (c *ApiController) Callback() {
code := c.GetString("code") code := c.GetString("code")

View File

@@ -24,7 +24,7 @@ import (
// Enforce // Enforce
// @Title Enforce // @Title Enforce
// @Tag Enforce API // @Tag Enforcer API
// @Description Call Casbin Enforce API // @Description Call Casbin Enforce API
// @Param body body []string true "Casbin request" // @Param body body []string true "Casbin request"
// @Param permissionId query string false "permission id" // @Param permissionId query string false "permission id"
@@ -151,7 +151,7 @@ func (c *ApiController) Enforce() {
// BatchEnforce // BatchEnforce
// @Title BatchEnforce // @Title BatchEnforce
// @Tag Enforce API // @Tag Enforcer API
// @Description Call Casbin BatchEnforce API // @Description Call Casbin BatchEnforce API
// @Param body body []string true "array of casbin requests" // @Param body body []string true "array of casbin requests"
// @Param permissionId query string false "permission id" // @Param permissionId query string false "permission id"

View File

@@ -18,7 +18,7 @@ import "github.com/casdoor/casdoor/object"
// GetDashboard // GetDashboard
// @Title GetDashboard // @Title GetDashboard
// @Tag GetDashboard API // @Tag System API
// @Description get information of dashboard // @Description get information of dashboard
// @Success 200 {object} controllers.Response The Response object // @Success 200 {object} controllers.Response The Response object
// @router /get-dashboard [get] // @router /get-dashboard [get]

View File

@@ -20,7 +20,7 @@ import (
// GetPrometheusInfo // GetPrometheusInfo
// @Title GetPrometheusInfo // @Title GetPrometheusInfo
// @Tag Prometheus API // @Tag System API
// @Description get Prometheus Info // @Description get Prometheus Info
// @Success 200 {object} object.PrometheusInfo The Response object // @Success 200 {object} object.PrometheusInfo The Response object
// @router /get-prometheus-info [get] // @router /get-prometheus-info [get]

View File

@@ -52,7 +52,7 @@ type NotificationForm struct {
// @Param clientSecret query string true "The clientSecret of the application" // @Param clientSecret query string true "The clientSecret of the application"
// @Param from body controllers.EmailForm true "Details of the email request" // @Param from body controllers.EmailForm true "Details of the email request"
// @Success 200 {object} controllers.Response The Response object // @Success 200 {object} controllers.Response The Response object
// @router /api/send-email [post] // @router /send-email [post]
func (c *ApiController) SendEmail() { func (c *ApiController) SendEmail() {
userId, ok := c.RequireSignedIn() userId, ok := c.RequireSignedIn()
if !ok { if !ok {
@@ -148,7 +148,7 @@ func (c *ApiController) SendEmail() {
// @Param clientSecret query string true "The clientSecret of the application" // @Param clientSecret query string true "The clientSecret of the application"
// @Param from body controllers.SmsForm true "Details of the sms request" // @Param from body controllers.SmsForm true "Details of the sms request"
// @Success 200 {object} controllers.Response The Response object // @Success 200 {object} controllers.Response The Response object
// @router /api/send-sms [post] // @router /send-sms [post]
func (c *ApiController) SendSms() { func (c *ApiController) SendSms() {
provider, err := c.GetProviderFromContext("SMS") provider, err := c.GetProviderFromContext("SMS")
if err != nil { if err != nil {
@@ -186,7 +186,7 @@ func (c *ApiController) SendSms() {
// @Description This API is not for Casdoor frontend to call, it is for Casdoor SDKs. // @Description This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
// @Param from body controllers.NotificationForm true "Details of the notification request" // @Param from body controllers.NotificationForm true "Details of the notification request"
// @Success 200 {object} controllers.Response The Response object // @Success 200 {object} controllers.Response The Response object
// @router /api/send-notification [post] // @router /send-notification [post]
func (c *ApiController) SendNotification() { func (c *ApiController) SendNotification() {
provider, err := c.GetProviderFromContext("Notification") provider, err := c.GetProviderFromContext("Notification")
if err != nil { if err != nil {

View File

@@ -156,7 +156,7 @@ func (c *ApiController) DeleteToken() {
// @Success 200 {object} object.TokenWrapper The Response object // @Success 200 {object} object.TokenWrapper The Response object
// @Success 400 {object} object.TokenError The Response object // @Success 400 {object} object.TokenError The Response object
// @Success 401 {object} object.TokenError The Response object // @Success 401 {object} object.TokenError The Response object
// @router api/login/oauth/access_token [post] // @router /login/oauth/access_token [post]
func (c *ApiController) GetOAuthToken() { func (c *ApiController) GetOAuthToken() {
clientId := c.Input().Get("client_id") clientId := c.Input().Get("client_id")
clientSecret := c.Input().Get("client_secret") clientSecret := c.Input().Get("client_secret")
@@ -273,6 +273,7 @@ func (c *ApiController) RefreshToken() {
// IntrospectToken // IntrospectToken
// @Title IntrospectToken // @Title IntrospectToken
// @Tag Login API
// @Description The introspection endpoint is an OAuth 2.0 endpoint that takes a // @Description The introspection endpoint is an OAuth 2.0 endpoint that takes a
// parameter representing an OAuth 2.0 token and returns a JSON document // parameter representing an OAuth 2.0 token and returns a JSON document
// representing the meta information surrounding the // representing the meta information surrounding the

View File

@@ -272,7 +272,7 @@ func (c *ApiController) VerifyCaptcha() {
// ResetEmailOrPhone ... // ResetEmailOrPhone ...
// @Tag Account API // @Tag Account API
// @Title ResetEmailOrPhone // @Title ResetEmailOrPhone
// @router /api/reset-email-or-phone [post] // @router /reset-email-or-phone [post]
// @Success 200 {object} object.Userinfo The Response object // @Success 200 {object} object.Userinfo The Response object
func (c *ApiController) ResetEmailOrPhone() { func (c *ApiController) ResetEmailOrPhone() {
user, ok := c.RequireSignedInUser() user, ok := c.RequireSignedInUser()
@@ -367,7 +367,7 @@ func (c *ApiController) ResetEmailOrPhone() {
// VerifyCode // VerifyCode
// @Tag Verification API // @Tag Verification API
// @Title VerifyCode // @Title VerifyCode
// @router /api/verify-code [post] // @router /verify-code [post]
// @Success 200 {object} object.Userinfo The Response object // @Success 200 {object} object.Userinfo The Response object
func (c *ApiController) VerifyCode() { func (c *ApiController) VerifyCode() {
var authForm form.AuthForm var authForm form.AuthForm

View File

@@ -14,6 +14,8 @@
package form package form
import "reflect"
type AuthForm struct { type AuthForm struct {
Type string `json:"type"` Type string `json:"type"`
SigninMethod string `json:"signinMethod"` SigninMethod string `json:"signinMethod"`
@@ -60,3 +62,13 @@ type AuthForm struct {
Plan string `json:"plan"` Plan string `json:"plan"`
Pricing string `json:"pricing"` Pricing string `json:"pricing"`
} }
func GetAuthFormFieldValue(form *AuthForm, fieldName string) (bool, string) {
val := reflect.ValueOf(*form)
fieldValue := val.FieldByName(fieldName)
if fieldValue.IsValid() && fieldValue.Kind() == reflect.String {
return true, fieldValue.String()
}
return false, ""
}

View File

@@ -16,6 +16,7 @@ package object
import ( import (
"fmt" "fmt"
"regexp"
"strings" "strings"
"time" "time"
"unicode" "unicode"
@@ -32,89 +33,89 @@ const (
DefaultFailedSigninFrozenTime = 15 DefaultFailedSigninFrozenTime = 15
) )
func CheckUserSignup(application *Application, organization *Organization, form *form.AuthForm, lang string) string { func CheckUserSignup(application *Application, organization *Organization, authForm *form.AuthForm, lang string) string {
if organization == nil { if organization == nil {
return i18n.Translate(lang, "check:Organization does not exist") return i18n.Translate(lang, "check:Organization does not exist")
} }
if application.IsSignupItemVisible("Username") { if application.IsSignupItemVisible("Username") {
if len(form.Username) <= 1 { if len(authForm.Username) <= 1 {
return i18n.Translate(lang, "check:Username must have at least 2 characters") return i18n.Translate(lang, "check:Username must have at least 2 characters")
} }
if unicode.IsDigit(rune(form.Username[0])) { if unicode.IsDigit(rune(authForm.Username[0])) {
return i18n.Translate(lang, "check:Username cannot start with a digit") return i18n.Translate(lang, "check:Username cannot start with a digit")
} }
if util.IsEmailValid(form.Username) { if util.IsEmailValid(authForm.Username) {
return i18n.Translate(lang, "check:Username cannot be an email address") return i18n.Translate(lang, "check:Username cannot be an email address")
} }
if util.ReWhiteSpace.MatchString(form.Username) { if util.ReWhiteSpace.MatchString(authForm.Username) {
return i18n.Translate(lang, "check:Username cannot contain white spaces") return i18n.Translate(lang, "check:Username cannot contain white spaces")
} }
if msg := CheckUsername(form.Username, lang); msg != "" { if msg := CheckUsername(authForm.Username, lang); msg != "" {
return msg return msg
} }
if HasUserByField(organization.Name, "name", form.Username) { if HasUserByField(organization.Name, "name", authForm.Username) {
return i18n.Translate(lang, "check:Username already exists") return i18n.Translate(lang, "check:Username already exists")
} }
if HasUserByField(organization.Name, "email", form.Email) { if HasUserByField(organization.Name, "email", authForm.Email) {
return i18n.Translate(lang, "check:Email already exists") return i18n.Translate(lang, "check:Email already exists")
} }
if HasUserByField(organization.Name, "phone", form.Phone) { if HasUserByField(organization.Name, "phone", authForm.Phone) {
return i18n.Translate(lang, "check:Phone already exists") return i18n.Translate(lang, "check:Phone already exists")
} }
} }
if application.IsSignupItemVisible("Password") { if application.IsSignupItemVisible("Password") {
msg := CheckPasswordComplexityByOrg(organization, form.Password) msg := CheckPasswordComplexityByOrg(organization, authForm.Password)
if msg != "" { if msg != "" {
return msg return msg
} }
} }
if application.IsSignupItemVisible("Email") { if application.IsSignupItemVisible("Email") {
if form.Email == "" { if authForm.Email == "" {
if application.IsSignupItemRequired("Email") { if application.IsSignupItemRequired("Email") {
return i18n.Translate(lang, "check:Email cannot be empty") return i18n.Translate(lang, "check:Email cannot be empty")
} }
} else { } else {
if HasUserByField(organization.Name, "email", form.Email) { if HasUserByField(organization.Name, "email", authForm.Email) {
return i18n.Translate(lang, "check:Email already exists") return i18n.Translate(lang, "check:Email already exists")
} else if !util.IsEmailValid(form.Email) { } else if !util.IsEmailValid(authForm.Email) {
return i18n.Translate(lang, "check:Email is invalid") return i18n.Translate(lang, "check:Email is invalid")
} }
} }
} }
if application.IsSignupItemVisible("Phone") { if application.IsSignupItemVisible("Phone") {
if form.Phone == "" { if authForm.Phone == "" {
if application.IsSignupItemRequired("Phone") { if application.IsSignupItemRequired("Phone") {
return i18n.Translate(lang, "check:Phone cannot be empty") return i18n.Translate(lang, "check:Phone cannot be empty")
} }
} else { } else {
if HasUserByField(organization.Name, "phone", form.Phone) { if HasUserByField(organization.Name, "phone", authForm.Phone) {
return i18n.Translate(lang, "check:Phone already exists") return i18n.Translate(lang, "check:Phone already exists")
} else if !util.IsPhoneAllowInRegin(form.CountryCode, organization.CountryCodes) { } else if !util.IsPhoneAllowInRegin(authForm.CountryCode, organization.CountryCodes) {
return i18n.Translate(lang, "check:Your region is not allow to signup by phone") return i18n.Translate(lang, "check:Your region is not allow to signup by phone")
} else if !util.IsPhoneValid(form.Phone, form.CountryCode) { } else if !util.IsPhoneValid(authForm.Phone, authForm.CountryCode) {
return i18n.Translate(lang, "check:Phone number is invalid") return i18n.Translate(lang, "check:Phone number is invalid")
} }
} }
} }
if application.IsSignupItemVisible("Display name") { if application.IsSignupItemVisible("Display name") {
if application.GetSignupItemRule("Display name") == "First, last" && (form.FirstName != "" || form.LastName != "") { if application.GetSignupItemRule("Display name") == "First, last" && (authForm.FirstName != "" || authForm.LastName != "") {
if form.FirstName == "" { if authForm.FirstName == "" {
return i18n.Translate(lang, "check:FirstName cannot be blank") return i18n.Translate(lang, "check:FirstName cannot be blank")
} else if form.LastName == "" { } else if authForm.LastName == "" {
return i18n.Translate(lang, "check:LastName cannot be blank") return i18n.Translate(lang, "check:LastName cannot be blank")
} }
} else { } else {
if form.Name == "" { if authForm.Name == "" {
return i18n.Translate(lang, "check:DisplayName cannot be blank") return i18n.Translate(lang, "check:DisplayName cannot be blank")
} else if application.GetSignupItemRule("Display name") == "Real name" { } else if application.GetSignupItemRule("Display name") == "Real name" {
if !isValidRealName(form.Name) { if !isValidRealName(authForm.Name) {
return i18n.Translate(lang, "check:DisplayName is not valid real name") return i18n.Translate(lang, "check:DisplayName is not valid real name")
} }
} }
@@ -122,23 +123,44 @@ func CheckUserSignup(application *Application, organization *Organization, form
} }
if application.IsSignupItemVisible("Affiliation") { if application.IsSignupItemVisible("Affiliation") {
if form.Affiliation == "" { if authForm.Affiliation == "" {
return i18n.Translate(lang, "check:Affiliation cannot be blank") return i18n.Translate(lang, "check:Affiliation cannot be blank")
} }
} }
if len(application.InvitationCodes) > 0 { if len(application.InvitationCodes) > 0 {
if form.InvitationCode == "" { if authForm.InvitationCode == "" {
if application.IsSignupItemRequired("Invitation code") { if application.IsSignupItemRequired("Invitation code") {
return i18n.Translate(lang, "check:Invitation code cannot be blank") return i18n.Translate(lang, "check:Invitation code cannot be blank")
} }
} else { } else {
if !util.InSlice(application.InvitationCodes, form.InvitationCode) { if !util.InSlice(application.InvitationCodes, authForm.InvitationCode) {
return i18n.Translate(lang, "check:Invitation code is invalid") return i18n.Translate(lang, "check:Invitation code is invalid")
} }
} }
} }
for _, signupItem := range application.SignupItems {
if signupItem.Regex == "" {
continue
}
isString, value := form.GetAuthFormFieldValue(authForm, signupItem.Name)
if !isString {
continue
}
regexSignupItem, err := regexp.Compile(signupItem.Regex)
if err != nil {
return err.Error()
}
matched := regexSignupItem.MatchString(value)
if !matched {
return fmt.Sprintf(i18n.Translate(lang, "check:The value \"%s\" for signup field \"%s\" doesn't match the signup item regex of the application \"%s\""), value, signupItem.Name, application.Name)
}
}
return "" return ""
} }

View File

@@ -24,7 +24,7 @@ var (
regexLowerCase = regexp.MustCompile(`[a-z]`) regexLowerCase = regexp.MustCompile(`[a-z]`)
regexUpperCase = regexp.MustCompile(`[A-Z]`) regexUpperCase = regexp.MustCompile(`[A-Z]`)
regexDigit = regexp.MustCompile(`\d`) regexDigit = regexp.MustCompile(`\d`)
regexSpecial = regexp.MustCompile(`[!@#$%^&*]`) regexSpecial = regexp.MustCompile("[!-/:-@[-`{-~]")
) )
func isValidOption_AtLeast6(password string) string { func isValidOption_AtLeast6(password string) string {

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,17 @@ paths:
description: "" description: ""
schema: schema:
$ref: '#/definitions/object.OidcDiscovery' $ref: '#/definitions/object.OidcDiscovery'
/api/Callback:
post:
tags:
- Callback API
description: Get Login Error Counts
operationId: ApiController.Callback
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/add-adapter: /api/add-adapter:
post: post:
tags: tags:
@@ -121,6 +132,24 @@ paths:
description: The Response object description: The Response object
schema: schema:
$ref: '#/definitions/controllers.Response' $ref: '#/definitions/controllers.Response'
/api/add-invitation:
post:
tags:
- Invitation API
description: add invitation
operationId: ApiController.AddInvitation
parameters:
- in: body
name: body
description: The details of the invitation
required: true
schema:
$ref: '#/definitions/object.Invitation'
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/add-ldap: /api/add-ldap:
post: post:
tags: tags:
@@ -442,162 +471,10 @@ paths:
description: The Response object description: The Response object
schema: schema:
$ref: '#/definitions/controllers.Response' $ref: '#/definitions/controllers.Response'
/api/api/Callback:
post:
tags:
- Callback API
description: Get Login Error Counts
operationId: ApiController.Callback
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/api/get-captcha:
get:
tags:
- Login API
operationId: ApiController.GetCaptcha
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/api/get-captcha-status:
get:
tags:
- Token API
description: Get Login Error Counts
operationId: ApiController.GetCaptchaStatus
parameters:
- in: query
name: id
description: The id ( owner/name ) of user
required: true
type: string
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/api/get-webhook-event:
get:
tags:
- GetWebhookEventType API
operationId: ApiController.GetWebhookEventType
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/api/reset-email-or-phone:
post:
tags:
- Account API
operationId: ApiController.ResetEmailOrPhone
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/api/send-email:
post:
tags:
- Service API
description: This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
operationId: ApiController.SendEmail
parameters:
- in: query
name: clientId
description: The clientId of the application
required: true
type: string
- in: query
name: clientSecret
description: The clientSecret of the application
required: true
type: string
- in: body
name: from
description: Details of the email request
required: true
schema:
$ref: '#/definitions/controllers.EmailForm'
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/api/send-notification:
post:
tags:
- Service API
description: This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
operationId: ApiController.SendNotification
parameters:
- in: body
name: from
description: Details of the notification request
required: true
schema:
$ref: '#/definitions/controllers.NotificationForm'
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/api/send-sms:
post:
tags:
- Service API
description: This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
operationId: ApiController.SendSms
parameters:
- in: query
name: clientId
description: The clientId of the application
required: true
type: string
- in: query
name: clientSecret
description: The clientSecret of the application
required: true
type: string
- in: body
name: from
description: Details of the sms request
required: true
schema:
$ref: '#/definitions/controllers.SmsForm'
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/api/verify-code:
post:
tags:
- Verification API
operationId: ApiController.VerifyCode
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/api/webhook:
post:
tags:
- HandleOfficialAccountEvent API
operationId: ApiController.HandleOfficialAccountEvent
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/batch-enforce: /api/batch-enforce:
post: post:
tags: tags:
- Enforce API - Enforcer API
description: Call Casbin BatchEnforce API description: Call Casbin BatchEnforce API
operationId: ApiController.BatchEnforce operationId: ApiController.BatchEnforce
parameters: parameters:
@@ -617,6 +494,10 @@ paths:
name: modelId name: modelId
description: model id description: model id
type: string type: string
- in: query
name: owner
description: owner
type: string
responses: responses:
"200": "200":
description: The Response object description: The Response object
@@ -744,6 +625,24 @@ paths:
description: The Response object description: The Response object
schema: schema:
$ref: '#/definitions/controllers.Response' $ref: '#/definitions/controllers.Response'
/api/delete-invitation:
post:
tags:
- Invitation API
description: delete invitation
operationId: ApiController.DeleteInvitation
parameters:
- in: body
name: body
description: The details of the invitation
required: true
schema:
$ref: '#/definitions/object.Invitation'
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/delete-ldap: /api/delete-ldap:
post: post:
tags: tags:
@@ -1064,7 +963,7 @@ paths:
/api/enforce: /api/enforce:
post: post:
tags: tags:
- Enforce API - Enforcer API
description: Call Casbin Enforce API description: Call Casbin Enforce API
operationId: ApiController.Enforce operationId: ApiController.Enforce
parameters: parameters:
@@ -1088,6 +987,10 @@ paths:
name: resourceId name: resourceId
description: resource id description: resource id
type: string type: string
- in: query
name: owner
description: owner
type: string
responses: responses:
"200": "200":
description: The Response object description: The Response object
@@ -1213,6 +1116,33 @@ paths:
type: array type: array
items: items:
$ref: '#/definitions/object.Application' $ref: '#/definitions/object.Application'
/api/get-captcha:
get:
tags:
- Login API
operationId: ApiController.GetCaptcha
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/get-captcha-status:
get:
tags:
- Token API
description: Get Login Error Counts
operationId: ApiController.GetCaptchaStatus
parameters:
- in: query
name: id
description: The id ( owner/name ) of user
required: true
type: string
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/get-cert: /api/get-cert:
get: get:
tags: tags:
@@ -1252,7 +1182,7 @@ paths:
/api/get-dashboard: /api/get-dashboard:
get: get:
tags: tags:
- GetDashboard API - System API
description: get information of dashboard description: get information of dashboard
operationId: ApiController.GetDashboard operationId: ApiController.GetDashboard
responses: responses:
@@ -1410,6 +1340,42 @@ paths:
type: array type: array
items: items:
$ref: '#/definitions/object.Group' $ref: '#/definitions/object.Group'
/api/get-invitation:
get:
tags:
- Invitation API
description: get invitation
operationId: ApiController.GetInvitation
parameters:
- in: query
name: id
description: The id ( owner/name ) of the invitation
required: true
type: string
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Invitation'
/api/get-invitations:
get:
tags:
- Invitation API
description: get invitations
operationId: ApiController.GetInvitations
parameters:
- in: query
name: owner
description: The owner of invitations
required: true
type: string
responses:
"200":
description: The Response object
schema:
type: array
items:
$ref: '#/definitions/object.Invitation'
/api/get-ldap: /api/get-ldap:
get: get:
tags: tags:
@@ -1785,7 +1751,7 @@ paths:
/api/get-prometheus-info: /api/get-prometheus-info:
get: get:
tags: tags:
- Prometheus API - System API
description: get Prometheus Info description: get Prometheus Info
operationId: ApiController.GetPrometheusInfo operationId: ApiController.GetPrometheusInfo
responses: responses:
@@ -2269,6 +2235,16 @@ paths:
description: The Response object description: The Response object
schema: schema:
$ref: '#/definitions/object.Webhook' $ref: '#/definitions/object.Webhook'
/api/get-webhook-event:
get:
tags:
- System API
operationId: ApiController.GetWebhookEventType
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/get-webhooks: /api/get-webhooks:
get: get:
tags: tags:
@@ -2396,8 +2372,50 @@ paths:
description: The Response object description: The Response object
schema: schema:
$ref: '#/definitions/controllers.Response' $ref: '#/definitions/controllers.Response'
/api/login/oauth/access_token:
post:
tags:
- Token API
description: get OAuth access token
operationId: ApiController.GetOAuthToken
parameters:
- in: query
name: grant_type
description: OAuth grant type
required: true
type: string
- in: query
name: client_id
description: OAuth client id
required: true
type: string
- in: query
name: client_secret
description: OAuth client secret
required: true
type: string
- in: query
name: code
description: OAuth code
required: true
type: string
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.TokenWrapper'
"400":
description: The Response object
schema:
$ref: '#/definitions/object.TokenError'
"401":
description: The Response object
schema:
$ref: '#/definitions/object.TokenError'
/api/login/oauth/introspect: /api/login/oauth/introspect:
post: post:
tags:
- Login API
description: The introspection endpoint is an OAuth 2.0 endpoint that takes a description: The introspection endpoint is an OAuth 2.0 endpoint that takes a
operationId: ApiController.IntrospectToken operationId: ApiController.IntrospectToken
parameters: parameters:
@@ -2543,6 +2561,16 @@ paths:
description: The Response object description: The Response object
schema: schema:
$ref: '#/definitions/controllers.Response' $ref: '#/definitions/controllers.Response'
/api/reset-email-or-phone:
post:
tags:
- Account API
operationId: ApiController.ResetEmailOrPhone
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/run-syncer: /api/run-syncer:
get: get:
tags: tags:
@@ -2561,6 +2589,80 @@ paths:
description: The Response object description: The Response object
schema: schema:
$ref: '#/definitions/controllers.Response' $ref: '#/definitions/controllers.Response'
/api/send-email:
post:
tags:
- Service API
description: This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
operationId: ApiController.SendEmail
parameters:
- in: query
name: clientId
description: The clientId of the application
required: true
type: string
- in: query
name: clientSecret
description: The clientSecret of the application
required: true
type: string
- in: body
name: from
description: Details of the email request
required: true
schema:
$ref: '#/definitions/controllers.EmailForm'
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/send-notification:
post:
tags:
- Service API
description: This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
operationId: ApiController.SendNotification
parameters:
- in: body
name: from
description: Details of the notification request
required: true
schema:
$ref: '#/definitions/controllers.NotificationForm'
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/send-sms:
post:
tags:
- Service API
description: This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
operationId: ApiController.SendSms
parameters:
- in: query
name: clientId
description: The clientId of the application
required: true
type: string
- in: query
name: clientSecret
description: The clientSecret of the application
required: true
type: string
- in: body
name: from
description: Details of the sms request
required: true
schema:
$ref: '#/definitions/controllers.SmsForm'
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/send-verification-code: /api/send-verification-code:
post: post:
tags: tags:
@@ -2778,6 +2880,29 @@ paths:
description: The Response object description: The Response object
schema: schema:
$ref: '#/definitions/controllers.Response' $ref: '#/definitions/controllers.Response'
/api/update-invitation:
post:
tags:
- Invitation API
description: update invitation
operationId: ApiController.UpdateInvitation
parameters:
- in: query
name: id
description: The id ( owner/name ) of the invitation
required: true
type: string
- in: body
name: body
description: The details of the invitation
required: true
schema:
$ref: '#/definitions/object.Invitation'
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/update-ldap: /api/update-ldap:
post: post:
tags: tags:
@@ -3245,6 +3370,33 @@ paths:
description: The Response object description: The Response object
schema: schema:
$ref: '#/definitions/object.Userinfo' $ref: '#/definitions/object.Userinfo'
/api/verify-code:
post:
tags:
- Verification API
operationId: ApiController.VerifyCode
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.Userinfo'
/api/verify-invitation:
get:
tags:
- Invitation API
description: verify invitation
operationId: ApiController.VerifyInvitation
parameters:
- in: query
name: id
description: The id ( owner/name ) of the invitation
required: true
type: string
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/controllers.Response'
/api/webauthn/signin/begin: /api/webauthn/signin/begin:
get: get:
tags: tags:
@@ -3314,46 +3466,16 @@ paths:
description: '"The Response object"' description: '"The Response object"'
schema: schema:
$ref: '#/definitions/controllers.Response' $ref: '#/definitions/controllers.Response'
/apiapi/login/oauth/access_token: /api/webhook:
post: post:
tags: tags:
- Token API - System API
description: get OAuth access token operationId: ApiController.HandleOfficialAccountEvent
operationId: ApiController.GetOAuthToken
parameters:
- in: query
name: grant_type
description: OAuth grant type
required: true
type: string
- in: query
name: client_id
description: OAuth client id
required: true
type: string
- in: query
name: client_secret
description: OAuth client secret
required: true
type: string
- in: query
name: code
description: OAuth code
required: true
type: string
responses: responses:
"200": "200":
description: The Response object description: The Response object
schema: schema:
$ref: '#/definitions/object.TokenWrapper' $ref: '#/definitions/object.Userinfo'
"400":
description: The Response object
schema:
$ref: '#/definitions/object.TokenError'
"401":
description: The Response object
schema:
$ref: '#/definitions/object.TokenError'
definitions: definitions:
casbin.Enforcer: casbin.Enforcer:
title: Enforcer title: Enforcer
@@ -3546,10 +3668,10 @@ definitions:
expireInHours: expireInHours:
type: integer type: integer
format: int64 format: int64
failedSigninLimit: failedSigninFrozenTime:
type: integer type: integer
format: int64 format: int64
failedSigninFrozenTime: failedSigninLimit:
type: integer type: integer
format: int64 format: int64
forgetUrl: forgetUrl:
@@ -3606,6 +3728,10 @@ definitions:
type: string type: string
signinHtml: signinHtml:
type: string type: string
signinMethods:
type: array
items:
$ref: '#/definitions/object.SigninMethod'
signinUrl: signinUrl:
type: string type: string
signupHtml: signupHtml:
@@ -3624,6 +3750,10 @@ definitions:
type: string type: string
themeData: themeData:
$ref: '#/definitions/object.ThemeData' $ref: '#/definitions/object.ThemeData'
tokenFields:
type: array
items:
type: string
tokenFormat: tokenFormat:
type: string type: string
object.Cert: object.Cert:
@@ -3780,6 +3910,40 @@ definitions:
type: string type: string
username: username:
type: string type: string
object.Invitation:
title: Invitation
type: object
properties:
application:
type: string
code:
type: string
createdTime:
type: string
displayName:
type: string
email:
type: string
name:
type: string
owner:
type: string
phone:
type: string
quota:
type: integer
format: int64
signupGroup:
type: string
state:
type: string
updatedTime:
type: string
usedCount:
type: integer
format: int64
username:
type: string
object.Ldap: object.Ldap:
title: Ldap title: Ldap
type: object type: object
@@ -4455,6 +4619,16 @@ definitions:
type: string type: string
value: value:
type: string type: string
object.SigninMethod:
title: SigninMethod
type: object
properties:
displayName:
type: string
name:
type: string
rule:
type: string
object.SignupItem: object.SignupItem:
title: SignupItem title: SignupItem
type: object type: object
@@ -4467,6 +4641,8 @@ definitions:
type: string type: string
prompted: prompted:
type: boolean type: boolean
regex:
type: string
required: required:
type: boolean type: boolean
rule: rule:

View File

@@ -37,7 +37,7 @@ function isValidOption_Aa123(password) {
} }
function isValidOption_SpecialChar(password) { function isValidOption_SpecialChar(password) {
const regex = /^(?=.*[!@#$%^&*]).+$/; const regex = /^(?=.*[!-/:-@[-`{-~]).+$/;
if (!regex.test(password)) { if (!regex.test(password)) {
return i18next.t("user:The password must contain at least one special character"); return i18next.t("user:The password must contain at least one special character");
} }