mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-09 01:13:41 +08:00
feat: add SMS test feature (#1606)
* feat: add SMS test * fix: Add missing translation * fix: Delete redundant information * fix: remove unnecessary field * Update sms.go --------- Co-authored-by: hsluoyz <hsluoyz@qq.com>
This commit is contained in:
@ -130,15 +130,7 @@ func (c *ApiController) SendSms() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var invalidReceivers []string
|
invalidReceivers := checkSmsReceivers(smsForm)
|
||||||
for idx, receiver := range smsForm.Receivers {
|
|
||||||
// The receiver phone format: E164 like +8613854673829 +441932567890
|
|
||||||
if !util.IsPhoneValid(receiver, "") {
|
|
||||||
invalidReceivers = append(invalidReceivers, receiver)
|
|
||||||
} else {
|
|
||||||
smsForm.Receivers[idx] = receiver
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(invalidReceivers) != 0 {
|
if len(invalidReceivers) != 0 {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("service:Invalid phone receivers: %s"), invalidReceivers))
|
c.ResponseError(fmt.Sprintf(c.T("service:Invalid phone receivers: %s"), invalidReceivers))
|
||||||
|
@ -197,3 +197,14 @@ func checkQuotaForUser(count int) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkSmsReceivers(smsForm SmsForm) []string {
|
||||||
|
var invalidReceivers []string
|
||||||
|
for _, receiver := range smsForm.Receivers {
|
||||||
|
// The receiver phone format: E164 like +8613854673829 +441932567890
|
||||||
|
if !util.IsPhoneValid(receiver, "") {
|
||||||
|
invalidReceivers = append(invalidReceivers, receiver)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invalidReceivers
|
||||||
|
}
|
||||||
|
@ -20,11 +20,21 @@ import (
|
|||||||
"github.com/casdoor/go-sms-sender"
|
"github.com/casdoor/go-sms-sender"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SendSms(provider *Provider, content string, phoneNumbers ...string) error {
|
func getSmsClient(provider *Provider) (go_sms_sender.SmsClient, error) {
|
||||||
client, err := go_sms_sender.NewSmsClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.SignName, provider.TemplateCode, provider.AppId)
|
client, err := go_sms_sender.NewSmsClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.SignName, provider.TemplateCode, provider.AppId)
|
||||||
|
|
||||||
if provider.Type == go_sms_sender.HuaweiCloud {
|
if provider.Type == go_sms_sender.HuaweiCloud {
|
||||||
client, err = go_sms_sender.NewSmsClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.SignName, provider.TemplateCode, provider.ProviderUrl, provider.AppId)
|
client, err = go_sms_sender.NewSmsClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.SignName, provider.TemplateCode, provider.ProviderUrl, provider.AppId)
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendSms(provider *Provider, content string, phoneNumbers ...string) error {
|
||||||
|
client, err := getSmsClient(provider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,11 @@ import * as Setting from "./Setting";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import {authConfig} from "./auth/Auth";
|
import {authConfig} from "./auth/Auth";
|
||||||
import * as ProviderEditTestEmail from "./TestEmailWidget";
|
import * as ProviderEditTestEmail from "./TestEmailWidget";
|
||||||
|
import * as ProviderEditTestSms from "./TestSmsWidget";
|
||||||
import copy from "copy-to-clipboard";
|
import copy from "copy-to-clipboard";
|
||||||
import {CaptchaPreview} from "./common/CaptchaPreview";
|
import {CaptchaPreview} from "./common/CaptchaPreview";
|
||||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||||
|
import {PhoneNumberInput} from "./common/PhoneNumberInput";
|
||||||
|
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
const {TextArea} = Input;
|
const {TextArea} = Input;
|
||||||
@ -659,6 +661,36 @@ class ProviderEditPage extends React.Component {
|
|||||||
}} />
|
}} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("provider:SMS Test"), i18next.t("provider:SMS Test - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={4} >
|
||||||
|
<Input.Group compact>
|
||||||
|
<PhoneNumberInput
|
||||||
|
style={{width: "30%"}}
|
||||||
|
value={this.state.provider.content}
|
||||||
|
onChange={(value) => {
|
||||||
|
this.updateProviderField("content", value);
|
||||||
|
}}
|
||||||
|
countryCodes={this.props.account.organization.countryCodes}
|
||||||
|
/>
|
||||||
|
<Input value={this.state.provider.receiver}
|
||||||
|
style={{width: "70%"}}
|
||||||
|
placeholder = {i18next.t("user:Input your phone number")}
|
||||||
|
onChange={e => {
|
||||||
|
this.updateProviderField("receiver", e.target.value);
|
||||||
|
}} />
|
||||||
|
</Input.Group>
|
||||||
|
</Col>
|
||||||
|
<Col span={2} >
|
||||||
|
<Button style={{marginLeft: "10px", marginBottom: "5px"}} type="primary"
|
||||||
|
disabled={!Setting.isValidPhone(this.state.provider.receiver)}
|
||||||
|
onClick={() => ProviderEditTestSms.sendTestSms(this.state.provider, "+" + Setting.getCountryCode(this.state.provider.content) + this.state.provider.receiver)} >
|
||||||
|
{i18next.t("provider:SMS Send Test")}
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
) : this.state.provider.category === "SAML" ? (
|
) : this.state.provider.category === "SAML" ? (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
@ -19,7 +19,7 @@ export function sendTestEmail(provider, email) {
|
|||||||
testEmailProvider(provider, email)
|
testEmailProvider(provider, email)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", "Successfully send email");
|
Setting.showMessage("success", `${i18next.t("provider:Email sent successfully")}`);
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ export function connectSmtpServer(provider) {
|
|||||||
testEmailProvider(provider)
|
testEmailProvider(provider)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", "Successfully connecting smtp server");
|
Setting.showMessage("success", "provider:SMTP connected successfully");
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
}
|
}
|
||||||
|
43
web/src/TestSmsWidget.js
Normal file
43
web/src/TestSmsWidget.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2023 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.
|
||||||
|
|
||||||
|
import * as Setting from "./Setting";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export function sendTestSms(provider, phone) {
|
||||||
|
testSmsProvider(provider, phone)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status === "ok") {
|
||||||
|
Setting.showMessage("success", `${i18next.t("provider:SMS send Successfully")}`);
|
||||||
|
} else {
|
||||||
|
Setting.showMessage("error", res.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSmsProvider(provider, phone = "") {
|
||||||
|
const SmsForm = {
|
||||||
|
content: provider.content,
|
||||||
|
receivers: [phone],
|
||||||
|
};
|
||||||
|
|
||||||
|
return fetch(`${Setting.ServerUrl}/api/send-sms?provider=` + provider.name, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
|
body: JSON.stringify(SmsForm),
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
@ -518,6 +518,7 @@
|
|||||||
"Email Content - Tooltip": "邮件内容",
|
"Email Content - Tooltip": "邮件内容",
|
||||||
"Email Title": "邮件标题",
|
"Email Title": "邮件标题",
|
||||||
"Email Title - Tooltip": "邮件标题",
|
"Email Title - Tooltip": "邮件标题",
|
||||||
|
"Email sent successfully": "邮件发送成功",
|
||||||
"Enable QR code": "扫码登陆",
|
"Enable QR code": "扫码登陆",
|
||||||
"Enable QR code - Tooltip": "扫码登陆 - 工具提示",
|
"Enable QR code - Tooltip": "扫码登陆 - 工具提示",
|
||||||
"Endpoint": "地域节点 (外网)",
|
"Endpoint": "地域节点 (外网)",
|
||||||
@ -552,6 +553,11 @@
|
|||||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||||
"SMS account": "SMS account",
|
"SMS account": "SMS account",
|
||||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||||
|
"SMS Send Test": "发送测试短信",
|
||||||
|
"SMS Test": "SMS测试",
|
||||||
|
"SMS Test - Tooltip": "SMS测试 - 工具提示",
|
||||||
|
"SMS send Failed": "短信发送失败",
|
||||||
|
"SMS send Successfully": "短信发送成功",
|
||||||
"SP ACS URL": "SP ACS URL",
|
"SP ACS URL": "SP ACS URL",
|
||||||
"SP ACS URL - Tooltip": "SP ACS URL - 工具提示",
|
"SP ACS URL - Tooltip": "SP ACS URL - 工具提示",
|
||||||
"SP Entity ID": "SP 实体 ID",
|
"SP Entity ID": "SP 实体 ID",
|
||||||
@ -576,6 +582,7 @@
|
|||||||
"Signup HTML - Tooltip": "自定义HTML,用于替换默认的注册页面样式",
|
"Signup HTML - Tooltip": "自定义HTML,用于替换默认的注册页面样式",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "用于前端嵌入页面",
|
"Site key - Tooltip": "用于前端嵌入页面",
|
||||||
|
"SMTP connected successfully": "SMTP连接成功",
|
||||||
"Sub type": "子类型",
|
"Sub type": "子类型",
|
||||||
"Sub type - Tooltip": "子类型",
|
"Sub type - Tooltip": "子类型",
|
||||||
"Template Code": "模板代码",
|
"Template Code": "模板代码",
|
||||||
|
Reference in New Issue
Block a user