mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-04 03:50:30 +08:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ff94e5164a | ||
![]() |
15a6fd2b52 | ||
![]() |
37b6b50751 | ||
![]() |
efe5431f54 | ||
![]() |
e9159902eb | ||
![]() |
604e2757c8 | ||
![]() |
88c5aae9e9 | ||
![]() |
3d0cf8788b | ||
![]() |
e78ea2546f | ||
![]() |
f7705931f7 | ||
![]() |
5d8b710bf7 | ||
![]() |
b85ad896bf |
@@ -28,6 +28,7 @@ import (
|
|||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/proxy"
|
"github.com/casdoor/casdoor/proxy"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func codeToResponse(code *object.Code) *Response {
|
func codeToResponse(code *object.Code) *Response {
|
||||||
@@ -252,7 +253,7 @@ func (c *ApiController) Login() {
|
|||||||
record := object.NewRecord(c.Ctx)
|
record := object.NewRecord(c.Ctx)
|
||||||
record.Organization = application.Organization
|
record.Organization = application.Organization
|
||||||
record.User = user.Name
|
record.User = user.Name
|
||||||
util.SafeGoroutine(func() {object.AddRecord(record)})
|
util.SafeGoroutine(func() { object.AddRecord(record) })
|
||||||
}
|
}
|
||||||
} else if form.Provider != "" {
|
} else if form.Provider != "" {
|
||||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
||||||
@@ -325,12 +326,6 @@ func (c *ApiController) Login() {
|
|||||||
user = object.GetUser(fmt.Sprintf("%s/%s", application.Organization, userInfo.Id))
|
user = object.GetUser(fmt.Sprintf("%s/%s", application.Organization, userInfo.Id))
|
||||||
} else if provider.Category == "OAuth" {
|
} else if provider.Category == "OAuth" {
|
||||||
user = object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
|
user = object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
|
||||||
if user == nil {
|
|
||||||
user = object.GetUserByField(application.Organization, provider.Type, userInfo.Username)
|
|
||||||
}
|
|
||||||
if user == nil {
|
|
||||||
user = object.GetUserByField(application.Organization, "name", userInfo.Username)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if user != nil && user.IsDeleted == false {
|
if user != nil && user.IsDeleted == false {
|
||||||
@@ -345,7 +340,7 @@ func (c *ApiController) Login() {
|
|||||||
record := object.NewRecord(c.Ctx)
|
record := object.NewRecord(c.Ctx)
|
||||||
record.Organization = application.Organization
|
record.Organization = application.Organization
|
||||||
record.User = user.Name
|
record.User = user.Name
|
||||||
util.SafeGoroutine(func() {object.AddRecord(record)})
|
util.SafeGoroutine(func() { object.AddRecord(record) })
|
||||||
} else if provider.Category == "OAuth" {
|
} else if provider.Category == "OAuth" {
|
||||||
// Sign up via OAuth
|
// Sign up via OAuth
|
||||||
if !application.EnableSignUp {
|
if !application.EnableSignUp {
|
||||||
@@ -358,6 +353,19 @@ func (c *ApiController) Login() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle username conflicts
|
||||||
|
tmpUser := object.GetUser(fmt.Sprintf("%s/%s", application.Organization, userInfo.Username))
|
||||||
|
if tmpUser != nil {
|
||||||
|
uid, err := uuid.NewRandom()
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
uidStr := strings.Split(uid.String(), "-")
|
||||||
|
userInfo.Username = fmt.Sprintf("%s_%s", userInfo.Username, uidStr[1])
|
||||||
|
}
|
||||||
|
|
||||||
properties := map[string]string{}
|
properties := map[string]string{}
|
||||||
properties["no"] = strconv.Itoa(len(object.GetUsers(application.Organization)) + 2)
|
properties["no"] = strconv.Itoa(len(object.GetUsers(application.Organization)) + 2)
|
||||||
user = &object.User{
|
user = &object.User{
|
||||||
@@ -394,7 +402,13 @@ func (c *ApiController) Login() {
|
|||||||
record := object.NewRecord(c.Ctx)
|
record := object.NewRecord(c.Ctx)
|
||||||
record.Organization = application.Organization
|
record.Organization = application.Organization
|
||||||
record.User = user.Name
|
record.User = user.Name
|
||||||
util.SafeGoroutine(func() {object.AddRecord(record)})
|
util.SafeGoroutine(func() { object.AddRecord(record) })
|
||||||
|
|
||||||
|
record2 := object.NewRecord(c.Ctx)
|
||||||
|
record2.Action = "signup"
|
||||||
|
record2.Organization = application.Organization
|
||||||
|
record2.User = user.Name
|
||||||
|
util.SafeGoroutine(func() { object.AddRecord(record2) })
|
||||||
} else if provider.Category == "SAML" {
|
} else if provider.Category == "SAML" {
|
||||||
resp = &Response{Status: "error", Msg: "The account does not exist"}
|
resp = &Response{Status: "error", Msg: "The account does not exist"}
|
||||||
}
|
}
|
||||||
@@ -407,9 +421,6 @@ func (c *ApiController) Login() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
oldUser := object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
|
oldUser := object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
|
||||||
if oldUser == nil {
|
|
||||||
oldUser = object.GetUserByField(application.Organization, provider.Type, userInfo.Username)
|
|
||||||
}
|
|
||||||
if oldUser != nil {
|
if oldUser != nil {
|
||||||
c.ResponseError(fmt.Sprintf("The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)", provider.Type, userInfo.Username, userInfo.DisplayName, oldUser.Name, oldUser.DisplayName))
|
c.ResponseError(fmt.Sprintf("The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)", provider.Type, userInfo.Username, userInfo.DisplayName, oldUser.Name, oldUser.DisplayName))
|
||||||
return
|
return
|
||||||
@@ -438,6 +449,11 @@ func (c *ApiController) Login() {
|
|||||||
|
|
||||||
user := c.getCurrentUser()
|
user := c.getCurrentUser()
|
||||||
resp = c.HandleLoggedIn(application, user, &form)
|
resp = c.HandleLoggedIn(application, user, &form)
|
||||||
|
|
||||||
|
record := object.NewRecord(c.Ctx)
|
||||||
|
record.Organization = application.Organization
|
||||||
|
record.User = user.Name
|
||||||
|
util.SafeGoroutine(func() { object.AddRecord(record) })
|
||||||
} else {
|
} else {
|
||||||
c.ResponseError(fmt.Sprintf("unknown authentication type (not password or provider), form = %s", util.StructToJson(form)))
|
c.ResponseError(fmt.Sprintf("unknown authentication type (not password or provider), form = %s", util.StructToJson(form)))
|
||||||
return
|
return
|
||||||
|
@@ -26,6 +26,7 @@ func (c *ApiController) GetSamlMeta() {
|
|||||||
application := object.GetApplication(paramApp)
|
application := object.GetApplication(paramApp)
|
||||||
if application == nil {
|
if application == nil {
|
||||||
c.ResponseError(fmt.Sprintf("err: application %s not found", paramApp))
|
c.ResponseError(fmt.Sprintf("err: application %s not found", paramApp))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
metadata, _ := object.GetSamlMeta(application, host)
|
metadata, _ := object.GetSamlMeta(application, host)
|
||||||
c.Data["xml"] = metadata
|
c.Data["xml"] = metadata
|
||||||
|
@@ -187,9 +187,10 @@ func (idp *BilibiliIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
userInfo := &UserInfo{
|
userInfo := &UserInfo{
|
||||||
Id: bUserInfoResponse.Data.OpenId,
|
Id: bUserInfoResponse.Data.OpenId,
|
||||||
Username: bUserInfoResponse.Data.Name,
|
Username: bUserInfoResponse.Data.Name,
|
||||||
AvatarUrl: bUserInfoResponse.Data.Face,
|
DisplayName: bUserInfoResponse.Data.Name,
|
||||||
|
AvatarUrl: bUserInfoResponse.Data.Face,
|
||||||
}
|
}
|
||||||
|
|
||||||
return userInfo, nil
|
return userInfo, nil
|
||||||
|
@@ -121,11 +121,15 @@ func UpdateOrganization(id string, organization *Organization) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if name != organization.Name {
|
if name != organization.Name {
|
||||||
applications := GetApplicationsByOrganizationName("admin", name)
|
go func() {
|
||||||
for _, application := range applications {
|
application := new(Application)
|
||||||
application.Organization = organization.Name
|
application.Organization = organization.Name
|
||||||
UpdateApplication(application.GetId(), application)
|
_, _ = adapter.Engine.Where("organization=?", name).Update(application)
|
||||||
}
|
|
||||||
|
user := new(User)
|
||||||
|
user.Owner = organization.Name
|
||||||
|
_, _ = adapter.Engine.Where("owner=?", name).Update(user)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if organization.MasterPassword != "" && organization.MasterPassword != "***" {
|
if organization.MasterPassword != "" && organization.MasterPassword != "***" {
|
||||||
|
@@ -65,5 +65,5 @@ func RecordMessage(ctx *context.Context) {
|
|||||||
record.Organization, record.User = util.GetOwnerAndNameFromId(userId)
|
record.Organization, record.User = util.GetOwnerAndNameFromId(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
util.SafeGoroutine(func() {object.AddRecord(record)})
|
util.SafeGoroutine(func() { object.AddRecord(record) })
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,23 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<script>
|
||||||
|
var _hmt = _hmt || [];
|
||||||
|
(function() {
|
||||||
|
var hm = document.createElement("script");
|
||||||
|
hm.src = "https://hm.baidu.com/hm.js?5998fcd123c220efc0936edf4f250504";
|
||||||
|
var s = document.getElementsByTagName("script")[0];
|
||||||
|
s.parentNode.insertBefore(hm, s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<!-- <link rel="icon" href="%PUBLIC_URL%/favicon.png" />-->
|
<!-- <link rel="icon" href="%PUBLIC_URL%/favicon.png" />-->
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Web site created using create-react-app"
|
content="Casdoor - An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS"
|
||||||
/>
|
/>
|
||||||
<link rel="apple-touch-icon" href="https://cdn.casdoor.com/static/favicon.png" />
|
<link rel="apple-touch-icon" href="https://cdn.casdoor.com/static/favicon.png" />
|
||||||
<!--
|
<!--
|
||||||
|
@@ -534,6 +534,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
renderPreview() {
|
renderPreview() {
|
||||||
let signUpUrl = `/signup/${this.state.application.name}`;
|
let signUpUrl = `/signup/${this.state.application.name}`;
|
||||||
let signInUrl = `/login/oauth/authorize?client_id=${this.state.application.clientId}&response_type=code&redirect_uri=${this.state.application.redirectUris[0]}&scope=read&state=casdoor`;
|
let signInUrl = `/login/oauth/authorize?client_id=${this.state.application.clientId}&response_type=code&redirect_uri=${this.state.application.redirectUris[0]}&scope=read&state=casdoor`;
|
||||||
|
let maskStyle = {position: 'absolute', top: '0px', left: '0px', zIndex: 10, height: '100%', width: '100%', background: 'rgba(0,0,0,0.4)'};
|
||||||
if (!this.state.application.enablePassword) {
|
if (!this.state.application.enablePassword) {
|
||||||
signUpUrl = signInUrl.replace("/login/oauth/authorize", "/signup/oauth/authorize");
|
signUpUrl = signInUrl.replace("/login/oauth/authorize", "/signup/oauth/authorize");
|
||||||
}
|
}
|
||||||
@@ -546,7 +547,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
<div style={{width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems:"center", overflow:"auto", flexDirection:"column", flex: "auto"}}>
|
<div style={{position:'relative', width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems:"center", overflow:"auto", flexDirection:"column", flex: "auto"}}>
|
||||||
{
|
{
|
||||||
this.state.application.enablePassword ? (
|
this.state.application.enablePassword ? (
|
||||||
<SignupPage application={this.state.application} />
|
<SignupPage application={this.state.application} />
|
||||||
@@ -554,6 +555,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
<LoginPage type={"login"} mode={"signup"} application={this.state.application} />
|
<LoginPage type={"login"} mode={"signup"} application={this.state.application} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
<div style={maskStyle}></div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={11} style={{display:"flex", flexDirection: "column"}}>
|
<Col span={11} style={{display:"flex", flexDirection: "column"}}>
|
||||||
@@ -562,8 +564,9 @@ class ApplicationEditPage extends React.Component {
|
|||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
<div style={{width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems:"center", overflow:"auto", flexDirection:"column", flex: "auto"}}>
|
<div style={{position:'relative', width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems:"center", overflow:"auto", flexDirection:"column", flex: "auto"}}>
|
||||||
<LoginPage type={"login"} mode={"signin"} application={this.state.application} />
|
<LoginPage type={"login"} mode={"signin"} application={this.state.application} />
|
||||||
|
<div style={maskStyle}></div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
@@ -575,7 +578,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
<a style={{marginBottom: "10px", display: "flex"}} target="_blank" rel="noreferrer" href={signUpUrl}>
|
<a style={{marginBottom: "10px", display: "flex"}} target="_blank" rel="noreferrer" href={signUpUrl}>
|
||||||
<Button type="primary">{i18next.t("application:Test signup page..")}</Button>
|
<Button type="primary">{i18next.t("application:Test signup page..")}</Button>
|
||||||
</a>
|
</a>
|
||||||
<div style={{marginBottom:"10px", width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems: "center", overflow: "auto", flexDirection: "column", flex: "auto"}}>
|
<div style={{position:'relative', marginBottom:"10px", width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems: "center", overflow: "auto", flexDirection: "column", flex: "auto"}}>
|
||||||
{
|
{
|
||||||
this.state.application.enablePassword ? (
|
this.state.application.enablePassword ? (
|
||||||
<SignupPage application={this.state.application} />
|
<SignupPage application={this.state.application} />
|
||||||
@@ -583,12 +586,14 @@ class ApplicationEditPage extends React.Component {
|
|||||||
<LoginPage type={"login"} mode={"signup"} application={this.state.application} />
|
<LoginPage type={"login"} mode={"signup"} application={this.state.application} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
<div style={maskStyle}></div>
|
||||||
</div>
|
</div>
|
||||||
<a style={{marginBottom: "10px", display: "flex"}} target="_blank" rel="noreferrer" href={signInUrl}>
|
<a style={{marginBottom: "10px", display: "flex"}} target="_blank" rel="noreferrer" href={signInUrl}>
|
||||||
<Button type="primary">{i18next.t("application:Test signin page..")}</Button>
|
<Button type="primary">{i18next.t("application:Test signin page..")}</Button>
|
||||||
</a>
|
</a>
|
||||||
<div style={{width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems: "center", overflow: "auto", flexDirection: "column", flex: "auto"}}>
|
<div style={{position:'relative', width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems: "center", overflow: "auto", flexDirection: "column", flex: "auto"}}>
|
||||||
<LoginPage type={"login"} mode={"signin"} application={this.state.application} />
|
<LoginPage type={"login"} mode={"signin"} application={this.state.application} />
|
||||||
|
<div style={maskStyle}></div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
@@ -206,7 +206,7 @@ class ProductBuyPage extends React.Component {
|
|||||||
<Descriptions.Item label={i18next.t("product:Tag")}><span style={{fontSize: 16}}>{product?.tag}</span></Descriptions.Item>
|
<Descriptions.Item label={i18next.t("product:Tag")}><span style={{fontSize: 16}}>{product?.tag}</span></Descriptions.Item>
|
||||||
<Descriptions.Item label={i18next.t("product:SKU")}><span style={{fontSize: 16}}>{product?.name}</span></Descriptions.Item>
|
<Descriptions.Item label={i18next.t("product:SKU")}><span style={{fontSize: 16}}>{product?.name}</span></Descriptions.Item>
|
||||||
<Descriptions.Item label={i18next.t("product:Image")} span={3}>
|
<Descriptions.Item label={i18next.t("product:Image")} span={3}>
|
||||||
<img src={product?.image} alt={product?.image} height={90} style={{marginBottom: '20px'}}/>
|
<img src={product?.image} alt={product?.name} height={90} style={{marginBottom: '20px'}}/>
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label={i18next.t("product:Price")}>
|
<Descriptions.Item label={i18next.t("product:Price")}>
|
||||||
<span style={{fontSize: 28, color: "red", fontWeight: "bold"}}>
|
<span style={{fontSize: 28, color: "red", fontWeight: "bold"}}>
|
||||||
|
@@ -70,10 +70,13 @@ class ProviderEditPage extends React.Component {
|
|||||||
case "Email":
|
case "Email":
|
||||||
return Setting.getLabel(i18next.t("signup:Username"), i18next.t("signup:Username - Tooltip"));
|
return Setting.getLabel(i18next.t("signup:Username"), i18next.t("signup:Username - Tooltip"));
|
||||||
case "SMS":
|
case "SMS":
|
||||||
if (this.state.provider.type === "Volc Engine SMS")
|
if (this.state.provider.type === "Volc Engine SMS") {
|
||||||
return Setting.getLabel(i18next.t("provider:Access key"), i18next.t("provider:Access key - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Access key"), i18next.t("provider:Access key - Tooltip"));
|
||||||
if (this.state.provider.type === "Huawei Cloud SMS")
|
} else if (this.state.provider.type === "Huawei Cloud SMS") {
|
||||||
return Setting.getLabel(i18next.t("provider:App key"), i18next.t("provider:App key - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:App key"), i18next.t("provider:App key - Tooltip"));
|
||||||
|
} else {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Client ID"), i18next.t("provider:Client ID - Tooltip"));
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return Setting.getLabel(i18next.t("provider:Client ID"), i18next.t("provider:Client ID - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Client ID"), i18next.t("provider:Client ID - Tooltip"));
|
||||||
}
|
}
|
||||||
@@ -84,10 +87,13 @@ class ProviderEditPage extends React.Component {
|
|||||||
case "Email":
|
case "Email":
|
||||||
return Setting.getLabel(i18next.t("login:Password"), i18next.t("login:Password - Tooltip"));
|
return Setting.getLabel(i18next.t("login:Password"), i18next.t("login:Password - Tooltip"));
|
||||||
case "SMS":
|
case "SMS":
|
||||||
if (this.state.provider.type === "Volc Engine SMS")
|
if (this.state.provider.type === "Volc Engine SMS") {
|
||||||
return Setting.getLabel(i18next.t("provider:Secret access key"), i18next.t("provider:SecretAccessKey - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Secret access key"), i18next.t("provider:SecretAccessKey - Tooltip"));
|
||||||
if (this.state.provider.type === "Huawei Cloud SMS")
|
} else if (this.state.provider.type === "Huawei Cloud SMS") {
|
||||||
return Setting.getLabel(i18next.t("provider:App secret"), i18next.t("provider:AppSecret - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:App secret"), i18next.t("provider:AppSecret - Tooltip"));
|
||||||
|
} else {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Client secret"), i18next.t("provider:Client secret - Tooltip"));
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return Setting.getLabel(i18next.t("provider:Client secret"), i18next.t("provider:Client secret - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Client secret"), i18next.t("provider:Client secret - Tooltip"));
|
||||||
}
|
}
|
||||||
|
@@ -206,7 +206,7 @@ class ResourceListPage extends BaseListPage {
|
|||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
if (record.fileType === "image") {
|
if (record.fileType === "image") {
|
||||||
return (
|
return (
|
||||||
<a target="_blank" href={record.url}>
|
<a target="_blank" rel="noreferrer" href={record.url}>
|
||||||
<img src={record.url} alt={record.name} width={100} />
|
<img src={record.url} alt={record.name} width={100} />
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
|
@@ -21,7 +21,6 @@ import i18next from "i18next";
|
|||||||
import copy from "copy-to-clipboard";
|
import copy from "copy-to-clipboard";
|
||||||
import {authConfig} from "./auth/Auth";
|
import {authConfig} from "./auth/Auth";
|
||||||
import {Helmet} from "react-helmet";
|
import {Helmet} from "react-helmet";
|
||||||
import moment from "moment";
|
|
||||||
import * as Conf from "./Conf";
|
import * as Conf from "./Conf";
|
||||||
|
|
||||||
export let ServerUrl = "";
|
export let ServerUrl = "";
|
||||||
@@ -225,7 +224,7 @@ export function isValidInvoiceTitle(invoiceTitle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://blog.css8.cn/post/14210975.html
|
// https://blog.css8.cn/post/14210975.html
|
||||||
const invoiceTitleRegex = /^[\(\)\(\)\u4e00-\u9fa5]{0,50}$/;
|
const invoiceTitleRegex = /^[()()\u4e00-\u9fa5]{0,50}$/;
|
||||||
return invoiceTitleRegex.test(invoiceTitle);
|
return invoiceTitleRegex.test(invoiceTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,27 +473,26 @@ export function changeLanguage(language) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function changeMomentLanguage(language) {
|
export function changeMomentLanguage(language) {
|
||||||
return;
|
// if (language === "zh") {
|
||||||
if (language === "zh") {
|
// moment.locale("zh", {
|
||||||
moment.locale("zh", {
|
// relativeTime: {
|
||||||
relativeTime: {
|
// future: "%s内",
|
||||||
future: "%s内",
|
// past: "%s前",
|
||||||
past: "%s前",
|
// s: "几秒",
|
||||||
s: "几秒",
|
// ss: "%d秒",
|
||||||
ss: "%d秒",
|
// m: "1分钟",
|
||||||
m: "1分钟",
|
// mm: "%d分钟",
|
||||||
mm: "%d分钟",
|
// h: "1小时",
|
||||||
h: "1小时",
|
// hh: "%d小时",
|
||||||
hh: "%d小时",
|
// d: "1天",
|
||||||
d: "1天",
|
// dd: "%d天",
|
||||||
dd: "%d天",
|
// M: "1个月",
|
||||||
M: "1个月",
|
// MM: "%d个月",
|
||||||
MM: "%d个月",
|
// y: "1年",
|
||||||
y: "1年",
|
// yy: "%d年",
|
||||||
yy: "%d年",
|
// },
|
||||||
},
|
// });
|
||||||
});
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getClickable(text) {
|
export function getClickable(text) {
|
||||||
|
@@ -119,8 +119,12 @@ class SyncerEditPage extends React.Component {
|
|||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: '100%'}} value={this.state.syncer.type} onChange={(value => {
|
<Select virtual={false} style={{width: '100%'}} value={this.state.syncer.type} onChange={(value => {
|
||||||
this.updateSyncerField('type', value);
|
this.updateSyncerField('type', value);
|
||||||
this.state.syncer["tableColumns"] = Setting.getSyncerTableColumns(this.state.syncer);
|
let syncer = this.state.syncer;
|
||||||
this.state.syncer.table = value === "Keycloak" ? "user_entity" : this.state.syncer.table;
|
syncer["tableColumns"] = Setting.getSyncerTableColumns(this.state.syncer);
|
||||||
|
syncer.table = (value === "Keycloak") ? "user_entity" : this.state.syncer.table;
|
||||||
|
this.setState({
|
||||||
|
syncer: syncer,
|
||||||
|
});
|
||||||
})}>
|
})}>
|
||||||
{
|
{
|
||||||
['Database', 'LDAP', 'Keycloak']
|
['Database', 'LDAP', 'Keycloak']
|
||||||
|
@@ -28,10 +28,10 @@ import OAuthWidget from "./common/OAuthWidget";
|
|||||||
import SamlWidget from "./common/SamlWidget";
|
import SamlWidget from "./common/SamlWidget";
|
||||||
import SelectRegionBox from "./SelectRegionBox";
|
import SelectRegionBox from "./SelectRegionBox";
|
||||||
|
|
||||||
import {Controlled as CodeMirror} from 'react-codemirror2';
|
// import {Controlled as CodeMirror} from 'react-codemirror2';
|
||||||
import "codemirror/lib/codemirror.css";
|
// import "codemirror/lib/codemirror.css";
|
||||||
require('codemirror/theme/material-darker.css');
|
// require('codemirror/theme/material-darker.css');
|
||||||
require("codemirror/mode/javascript/javascript");
|
// require("codemirror/mode/javascript/javascript");
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
|
@@ -144,47 +144,48 @@ class LoginPage extends React.Component {
|
|||||||
const application = this.getApplicationObj();
|
const application = this.getApplicationObj();
|
||||||
const ths = this;
|
const ths = this;
|
||||||
|
|
||||||
//here we are supposed to judge whether casdoor is working as a oauth server or CAS server
|
// here we are supposed to determine whether Casdoor is working as an OAuth server or CAS server
|
||||||
if (this.state.type === "cas") {
|
if (this.state.type === "cas") {
|
||||||
//cas
|
// CAS
|
||||||
const casParams = Util.getCasParameters()
|
const casParams = Util.getCasParameters();
|
||||||
values["type"] = this.state.type;
|
values["type"] = this.state.type;
|
||||||
AuthBackend.loginCas(values, casParams).then((res) => {
|
AuthBackend.loginCas(values, casParams).then((res) => {
|
||||||
if (res.status === 'ok') {
|
if (res.status === 'ok') {
|
||||||
let msg = "Logged in successfully. "
|
let msg = "Logged in successfully. ";
|
||||||
if (casParams.service === "") {
|
if (casParams.service === "") {
|
||||||
//If service was not specified, CAS MUST display a message notifying the client that it has successfully initiated a single sign-on session.
|
// If service was not specified, Casdoor must display a message notifying the client that it has successfully initiated a single sign-on session.
|
||||||
msg += "Now you can visit apps protected by casdoor."
|
msg += "Now you can visit apps protected by Casdoor.";
|
||||||
}
|
}
|
||||||
Util.showMessage("success", msg);
|
Util.showMessage("success", msg);
|
||||||
if (casParams.service !== "") {
|
|
||||||
let st = res.data
|
|
||||||
window.location.href = casParams.service + "?ticket=" + st
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (casParams.service !== "") {
|
||||||
|
let st = res.data;
|
||||||
|
let newUrl = new URL(casParams.service);
|
||||||
|
newUrl.searchParams.append("ticket", st);
|
||||||
|
window.location.href = newUrl.toString();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Util.showMessage("error", `Failed to log in: ${res.msg}`);
|
Util.showMessage("error", `Failed to log in: ${res.msg}`);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
//oauth
|
// OAuth
|
||||||
const oAuthParams = Util.getOAuthGetParameters();
|
const oAuthParams = Util.getOAuthGetParameters();
|
||||||
if (oAuthParams !== null && oAuthParams.responseType != null && oAuthParams.responseType !== "") {
|
if (oAuthParams !== null && oAuthParams.responseType != null && oAuthParams.responseType !== "") {
|
||||||
values["type"] = oAuthParams.responseType
|
values["type"] = oAuthParams.responseType;
|
||||||
}else{
|
} else {
|
||||||
values["type"] = this.state.type;
|
values["type"] = this.state.type;
|
||||||
}
|
}
|
||||||
values["phonePrefix"] = this.getApplicationObj()?.organizationObj.phonePrefix;
|
values["phonePrefix"] = this.getApplicationObj()?.organizationObj.phonePrefix;
|
||||||
|
|
||||||
if (oAuthParams !== null){
|
if (oAuthParams !== null) {
|
||||||
values["samlRequest"] = oAuthParams.samlRequest;
|
values["samlRequest"] = oAuthParams.samlRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (values["samlRequest"] != null && values["samlRequest"] !== "") {
|
if (values["samlRequest"] != null && values["samlRequest"] !== "") {
|
||||||
values["type"] = "saml";
|
values["type"] = "saml";
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthBackend.login(values, oAuthParams)
|
AuthBackend.login(values, oAuthParams)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === 'ok') {
|
if (res.status === 'ok') {
|
||||||
@@ -319,7 +320,7 @@ class LoginPage extends React.Component {
|
|||||||
)
|
)
|
||||||
} else if (provider.category === "SAML") {
|
} else if (provider.category === "SAML") {
|
||||||
return (
|
return (
|
||||||
<a key={provider.displayName} onClick={this.getSamlUrl.bind(this, provider)}>
|
<a href="/#" key={provider.displayName} onClick={this.getSamlUrl.bind(this, provider)}>
|
||||||
<img width={width} height={width} src={Setting.getProviderLogoURL(provider)} alt={provider.displayName} style={{margin: margin}} />
|
<img width={width} height={width} src={Setting.getProviderLogoURL(provider)} alt={provider.displayName} style={{margin: margin}} />
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
@@ -475,7 +476,7 @@ class LoginPage extends React.Component {
|
|||||||
{i18next.t("login:Auto sign in")}
|
{i18next.t("login:Auto sign in")}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<a style={{float: "right"}} onClick={() => {
|
<a href="/#" style={{float: "right"}} onClick={() => {
|
||||||
Setting.goToForget(this, application);
|
Setting.goToForget(this, application);
|
||||||
}}>
|
}}>
|
||||||
{i18next.t("login:Forgot password?")}
|
{i18next.t("login:Forgot password?")}
|
||||||
@@ -554,7 +555,7 @@ class LoginPage extends React.Component {
|
|||||||
<span style={{float: "left"}}>
|
<span style={{float: "left"}}>
|
||||||
{
|
{
|
||||||
!application.enableCodeSignin ? null : (
|
!application.enableCodeSignin ? null : (
|
||||||
<a onClick={() => {
|
<a href="/#" onClick={() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
isCodeSignin: !this.state.isCodeSignin,
|
isCodeSignin: !this.state.isCodeSignin,
|
||||||
});
|
});
|
||||||
@@ -566,7 +567,7 @@ class LoginPage extends React.Component {
|
|||||||
</span>
|
</span>
|
||||||
<span style={{float: "right"}}>
|
<span style={{float: "right"}}>
|
||||||
{i18next.t("login:No account?")}
|
{i18next.t("login:No account?")}
|
||||||
<a onClick={() => {
|
<a href="/#" onClick={() => {
|
||||||
sessionStorage.setItem("loginURL", window.location.href)
|
sessionStorage.setItem("loginURL", window.location.href)
|
||||||
Setting.goToSignup(this, application);
|
Setting.goToSignup(this, application);
|
||||||
}}>
|
}}>
|
||||||
|
@@ -559,7 +559,7 @@ class SignupPage extends React.Component {
|
|||||||
{i18next.t("account:Sign Up")}
|
{i18next.t("account:Sign Up")}
|
||||||
</Button>
|
</Button>
|
||||||
{i18next.t("signup:Have account?")}
|
{i18next.t("signup:Have account?")}
|
||||||
<a onClick={() => {
|
<a href="/#" onClick={() => {
|
||||||
let linkInStorage = sessionStorage.getItem("loginURL")
|
let linkInStorage = sessionStorage.getItem("loginURL")
|
||||||
if(linkInStorage != null){
|
if(linkInStorage != null){
|
||||||
Setting.goToLink(linkInStorage)
|
Setting.goToLink(linkInStorage)
|
||||||
|
@@ -142,7 +142,7 @@ class OAuthWidget extends React.Component {
|
|||||||
</span>
|
</span>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={24 - this.props.labelSpan} >
|
<Col span={24 - this.props.labelSpan} >
|
||||||
<img style={{marginRight: '10px'}} width={30} height={30} src={avatarUrl} alt={name} />
|
<img style={{marginRight: '10px'}} width={30} height={30} src={avatarUrl} alt={name} referrerPolicy="no-referrer" />
|
||||||
<span style={{width: this.props.labelSpan === 3 ? '300px' : '130px', display: (Setting.isMobile()) ? 'inline' : "inline-block"}}>
|
<span style={{width: this.props.labelSpan === 3 ? '300px' : '130px', display: (Setting.isMobile()) ? 'inline' : "inline-block"}}>
|
||||||
{
|
{
|
||||||
linkedValue === "" ? (
|
linkedValue === "" ? (
|
||||||
|
Reference in New Issue
Block a user