Compare commits

...

8 Commits

Author SHA1 Message Date
05bfd3a3a3 feat: fix bug that custom SAML providers are removed by GetMaskedApplication() (#3165) 2024-09-05 20:08:56 +08:00
69aa3c8a8b feat: Revert "feat: add Casbin editor's checking in model editor" (#3167)
This reverts commit a1b010a406.
2024-09-03 21:59:06 +08:00
a1b010a406 feat: add Casbin editor's checking in model editor (#3166)
* feat: add model syntax linting and update dependencies

* refactor: move model linter logic to separate module
2024-09-03 21:32:45 +08:00
89e92cbd47 feat: when using basic auth to fetch access_token will return restful response to oidc client (#3164) 2024-09-03 08:05:29 +08:00
d4c8193357 feat: support reCAPTCHA v3 captcha provider (#3160)
* feat: support reCAPTCHA v3 captcha provider

* fix: modify the implementation of row component style in CaptchaModal.js
2024-09-02 22:15:03 +08:00
9b33800b4c feat: add email_verified, phone_number and phone_number_verified field for standard jwt token (#3156)
* feat: add email_verified, phone_number and phone_number_verified field for standard jwt token

* fix: fix linter err
2024-08-31 12:49:39 +08:00
ec98785172 feat: certEditPage will be redirected to 404 when name is changed (#3154) 2024-08-30 23:04:50 +08:00
45dd4cc344 feat: fix nonce not parsed issue in fastAutoSignin() (#3153)
* fix: fix nonce none passed when auto sign enabled

* fix: fix query error
2024-08-30 22:29:23 +08:00
9 changed files with 77 additions and 17 deletions

View File

@ -26,6 +26,10 @@ func GetCaptchaProvider(captchaType string) CaptchaProvider {
return NewDefaultCaptchaProvider()
case "reCAPTCHA":
return NewReCaptchaProvider()
case "reCAPTCHA v2":
return NewReCaptchaProvider()
case "reCAPTCHA v3":
return NewReCaptchaProvider()
case "Aliyun Captcha":
return NewAliyunCaptchaProvider()
case "hCaptcha":

View File

@ -531,7 +531,7 @@ func GetMaskedApplication(application *Application, userId string) *Application
providerItems := []*ProviderItem{}
for _, providerItem := range application.Providers {
if providerItem.Provider != nil && (providerItem.Provider.Category == "OAuth" || providerItem.Provider.Category == "Web3" || providerItem.Provider.Category == "Captcha") {
if providerItem.Provider != nil && (providerItem.Provider.Category == "OAuth" || providerItem.Provider.Category == "Web3" || providerItem.Provider.Category == "Captcha" || providerItem.Provider.Category == "SAML") {
providerItems = append(providerItems, providerItem)
}
}

View File

@ -18,11 +18,15 @@ import (
"fmt"
"strings"
"github.com/casdoor/casdoor/util"
"github.com/golang-jwt/jwt/v4"
)
type ClaimsStandard struct {
*UserShort
EmailVerified bool `json:"email_verified,omitempty"`
PhoneNumber string `json:"phone_number,omitempty"`
PhoneNumberVerified bool `json:"phone_number_verified,omitempty"`
Gender string `json:"gender,omitempty"`
TokenType string `json:"tokenType,omitempty"`
Nonce string `json:"nonce,omitempty"`
@ -43,12 +47,14 @@ func getStreetAddress(user *User) string {
func getStandardClaims(claims Claims) ClaimsStandard {
res := ClaimsStandard{
UserShort: getShortUser(claims.User),
EmailVerified: claims.User.EmailVerified,
TokenType: claims.TokenType,
Nonce: claims.Nonce,
Scope: claims.Scope,
RegisteredClaims: claims.RegisteredClaims,
}
res.Phone = ""
var scopes []string
if strings.Contains(claims.Scope, ",") {
@ -62,6 +68,15 @@ func getStandardClaims(claims Claims) ClaimsStandard {
res.Address = OIDCAddress{StreetAddress: getStreetAddress(claims.User)}
} else if scope == "profile" {
res.Gender = claims.User.Gender
} else if scope == "phone" && claims.User.Phone != "" {
res.PhoneNumberVerified = true
phoneNumber, ok := util.GetE164Number(claims.User.Phone, claims.User.CountryCode)
if !ok {
res.PhoneNumberVerified = false
} else {
res.PhoneNumber = phoneNumber
}
}
}

View File

@ -16,6 +16,7 @@ package routers
import (
"fmt"
"strings"
"github.com/beego/beego/context"
"github.com/casdoor/casdoor/object"
@ -23,6 +24,10 @@ import (
)
func AutoSigninFilter(ctx *context.Context) {
urlPath := ctx.Request.URL.Path
if strings.HasPrefix(urlPath, "/api/login/oauth/access_token") {
return
}
//if getSessionUser(ctx) != "" {
// return
//}

View File

@ -58,7 +58,7 @@ func fastAutoSignin(ctx *context.Context) (string, error) {
redirectUri := ctx.Input.Query("redirect_uri")
scope := ctx.Input.Query("scope")
state := ctx.Input.Query("state")
nonce := ""
nonce := ctx.Input.Query("nonce")
codeChallenge := ctx.Input.Query("code_challenge")
if clientId == "" || responseType != "code" || redirectUri == "" {
return "", nil

View File

@ -288,14 +288,14 @@ class CertEditPage extends React.Component {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
certName: this.state.cert.name,
});
}, () => {
if (exitAfterSave) {
this.props.history.push("/certs");
} else {
this.props.history.push(`/certs/${this.state.cert.owner}/${this.state.cert.name}`);
this.getCert();
}
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateCertField("name", this.state.certName);

View File

@ -287,6 +287,14 @@ export const OtherProviderInfo = {
logo: `${StaticBaseUrl}/img/social_recaptcha.png`,
url: "https://www.google.com/recaptcha",
},
"reCAPTCHA v2": {
logo: `${StaticBaseUrl}/img/social_recaptcha.png`,
url: "https://www.google.com/recaptcha",
},
"reCAPTCHA v3": {
logo: `${StaticBaseUrl}/img/social_recaptcha.png`,
url: "https://www.google.com/recaptcha",
},
"hCaptcha": {
logo: `${StaticBaseUrl}/img/social_hcaptcha.png`,
url: "https://www.hcaptcha.com",
@ -1088,7 +1096,8 @@ export function getProviderTypeOptions(category) {
} else if (category === "Captcha") {
return ([
{id: "Default", name: "Default"},
{id: "reCAPTCHA", name: "reCAPTCHA"},
{id: "reCAPTCHA v2", name: "reCAPTCHA v2"},
{id: "reCAPTCHA v3", name: "reCAPTCHA v3"},
{id: "hCaptcha", name: "hCaptcha"},
{id: "Aliyun Captcha", name: "Aliyun Captcha"},
{id: "GEETEST", name: "GEETEST"},

View File

@ -27,7 +27,8 @@ export const CaptchaWidget = (props) => {
useEffect(() => {
switch (captchaType) {
case "reCAPTCHA": {
case "reCAPTCHA" :
case "reCAPTCHA v2": {
const reTimer = setInterval(() => {
if (!window.grecaptcha) {
loadScript("https://recaptcha.net/recaptcha/api.js");
@ -42,6 +43,32 @@ export const CaptchaWidget = (props) => {
}, 300);
break;
}
case "reCAPTCHA v3": {
const reTimer = setInterval(() => {
if (!window.grecaptcha) {
loadScript(`https://recaptcha.net/recaptcha/api.js?render=${siteKey}`);
}
if (window.grecaptcha && window.grecaptcha.render) {
const clientId = window.grecaptcha.render("captcha", {
"sitekey": siteKey,
"badge": "inline",
"size": "invisible",
"callback": onChange,
"error-callback": function() {
const logoWidth = `${document.getElementById("captcha").offsetWidth + 40}px`;
document.getElementsByClassName("grecaptcha-logo")[0].firstChild.style.width = logoWidth;
document.getElementsByClassName("grecaptcha-badge")[0].style.width = logoWidth;
},
});
window.grecaptcha.ready(function() {
window.grecaptcha.execute(clientId, {action: "submit"});
});
clearInterval(reTimer);
}
}, 300);
break;
}
case "hCaptcha": {
const hTimer = setInterval(() => {
if (!window.hcaptcha) {

View File

@ -115,7 +115,7 @@ export const CaptchaModal = (props) => {
} else {
return (
<Col>
<Row>
<Row justify={"center"}>
<CaptchaWidget
captchaType={captchaType}
subType={subType}