mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +08:00
feat: support google one tap signin (#2131)
* feat: add google one tap support * feat: gofumpt * feat: add google provider rule conf * feat: update i18n
This commit is contained in:
parent
bfe8e5f3e7
commit
d1f88ca9b8
@ -21,15 +21,39 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/util"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const GoogleIdTokenKey = "GoogleIdToken"
|
||||||
|
|
||||||
type GoogleIdProvider struct {
|
type GoogleIdProvider struct {
|
||||||
Client *http.Client
|
Client *http.Client
|
||||||
Config *oauth2.Config
|
Config *oauth2.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://developers.google.com/identity/sign-in/web/backend-auth#calling-the-tokeninfo-endpoint
|
||||||
|
type GoogleIdToken struct {
|
||||||
|
// These six fields are included in all Google ID Tokens.
|
||||||
|
Iss string `json:"iss"` // The issuer, or signer, of the token. For Google-signed ID tokens, this value is https://accounts.google.com.
|
||||||
|
Sub string `json:"sub"` // The subject: the ID that represents the principal making the request.
|
||||||
|
Azp string `json:"azp"` // Optional. Who the token was issued to. Here is the ClientID
|
||||||
|
Aud string `json:"aud"` // The audience of the token. Here is the ClientID
|
||||||
|
Iat string `json:"iat"` // Unix epoch time when the token was issued.
|
||||||
|
Exp string `json:"exp"` // Unix epoch time when the token expires.
|
||||||
|
// These seven fields are only included when the user has granted the "profile" and "email" OAuth scopes to the application.
|
||||||
|
Email string `json:"email"`
|
||||||
|
EmailVerified string `json:"email_verified"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Picture string `json:"picture"`
|
||||||
|
GivenName string `json:"given_name"`
|
||||||
|
FamilyName string `json:"family_name"`
|
||||||
|
Locale string `json:"locale"`
|
||||||
|
}
|
||||||
|
|
||||||
func NewGoogleIdProvider(clientId string, clientSecret string, redirectUrl string) *GoogleIdProvider {
|
func NewGoogleIdProvider(clientId string, clientSecret string, redirectUrl string) *GoogleIdProvider {
|
||||||
idp := &GoogleIdProvider{}
|
idp := &GoogleIdProvider{}
|
||||||
|
|
||||||
@ -61,6 +85,25 @@ func (idp *GoogleIdProvider) getConfig() *oauth2.Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (idp *GoogleIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
func (idp *GoogleIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||||
|
// Obtained the GoogleIdToken through Google OneTap authorization.
|
||||||
|
if strings.HasPrefix(code, GoogleIdTokenKey) {
|
||||||
|
code = strings.TrimPrefix(code, GoogleIdTokenKey+"-")
|
||||||
|
var googleIdToken GoogleIdToken
|
||||||
|
if err := json.Unmarshal([]byte(code), &googleIdToken); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
expiry := int64(util.ParseInt(googleIdToken.Exp))
|
||||||
|
token := &oauth2.Token{
|
||||||
|
AccessToken: fmt.Sprintf("%v-%v", GoogleIdTokenKey, googleIdToken.Sub),
|
||||||
|
TokenType: "Bearer",
|
||||||
|
Expiry: time.Unix(expiry, 0),
|
||||||
|
}
|
||||||
|
token = token.WithExtra(map[string]interface{}{
|
||||||
|
GoogleIdTokenKey: googleIdToken,
|
||||||
|
})
|
||||||
|
return token, nil
|
||||||
|
}
|
||||||
|
|
||||||
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, idp.Client)
|
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, idp.Client)
|
||||||
return idp.Config.Exchange(ctx, code)
|
return idp.Config.Exchange(ctx, code)
|
||||||
}
|
}
|
||||||
@ -88,6 +131,20 @@ type GoogleUserInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (idp *GoogleIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
func (idp *GoogleIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||||
|
if strings.HasPrefix(token.AccessToken, GoogleIdTokenKey) {
|
||||||
|
googleIdToken, ok := token.Extra(GoogleIdTokenKey).(GoogleIdToken)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("invalid googleIdToken")
|
||||||
|
}
|
||||||
|
userInfo := UserInfo{
|
||||||
|
Id: googleIdToken.Sub,
|
||||||
|
Username: googleIdToken.Email,
|
||||||
|
DisplayName: googleIdToken.Name,
|
||||||
|
Email: googleIdToken.Email,
|
||||||
|
AvatarUrl: googleIdToken.Picture,
|
||||||
|
}
|
||||||
|
return &userInfo, nil
|
||||||
|
}
|
||||||
url := fmt.Sprintf("https://www.googleapis.com/oauth2/v2/userinfo?alt=json&access_token=%s", token.AccessToken)
|
url := fmt.Sprintf("https://www.googleapis.com/oauth2/v2/userinfo?alt=json&access_token=%s", token.AccessToken)
|
||||||
resp, err := idp.Client.Get(url)
|
resp, err := idp.Client.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
"react-device-detect": "^2.2.2",
|
"react-device-detect": "^2.2.2",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-github-corner": "^2.5.0",
|
"react-github-corner": "^2.5.0",
|
||||||
|
"react-google-one-tap-login": "^0.1.1",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-highlight-words": "^0.18.0",
|
"react-highlight-words": "^0.18.0",
|
||||||
"react-i18next": "^11.8.7",
|
"react-i18next": "^11.8.7",
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
|
|
||||||
import {createButton} from "react-social-login-buttons";
|
import {createButton} from "react-social-login-buttons";
|
||||||
import {StaticBaseUrl} from "../Setting";
|
import {StaticBaseUrl} from "../Setting";
|
||||||
|
import {useGoogleOneTapLogin} from "react-google-one-tap-login";
|
||||||
|
import * as Setting from "../Setting";
|
||||||
|
import * as Provider from "./Provider";
|
||||||
|
|
||||||
function Icon({width = 24, height = 24, color}) {
|
function Icon({width = 24, height = 24, color}) {
|
||||||
return <img src={`${StaticBaseUrl}/buttons/google.svg`} alt="Sign in with Google" />;
|
return <img src={`${StaticBaseUrl}/buttons/google.svg`} alt="Sign in with Google" />;
|
||||||
@ -29,4 +32,29 @@ const config = {
|
|||||||
|
|
||||||
const GoogleLoginButton = createButton(config);
|
const GoogleLoginButton = createButton(config);
|
||||||
|
|
||||||
|
export function GoogleOneTapLoginVirtualButton(prop) {
|
||||||
|
const application = prop.application;
|
||||||
|
const providerConf = prop.providerConf;
|
||||||
|
// https://stackoverflow.com/questions/62281579/google-one-tap-sign-in-ui-not-displayed-after-clicking-the-close-button
|
||||||
|
// document.cookie = "g_state=;path=/;expires=Thu, 01 Jan 1970 00:00:01 GMT";
|
||||||
|
useGoogleOneTapLogin({
|
||||||
|
googleAccountConfigs: {
|
||||||
|
client_id: providerConf.provider.clientId,
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
Setting.showMessage("error", error);
|
||||||
|
},
|
||||||
|
onSuccess: (response) => {
|
||||||
|
const code = "GoogleIdToken-" + JSON.stringify(response);
|
||||||
|
const authUrlParams = new URLSearchParams(Provider.getAuthUrl(application, providerConf.provider, "signup"));
|
||||||
|
const state = authUrlParams.get("state");
|
||||||
|
let redirectUri = authUrlParams.get("redirect_uri");
|
||||||
|
redirectUri = `${redirectUri}?state=${state}&code=${encodeURIComponent(code)}`;
|
||||||
|
Setting.goToLink(redirectUri);
|
||||||
|
},
|
||||||
|
disableCancelOnUnmount: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export default GoogleLoginButton;
|
export default GoogleLoginButton;
|
||||||
|
@ -36,7 +36,7 @@ import {CaptchaModal} from "../common/modal/CaptchaModal";
|
|||||||
import {CaptchaRule} from "../common/modal/CaptchaModal";
|
import {CaptchaRule} from "../common/modal/CaptchaModal";
|
||||||
import RedirectForm from "../common/RedirectForm";
|
import RedirectForm from "../common/RedirectForm";
|
||||||
import {MfaAuthVerifyForm, NextMfa, RequiredMfa} from "./mfa/MfaAuthVerifyForm";
|
import {MfaAuthVerifyForm, NextMfa, RequiredMfa} from "./mfa/MfaAuthVerifyForm";
|
||||||
|
import {GoogleOneTapLoginVirtualButton} from "./GoogleLoginButton";
|
||||||
class LoginPage extends React.Component {
|
class LoginPage extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -423,6 +423,16 @@ class LoginPage extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderOtherFormProvider(application) {
|
||||||
|
for (const providerConf of application.providers) {
|
||||||
|
if (providerConf.provider?.type === "Google" && providerConf.rule === "OneTap" && this.props.preview !== "auto") {
|
||||||
|
return (
|
||||||
|
<GoogleOneTapLoginVirtualButton application={application} providerConf={providerConf} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderForm(application) {
|
renderForm(application) {
|
||||||
if (this.state.msg !== null) {
|
if (this.state.msg !== null) {
|
||||||
return Util.renderMessage(this.state.msg);
|
return Util.renderMessage(this.state.msg);
|
||||||
@ -580,6 +590,9 @@ class LoginPage extends React.Component {
|
|||||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, 30, 5, "small", this.props.location);
|
return ProviderButton.renderProviderLogo(providerItem.provider, application, 30, 5, "small", this.props.location);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
this.renderOtherFormProvider(application)
|
||||||
|
}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
@ -601,6 +614,9 @@ class LoginPage extends React.Component {
|
|||||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, 40, 10, "big", this.props.location);
|
return ProviderButton.renderProviderLogo(providerItem.provider, application, 40, 10, "big", this.props.location);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
this.renderOtherFormProvider(application)
|
||||||
|
}
|
||||||
<div>
|
<div>
|
||||||
<br />
|
<br />
|
||||||
{
|
{
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Created time": "Erstellte Zeit",
|
"Created time": "Erstellte Zeit",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "Standard Anwendung",
|
"Default application": "Standard Anwendung",
|
||||||
"Default application - Tooltip": "Standard-Anwendung für Benutzer, die direkt von der Organisationsseite registriert wurden",
|
"Default application - Tooltip": "Standard-Anwendung für Benutzer, die direkt von der Organisationsseite registriert wurden",
|
||||||
"Default avatar": "Standard-Avatar",
|
"Default avatar": "Standard-Avatar",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "Vom Server verwendet, um die API des Verifizierungscodes-Providers für die Verifizierung aufzurufen",
|
"Secret key - Tooltip": "Vom Server verwendet, um die API des Verifizierungscodes-Providers für die Verifizierung aufzurufen",
|
||||||
"Send Testing Email": "Senden Sie eine Test-E-Mail",
|
"Send Testing Email": "Senden Sie eine Test-E-Mail",
|
||||||
"Send Testing SMS": "Sende Test-SMS",
|
"Send Testing SMS": "Sende Test-SMS",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "Signatur Namen",
|
"Sign Name": "Signatur Namen",
|
||||||
"Sign Name - Tooltip": "Name der Signatur, die verwendet werden soll",
|
"Sign Name - Tooltip": "Name der Signatur, die verwendet werden soll",
|
||||||
"Sign request": "Signaturanfrage",
|
"Sign request": "Signaturanfrage",
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Created time": "Created time",
|
"Created time": "Created time",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "Default application",
|
"Default application": "Default application",
|
||||||
"Default application - Tooltip": "Default application for users registered directly from the organization page",
|
"Default application - Tooltip": "Default application for users registered directly from the organization page",
|
||||||
"Default avatar": "Default avatar",
|
"Default avatar": "Default avatar",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "Used by the server to call the verification code provider API for verification",
|
"Secret key - Tooltip": "Used by the server to call the verification code provider API for verification",
|
||||||
"Send Testing Email": "Send Testing Email",
|
"Send Testing Email": "Send Testing Email",
|
||||||
"Send Testing SMS": "Send Testing SMS",
|
"Send Testing SMS": "Send Testing SMS",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "Sign Name",
|
"Sign Name": "Sign Name",
|
||||||
"Sign Name - Tooltip": "Name of the signature to be used",
|
"Sign Name - Tooltip": "Name of the signature to be used",
|
||||||
"Sign request": "Sign request",
|
"Sign request": "Sign request",
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Created time": "Tiempo creado",
|
"Created time": "Tiempo creado",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "Aplicación predeterminada",
|
"Default application": "Aplicación predeterminada",
|
||||||
"Default application - Tooltip": "Aplicación predeterminada para usuarios registrados directamente desde la página de la organización",
|
"Default application - Tooltip": "Aplicación predeterminada para usuarios registrados directamente desde la página de la organización",
|
||||||
"Default avatar": "Avatar predeterminado",
|
"Default avatar": "Avatar predeterminado",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "Utilizado por el servidor para llamar a la API del proveedor de códigos de verificación para verificar",
|
"Secret key - Tooltip": "Utilizado por el servidor para llamar a la API del proveedor de códigos de verificación para verificar",
|
||||||
"Send Testing Email": "Enviar correo electrónico de prueba",
|
"Send Testing Email": "Enviar correo electrónico de prueba",
|
||||||
"Send Testing SMS": "Enviar SMS de prueba",
|
"Send Testing SMS": "Enviar SMS de prueba",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "Firma de Nombre",
|
"Sign Name": "Firma de Nombre",
|
||||||
"Sign Name - Tooltip": "Nombre de la firma a ser utilizada",
|
"Sign Name - Tooltip": "Nombre de la firma a ser utilizada",
|
||||||
"Sign request": "Solicitud de firma",
|
"Sign request": "Solicitud de firma",
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Created time": "Temps créé",
|
"Created time": "Temps créé",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "Application par défaut",
|
"Default application": "Application par défaut",
|
||||||
"Default application - Tooltip": "Application par défaut pour les utilisateurs enregistrés directement depuis la page de l'organisation",
|
"Default application - Tooltip": "Application par défaut pour les utilisateurs enregistrés directement depuis la page de l'organisation",
|
||||||
"Default avatar": "Avatar par défaut",
|
"Default avatar": "Avatar par défaut",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "Utilisé par le serveur pour appeler l'API du fournisseur de code de vérification pour vérifier",
|
"Secret key - Tooltip": "Utilisé par le serveur pour appeler l'API du fournisseur de code de vérification pour vérifier",
|
||||||
"Send Testing Email": "Envoyer un e-mail de test",
|
"Send Testing Email": "Envoyer un e-mail de test",
|
||||||
"Send Testing SMS": "Envoyer des messages SMS de tests",
|
"Send Testing SMS": "Envoyer des messages SMS de tests",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "Nom de signature",
|
"Sign Name": "Nom de signature",
|
||||||
"Sign Name - Tooltip": "Nom de la signature à utiliser",
|
"Sign Name - Tooltip": "Nom de la signature à utiliser",
|
||||||
"Sign request": "Demande de signature",
|
"Sign request": "Demande de signature",
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Created time": "Waktu dibuat",
|
"Created time": "Waktu dibuat",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "Aplikasi default",
|
"Default application": "Aplikasi default",
|
||||||
"Default application - Tooltip": "Aplikasi default untuk pengguna yang terdaftar langsung dari halaman organisasi",
|
"Default application - Tooltip": "Aplikasi default untuk pengguna yang terdaftar langsung dari halaman organisasi",
|
||||||
"Default avatar": "Avatar default",
|
"Default avatar": "Avatar default",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "Digunakan oleh server untuk memanggil API penyedia kode verifikasi untuk melakukan verifikasi",
|
"Secret key - Tooltip": "Digunakan oleh server untuk memanggil API penyedia kode verifikasi untuk melakukan verifikasi",
|
||||||
"Send Testing Email": "Kirim Email Uji Coba",
|
"Send Testing Email": "Kirim Email Uji Coba",
|
||||||
"Send Testing SMS": "Kirim SMS Uji Coba",
|
"Send Testing SMS": "Kirim SMS Uji Coba",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "Tanda Tangan",
|
"Sign Name": "Tanda Tangan",
|
||||||
"Sign Name - Tooltip": "Nama tanda tangan yang akan digunakan",
|
"Sign Name - Tooltip": "Nama tanda tangan yang akan digunakan",
|
||||||
"Sign request": "Permintaan tanda tangan",
|
"Sign request": "Permintaan tanda tangan",
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Created time": "作成された時間",
|
"Created time": "作成された時間",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "デフォルトアプリケーション",
|
"Default application": "デフォルトアプリケーション",
|
||||||
"Default application - Tooltip": "組織ページから直接登録されたユーザーのデフォルトアプリケーション",
|
"Default application - Tooltip": "組織ページから直接登録されたユーザーのデフォルトアプリケーション",
|
||||||
"Default avatar": "デフォルトのアバター",
|
"Default avatar": "デフォルトのアバター",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "認証のためにサーバーによって使用され、認証コードプロバイダAPIを呼び出すためのもの",
|
"Secret key - Tooltip": "認証のためにサーバーによって使用され、認証コードプロバイダAPIを呼び出すためのもの",
|
||||||
"Send Testing Email": "テスト用メールを送信する",
|
"Send Testing Email": "テスト用メールを送信する",
|
||||||
"Send Testing SMS": "テストSMSを送信してください",
|
"Send Testing SMS": "テストSMSを送信してください",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "署名",
|
"Sign Name": "署名",
|
||||||
"Sign Name - Tooltip": "使用する署名の名前",
|
"Sign Name - Tooltip": "使用する署名の名前",
|
||||||
"Sign request": "サインリクエスト",
|
"Sign request": "サインリクエスト",
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Created time": "작성한 시간",
|
"Created time": "작성한 시간",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "기본 애플리케이션",
|
"Default application": "기본 애플리케이션",
|
||||||
"Default application - Tooltip": "조직 페이지에서 직접 등록한 사용자의 기본 응용 프로그램",
|
"Default application - Tooltip": "조직 페이지에서 직접 등록한 사용자의 기본 응용 프로그램",
|
||||||
"Default avatar": "기본 아바타",
|
"Default avatar": "기본 아바타",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "검증을 위해 서버에서 인증 코드 공급자 API를 호출하는 데 사용됩니다",
|
"Secret key - Tooltip": "검증을 위해 서버에서 인증 코드 공급자 API를 호출하는 데 사용됩니다",
|
||||||
"Send Testing Email": "테스트 이메일을 보내기",
|
"Send Testing Email": "테스트 이메일을 보내기",
|
||||||
"Send Testing SMS": "테스트 SMS를 보내세요",
|
"Send Testing SMS": "테스트 SMS를 보내세요",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "신명서",
|
"Sign Name": "신명서",
|
||||||
"Sign Name - Tooltip": "사용할 서명의 이름",
|
"Sign Name - Tooltip": "사용할 서명의 이름",
|
||||||
"Sign request": "표지 요청",
|
"Sign request": "표지 요청",
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Created time": "Hora de Criação",
|
"Created time": "Hora de Criação",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "Aplicação padrão",
|
"Default application": "Aplicação padrão",
|
||||||
"Default application - Tooltip": "Aplicação padrão para usuários registrados diretamente na página da organização",
|
"Default application - Tooltip": "Aplicação padrão para usuários registrados diretamente na página da organização",
|
||||||
"Default avatar": "Avatar padrão",
|
"Default avatar": "Avatar padrão",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "Usada pelo servidor para chamar a API do fornecedor de código de verificação para verificação",
|
"Secret key - Tooltip": "Usada pelo servidor para chamar a API do fornecedor de código de verificação para verificação",
|
||||||
"Send Testing Email": "Enviar E-mail de Teste",
|
"Send Testing Email": "Enviar E-mail de Teste",
|
||||||
"Send Testing SMS": "Enviar SMS de Teste",
|
"Send Testing SMS": "Enviar SMS de Teste",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "Nome do Sinal",
|
"Sign Name": "Nome do Sinal",
|
||||||
"Sign Name - Tooltip": "Nome da assinatura a ser usada",
|
"Sign Name - Tooltip": "Nome da assinatura a ser usada",
|
||||||
"Sign request": "Solicitação de assinatura",
|
"Sign request": "Solicitação de assinatura",
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Created time": "Созданное время",
|
"Created time": "Созданное время",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "Приложение по умолчанию",
|
"Default application": "Приложение по умолчанию",
|
||||||
"Default application - Tooltip": "По умолчанию приложение для пользователей, зарегистрированных непосредственно со страницы организации",
|
"Default application - Tooltip": "По умолчанию приложение для пользователей, зарегистрированных непосредственно со страницы организации",
|
||||||
"Default avatar": "Стандартный аватар",
|
"Default avatar": "Стандартный аватар",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "Используется сервером для вызова API-интерфейса поставщика кода подтверждения для проверки",
|
"Secret key - Tooltip": "Используется сервером для вызова API-интерфейса поставщика кода подтверждения для проверки",
|
||||||
"Send Testing Email": "Отправить тестовое письмо",
|
"Send Testing Email": "Отправить тестовое письмо",
|
||||||
"Send Testing SMS": "Отправить тестовое SMS-сообщение",
|
"Send Testing SMS": "Отправить тестовое SMS-сообщение",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "Подпись имени",
|
"Sign Name": "Подпись имени",
|
||||||
"Sign Name - Tooltip": "Имя подписи, которую нужно использовать",
|
"Sign Name - Tooltip": "Имя подписи, которую нужно использовать",
|
||||||
"Sign request": "Подписать запрос",
|
"Sign request": "Подписать запрос",
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Created time": "Thời gian tạo",
|
"Created time": "Thời gian tạo",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "Ứng dụng mặc định",
|
"Default application": "Ứng dụng mặc định",
|
||||||
"Default application - Tooltip": "Ứng dụng mặc định cho người dùng đăng ký trực tiếp từ trang tổ chức",
|
"Default application - Tooltip": "Ứng dụng mặc định cho người dùng đăng ký trực tiếp từ trang tổ chức",
|
||||||
"Default avatar": "Hình đại diện mặc định",
|
"Default avatar": "Hình đại diện mặc định",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "Được sử dụng bởi máy chủ để gọi API nhà cung cấp mã xác minh để xác minh",
|
"Secret key - Tooltip": "Được sử dụng bởi máy chủ để gọi API nhà cung cấp mã xác minh để xác minh",
|
||||||
"Send Testing Email": "Gửi Email kiểm tra",
|
"Send Testing Email": "Gửi Email kiểm tra",
|
||||||
"Send Testing SMS": "Gửi SMS kiểm tra",
|
"Send Testing SMS": "Gửi SMS kiểm tra",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "Ký tên",
|
"Sign Name": "Ký tên",
|
||||||
"Sign Name - Tooltip": "Tên chữ ký sẽ được sử dụng",
|
"Sign Name - Tooltip": "Tên chữ ký sẽ được sử dụng",
|
||||||
"Sign request": "Yêu cầu ký tên",
|
"Sign request": "Yêu cầu ký tên",
|
||||||
|
@ -197,6 +197,7 @@
|
|||||||
"Confirm": "确认",
|
"Confirm": "确认",
|
||||||
"Created time": "创建时间",
|
"Created time": "创建时间",
|
||||||
"Custom": "自定义",
|
"Custom": "自定义",
|
||||||
|
"Default": "默认",
|
||||||
"Default application": "默认应用",
|
"Default application": "默认应用",
|
||||||
"Default application - Tooltip": "直接从组织页面注册的用户默认所属的应用",
|
"Default application - Tooltip": "直接从组织页面注册的用户默认所属的应用",
|
||||||
"Default avatar": "默认头像",
|
"Default avatar": "默认头像",
|
||||||
@ -722,6 +723,8 @@
|
|||||||
"Secret key - Tooltip": "用于服务端调用验证码提供商API进行验证",
|
"Secret key - Tooltip": "用于服务端调用验证码提供商API进行验证",
|
||||||
"Send Testing Email": "发送测试邮件",
|
"Send Testing Email": "发送测试邮件",
|
||||||
"Send Testing SMS": "发送测试短信",
|
"Send Testing SMS": "发送测试短信",
|
||||||
|
"Sender number": "Sender number",
|
||||||
|
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||||
"Sign Name": "签名名称",
|
"Sign Name": "签名名称",
|
||||||
"Sign Name - Tooltip": "签名名称",
|
"Sign Name - Tooltip": "签名名称",
|
||||||
"Sign request": "签名请求",
|
"Sign request": "签名请求",
|
||||||
|
@ -178,21 +178,37 @@ class ProviderTable extends React.Component {
|
|||||||
key: "rule",
|
key: "rule",
|
||||||
width: "100px",
|
width: "100px",
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
if (record.provider?.category !== "Captcha") {
|
if (record.provider?.type === "Google") {
|
||||||
|
if (text === "None") {
|
||||||
|
text = "Default";
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Select virtual={false} style={{width: "100%"}}
|
||||||
|
value={text}
|
||||||
|
defaultValue="Default"
|
||||||
|
onChange={value => {
|
||||||
|
this.updateField(table, index, "rule", value);
|
||||||
|
}} >
|
||||||
|
<Option key="Default" value="Default">{i18next.t("general:Default")}</Option>
|
||||||
|
<Option key="OneTap" value="OneTap">{"One Tap"}</Option>
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
} else if (record.provider?.category === "Captcha") {
|
||||||
|
return (
|
||||||
|
<Select virtual={false} style={{width: "100%"}}
|
||||||
|
value={text}
|
||||||
|
defaultValue="None"
|
||||||
|
onChange={value => {
|
||||||
|
this.updateField(table, index, "rule", value);
|
||||||
|
}} >
|
||||||
|
<Option key="None" value="None">{i18next.t("general:None")}</Option>
|
||||||
|
<Option key="Dynamic" value="Dynamic">{i18next.t("application:Dynamic")}</Option>
|
||||||
|
<Option key="Always" value="Always">{i18next.t("application:Always")}</Option>
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
|
||||||
<Select virtual={false} style={{width: "100%"}}
|
|
||||||
value={text}
|
|
||||||
defaultValue="None"
|
|
||||||
onChange={value => {
|
|
||||||
this.updateField(table, index, "rule", value);
|
|
||||||
}} >
|
|
||||||
<Option key="None" value="None">{i18next.t("general:None")}</Option>
|
|
||||||
<Option key="Dynamic" value="Dynamic">{i18next.t("application:Dynamic")}</Option>
|
|
||||||
<Option key="Always" value="Always">{i18next.t("application:Always")}</Option>
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -10199,6 +10199,11 @@ react-github-corner@^2.5.0:
|
|||||||
resolved "https://registry.yarnpkg.com/react-github-corner/-/react-github-corner-2.5.0.tgz#e350d0c69f69c075bc0f1d2a6f1df6ee91da31f2"
|
resolved "https://registry.yarnpkg.com/react-github-corner/-/react-github-corner-2.5.0.tgz#e350d0c69f69c075bc0f1d2a6f1df6ee91da31f2"
|
||||||
integrity sha512-ofds9l6n61LJc6ML+jSE6W9ZSQvATcMR9evnHPXua1oDYj289HKODnVqFUB/g2a4ieBjDHw416iHP3MjqnU76Q==
|
integrity sha512-ofds9l6n61LJc6ML+jSE6W9ZSQvATcMR9evnHPXua1oDYj289HKODnVqFUB/g2a4ieBjDHw416iHP3MjqnU76Q==
|
||||||
|
|
||||||
|
react-google-one-tap-login@^0.1.1:
|
||||||
|
version "0.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-google-one-tap-login/-/react-google-one-tap-login-0.1.1.tgz#12a61e63e19251622cf1575b601d79fd4d07847a"
|
||||||
|
integrity sha512-RCbOfR3Z7VcRae4AzrLoBfY/aqqdN24pkQeNz9CJ0W65C9SY3vAwF0Yp8mwpeFwsugaZ5b1HZsfhUYWtb3IMrw==
|
||||||
|
|
||||||
react-helmet@^6.1.0:
|
react-helmet@^6.1.0:
|
||||||
version "6.1.0"
|
version "6.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.1.0.tgz#a750d5165cb13cf213e44747502652e794468726"
|
resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.1.0.tgz#a750d5165cb13cf213e44747502652e794468726"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user