Compare commits

...

8 Commits

Author SHA1 Message Date
Yang Luo
5846e337c7 feat: fix gofmt issue 2023-12-30 19:47:04 +08:00
Yang Luo
44f4de1440 feat: support empty fileUrl in GetUploadFileUrl() 2023-12-30 19:06:35 +08:00
Yang Luo
27adeb4620 Refactor initAPI() 2023-12-30 14:28:45 +08:00
Yang Luo
5c107db43b fix: fix i18n typo 2023-12-30 00:49:39 +08:00
Yang Luo
27187b3a54 feat: add "Reset to Default HTML" button 2023-12-30 00:47:10 +08:00
Yang Luo
14fcedcc5d feat: support HTML in Email content 2023-12-29 23:31:50 +08:00
xiao-kong-long
e7c015f288 feat: fix comment and configs for successfully generating OpenAPI typescript-axios sdk (#2560)
* fix: fix swagger.json, successfully generate java sdk

* fix:fix comment and change some content for successfully generating typescript-axios sdk
2023-12-29 15:12:40 +08:00
Yang Luo
c4819602ec fix: add mfa API to isAllowedInDemoMode() 2023-12-26 20:06:27 +08:00
24 changed files with 688 additions and 381 deletions

View File

@@ -150,7 +150,7 @@ func IsAllowed(subOwner string, subName string, method string, urlPath string, o
func isAllowedInDemoMode(subOwner string, subName string, method string, urlPath string, objOwner string, objName string) bool {
if method == "POST" {
if strings.HasPrefix(urlPath, "/api/login") || urlPath == "/api/logout" || urlPath == "/api/signup" || urlPath == "/api/callback" || urlPath == "/api/send-verification-code" || urlPath == "/api/send-email" || urlPath == "/api/verify-captcha" {
if strings.HasPrefix(urlPath, "/api/login") || urlPath == "/api/logout" || urlPath == "/api/signup" || urlPath == "/api/callback" || urlPath == "/api/send-verification-code" || urlPath == "/api/send-email" || urlPath == "/api/verify-captcha" || urlPath == "/api/check-user-password" || strings.HasPrefix(urlPath, "/api/mfa/") {
return true
} else if urlPath == "/api/update-user" {
// Allow ordinary users to update their own information

View File

@@ -56,6 +56,17 @@ type Captcha struct {
SubType string `json:"subType"`
}
// this API is used by "Api URL" of Flarum's FoF Passport plugin
// https://github.com/FriendsOfFlarum/passport
type LaravelResponse struct {
Id string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
EmailVerifiedAt string `json:"email_verified_at"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
// Signup
// @Tag Login API
// @Title Signup
@@ -418,7 +429,7 @@ func (c *ApiController) GetUserinfo() {
// @Title UserInfo2
// @Tag Account API
// @Description return Laravel compatible user information according to OAuth 2.0
// @Success 200 {object} LaravelResponse The Response object
// @Success 200 {object} controllers.LaravelResponse The Response object
// @router /user [get]
func (c *ApiController) GetUserinfo2() {
user, ok := c.RequireSignedInUser()
@@ -426,17 +437,6 @@ func (c *ApiController) GetUserinfo2() {
return
}
// this API is used by "Api URL" of Flarum's FoF Passport plugin
// https://github.com/FriendsOfFlarum/passport
type LaravelResponse struct {
Id string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
EmailVerifiedAt string `json:"email_verified_at"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
response := LaravelResponse{
Id: user.Id,
Name: user.Name,

View File

@@ -222,7 +222,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
// @Param redirectUri query string true "redirect uri"
// @Param scope query string true "scope"
// @Param state query string true "state"
// @Success 200 {object} Response The Response object
// @Success 200 {object} controllers.Response The Response object
// @router /get-app-login [get]
func (c *ApiController) GetApplicationLogin() {
clientId := c.Input().Get("clientId")

View File

@@ -26,7 +26,7 @@ import (
// @Title Enforce
// @Tag Enforce API
// @Description Call Casbin Enforce API
// @Param body body object.CasbinRequest true "Casbin request"
// @Param body body []string true "Casbin request"
// @Param permissionId query string false "permission id"
// @Param modelId query string false "model id"
// @Param resourceId query string false "resource id"
@@ -43,7 +43,7 @@ func (c *ApiController) Enforce() {
return
}
var request object.CasbinRequest
var request []string
err := json.Unmarshal(c.Ctx.Input.RequestBody, &request)
if err != nil {
c.ResponseError(err.Error())
@@ -60,7 +60,10 @@ func (c *ApiController) Enforce() {
res := []bool{}
keyRes := []string{}
enforceResult, err := enforcer.Enforce(request...)
// type transformation
interfaceRequest := util.StringToInterfaceArray(request)
enforceResult, err := enforcer.Enforce(interfaceRequest...)
if err != nil {
c.ResponseError(err.Error())
return
@@ -87,7 +90,7 @@ func (c *ApiController) Enforce() {
res := []bool{}
keyRes := []string{}
enforceResult, err := object.Enforce(permission, &request)
enforceResult, err := object.Enforce(permission, request)
if err != nil {
c.ResponseError(err.Error())
return
@@ -129,7 +132,7 @@ func (c *ApiController) Enforce() {
return
}
enforceResult, err := object.Enforce(firstPermission, &request, permissionIds...)
enforceResult, err := object.Enforce(firstPermission, request, permissionIds...)
if err != nil {
c.ResponseError(err.Error())
return
@@ -146,7 +149,7 @@ func (c *ApiController) Enforce() {
// @Title BatchEnforce
// @Tag Enforce API
// @Description Call Casbin BatchEnforce API
// @Param body body object.CasbinRequest true "array of casbin requests"
// @Param body body []string true "array of casbin requests"
// @Param permissionId query string false "permission id"
// @Param modelId query string false "model id"
// @Success 200 {object} controllers.Response The Response object
@@ -156,7 +159,7 @@ func (c *ApiController) BatchEnforce() {
modelId := c.Input().Get("modelId")
enforcerId := c.Input().Get("enforcerId")
var requests []object.CasbinRequest
var requests [][]string
err := json.Unmarshal(c.Ctx.Input.RequestBody, &requests)
if err != nil {
c.ResponseError(err.Error())
@@ -173,7 +176,10 @@ func (c *ApiController) BatchEnforce() {
res := [][]bool{}
keyRes := []string{}
enforceResult, err := enforcer.BatchEnforce(requests)
// type transformation
interfaceRequests := util.StringToInterfaceArray2d(requests)
enforceResult, err := enforcer.BatchEnforce(interfaceRequests)
if err != nil {
c.ResponseError(err.Error())
return
@@ -200,7 +206,7 @@ func (c *ApiController) BatchEnforce() {
res := [][]bool{}
keyRes := []string{}
enforceResult, err := object.BatchEnforce(permission, &requests)
enforceResult, err := object.BatchEnforce(permission, requests)
if err != nil {
c.ResponseError(err.Error())
return
@@ -236,7 +242,7 @@ func (c *ApiController) BatchEnforce() {
return
}
enforceResult, err := object.BatchEnforce(firstPermission, &requests, permissionIds...)
enforceResult, err := object.BatchEnforce(firstPermission, requests, permissionIds...)
if err != nil {
c.ResponseError(err.Error())
return

View File

@@ -138,7 +138,7 @@ func (c *ApiController) AddEnforcer() {
// @Title DeleteEnforcer
// @Tag Enforcer API
// @Description delete enforcer
// @Param body body object.Enforce true "The enforcer object"
// @Param body body object.Enforcer true "The enforcer object"
// @Success 200 {object} object.Enforcer
// @router /delete-enforcer [post]
func (c *ApiController) DeleteEnforcer() {

View File

@@ -42,7 +42,7 @@ type LdapSyncResp struct {
// @Tag Account API
// @Description get ldap users
// Param id string true "id"
// @Success 200 {object} LdapResp The Response object
// @Success 200 {object} controllers.LdapResp The Response object
// @router /get-ldap-users [get]
func (c *ApiController) GetLdapUsers() {
id := c.Input().Get("id")
@@ -250,7 +250,7 @@ func (c *ApiController) DeleteLdap() {
// @Tag Account API
// @Description sync ldap users
// @Param id query string true "id"
// @Success 200 {object} LdapSyncResp The Response object
// @Success 200 {object} controllers.LdapSyncResp The Response object
// @router /sync-ldap-users [post]
func (c *ApiController) SyncLdapUsers() {
id := c.Input().Get("id")

View File

@@ -73,7 +73,7 @@ func (c *ApiController) MfaSetupInitiate() {
// @Description setup verify totp
// @param secret form string true "MFA secret"
// @param passcode form string true "MFA passcode"
// @Success 200 {object} Response object
// @Success 200 {object} controllers.Response The Response object
// @router /mfa/setup/verify [post]
func (c *ApiController) MfaSetupVerify() {
mfaType := c.Ctx.Request.Form.Get("mfaType")
@@ -104,7 +104,7 @@ func (c *ApiController) MfaSetupVerify() {
// @param owner form string true "owner of user"
// @param name form string true "name of user"
// @param type form string true "MFA auth type"
// @Success 200 {object} Response object
// @Success 200 {object} controllers.Response The Response object
// @router /mfa/setup/enable [post]
func (c *ApiController) MfaSetupEnable() {
owner := c.Ctx.Request.Form.Get("owner")
@@ -143,7 +143,7 @@ func (c *ApiController) MfaSetupEnable() {
// @Description: Delete MFA
// @param owner form string true "owner of user"
// @param name form string true "name of user"
// @Success 200 {object} Response object
// @Success 200 {object} controllers.Response The Response object
// @router /delete-mfa/ [post]
func (c *ApiController) DeleteMfa() {
owner := c.Ctx.Request.Form.Get("owner")
@@ -176,7 +176,7 @@ func (c *ApiController) DeleteMfa() {
// @param owner form string true "owner of user"
// @param name form string true "name of user"
// @param id form string true "id of user's MFA props"
// @Success 200 {object} Response object
// @Success 200 {object} controllers.Response The Response object
// @router /set-preferred-mfa [post]
func (c *ApiController) SetPreferredMfa() {
mfaType := c.Ctx.Request.Form.Get("mfaType")

View File

@@ -178,7 +178,7 @@ func (c *ApiController) DeleteOrganization() {
// @Tag Organization API
// @Description get default application
// @Param id query string true "organization id"
// @Success 200 {object} Response The Response object
// @Success 200 {object} controllers.Response The Response object
// @router /get-default-application [get]
func (c *ApiController) GetDefaultApplication() {
userId := c.GetSessionUsername()

View File

@@ -51,9 +51,14 @@ type NotificationForm struct {
// @Param clientId query string true "The clientId of the application"
// @Param clientSecret query string true "The clientSecret of the application"
// @Param from body controllers.EmailForm true "Details of the email request"
// @Success 200 {object} Response object
// @Success 200 {object} controllers.Response The Response object
// @router /api/send-email [post]
func (c *ApiController) SendEmail() {
user, ok := c.RequireSignedInUser()
if !ok {
return
}
var emailForm EmailForm
err := json.Unmarshal(c.Ctx.Input.RequestBody, &emailForm)
@@ -108,8 +113,13 @@ func (c *ApiController) SendEmail() {
}
code := "123456"
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
content := fmt.Sprintf(emailForm.Content, code)
content := strings.Replace(provider.Content, "%s", code, 1)
if user != nil {
content = strings.Replace(content, "%{user.friendlyName}", user.GetFriendlyName(), 1)
}
for _, receiver := range emailForm.Receivers {
err = object.SendEmail(provider, emailForm.Title, content, receiver, emailForm.Sender)
if err != nil {
@@ -128,7 +138,7 @@ func (c *ApiController) SendEmail() {
// @Param clientId query string true "The clientId of the application"
// @Param clientSecret query string true "The clientSecret of the application"
// @Param from body controllers.SmsForm true "Details of the sms request"
// @Success 200 {object} Response object
// @Success 200 {object} controllers.Response The Response object
// @router /api/send-sms [post]
func (c *ApiController) SendSms() {
provider, err := c.GetProviderFromContext("SMS")
@@ -166,7 +176,7 @@ func (c *ApiController) SendSms() {
// @Tag Service API
// @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"
// @Success 200 {object} Response object
// @Success 200 {object} controllers.Response The Response object
// @router /api/send-notification [post]
func (c *ApiController) SendNotification() {
provider, err := c.GetProviderFromContext("Notification")

View File

@@ -234,12 +234,32 @@ func (a *Ormer) createTable() {
panic(err)
}
err = a.Engine.Sync2(new(Group))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(User))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Group))
err = a.Engine.Sync2(new(Application))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Provider))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Resource))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Cert))
if err != nil {
panic(err)
}
@@ -269,17 +289,7 @@ func (a *Ormer) createTable() {
panic(err)
}
err = a.Engine.Sync2(new(Provider))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Application))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Resource))
err = a.Engine.Sync2(new(Session))
if err != nil {
panic(err)
}
@@ -289,26 +299,6 @@ func (a *Ormer) createTable() {
panic(err)
}
err = a.Engine.Sync2(new(VerificationRecord))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Webhook))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Syncer))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Cert))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Product))
if err != nil {
panic(err)
@@ -319,6 +309,36 @@ func (a *Ormer) createTable() {
panic(err)
}
err = a.Engine.Sync2(new(Plan))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Pricing))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Subscription))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Syncer))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Webhook))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(VerificationRecord))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Ldap))
if err != nil {
panic(err)
@@ -333,24 +353,4 @@ func (a *Ormer) createTable() {
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Session))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Subscription))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Plan))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Pricing))
if err != nil {
panic(err)
}
}

View File

@@ -284,24 +284,28 @@ func removeGroupingPolicies(permission *Permission) error {
return nil
}
type CasbinRequest = []interface{}
func Enforce(permission *Permission, request *CasbinRequest, permissionIds ...string) (bool, error) {
func Enforce(permission *Permission, request []string, permissionIds ...string) (bool, error) {
enforcer, err := getPermissionEnforcer(permission, permissionIds...)
if err != nil {
return false, err
}
return enforcer.Enforce(*request...)
// type transformation
interfaceRequest := util.StringToInterfaceArray(request)
return enforcer.Enforce(interfaceRequest...)
}
func BatchEnforce(permission *Permission, requests *[]CasbinRequest, permissionIds ...string) ([]bool, error) {
func BatchEnforce(permission *Permission, requests [][]string, permissionIds ...string) ([]bool, error) {
enforcer, err := getPermissionEnforcer(permission, permissionIds...)
if err != nil {
return nil, err
}
return enforcer.BatchEnforce(*requests)
// type transformation
interfaceRequests := util.StringToInterfaceArray2d(requests)
return enforcer.BatchEnforce(interfaceRequests)
}
func getAllValues(userId string, fn func(enforcer *casbin.Enforcer) []string) ([]string, error) {

View File

@@ -52,7 +52,7 @@ type Provider struct {
Port int `json:"port"`
DisableSsl bool `json:"disableSsl"` // If the provider type is WeChat, DisableSsl means EnableQRCode
Title string `xorm:"varchar(100)" json:"title"`
Content string `xorm:"varchar(1000)" json:"content"` // If provider type is WeChat, Content means QRCode string by Base64 encoding
Content string `xorm:"varchar(2000)" json:"content"` // If provider type is WeChat, Content means QRCode string by Base64 encoding
Receiver string `xorm:"varchar(100)" json:"receiver"`
RegionId string `xorm:"varchar(100)" json:"regionId"`

View File

@@ -72,6 +72,10 @@ func GetTruncatedPath(provider *Provider, fullFilePath string, limit int) string
}
func GetUploadFileUrl(provider *Provider, fullFilePath string, hasTimestamp bool) (string, string) {
if provider.Domain != "" && !strings.HasPrefix(provider.Domain, "http://") && !strings.HasPrefix(provider.Domain, "https://") {
provider.Domain = fmt.Sprintf("https://%s", provider.Domain)
}
escapedPath := util.UrlJoin(provider.PathPrefix, fullFilePath)
objectKey := util.UrlJoin(util.GetUrlPath(provider.Domain), escapedPath)
@@ -79,9 +83,6 @@ func GetUploadFileUrl(provider *Provider, fullFilePath string, hasTimestamp bool
if provider.Type != "Local File System" {
// provider.Domain = "https://cdn.casbin.com/casdoor/"
host = util.GetUrlHost(provider.Domain)
if !strings.HasPrefix(host, "http://") && !strings.HasPrefix(host, "https://") {
host = fmt.Sprintf("https://%s", host)
}
} else {
// provider.Domain = "http://localhost:8000" or "https://door.casdoor.com"
host = util.UrlJoin(provider.Domain, "/files")
@@ -90,9 +91,12 @@ func GetUploadFileUrl(provider *Provider, fullFilePath string, hasTimestamp bool
host = util.UrlJoin(host, provider.Bucket)
}
fileUrl := util.UrlJoin(host, escapePath(objectKey))
fileUrl := ""
if host != "" {
fileUrl = util.UrlJoin(host, escapePath(objectKey))
}
if hasTimestamp {
if fileUrl != "" && hasTimestamp {
fileUrl = fmt.Sprintf("%s?t=%s", fileUrl, util.GetCurrentUnixTime())
}

View File

@@ -886,6 +886,18 @@ func (user *User) GetId() string {
return fmt.Sprintf("%s/%s", user.Owner, user.Name)
}
func (user *User) GetFriendlyName() string {
if user.FirstName != "" && user.LastName != "" {
return fmt.Sprintf("%s, %s", user.FirstName, user.LastName)
} else if user.DisplayName != "" {
return user.DisplayName
} else if user.Name != "" {
return user.Name
} else {
return user.Id
}
}
func isUserIdGlobalAdmin(userId string) bool {
return strings.HasPrefix(userId, "built-in/") || strings.HasPrefix(userId, "app/")
}

View File

@@ -89,7 +89,10 @@ func SendVerificationCodeToEmail(organization *Organization, user *User, provide
}
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
content := fmt.Sprintf(provider.Content, code)
content := strings.Replace(provider.Content, "%s", code, 1)
if user != nil {
content = strings.Replace(content, "%{user.friendlyName}", user.GetFriendlyName(), 1)
}
if err := IsAllowSend(user, remoteAddr, provider.Category); err != nil {
return err

View File

@@ -73,6 +73,12 @@ func initAPI() {
beego.Router("/api/get-default-application", &controllers.ApiController{}, "GET:GetDefaultApplication")
beego.Router("/api/get-organization-names", &controllers.ApiController{}, "GET:GetOrganizationNames")
beego.Router("/api/get-groups", &controllers.ApiController{}, "GET:GetGroups")
beego.Router("/api/get-group", &controllers.ApiController{}, "GET:GetGroup")
beego.Router("/api/update-group", &controllers.ApiController{}, "POST:UpdateGroup")
beego.Router("/api/add-group", &controllers.ApiController{}, "POST:AddGroup")
beego.Router("/api/delete-group", &controllers.ApiController{}, "POST:DeleteGroup")
beego.Router("/api/get-global-users", &controllers.ApiController{}, "GET:GetGlobalUsers")
beego.Router("/api/get-users", &controllers.ApiController{}, "GET:GetUsers")
beego.Router("/api/get-sorted-users", &controllers.ApiController{}, "GET:GetSortedUsers")
@@ -85,11 +91,34 @@ func initAPI() {
beego.Router("/api/upload-users", &controllers.ApiController{}, "POST:UploadUsers")
beego.Router("/api/remove-user-from-group", &controllers.ApiController{}, "POST:RemoveUserFromGroup")
beego.Router("/api/get-groups", &controllers.ApiController{}, "GET:GetGroups")
beego.Router("/api/get-group", &controllers.ApiController{}, "GET:GetGroup")
beego.Router("/api/update-group", &controllers.ApiController{}, "POST:UpdateGroup")
beego.Router("/api/add-group", &controllers.ApiController{}, "POST:AddGroup")
beego.Router("/api/delete-group", &controllers.ApiController{}, "POST:DeleteGroup")
beego.Router("/api/get-applications", &controllers.ApiController{}, "GET:GetApplications")
beego.Router("/api/get-application", &controllers.ApiController{}, "GET:GetApplication")
beego.Router("/api/get-user-application", &controllers.ApiController{}, "GET:GetUserApplication")
beego.Router("/api/get-organization-applications", &controllers.ApiController{}, "GET:GetOrganizationApplications")
beego.Router("/api/update-application", &controllers.ApiController{}, "POST:UpdateApplication")
beego.Router("/api/add-application", &controllers.ApiController{}, "POST:AddApplication")
beego.Router("/api/delete-application", &controllers.ApiController{}, "POST:DeleteApplication")
beego.Router("/api/get-providers", &controllers.ApiController{}, "GET:GetProviders")
beego.Router("/api/get-provider", &controllers.ApiController{}, "GET:GetProvider")
beego.Router("/api/get-global-providers", &controllers.ApiController{}, "GET:GetGlobalProviders")
beego.Router("/api/update-provider", &controllers.ApiController{}, "POST:UpdateProvider")
beego.Router("/api/add-provider", &controllers.ApiController{}, "POST:AddProvider")
beego.Router("/api/delete-provider", &controllers.ApiController{}, "POST:DeleteProvider")
beego.Router("/api/get-resources", &controllers.ApiController{}, "GET:GetResources")
beego.Router("/api/get-resource", &controllers.ApiController{}, "GET:GetResource")
beego.Router("/api/update-resource", &controllers.ApiController{}, "POST:UpdateResource")
beego.Router("/api/add-resource", &controllers.ApiController{}, "POST:AddResource")
beego.Router("/api/delete-resource", &controllers.ApiController{}, "POST:DeleteResource")
beego.Router("/api/upload-resource", &controllers.ApiController{}, "POST:UploadResource")
beego.Router("/api/get-certs", &controllers.ApiController{}, "GET:GetCerts")
beego.Router("/api/get-global-certs", &controllers.ApiController{}, "GET:GetGlobalCerts")
beego.Router("/api/get-cert", &controllers.ApiController{}, "GET:GetCert")
beego.Router("/api/update-cert", &controllers.ApiController{}, "POST:UpdateCert")
beego.Router("/api/add-cert", &controllers.ApiController{}, "POST:AddCert")
beego.Router("/api/delete-cert", &controllers.ApiController{}, "POST:DeleteCert")
beego.Router("/api/get-roles", &controllers.ApiController{}, "GET:GetRoles")
beego.Router("/api/get-role", &controllers.ApiController{}, "GET:GetRole")
@@ -107,12 +136,6 @@ func initAPI() {
beego.Router("/api/delete-permission", &controllers.ApiController{}, "POST:DeletePermission")
beego.Router("/api/upload-permissions", &controllers.ApiController{}, "POST:UploadPermissions")
beego.Router("/api/enforce", &controllers.ApiController{}, "POST:Enforce")
beego.Router("/api/batch-enforce", &controllers.ApiController{}, "POST:BatchEnforce")
beego.Router("/api/get-all-objects", &controllers.ApiController{}, "GET:GetAllObjects")
beego.Router("/api/get-all-actions", &controllers.ApiController{}, "GET:GetAllActions")
beego.Router("/api/get-all-roles", &controllers.ApiController{}, "GET:GetAllRoles")
beego.Router("/api/get-models", &controllers.ApiController{}, "GET:GetModels")
beego.Router("/api/get-model", &controllers.ApiController{}, "GET:GetModel")
beego.Router("/api/update-model", &controllers.ApiController{}, "POST:UpdateModel")
@@ -135,53 +158,11 @@ func initAPI() {
beego.Router("/api/add-enforcer", &controllers.ApiController{}, "POST:AddEnforcer")
beego.Router("/api/delete-enforcer", &controllers.ApiController{}, "POST:DeleteEnforcer")
beego.Router("/api/set-password", &controllers.ApiController{}, "POST:SetPassword")
beego.Router("/api/check-user-password", &controllers.ApiController{}, "POST:CheckUserPassword")
beego.Router("/api/get-email-and-phone", &controllers.ApiController{}, "GET:GetEmailAndPhone")
beego.Router("/api/send-verification-code", &controllers.ApiController{}, "POST:SendVerificationCode")
beego.Router("/api/verify-code", &controllers.ApiController{}, "POST:VerifyCode")
beego.Router("/api/verify-captcha", &controllers.ApiController{}, "POST:VerifyCaptcha")
beego.Router("/api/reset-email-or-phone", &controllers.ApiController{}, "POST:ResetEmailOrPhone")
beego.Router("/api/get-captcha", &controllers.ApiController{}, "GET:GetCaptcha")
beego.Router("/api/get-ldap-users", &controllers.ApiController{}, "GET:GetLdapUsers")
beego.Router("/api/get-ldaps", &controllers.ApiController{}, "GET:GetLdaps")
beego.Router("/api/get-ldap", &controllers.ApiController{}, "GET:GetLdap")
beego.Router("/api/add-ldap", &controllers.ApiController{}, "POST:AddLdap")
beego.Router("/api/update-ldap", &controllers.ApiController{}, "POST:UpdateLdap")
beego.Router("/api/delete-ldap", &controllers.ApiController{}, "POST:DeleteLdap")
beego.Router("/api/sync-ldap-users", &controllers.ApiController{}, "POST:SyncLdapUsers")
beego.Router("/api/get-providers", &controllers.ApiController{}, "GET:GetProviders")
beego.Router("/api/get-provider", &controllers.ApiController{}, "GET:GetProvider")
beego.Router("/api/get-global-providers", &controllers.ApiController{}, "GET:GetGlobalProviders")
beego.Router("/api/update-provider", &controllers.ApiController{}, "POST:UpdateProvider")
beego.Router("/api/add-provider", &controllers.ApiController{}, "POST:AddProvider")
beego.Router("/api/delete-provider", &controllers.ApiController{}, "POST:DeleteProvider")
beego.Router("/api/get-applications", &controllers.ApiController{}, "GET:GetApplications")
beego.Router("/api/get-application", &controllers.ApiController{}, "GET:GetApplication")
beego.Router("/api/get-user-application", &controllers.ApiController{}, "GET:GetUserApplication")
beego.Router("/api/get-organization-applications", &controllers.ApiController{}, "GET:GetOrganizationApplications")
beego.Router("/api/update-application", &controllers.ApiController{}, "POST:UpdateApplication")
beego.Router("/api/add-application", &controllers.ApiController{}, "POST:AddApplication")
beego.Router("/api/delete-application", &controllers.ApiController{}, "POST:DeleteApplication")
beego.Router("/api/get-resources", &controllers.ApiController{}, "GET:GetResources")
beego.Router("/api/get-resource", &controllers.ApiController{}, "GET:GetResource")
beego.Router("/api/update-resource", &controllers.ApiController{}, "POST:UpdateResource")
beego.Router("/api/add-resource", &controllers.ApiController{}, "POST:AddResource")
beego.Router("/api/delete-resource", &controllers.ApiController{}, "POST:DeleteResource")
beego.Router("/api/upload-resource", &controllers.ApiController{}, "POST:UploadResource")
beego.Router("/api/get-tokens", &controllers.ApiController{}, "GET:GetTokens")
beego.Router("/api/get-token", &controllers.ApiController{}, "GET:GetToken")
beego.Router("/api/update-token", &controllers.ApiController{}, "POST:UpdateToken")
beego.Router("/api/add-token", &controllers.ApiController{}, "POST:AddToken")
beego.Router("/api/delete-token", &controllers.ApiController{}, "POST:DeleteToken")
beego.Router("/api/login/oauth/access_token", &controllers.ApiController{}, "POST:GetOAuthToken")
beego.Router("/api/login/oauth/refresh_token", &controllers.ApiController{}, "POST:RefreshToken")
beego.Router("/api/login/oauth/introspect", &controllers.ApiController{}, "POST:IntrospectToken")
beego.Router("/api/enforce", &controllers.ApiController{}, "POST:Enforce")
beego.Router("/api/batch-enforce", &controllers.ApiController{}, "POST:BatchEnforce")
beego.Router("/api/get-all-objects", &controllers.ApiController{}, "GET:GetAllObjects")
beego.Router("/api/get-all-actions", &controllers.ApiController{}, "GET:GetAllActions")
beego.Router("/api/get-all-roles", &controllers.ApiController{}, "GET:GetAllRoles")
beego.Router("/api/get-sessions", &controllers.ApiController{}, "GET:GetSessions")
beego.Router("/api/get-session", &controllers.ApiController{}, "GET:GetSingleSession")
@@ -190,43 +171,11 @@ func initAPI() {
beego.Router("/api/delete-session", &controllers.ApiController{}, "POST:DeleteSession")
beego.Router("/api/is-session-duplicated", &controllers.ApiController{}, "GET:IsSessionDuplicated")
beego.Router("/api/get-webhooks", &controllers.ApiController{}, "GET:GetWebhooks")
beego.Router("/api/get-webhook", &controllers.ApiController{}, "GET:GetWebhook")
beego.Router("/api/update-webhook", &controllers.ApiController{}, "POST:UpdateWebhook")
beego.Router("/api/add-webhook", &controllers.ApiController{}, "POST:AddWebhook")
beego.Router("/api/delete-webhook", &controllers.ApiController{}, "POST:DeleteWebhook")
beego.Router("/api/get-syncers", &controllers.ApiController{}, "GET:GetSyncers")
beego.Router("/api/get-syncer", &controllers.ApiController{}, "GET:GetSyncer")
beego.Router("/api/update-syncer", &controllers.ApiController{}, "POST:UpdateSyncer")
beego.Router("/api/add-syncer", &controllers.ApiController{}, "POST:AddSyncer")
beego.Router("/api/delete-syncer", &controllers.ApiController{}, "POST:DeleteSyncer")
beego.Router("/api/run-syncer", &controllers.ApiController{}, "GET:RunSyncer")
beego.Router("/api/get-certs", &controllers.ApiController{}, "GET:GetCerts")
beego.Router("/api/get-global-certs", &controllers.ApiController{}, "GET:GetGlobalCerts")
beego.Router("/api/get-cert", &controllers.ApiController{}, "GET:GetCert")
beego.Router("/api/update-cert", &controllers.ApiController{}, "POST:UpdateCert")
beego.Router("/api/add-cert", &controllers.ApiController{}, "POST:AddCert")
beego.Router("/api/delete-cert", &controllers.ApiController{}, "POST:DeleteCert")
beego.Router("/api/get-subscriptions", &controllers.ApiController{}, "GET:GetSubscriptions")
beego.Router("/api/get-subscription", &controllers.ApiController{}, "GET:GetSubscription")
beego.Router("/api/update-subscription", &controllers.ApiController{}, "POST:UpdateSubscription")
beego.Router("/api/add-subscription", &controllers.ApiController{}, "POST:AddSubscription")
beego.Router("/api/delete-subscription", &controllers.ApiController{}, "POST:DeleteSubscription")
beego.Router("/api/get-plans", &controllers.ApiController{}, "GET:GetPlans")
beego.Router("/api/get-plan", &controllers.ApiController{}, "GET:GetPlan")
beego.Router("/api/update-plan", &controllers.ApiController{}, "POST:UpdatePlan")
beego.Router("/api/add-plan", &controllers.ApiController{}, "POST:AddPlan")
beego.Router("/api/delete-plan", &controllers.ApiController{}, "POST:DeletePlan")
beego.Router("/api/get-pricings", &controllers.ApiController{}, "GET:GetPricings")
beego.Router("/api/get-pricing", &controllers.ApiController{}, "GET:GetPricing")
beego.Router("/api/update-pricing", &controllers.ApiController{}, "POST:UpdatePricing")
beego.Router("/api/add-pricing", &controllers.ApiController{}, "POST:AddPricing")
beego.Router("/api/delete-pricing", &controllers.ApiController{}, "POST:DeletePricing")
beego.Router("/api/get-tokens", &controllers.ApiController{}, "GET:GetTokens")
beego.Router("/api/get-token", &controllers.ApiController{}, "GET:GetToken")
beego.Router("/api/update-token", &controllers.ApiController{}, "POST:UpdateToken")
beego.Router("/api/add-token", &controllers.ApiController{}, "POST:AddToken")
beego.Router("/api/delete-token", &controllers.ApiController{}, "POST:DeleteToken")
beego.Router("/api/get-products", &controllers.ApiController{}, "GET:GetProducts")
beego.Router("/api/get-product", &controllers.ApiController{}, "GET:GetProduct")
@@ -244,6 +193,64 @@ func initAPI() {
beego.Router("/api/notify-payment/?:owner/?:payment", &controllers.ApiController{}, "POST:NotifyPayment")
beego.Router("/api/invoice-payment", &controllers.ApiController{}, "POST:InvoicePayment")
beego.Router("/api/get-plans", &controllers.ApiController{}, "GET:GetPlans")
beego.Router("/api/get-plan", &controllers.ApiController{}, "GET:GetPlan")
beego.Router("/api/update-plan", &controllers.ApiController{}, "POST:UpdatePlan")
beego.Router("/api/add-plan", &controllers.ApiController{}, "POST:AddPlan")
beego.Router("/api/delete-plan", &controllers.ApiController{}, "POST:DeletePlan")
beego.Router("/api/get-pricings", &controllers.ApiController{}, "GET:GetPricings")
beego.Router("/api/get-pricing", &controllers.ApiController{}, "GET:GetPricing")
beego.Router("/api/update-pricing", &controllers.ApiController{}, "POST:UpdatePricing")
beego.Router("/api/add-pricing", &controllers.ApiController{}, "POST:AddPricing")
beego.Router("/api/delete-pricing", &controllers.ApiController{}, "POST:DeletePricing")
beego.Router("/api/get-subscriptions", &controllers.ApiController{}, "GET:GetSubscriptions")
beego.Router("/api/get-subscription", &controllers.ApiController{}, "GET:GetSubscription")
beego.Router("/api/update-subscription", &controllers.ApiController{}, "POST:UpdateSubscription")
beego.Router("/api/add-subscription", &controllers.ApiController{}, "POST:AddSubscription")
beego.Router("/api/delete-subscription", &controllers.ApiController{}, "POST:DeleteSubscription")
beego.Router("/api/get-system-info", &controllers.ApiController{}, "GET:GetSystemInfo")
beego.Router("/api/get-version-info", &controllers.ApiController{}, "GET:GetVersionInfo")
beego.Router("/api/health", &controllers.ApiController{}, "GET:Health")
beego.Router("/api/get-prometheus-info", &controllers.ApiController{}, "GET:GetPrometheusInfo")
beego.Handler("/api/metrics", promhttp.Handler())
beego.Router("/api/get-syncers", &controllers.ApiController{}, "GET:GetSyncers")
beego.Router("/api/get-syncer", &controllers.ApiController{}, "GET:GetSyncer")
beego.Router("/api/update-syncer", &controllers.ApiController{}, "POST:UpdateSyncer")
beego.Router("/api/add-syncer", &controllers.ApiController{}, "POST:AddSyncer")
beego.Router("/api/delete-syncer", &controllers.ApiController{}, "POST:DeleteSyncer")
beego.Router("/api/run-syncer", &controllers.ApiController{}, "GET:RunSyncer")
beego.Router("/api/get-webhooks", &controllers.ApiController{}, "GET:GetWebhooks")
beego.Router("/api/get-webhook", &controllers.ApiController{}, "GET:GetWebhook")
beego.Router("/api/update-webhook", &controllers.ApiController{}, "POST:UpdateWebhook")
beego.Router("/api/add-webhook", &controllers.ApiController{}, "POST:AddWebhook")
beego.Router("/api/delete-webhook", &controllers.ApiController{}, "POST:DeleteWebhook")
beego.Router("/api/set-password", &controllers.ApiController{}, "POST:SetPassword")
beego.Router("/api/check-user-password", &controllers.ApiController{}, "POST:CheckUserPassword")
beego.Router("/api/get-email-and-phone", &controllers.ApiController{}, "GET:GetEmailAndPhone")
beego.Router("/api/send-verification-code", &controllers.ApiController{}, "POST:SendVerificationCode")
beego.Router("/api/verify-code", &controllers.ApiController{}, "POST:VerifyCode")
beego.Router("/api/verify-captcha", &controllers.ApiController{}, "POST:VerifyCaptcha")
beego.Router("/api/reset-email-or-phone", &controllers.ApiController{}, "POST:ResetEmailOrPhone")
beego.Router("/api/get-captcha", &controllers.ApiController{}, "GET:GetCaptcha")
beego.Router("/api/get-ldap-users", &controllers.ApiController{}, "GET:GetLdapUsers")
beego.Router("/api/get-ldaps", &controllers.ApiController{}, "GET:GetLdaps")
beego.Router("/api/get-ldap", &controllers.ApiController{}, "GET:GetLdap")
beego.Router("/api/add-ldap", &controllers.ApiController{}, "POST:AddLdap")
beego.Router("/api/update-ldap", &controllers.ApiController{}, "POST:UpdateLdap")
beego.Router("/api/delete-ldap", &controllers.ApiController{}, "POST:DeleteLdap")
beego.Router("/api/sync-ldap-users", &controllers.ApiController{}, "POST:SyncLdapUsers")
beego.Router("/api/login/oauth/access_token", &controllers.ApiController{}, "POST:GetOAuthToken")
beego.Router("/api/login/oauth/refresh_token", &controllers.ApiController{}, "POST:RefreshToken")
beego.Router("/api/login/oauth/introspect", &controllers.ApiController{}, "POST:IntrospectToken")
beego.Router("/api/send-email", &controllers.ApiController{}, "POST:SendEmail")
beego.Router("/api/send-sms", &controllers.ApiController{}, "POST:SendSms")
beego.Router("/api/send-notification", &controllers.ApiController{}, "POST:SendNotification")
@@ -259,13 +266,6 @@ func initAPI() {
beego.Router("/api/delete-mfa", &controllers.ApiController{}, "POST:DeleteMfa")
beego.Router("/api/set-preferred-mfa", &controllers.ApiController{}, "POST:SetPreferredMfa")
beego.Router("/api/get-system-info", &controllers.ApiController{}, "GET:GetSystemInfo")
beego.Router("/api/get-version-info", &controllers.ApiController{}, "GET:GetVersionInfo")
beego.Router("/api/health", &controllers.ApiController{}, "GET:Health")
beego.Router("/api/get-prometheus-info", &controllers.ApiController{}, "GET:GetPrometheusInfo")
beego.Handler("/api/metrics", promhttp.Handler())
beego.Router("/.well-known/openid-configuration", &controllers.RootController{}, "GET:GetOidcDiscovery")
beego.Router("/.well-known/jwks", &controllers.RootController{}, "*:GetJwks")

View File

@@ -811,9 +811,9 @@
],
"responses": {
"200": {
"description": "object",
"description": "The Response object",
"schema": {
"$ref": "#/definitions/Response"
"$ref": "#/definitions/controllers.Response"
}
}
}
@@ -839,9 +839,9 @@
],
"responses": {
"200": {
"description": "object",
"description": "The Response object",
"schema": {
"$ref": "#/definitions/Response"
"$ref": "#/definitions/controllers.Response"
}
}
}
@@ -881,9 +881,9 @@
],
"responses": {
"200": {
"description": "object",
"description": "The Response object",
"schema": {
"$ref": "#/definitions/Response"
"$ref": "#/definitions/controllers.Response"
}
}
}
@@ -935,7 +935,10 @@
"description": "array of casbin requests",
"required": true,
"schema": {
"$ref": "#/definitions/object.CasbinRequest"
"type": "array",
"items": {
"type": "string"
}
}
},
{
@@ -1108,7 +1111,7 @@
"description": "The enforcer object",
"required": true,
"schema": {
"$ref": "#/definitions/object.Enforce"
"$ref": "#/definitions/object.Enforcer"
}
}
],
@@ -1187,9 +1190,9 @@
"operationId": "ApiController.DeleteMfa",
"responses": {
"200": {
"description": "object",
"description": "The Response object",
"schema": {
"$ref": "#/definitions/Response"
"$ref": "#/definitions/controllers.Response"
}
}
}
@@ -1657,7 +1660,10 @@
"description": "Casbin request",
"required": true,
"schema": {
"$ref": "#/definitions/object.CasbinRequest"
"type": "array",
"items": {
"type": "string"
}
}
},
{
@@ -1809,7 +1815,7 @@
"200": {
"description": "The Response object",
"schema": {
"$ref": "#/definitions/Response"
"$ref": "#/definitions/controllers.Response"
}
}
}
@@ -1962,7 +1968,7 @@
"200": {
"description": "The Response object",
"schema": {
"$ref": "#/definitions/Response"
"$ref": "#/definitions/controllers.Response"
}
}
}
@@ -2208,7 +2214,7 @@
"200": {
"description": "The Response object",
"schema": {
"$ref": "#/definitions/LdapResp"
"$ref": "#/definitions/controllers.LdapResp"
}
}
}
@@ -3826,9 +3832,9 @@
"operationId": "ApiController.MfaSetupEnable",
"responses": {
"200": {
"description": "object",
"description": "The Response object",
"schema": {
"$ref": "#/definitions/Response"
"$ref": "#/definitions/controllers.Response"
}
}
}
@@ -3860,9 +3866,9 @@
"operationId": "ApiController.MfaSetupVerify",
"responses": {
"200": {
"description": "object",
"description": "The Response object",
"schema": {
"$ref": "#/definitions/Response"
"$ref": "#/definitions/controllers.Response"
}
}
}
@@ -3996,9 +4002,9 @@
"operationId": "ApiController.SetPreferredMfa",
"responses": {
"200": {
"description": "object",
"description": "The Response object",
"schema": {
"$ref": "#/definitions/Response"
"$ref": "#/definitions/controllers.Response"
}
}
}
@@ -4057,7 +4063,7 @@
"200": {
"description": "The Response object",
"schema": {
"$ref": "#/definitions/LdapSyncResp"
"$ref": "#/definitions/controllers.LdapSyncResp"
}
}
}
@@ -4925,7 +4931,7 @@
"200": {
"description": "The Response object",
"schema": {
"$ref": "#/definitions/LaravelResponse"
"$ref": "#/definitions/controllers.LaravelResponse"
}
}
}
@@ -5131,22 +5137,6 @@
}
},
"definitions": {
"LaravelResponse": {
"title": "LaravelResponse",
"type": "object"
},
"LdapResp": {
"title": "LdapResp",
"type": "object"
},
"LdapSyncResp": {
"title": "LdapSyncResp",
"type": "object"
},
"Response": {
"title": "Response",
"type": "object"
},
"casbin.Enforcer": {
"title": "Enforcer",
"type": "object"
@@ -5179,6 +5169,66 @@
}
}
},
"controllers.LaravelResponse": {
"title": "LaravelResponse",
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"email": {
"type": "string"
},
"email_verified_at": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"controllers.LdapResp": {
"title": "LdapResp",
"type": "object",
"properties": {
"existUuids": {
"type": "array",
"items": {
"type": "string"
}
},
"users": {
"type": "array",
"items": {
"$ref": "#/definitions/object.LdapUser"
}
}
}
},
"controllers.LdapSyncResp": {
"title": "LdapSyncResp",
"type": "object",
"properties": {
"exist": {
"type": "array",
"items": {
"$ref": "#/definitions/object.LdapUser"
}
},
"failed": {
"type": "array",
"items": {
"$ref": "#/definitions/object.LdapUser"
}
}
}
},
"controllers.NotificationForm": {
"title": "NotificationForm",
"type": "object",
@@ -5236,10 +5286,6 @@
}
}
},
"jose.JSONWebKey": {
"title": "JSONWebKey",
"type": "object"
},
"model.Model": {
"title": "Model",
"type": "object"
@@ -5368,6 +5414,14 @@
"type": "integer",
"format": "int64"
},
"failedSigninLimit": {
"type": "integer",
"format": "int64"
},
"failedSigninfrozenTime": {
"type": "integer",
"format": "int64"
},
"forgetUrl": {
"type": "string"
},
@@ -5480,12 +5534,6 @@
}
}
},
"object.CasbinRequest": {
"title": "CasbinRequest",
"type": "array",
"items": {
}
},
"object.Cert": {
"title": "Cert",
"type": "object",
@@ -5527,10 +5575,6 @@
}
}
},
"object.Enforce": {
"title": "Enforce",
"type": "object"
},
"object.Enforcer": {
"title": "Enforcer",
"type": "object",
@@ -5771,6 +5815,66 @@
}
}
},
"object.LdapUser": {
"title": "LdapUser",
"type": "object",
"properties": {
"EmailAddress": {
"type": "string"
},
"Mail": {
"type": "string"
},
"MobileTelephoneNumber": {
"type": "string"
},
"PostalAddress": {
"type": "string"
},
"RegisteredAddress": {
"type": "string"
},
"TelephoneNumber": {
"type": "string"
},
"address": {
"type": "string"
},
"cn": {
"type": "string"
},
"displayName": {
"type": "string"
},
"email": {
"type": "string"
},
"gidNumber": {
"type": "string"
},
"groupId": {
"type": "string"
},
"memberOf": {
"type": "string"
},
"mobile": {
"type": "string"
},
"uid": {
"type": "string"
},
"uidNumber": {
"type": "string"
},
"userPrincipalName": {
"type": "string"
},
"uuid": {
"type": "string"
}
}
},
"object.ManagedAccount": {
"title": "ManagedAccount",
"type": "object",
@@ -7529,22 +7633,6 @@
],
"example": "Paid"
},
"protocol.CredentialAssertion": {
"title": "CredentialAssertion",
"type": "object"
},
"protocol.CredentialAssertionResponse": {
"title": "CredentialAssertionResponse",
"type": "object"
},
"protocol.CredentialCreation": {
"title": "CredentialCreation",
"type": "object"
},
"protocol.CredentialCreationResponse": {
"title": "CredentialCreationResponse",
"type": "object"
},
"util.SystemInfo": {
"title": "SystemInfo",
"type": "object",

View File

@@ -525,9 +525,9 @@ paths:
$ref: '#/definitions/controllers.EmailForm'
responses:
"200":
description: object
description: The Response object
schema:
$ref: '#/definitions/Response'
$ref: '#/definitions/controllers.Response'
/api/api/send-notification:
post:
tags:
@@ -543,9 +543,9 @@ paths:
$ref: '#/definitions/controllers.NotificationForm'
responses:
"200":
description: object
description: The Response object
schema:
$ref: '#/definitions/Response'
$ref: '#/definitions/controllers.Response'
/api/api/send-sms:
post:
tags:
@@ -571,9 +571,9 @@ paths:
$ref: '#/definitions/controllers.SmsForm'
responses:
"200":
description: object
description: The Response object
schema:
$ref: '#/definitions/Response'
$ref: '#/definitions/controllers.Response'
/api/api/verify-code:
post:
tags:
@@ -606,7 +606,9 @@ paths:
description: array of casbin requests
required: true
schema:
$ref: '#/definitions/object.CasbinRequest'
type: array
items:
type: string
- in: query
name: permissionId
description: permission id
@@ -718,7 +720,7 @@ paths:
description: The enforcer object
required: true
schema:
$ref: '#/definitions/object.Enforce'
$ref: '#/definitions/object.Enforcer'
responses:
"200":
description: ""
@@ -768,9 +770,9 @@ paths:
operationId: ApiController.DeleteMfa
responses:
"200":
description: object
description: The Response object
schema:
$ref: '#/definitions/Response'
$ref: '#/definitions/controllers.Response'
/api/delete-model:
post:
tags:
@@ -1071,7 +1073,9 @@ paths:
description: Casbin request
required: true
schema:
$ref: '#/definitions/object.CasbinRequest'
type: array
items:
type: string
- in: query
name: permissionId
description: permission id
@@ -1172,7 +1176,7 @@ paths:
"200":
description: The Response object
schema:
$ref: '#/definitions/Response'
$ref: '#/definitions/controllers.Response'
/api/get-application:
get:
tags:
@@ -1272,7 +1276,7 @@ paths:
"200":
description: The Response object
schema:
$ref: '#/definitions/Response'
$ref: '#/definitions/controllers.Response'
/api/get-email-and-phone:
get:
tags:
@@ -1433,7 +1437,7 @@ paths:
"200":
description: The Response object
schema:
$ref: '#/definitions/LdapResp'
$ref: '#/definitions/controllers.LdapResp'
/api/get-ldaps:
get:
tags:
@@ -2496,9 +2500,9 @@ paths:
operationId: ApiController.MfaSetupEnable
responses:
"200":
description: object
description: The Response object
schema:
$ref: '#/definitions/Response'
$ref: '#/definitions/controllers.Response'
/api/mfa/setup/initiate:
post:
tags:
@@ -2518,9 +2522,9 @@ paths:
operationId: ApiController.MfaSetupVerify
responses:
"200":
description: object
description: The Response object
schema:
$ref: '#/definitions/Response'
$ref: '#/definitions/controllers.Response'
/api/notify-payment:
post:
tags:
@@ -2607,9 +2611,9 @@ paths:
operationId: ApiController.SetPreferredMfa
responses:
"200":
description: object
description: The Response object
schema:
$ref: '#/definitions/Response'
$ref: '#/definitions/controllers.Response'
/api/signup:
post:
tags:
@@ -2648,7 +2652,7 @@ paths:
"200":
description: The Response object
schema:
$ref: '#/definitions/LdapSyncResp'
$ref: '#/definitions/controllers.LdapSyncResp'
/api/unlink:
post:
tags:
@@ -3219,7 +3223,7 @@ paths:
"200":
description: The Response object
schema:
$ref: '#/definitions/LaravelResponse'
$ref: '#/definitions/controllers.LaravelResponse'
/api/userinfo:
get:
tags:
@@ -3351,18 +3355,6 @@ paths:
schema:
$ref: '#/definitions/object.TokenError'
definitions:
LaravelResponse:
title: LaravelResponse
type: object
LdapResp:
title: LdapResp
type: object
LdapSyncResp:
title: LdapSyncResp
type: object
Response:
title: Response
type: object
casbin.Enforcer:
title: Enforcer
type: object
@@ -3385,6 +3377,46 @@ definitions:
type: string
title:
type: string
controllers.LaravelResponse:
title: LaravelResponse
type: object
properties:
created_at:
type: string
email:
type: string
email_verified_at:
type: string
id:
type: string
name:
type: string
updated_at:
type: string
controllers.LdapResp:
title: LdapResp
type: object
properties:
existUuids:
type: array
items:
type: string
users:
type: array
items:
$ref: '#/definitions/object.LdapUser'
controllers.LdapSyncResp:
title: LdapSyncResp
type: object
properties:
exist:
type: array
items:
$ref: '#/definitions/object.LdapUser'
failed:
type: array
items:
$ref: '#/definitions/object.LdapUser'
controllers.NotificationForm:
title: NotificationForm
type: object
@@ -3514,6 +3546,12 @@ definitions:
expireInHours:
type: integer
format: int64
failedSigninLimit:
type: integer
format: int64
failedSigninfrozenTime:
type: integer
format: int64
forgetUrl:
type: string
formBackgroundUrl:
@@ -3588,11 +3626,6 @@ definitions:
$ref: '#/definitions/object.ThemeData'
tokenFormat:
type: string
object.CasbinRequest:
title: CasbinRequest
type: array
items:
$ref: '#/definitions/object.CasbinRequest'
object.Cert:
title: Cert
type: object
@@ -3621,9 +3654,6 @@ definitions:
type: string
type:
type: string
object.Enforce:
title: Enforce
type: object
object.Enforcer:
title: Enforcer
type: object
@@ -3786,6 +3816,46 @@ definitions:
type: string
username:
type: string
object.LdapUser:
title: LdapUser
type: object
properties:
EmailAddress:
type: string
Mail:
type: string
MobileTelephoneNumber:
type: string
PostalAddress:
type: string
RegisteredAddress:
type: string
TelephoneNumber:
type: string
address:
type: string
cn:
type: string
displayName:
type: string
email:
type: string
gidNumber:
type: string
groupId:
type: string
memberOf:
type: string
mobile:
type: string
uid:
type: string
uidNumber:
type: string
userPrincipalName:
type: string
uuid:
type: string
object.ManagedAccount:
title: ManagedAccount
type: object

View File

@@ -72,7 +72,15 @@ func GetUrlPath(urlString string) string {
}
func GetUrlHost(urlString string) string {
u, _ := url.Parse(urlString)
if urlString == "" {
return ""
}
u, err := url.Parse(urlString)
if err != nil {
return err.Error()
}
return fmt.Sprintf("%s://%s", u.Scheme, u.Host)
}

View File

@@ -322,3 +322,23 @@ func GetUsernameFromEmail(email string) string {
return tokens[0]
}
}
func StringToInterfaceArray(array []string) []interface{} {
var interfaceArray []interface{}
for _, v := range array {
interfaceArray = append(interfaceArray, v)
}
return interfaceArray
}
func StringToInterfaceArray2d(arrays [][]string) [][]interface{} {
var interfaceArrays [][]interface{}
for _, req := range arrays {
var interfaceArray []interface{}
for _, r := range req {
interfaceArray = append(interfaceArray, r)
}
interfaceArrays = append(interfaceArrays, interfaceArray)
}
return interfaceArrays
}

View File

@@ -15,62 +15,62 @@
import React, {Component} from "react";
import "./App.less";
import {Helmet} from "react-helmet";
import Dashboard from "./basic/Dashboard";
import ShortcutsPage from "./basic/ShortcutsPage";
import * as Setting from "./Setting";
import {StyleProvider, legacyLogicalPropertiesTransformer} from "@ant-design/cssinjs";
import {AppstoreTwoTone, BarsOutlined, DeploymentUnitOutlined, DollarTwoTone, DownOutlined, GithubOutlined, HomeTwoTone, InfoCircleFilled, LockTwoTone, LogoutOutlined, SafetyCertificateTwoTone, SettingOutlined, SettingTwoTone, ShareAltOutlined, WalletTwoTone} from "@ant-design/icons";
import {Alert, Avatar, Button, Card, ConfigProvider, Drawer, Dropdown, FloatButton, Layout, Menu, Result, Tooltip} from "antd";
import {Link, Redirect, Route, Switch, withRouter} from "react-router-dom";
import AccountPage from "./account/AccountPage";
import Dashboard from "./basic/Dashboard";
import ShortcutsPage from "./basic/ShortcutsPage";
import AppListPage from "./basic/AppListPage";
import OrganizationListPage from "./OrganizationListPage";
import OrganizationEditPage from "./OrganizationEditPage";
import GroupEditPage from "./GroupEdit";
import GroupListPage from "./GroupList";
import GroupTreePage from "./GroupTreePage";
import UserListPage from "./UserListPage";
import UserEditPage from "./UserEditPage";
import ApplicationListPage from "./ApplicationListPage";
import ApplicationEditPage from "./ApplicationEditPage";
import ProviderListPage from "./ProviderListPage";
import ProviderEditPage from "./ProviderEditPage";
import ResourceListPage from "./ResourceListPage";
import CertListPage from "./CertListPage";
import CertEditPage from "./CertEditPage";
import RoleListPage from "./RoleListPage";
import RoleEditPage from "./RoleEditPage";
import PermissionListPage from "./PermissionListPage";
import PermissionEditPage from "./PermissionEditPage";
import ModelListPage from "./ModelListPage";
import ModelEditPage from "./ModelEditPage";
import AdapterListPage from "./AdapterListPage";
import AdapterEditPage from "./AdapterEditPage";
import EnforcerEditPage from "./EnforcerEditPage";
import EnforcerListPage from "./EnforcerListPage";
import GroupTreePage from "./GroupTreePage";
import GroupEditPage from "./GroupEdit";
import GroupListPage from "./GroupList";
import ProviderListPage from "./ProviderListPage";
import ProviderEditPage from "./ProviderEditPage";
import ApplicationListPage from "./ApplicationListPage";
import ApplicationEditPage from "./ApplicationEditPage";
import ResourceListPage from "./ResourceListPage";
import LdapEditPage from "./LdapEditPage";
import LdapSyncPage from "./LdapSyncPage";
import SessionListPage from "./SessionListPage";
import TokenListPage from "./TokenListPage";
import TokenEditPage from "./TokenEditPage";
import WebhookListPage from "./WebhookListPage";
import WebhookEditPage from "./WebhookEditPage";
import SyncerListPage from "./SyncerListPage";
import SyncerEditPage from "./SyncerEditPage";
import CertListPage from "./CertListPage";
import CertEditPage from "./CertEditPage";
import SubscriptionListPage from "./SubscriptionListPage";
import SubscriptionEditPage from "./SubscriptionEditPage";
import PricingListPage from "./PricingListPage";
import PricingEditPage from "./PricingEditPage";
import PlanListPage from "./PlanListPage";
import PlanEditPage from "./PlanEditPage";
import ProductListPage from "./ProductListPage";
import ProductEditPage from "./ProductEditPage";
import ProductBuyPage from "./ProductBuyPage";
import PaymentListPage from "./PaymentListPage";
import PaymentEditPage from "./PaymentEditPage";
import PaymentResultPage from "./PaymentResultPage";
import ModelListPage from "./ModelListPage";
import ModelEditPage from "./ModelEditPage";
import AdapterListPage from "./AdapterListPage";
import AdapterEditPage from "./AdapterEditPage";
import SessionListPage from "./SessionListPage";
import MfaSetupPage from "./auth/MfaSetupPage";
import PricingListPage from "./PricingListPage";
import PricingEditPage from "./PricingEditPage";
import PlanListPage from "./PlanListPage";
import PlanEditPage from "./PlanEditPage";
import SubscriptionListPage from "./SubscriptionListPage";
import SubscriptionEditPage from "./SubscriptionEditPage";
import SystemInfo from "./SystemInfo";
import AccountPage from "./account/AccountPage";
import AppListPage from "./basic/AppListPage";
import SyncerListPage from "./SyncerListPage";
import SyncerEditPage from "./SyncerEditPage";
import WebhookListPage from "./WebhookListPage";
import WebhookEditPage from "./WebhookEditPage";
import LdapEditPage from "./LdapEditPage";
import LdapSyncPage from "./LdapSyncPage";
import MfaSetupPage from "./auth/MfaSetupPage";
import CustomGithubCorner from "./common/CustomGithubCorner";
import * as Conf from "./Conf";
@@ -514,48 +514,47 @@ class App extends Component {
<Route exact path="/groups/:organizationName/:groupName" render={(props) => this.renderLoginIfNotLoggedIn(<GroupEditPage account={this.state.account} {...props} />)} />
<Route exact path="/users" render={(props) => this.renderLoginIfNotLoggedIn(<UserListPage account={this.state.account} {...props} />)} />
<Route exact path="/users/:organizationName/:userName" render={(props) => <UserEditPage account={this.state.account} {...props} />} />
<Route exact path="/applications" render={(props) => this.renderLoginIfNotLoggedIn(<ApplicationListPage account={this.state.account} {...props} />)} />
<Route exact path="/applications/:organizationName/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<ApplicationEditPage account={this.state.account} {...props} />)} />
<Route exact path="/providers" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderListPage account={this.state.account} {...props} />)} />
<Route exact path="/providers/:organizationName/:providerName" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderEditPage account={this.state.account} {...props} />)} />
<Route exact path="/resources" render={(props) => this.renderLoginIfNotLoggedIn(<ResourceListPage account={this.state.account} {...props} />)} />
<Route exact path="/certs" render={(props) => this.renderLoginIfNotLoggedIn(<CertListPage account={this.state.account} {...props} />)} />
<Route exact path="/certs/:organizationName/:certName" render={(props) => this.renderLoginIfNotLoggedIn(<CertEditPage account={this.state.account} {...props} />)} />
<Route exact path="/roles" render={(props) => this.renderLoginIfNotLoggedIn(<RoleListPage account={this.state.account} {...props} />)} />
<Route exact path="/roles/:organizationName/:roleName" render={(props) => this.renderLoginIfNotLoggedIn(<RoleEditPage account={this.state.account} {...props} />)} />
<Route exact path="/permissions" render={(props) => this.renderLoginIfNotLoggedIn(<PermissionListPage account={this.state.account} {...props} />)} />
<Route exact path="/permissions/:organizationName/:permissionName" render={(props) => this.renderLoginIfNotLoggedIn(<PermissionEditPage account={this.state.account} {...props} />)} />
<Route exact path="/models" render={(props) => this.renderLoginIfNotLoggedIn(<ModelListPage account={this.state.account} {...props} />)} />
<Route exact path="/models/:organizationName/:modelName" render={(props) => this.renderLoginIfNotLoggedIn(<ModelEditPage account={this.state.account} {...props} />)} />
<Route exact path="/enforcers" render={(props) => this.renderLoginIfNotLoggedIn(<EnforcerListPage account={this.state.account} {...props} />)} />
<Route exact path="/enforcers/:organizationName/:enforcerName" render={(props) => this.renderLoginIfNotLoggedIn(<EnforcerEditPage account={this.state.account} {...props} />)} />
<Route exact path="/adapters" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterListPage account={this.state.account} {...props} />)} />
<Route exact path="/adapters/:organizationName/:adapterName" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterEditPage account={this.state.account} {...props} />)} />
<Route exact path="/providers" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderListPage account={this.state.account} {...props} />)} />
<Route exact path="/providers/:organizationName/:providerName" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderEditPage account={this.state.account} {...props} />)} />
<Route exact path="/applications" render={(props) => this.renderLoginIfNotLoggedIn(<ApplicationListPage account={this.state.account} {...props} />)} />
<Route exact path="/applications/:organizationName/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<ApplicationEditPage account={this.state.account} {...props} />)} />
<Route exact path="/resources" render={(props) => this.renderLoginIfNotLoggedIn(<ResourceListPage account={this.state.account} {...props} />)} />
{/* <Route exact path="/resources/:resourceName" render={(props) => this.renderLoginIfNotLoggedIn(<ResourceEditPage account={this.state.account} {...props} />)}/>*/}
<Route exact path="/ldap/:organizationName/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapEditPage account={this.state.account} {...props} />)} />
<Route exact path="/ldap/sync/:organizationName/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapSyncPage account={this.state.account} {...props} />)} />
<Route exact path="/tokens" render={(props) => this.renderLoginIfNotLoggedIn(<TokenListPage account={this.state.account} {...props} />)} />
<Route exact path="/enforcers" render={(props) => this.renderLoginIfNotLoggedIn(<EnforcerListPage account={this.state.account} {...props} />)} />
<Route exact path="/enforcers/:organizationName/:enforcerName" render={(props) => this.renderLoginIfNotLoggedIn(<EnforcerEditPage account={this.state.account} {...props} />)} />
<Route exact path="/sessions" render={(props) => this.renderLoginIfNotLoggedIn(<SessionListPage account={this.state.account} {...props} />)} />
<Route exact path="/tokens" render={(props) => this.renderLoginIfNotLoggedIn(<TokenListPage account={this.state.account} {...props} />)} />
<Route exact path="/tokens/:tokenName" render={(props) => this.renderLoginIfNotLoggedIn(<TokenEditPage account={this.state.account} {...props} />)} />
<Route exact path="/webhooks" render={(props) => this.renderLoginIfNotLoggedIn(<WebhookListPage account={this.state.account} {...props} />)} />
<Route exact path="/webhooks/:webhookName" render={(props) => this.renderLoginIfNotLoggedIn(<WebhookEditPage account={this.state.account} {...props} />)} />
<Route exact path="/syncers" render={(props) => this.renderLoginIfNotLoggedIn(<SyncerListPage account={this.state.account} {...props} />)} />
<Route exact path="/syncers/:syncerName" render={(props) => this.renderLoginIfNotLoggedIn(<SyncerEditPage account={this.state.account} {...props} />)} />
<Route exact path="/certs" render={(props) => this.renderLoginIfNotLoggedIn(<CertListPage account={this.state.account} {...props} />)} />
<Route exact path="/certs/:organizationName/:certName" render={(props) => this.renderLoginIfNotLoggedIn(<CertEditPage account={this.state.account} {...props} />)} />
<Route exact path="/plans" render={(props) => this.renderLoginIfNotLoggedIn(<PlanListPage account={this.state.account} {...props} />)} />
<Route exact path="/plans/:organizationName/:planName" render={(props) => this.renderLoginIfNotLoggedIn(<PlanEditPage account={this.state.account} {...props} />)} />
<Route exact path="/pricings" render={(props) => this.renderLoginIfNotLoggedIn(<PricingListPage account={this.state.account} {...props} />)} />
<Route exact path="/pricings/:organizationName/:pricingName" render={(props) => this.renderLoginIfNotLoggedIn(<PricingEditPage account={this.state.account} {...props} />)} />
<Route exact path="/subscriptions" render={(props) => this.renderLoginIfNotLoggedIn(<SubscriptionListPage account={this.state.account} {...props} />)} />
<Route exact path="/subscriptions/:organizationName/:subscriptionName" render={(props) => this.renderLoginIfNotLoggedIn(<SubscriptionEditPage account={this.state.account} {...props} />)} />
<Route exact path="/products" render={(props) => this.renderLoginIfNotLoggedIn(<ProductListPage account={this.state.account} {...props} />)} />
<Route exact path="/products/:organizationName/:productName" render={(props) => this.renderLoginIfNotLoggedIn(<ProductEditPage account={this.state.account} {...props} />)} />
<Route exact path="/products/:organizationName/:productName/buy" render={(props) => this.renderLoginIfNotLoggedIn(<ProductBuyPage account={this.state.account} {...props} />)} />
<Route exact path="/payments" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentListPage account={this.state.account} {...props} />)} />
<Route exact path="/payments/:organizationName/:paymentName" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentEditPage account={this.state.account} {...props} />)} />
<Route exact path="/payments/:organizationName/:paymentName/result" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentResultPage account={this.state.account} {...props} />)} />
<Route exact path="/plans" render={(props) => this.renderLoginIfNotLoggedIn(<PlanListPage account={this.state.account} {...props} />)} />
<Route exact path="/plans/:organizationName/:planName" render={(props) => this.renderLoginIfNotLoggedIn(<PlanEditPage account={this.state.account} {...props} />)} />
<Route exact path="/pricings" render={(props) => this.renderLoginIfNotLoggedIn(<PricingListPage account={this.state.account} {...props} />)} />
<Route exact path="/pricings/:organizationName/:pricingName" render={(props) => this.renderLoginIfNotLoggedIn(<PricingEditPage account={this.state.account} {...props} />)} />
<Route exact path="/subscriptions" render={(props) => this.renderLoginIfNotLoggedIn(<SubscriptionListPage account={this.state.account} {...props} />)} />
<Route exact path="/subscriptions/:organizationName/:subscriptionName" render={(props) => this.renderLoginIfNotLoggedIn(<SubscriptionEditPage account={this.state.account} {...props} />)} />
<Route exact path="/sysinfo" render={(props) => this.renderLoginIfNotLoggedIn(<SystemInfo account={this.state.account} {...props} />)} />
<Route exact path="/syncers" render={(props) => this.renderLoginIfNotLoggedIn(<SyncerListPage account={this.state.account} {...props} />)} />
<Route exact path="/syncers/:syncerName" render={(props) => this.renderLoginIfNotLoggedIn(<SyncerEditPage account={this.state.account} {...props} />)} />
<Route exact path="/webhooks" render={(props) => this.renderLoginIfNotLoggedIn(<WebhookListPage account={this.state.account} {...props} />)} />
<Route exact path="/webhooks/:webhookName" render={(props) => this.renderLoginIfNotLoggedIn(<WebhookEditPage account={this.state.account} {...props} />)} />
<Route exact path="/ldap/:organizationName/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapEditPage account={this.state.account} {...props} />)} />
<Route exact path="/ldap/sync/:organizationName/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapSyncPage account={this.state.account} {...props} />)} />
<Route exact path="/mfa/setup" render={(props) => this.renderLoginIfNotLoggedIn(<MfaSetupPage account={this.state.account} onfinish={() => this.setState({requiredEnableMfa: false})} {...props} />)} />
<Route exact path="/.well-known/openid-configuration" render={(props) => <OdicDiscoveryPage />} />
<Route exact path="/sysinfo" render={(props) => this.renderLoginIfNotLoggedIn(<SystemInfo account={this.state.account} {...props} />)} />
<Route path="" render={() => <Result status="404" title="404 NOT FOUND" subTitle={i18next.t("general:Sorry, the page you visited does not exist.")}
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>} />} />
</Switch>

View File

@@ -29,6 +29,14 @@ import {CaptchaPreview} from "./common/CaptchaPreview";
import {CountryCodeSelect} from "./common/select/CountryCodeSelect";
import * as Web3Auth from "./auth/Web3Auth";
import {Controlled as CodeMirror} from "react-codemirror2";
import "codemirror/lib/codemirror.css";
require("codemirror/theme/material-darker.css");
require("codemirror/mode/htmlmixed/htmlmixed");
require("codemirror/mode/xml/xml");
require("codemirror/mode/css/css");
const {Option} = Select;
const {TextArea} = Input;
@@ -480,7 +488,7 @@ class ProviderEditPage extends React.Component {
this.updateProviderField("port", 465);
this.updateProviderField("disableSsl", false);
this.updateProviderField("title", "Casdoor Verification Code");
this.updateProviderField("content", "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes.");
this.updateProviderField("content", Setting.getDefaultHtmlEmailContent());
this.updateProviderField("receiver", this.props.account.email);
} else if (value === "SMS") {
this.updateProviderField("type", "Twilio SMS");
@@ -966,22 +974,47 @@ class ProviderEditPage extends React.Component {
{Setting.getLabel(i18next.t("provider:Email content"), i18next.t("provider:Email content - Tooltip"))} :
</Col>
<Col span={22} >
<TextArea autoSize={{minRows: 3, maxRows: 100}} value={this.state.provider.content} onChange={e => {
this.updateProviderField("content", e.target.value);
}} />
<Row style={{marginTop: "20px"}} >
<Button style={{marginLeft: "10px", marginBottom: "5px"}} onClick={() => this.updateProviderField("content", "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes.")} >
{i18next.t("provider:Reset to Default Text")}
</Button>
<Button style={{marginLeft: "10px", marginBottom: "5px"}} type="primary" onClick={() => this.updateProviderField("content", Setting.getDefaultHtmlEmailContent())} >
{i18next.t("provider:Reset to Default HTML")}
</Button>
</Row>
<Row>
<Col span={Setting.isMobile() ? 22 : 11}>
<div style={{height: "300px", margin: "10px"}}>
<CodeMirror
value={this.state.provider.content}
options={{mode: "htmlmixed", theme: "material-darker"}}
onBeforeChange={(editor, data, value) => {
this.updateProviderField("content", value);
}}
/>
</div>
</Col>
<Col span={1} />
<Col span={Setting.isMobile() ? 22 : 11}>
<div style={{margin: "10px"}}>
<div dangerouslySetInnerHTML={{__html: this.state.provider.content.replace("%s", "123456").replace("%{user.friendlyName}", Setting.getFriendlyUserName(this.props.account))}} />
</div>
</Col>
</Row>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Row style={{marginTop: "20px"}}>
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("provider:Test Email"), i18next.t("provider:Test Email - Tooltip"))} :
</Col>
<Col span={4} >
<Input value={this.state.provider.receiver} placeholder = {i18next.t("user:Input your email")} onChange={e => {
this.updateProviderField("receiver", e.target.value);
}} />
<Col span={4}>
<Input value={this.state.provider.receiver} placeholder={i18next.t("user:Input your email")}
onChange={e => {
this.updateProviderField("receiver", e.target.value);
}} />
</Col>
{["Azure ACS"].includes(this.state.provider.type) ? null : (
<Button style={{marginLeft: "10px", marginBottom: "5px"}} type="primary" onClick={() => ProviderEditTestEmail.connectSmtpServer(this.state.provider)} >
<Button style={{marginLeft: "10px", marginBottom: "5px"}} onClick={() => ProviderEditTestEmail.connectSmtpServer(this.state.provider)} >
{i18next.t("provider:Test SMTP Connection")}
</Button>
)}

View File

@@ -1405,3 +1405,53 @@ export function getCurrencySymbol(currency) {
return currency;
}
}
export function getFriendlyUserName(account) {
if (account.firstName !== "" && account.lastName !== "") {
return `${account.firstName}, ${account.lastName}`;
} else if (account.displayName !== "") {
return account.displayName;
} else if (account.name !== "") {
return account.name;
} else {
return account.id;
}
}
export function getDefaultHtmlEmailContent() {
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Verification Code Email</title>
<style>
body { font-family: Arial, sans-serif; }
.email-container { width: 600px; margin: 0 auto; }
.header { text-align: center; }
.code { font-size: 24px; margin: 20px 0; text-align: center; }
.footer { font-size: 12px; text-align: center; margin-top: 50px; }
.footer a { color: #000; text-decoration: none; }
</style>
</head>
<body>
<div class="email-container">
<div class="header">
<h3>Casbin Organization</h3>
<img src="https://cdn.casbin.org/img/casdoor-logo_1185x256.png" alt="Casdoor Logo" width="300">
</div>
<p><strong>%{user.friendlyName}</strong>, here is your verification code</p>
<p>Use this code for your transaction. It's valid for 5 minutes</p>
<div class="code">
%s
</div>
<p>Thanks</p>
<p>Casbin Team</p>
<hr>
<div class="footer">
<p>Casdoor is a brand operated by Casbin organization. For more info please refer to <a href="https://casdoor.org">https://casdoor.org</a></p>
</div>
</div>
</body>
</html>`;
}

View File

@@ -33,7 +33,7 @@ export function connectSmtpServer(provider) {
testEmailProvider(provider)
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", "provider:SMTP connected successfully");
Setting.showMessage("success", i18next.t("provider:SMTP connected successfully"));
} else {
Setting.showMessage("error", res.msg);
}