mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-04 13:20:19 +08:00
feat: add Internet-Only captcha rule (#3919)
This commit is contained in:
@ -555,8 +555,11 @@ func (c *ApiController) Login() {
|
|||||||
c.ResponseError(c.T("auth:The login method: login with LDAP is not enabled for the application"))
|
c.ResponseError(c.T("auth:The login method: login with LDAP is not enabled for the application"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientIp := util.GetClientIpFromRequest(c.Ctx.Request)
|
||||||
|
|
||||||
var enableCaptcha bool
|
var enableCaptcha bool
|
||||||
if enableCaptcha, err = object.CheckToEnableCaptcha(application, authForm.Organization, authForm.Username); err != nil {
|
if enableCaptcha, err = object.CheckToEnableCaptcha(application, authForm.Organization, authForm.Username, clientIp); err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
} else if enableCaptcha {
|
} else if enableCaptcha {
|
||||||
@ -1222,27 +1225,26 @@ func (c *ApiController) GetQRCode() {
|
|||||||
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")
|
||||||
user, err := object.GetUserByFields(organization, userId)
|
applicationName := c.Input().Get("application")
|
||||||
|
|
||||||
|
application, err := object.GetApplication(fmt.Sprintf("admin/%s", applicationName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if application == nil {
|
||||||
captchaEnabled := false
|
c.ResponseError("application not found")
|
||||||
if user != nil {
|
return
|
||||||
var failedSigninLimit int
|
|
||||||
failedSigninLimit, _, err = object.GetFailedSigninConfigByUser(user)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if user.SigninWrongTimes >= failedSigninLimit {
|
|
||||||
captchaEnabled = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientIp := util.GetClientIpFromRequest(c.Ctx.Request)
|
||||||
|
captchaEnabled, err := object.CheckToEnableCaptcha(application, organization, userId, clientIp)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
c.ResponseOk(captchaEnabled)
|
c.ResponseOk(captchaEnabled)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback
|
// Callback
|
||||||
|
@ -593,7 +593,7 @@ func CheckUpdateUser(oldUser, user *User, lang string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckToEnableCaptcha(application *Application, organization, username string) (bool, error) {
|
func CheckToEnableCaptcha(application *Application, organization, username string, clientIp string) (bool, error) {
|
||||||
if len(application.Providers) == 0 {
|
if len(application.Providers) == 0 {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
@ -603,6 +603,12 @@ func CheckToEnableCaptcha(application *Application, organization, username strin
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if providerItem.Rule == "Internet-Only" {
|
||||||
|
if util.IsInternetIp(clientIp) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if providerItem.Rule == "Dynamic" {
|
if providerItem.Rule == "Dynamic" {
|
||||||
user, err := GetUserByFields(organization, username)
|
user, err := GetUserByFields(organization, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -185,17 +185,3 @@ func removePort(s string) string {
|
|||||||
}
|
}
|
||||||
return ipStr
|
return ipStr
|
||||||
}
|
}
|
||||||
|
|
||||||
func isHostIntranet(s string) bool {
|
|
||||||
ipStr, _, err := net.SplitHostPort(s)
|
|
||||||
if err != nil {
|
|
||||||
ipStr = s
|
|
||||||
}
|
|
||||||
|
|
||||||
ip := net.ParseIP(ipStr)
|
|
||||||
if ip == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast()
|
|
||||||
}
|
|
||||||
|
@ -83,7 +83,7 @@ func CorsFilter(ctx *context.Context) {
|
|||||||
setCorsHeaders(ctx, origin)
|
setCorsHeaders(ctx, origin)
|
||||||
} else if originHostname == host {
|
} else if originHostname == host {
|
||||||
setCorsHeaders(ctx, origin)
|
setCorsHeaders(ctx, origin)
|
||||||
} else if isHostIntranet(host) {
|
} else if util.IsHostIntranet(host) {
|
||||||
setCorsHeaders(ctx, origin)
|
setCorsHeaders(ctx, origin)
|
||||||
} else {
|
} else {
|
||||||
ok, err := object.IsOriginAllowed(origin)
|
ok, err := object.IsOriginAllowed(origin)
|
||||||
|
47
util/network.go
Normal file
47
util/network.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2025 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func IsInternetIp(ip string) bool {
|
||||||
|
ipStr, _, err := net.SplitHostPort(ip)
|
||||||
|
if err != nil {
|
||||||
|
ipStr = ip
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedIP := net.ParseIP(ipStr)
|
||||||
|
if parsedIP == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return !parsedIP.IsPrivate() && !parsedIP.IsLoopback() && !parsedIP.IsMulticast() && !parsedIP.IsUnspecified()
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsHostIntranet(ip string) bool {
|
||||||
|
ipStr, _, err := net.SplitHostPort(ip)
|
||||||
|
if err != nil {
|
||||||
|
ipStr = ip
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedIP := net.ParseIP(ipStr)
|
||||||
|
if parsedIP == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedIP.IsPrivate() || parsedIP.IsLoopback() || parsedIP.IsLinkLocalUnicast() || parsedIP.IsLinkLocalMulticast()
|
||||||
|
}
|
@ -163,7 +163,7 @@ export function getWechatQRCode(providerId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getCaptchaStatus(values) {
|
export function getCaptchaStatus(values) {
|
||||||
return fetch(`${Setting.ServerUrl}/api/get-captcha-status?organization=${values["organization"]}&userId=${values["username"]}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-captcha-status?organization=${values["organization"]}&userId=${values["username"]}&application=${values["application"]}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -134,6 +134,8 @@ class LoginPage extends React.Component {
|
|||||||
return CaptchaRule.Always;
|
return CaptchaRule.Always;
|
||||||
} else if (captchaProviderItems.some(providerItem => providerItem.rule === "Dynamic")) {
|
} else if (captchaProviderItems.some(providerItem => providerItem.rule === "Dynamic")) {
|
||||||
return CaptchaRule.Dynamic;
|
return CaptchaRule.Dynamic;
|
||||||
|
} else if (captchaProviderItems.some(providerItem => providerItem.rule === "Internet-Only")) {
|
||||||
|
return CaptchaRule.InternetOnly;
|
||||||
} else {
|
} else {
|
||||||
return CaptchaRule.Never;
|
return CaptchaRule.Never;
|
||||||
}
|
}
|
||||||
@ -443,6 +445,9 @@ class LoginPage extends React.Component {
|
|||||||
} else if (captchaRule === CaptchaRule.Dynamic) {
|
} else if (captchaRule === CaptchaRule.Dynamic) {
|
||||||
this.checkCaptchaStatus(values);
|
this.checkCaptchaStatus(values);
|
||||||
return;
|
return;
|
||||||
|
} else if (captchaRule === CaptchaRule.InternetOnly) {
|
||||||
|
this.checkCaptchaStatus(values);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.login(values);
|
this.login(values);
|
||||||
@ -961,9 +966,23 @@ class LoginPage extends React.Component {
|
|||||||
const captchaProviderItems = this.getCaptchaProviderItems(application);
|
const captchaProviderItems = this.getCaptchaProviderItems(application);
|
||||||
const alwaysProviderItems = captchaProviderItems.filter(providerItem => providerItem.rule === "Always");
|
const alwaysProviderItems = captchaProviderItems.filter(providerItem => providerItem.rule === "Always");
|
||||||
const dynamicProviderItems = captchaProviderItems.filter(providerItem => providerItem.rule === "Dynamic");
|
const dynamicProviderItems = captchaProviderItems.filter(providerItem => providerItem.rule === "Dynamic");
|
||||||
const provider = alwaysProviderItems.length > 0
|
const internetOnlyProviderItems = captchaProviderItems.filter(providerItem => providerItem.rule === "Internet-Only");
|
||||||
? alwaysProviderItems[0].provider
|
|
||||||
: dynamicProviderItems[0].provider;
|
// Select provider based on the active captcha rule, not fixed priority
|
||||||
|
const captchaRule = this.getCaptchaRule(this.getApplicationObj());
|
||||||
|
let provider = null;
|
||||||
|
|
||||||
|
if (captchaRule === CaptchaRule.Always && alwaysProviderItems.length > 0) {
|
||||||
|
provider = alwaysProviderItems[0].provider;
|
||||||
|
} else if (captchaRule === CaptchaRule.Dynamic && dynamicProviderItems.length > 0) {
|
||||||
|
provider = dynamicProviderItems[0].provider;
|
||||||
|
} else if (captchaRule === CaptchaRule.InternetOnly && internetOnlyProviderItems.length > 0) {
|
||||||
|
provider = internetOnlyProviderItems[0].provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!provider) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return <CaptchaModal
|
return <CaptchaModal
|
||||||
owner={provider.owner}
|
owner={provider.owner}
|
||||||
|
@ -181,4 +181,5 @@ export const CaptchaRule = {
|
|||||||
Always: "Always",
|
Always: "Always",
|
||||||
Never: "Never",
|
Never: "Never",
|
||||||
Dynamic: "Dynamic",
|
Dynamic: "Dynamic",
|
||||||
|
InternetOnly: "Internet-Only",
|
||||||
};
|
};
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Left",
|
"Left": "Left",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Přizpůsobit hlavičku vstupní stránky vaší aplikace",
|
"Header HTML - Tooltip": "Přizpůsobit hlavičku vstupní stránky vaší aplikace",
|
||||||
"Incremental": "Inkrementální",
|
"Incremental": "Inkrementální",
|
||||||
"Input": "Vstup",
|
"Input": "Vstup",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Kód pozvánky",
|
"Invitation code": "Kód pozvánky",
|
||||||
"Left": "Vlevo",
|
"Left": "Vlevo",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Links",
|
"Left": "Links",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Left",
|
"Left": "Left",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Izquierda",
|
"Left": "Izquierda",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "کد head صفحه ورود برنامه خود را سفارشی کنید",
|
"Header HTML - Tooltip": "کد head صفحه ورود برنامه خود را سفارشی کنید",
|
||||||
"Incremental": "افزایشی",
|
"Incremental": "افزایشی",
|
||||||
"Input": "ورودی",
|
"Input": "ورودی",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "کد دعوت",
|
"Invitation code": "کد دعوت",
|
||||||
"Left": "چپ",
|
"Left": "چپ",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Left",
|
"Left": "Left",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incrémentale",
|
"Incremental": "Incrémentale",
|
||||||
"Input": "Saisie",
|
"Input": "Saisie",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Code d'invitation",
|
"Invitation code": "Code d'invitation",
|
||||||
"Left": "Gauche",
|
"Left": "Gauche",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Left",
|
"Left": "Left",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Kiri",
|
"Left": "Kiri",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Left",
|
"Left": "Left",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "左",
|
"Left": "左",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Left",
|
"Left": "Left",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "왼쪽",
|
"Left": "왼쪽",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Left",
|
"Left": "Left",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Left",
|
"Left": "Left",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Left",
|
"Left": "Left",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Código de convite",
|
"Invitation code": "Código de convite",
|
||||||
"Left": "Esquerda",
|
"Left": "Esquerda",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Последовательный",
|
"Incremental": "Последовательный",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Код приглашения",
|
"Invitation code": "Код приглашения",
|
||||||
"Left": "Левый",
|
"Left": "Левый",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Vlastný HTML kód pre hlavičku vašej vstupnej stránky aplikácie",
|
"Header HTML - Tooltip": "Vlastný HTML kód pre hlavičku vašej vstupnej stránky aplikácie",
|
||||||
"Incremental": "Postupný",
|
"Incremental": "Postupný",
|
||||||
"Input": "Vstup",
|
"Input": "Vstup",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Kód pozvania",
|
"Invitation code": "Kód pozvania",
|
||||||
"Left": "Vľavo",
|
"Left": "Vľavo",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Left",
|
"Left": "Left",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Incremental",
|
"Incremental": "Incremental",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Davet Kodu",
|
"Invitation code": "Davet Kodu",
|
||||||
"Left": "Sol",
|
"Left": "Sol",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Налаштуйте тег head на сторінці входу до програми",
|
"Header HTML - Tooltip": "Налаштуйте тег head на сторінці входу до програми",
|
||||||
"Incremental": "Інкрементний",
|
"Incremental": "Інкрементний",
|
||||||
"Input": "Введення",
|
"Input": "Введення",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Код запрошення",
|
"Invitation code": "Код запрошення",
|
||||||
"Left": "Ліворуч",
|
"Left": "Ліворуч",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
"Header HTML - Tooltip": "Custom the head tag of your application entry page",
|
||||||
"Incremental": "Tăng",
|
"Incremental": "Tăng",
|
||||||
"Input": "Input",
|
"Input": "Input",
|
||||||
|
"Internet-Only": "Internet-Only",
|
||||||
"Invalid characters in application name": "Invalid characters in application name",
|
"Invalid characters in application name": "Invalid characters in application name",
|
||||||
"Invitation code": "Invitation code",
|
"Invitation code": "Invitation code",
|
||||||
"Left": "Trái",
|
"Left": "Trái",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"Header HTML - Tooltip": "自定义应用页面的head标签",
|
"Header HTML - Tooltip": "自定义应用页面的head标签",
|
||||||
"Incremental": "递增",
|
"Incremental": "递增",
|
||||||
"Input": "输入",
|
"Input": "输入",
|
||||||
|
"Internet-Only": "外网启用",
|
||||||
"Invalid characters in application name": "应用名称内有非法字符",
|
"Invalid characters in application name": "应用名称内有非法字符",
|
||||||
"Invitation code": "邀请码",
|
"Invitation code": "邀请码",
|
||||||
"Left": "居左",
|
"Left": "居左",
|
||||||
|
@ -255,6 +255,7 @@ class ProviderTable extends React.Component {
|
|||||||
<Option key="None" value="None">{i18next.t("general:None")}</Option>
|
<Option key="None" value="None">{i18next.t("general:None")}</Option>
|
||||||
<Option key="Dynamic" value="Dynamic">{i18next.t("application:Dynamic")}</Option>
|
<Option key="Dynamic" value="Dynamic">{i18next.t("application:Dynamic")}</Option>
|
||||||
<Option key="Always" value="Always">{i18next.t("application:Always")}</Option>
|
<Option key="Always" value="Always">{i18next.t("application:Always")}</Option>
|
||||||
|
<Option key="Internet-Only" value="Internet-Only">{i18next.t("application:Internet-Only")}</Option>
|
||||||
</Select>
|
</Select>
|
||||||
);
|
);
|
||||||
} else if (record.provider?.category === "SMS" || record.provider?.category === "Email") {
|
} else if (record.provider?.category === "SMS" || record.provider?.category === "Email") {
|
||||||
|
Reference in New Issue
Block a user